rsmart_toolbox 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +10 -0
- data/README.md +10 -6
- data/bin/transform_CSV_to_HR_XML.rb +292 -0
- data/lib/rsmart_toolbox.rb +1 -1
- data/lib/rsmart_toolbox/etl.rb +8 -8
- data/lib/rsmart_toolbox/etl/grm.rb +25 -25
- data/lib/rsmart_toolbox/version.rb +2 -2
- data/rsmart_toolbox.gemspec +7 -3
- data/spec/rsmart_toolbox/etl/grm_spec.rb +3 -3
- data/spec/rsmart_toolbox/etl_spec.rb +2 -2
- data/spec/rsmart_toolbox_spec.rb +3 -3
- data/spec/spec_helper.rb +7 -4
- metadata +36 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8afbe2fe492b04562581bac6aba6f7c9cf718f1
|
4
|
+
data.tar.gz: 1e0a31972f97f9ceb0f5dd9de8e376e26e2970e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a21f4f09399e8396ab270134886d369937630d52d7ae9898a31c62449c6bf05ff105a0a62b3fa16fb3a1075cbe7b1e45c08bd55ed9c6d6e06298b5065c13ce27
|
7
|
+
data.tar.gz: a7e576398df5aced8c77532f2adfcb4b33b3d35acdd940039fc40400be0e3e77fd361f8c297d8a022af366b13208d32464e270f5997bc6309e8222cab3a932af
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# rsmart_toolbox
|
2
2
|
|
3
|
-
|
3
|
+
[![Build Status](https://travis-ci.org/rSmart/rsmart_toolbox.svg?branch=master)](https://travis-ci.org/rSmart/rsmart_toolbox)
|
4
|
+
[![Test Coverage](https://codeclimate.com/github/rSmart/rsmart_toolbox/badges/coverage.svg)](https://codeclimate.com/github/rSmart/rsmart_toolbox)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/rsmart_toolbox.svg)](http://badge.fury.io/rb/rsmart_toolbox)
|
6
|
+
|
7
|
+
Client library and command-line tools to help interact with rSmart's cloud APIs.
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -24,8 +28,8 @@ TODO: Write usage instructions here
|
|
24
28
|
|
25
29
|
## Contributing
|
26
30
|
|
27
|
-
1. Fork it
|
28
|
-
2. Create your feature branch
|
29
|
-
3. Commit your changes
|
30
|
-
4. Push to the branch
|
31
|
+
1. Fork it: https://github.com/rSmart/rsmart_toolbox/fork
|
32
|
+
2. Create your feature branch: `git checkout -b my-new-feature`
|
33
|
+
3. Commit your changes: `git commit -am 'Add some feature'`
|
34
|
+
4. Push to the branch: `git push origin my-new-feature`
|
31
35
|
5. Create a new Pull Request
|
@@ -0,0 +1,292 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
require 'builder'
|
7
|
+
require 'csv'
|
8
|
+
require 'net/http'
|
9
|
+
require 'nokogiri'
|
10
|
+
require 'optparse'
|
11
|
+
require 'ostruct'
|
12
|
+
require 'tempfile'
|
13
|
+
require 'time'
|
14
|
+
require 'rsmart_toolbox/etl/grm'
|
15
|
+
|
16
|
+
ETL = Rsmart::ETL
|
17
|
+
GRM = Rsmart::ETL::GRM
|
18
|
+
TextParseError = Rsmart::ETL::TextParseError
|
19
|
+
|
20
|
+
def self.parse_csv_command_line_options(
|
21
|
+
executable, args, opt={ csv_options: { headers: :first_row,
|
22
|
+
header_converters: :symbol,
|
23
|
+
skip_blanks: true,
|
24
|
+
col_sep: ",", # comma by default
|
25
|
+
quote_char: '"', # double quote by default
|
26
|
+
}
|
27
|
+
} )
|
28
|
+
optparse = OptionParser.new do |opts|
|
29
|
+
opts.banner = "Usage: #{executable} [options] csv_file"
|
30
|
+
opts.on( '-o [xml_file_output]' ,'--output [xml_file_output]', 'The file in which the the XML data will be writen (defaults to <csv_file>.xml)') do |f|
|
31
|
+
opt[:xml_filename] = f
|
32
|
+
end
|
33
|
+
opts.on( '-s [separator_character]' ,'--separator [separator_character]', 'The character that separates each column of the CSV file.') do |s|
|
34
|
+
opt[:col_sep] = s
|
35
|
+
end
|
36
|
+
opts.on( '-q [quote_character]' ,'--quote [quote_character]', 'The character used to quote fields.') do |q|
|
37
|
+
opt[:quote_char] = q
|
38
|
+
end
|
39
|
+
opts.on('-e [email_recipients]', '--email [email_recipients]', 'Email recipient list that will receive job report status.') do |e|
|
40
|
+
opt[:email_recipients] = e
|
41
|
+
end
|
42
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
43
|
+
puts opts
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
|
47
|
+
opt[:csv_filename] = args[0] unless opt[:csv_filename]
|
48
|
+
if opt[:csv_filename].nil? || opt[:csv_filename].empty?
|
49
|
+
puts opts
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
optparse.parse!
|
54
|
+
|
55
|
+
# construct a sensible default ouptput filename
|
56
|
+
unless opt[:xml_filename]
|
57
|
+
file_extension = File.extname opt[:csv_filename]
|
58
|
+
dir_name = File.dirname opt[:csv_filename]
|
59
|
+
base_name = File.basename opt[:csv_filename], file_extension
|
60
|
+
opt[:xml_filename] = "#{dir_name}/#{base_name}.xml"
|
61
|
+
end
|
62
|
+
|
63
|
+
unless opt[:email_recipients]
|
64
|
+
opt[:email_recipients] = "no-reply@rsmart.com"
|
65
|
+
end
|
66
|
+
|
67
|
+
return opt
|
68
|
+
end
|
69
|
+
|
70
|
+
opt = parse_csv_command_line_options (File.basename $0), ARGF.argv
|
71
|
+
|
72
|
+
CSV.open(opt[:csv_filename], opt[:csv_options]) do |csv|
|
73
|
+
record_count = csv.readlines.count
|
74
|
+
csv.rewind # go back to first row
|
75
|
+
|
76
|
+
File.open(opt[:xml_filename], 'w') do |xml_file|
|
77
|
+
xml = Builder::XmlMarkup.new target: xml_file, indent: 2
|
78
|
+
xml.instruct! :xml, encoding: "UTF-8"
|
79
|
+
xml.hrmanifest "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
80
|
+
"xsi:schemaLocation" => "https://github.com/rSmart/ce-tech-docs/tree/master/v1_0 https://raw.github.com/rSmart/ce-tech-docs/master/v1_0/hrmanifest.xsd",
|
81
|
+
xmlns: "https://github.com/rSmart/ce-tech-docs/tree/master/v1_0",
|
82
|
+
schemaVersion: "1.0",
|
83
|
+
statusEmailRecipient: opt[:email_recipients],
|
84
|
+
reportDate: Time.now.iso8601,
|
85
|
+
recordCount: record_count do |hrmanifest|
|
86
|
+
hrmanifest.records do |record|
|
87
|
+
csv.find_all do |row| # begin processing csv rows
|
88
|
+
begin
|
89
|
+
xml.record principalId: GRM.parse_principal_id( row[:prncpl_id] ),
|
90
|
+
principalName: GRM.parse_principal_name( row[:prncpl_nm] ) do |record|
|
91
|
+
record.affiliations do |affiliations|
|
92
|
+
aff = {}
|
93
|
+
afltn_typ_cd = ETL.parse_string row[:afltn_typ_cd], length: 40
|
94
|
+
campus = ETL.parse_string row[:campus_cd], length: 2
|
95
|
+
aff[:affiliationType] = afltn_typ_cd unless afltn_typ_cd.empty?
|
96
|
+
aff[:campus] = campus unless campus.empty?
|
97
|
+
aff[:default] = true
|
98
|
+
aff[:active] = true
|
99
|
+
|
100
|
+
affiliations.affiliation aff do |affiliation|
|
101
|
+
emp = {}
|
102
|
+
emp_stat_cd = GRM.parse_emp_stat_cd row[:emp_stat_cd]
|
103
|
+
emp_typ_cd = GRM.parse_emp_typ_cd row[:emp_typ_cd]
|
104
|
+
base_slry_amt = ETL.parse_float row[:base_slry_amt], length: 15
|
105
|
+
prmry_dept_cd = ETL.parse_string row[:prmry_dept_cd], length: 40
|
106
|
+
emp_id = ETL.parse_string row[:emp_id], length: 40
|
107
|
+
emp[:employeeStatus] = emp_stat_cd unless emp_stat_cd.empty?
|
108
|
+
emp[:employeeType] = emp_typ_cd unless emp_typ_cd.empty?
|
109
|
+
emp[:baseSalaryAmount] = base_slry_amt unless base_slry_amt.nil?
|
110
|
+
emp[:primaryDepartment] = prmry_dept_cd unless prmry_dept_cd.empty?
|
111
|
+
emp[:employeeId] = emp_id unless emp_id.empty?
|
112
|
+
emp[:primaryEmployment] = true
|
113
|
+
|
114
|
+
affiliation.employment emp
|
115
|
+
end
|
116
|
+
end # affiliations
|
117
|
+
record.names do |names|
|
118
|
+
nm = {}
|
119
|
+
nm_typ_cd = GRM.parse_name_code row[:nm_typ_cd]
|
120
|
+
prefix_nm = GRM.parse_prefix row[:prefix_nm]
|
121
|
+
first_nm = ETL.parse_string row[:first_nm], length: 40
|
122
|
+
middle_nm = ETL.parse_string row[:middle_nm], length: 40
|
123
|
+
last_nm = ETL.parse_string row[:last_nm], length: 80
|
124
|
+
suffix_nm = GRM.parse_suffix row[:suffix_nm]
|
125
|
+
title_nm = ETL.parse_string row[:title_nm], length: 20
|
126
|
+
nm[:nameCode] = nm_typ_cd unless nm_typ_cd.empty?
|
127
|
+
nm[:prefix] = prefix_nm unless prefix_nm.empty?
|
128
|
+
nm[:firstName] = first_nm unless first_nm.empty?
|
129
|
+
nm[:middleName] = middle_nm unless middle_nm.empty?
|
130
|
+
nm[:lastName] = last_nm unless last_nm.empty?
|
131
|
+
nm[:suffix] = suffix_nm unless suffix_nm.empty?
|
132
|
+
nm[:title] = title_nm unless title_nm.empty?
|
133
|
+
nm[:default] = true
|
134
|
+
nm[:active] = true
|
135
|
+
|
136
|
+
names.name nm
|
137
|
+
end # names
|
138
|
+
|
139
|
+
ph = {}
|
140
|
+
phone_typ_cd = GRM.parse_phone_type row[:phone_typ_cd]
|
141
|
+
phone_nbr = GRM.parse_phone_number row[:phone_nbr]
|
142
|
+
phone_extn_nbr = ETL.parse_string row[:phone_extn_nbr], length: 8
|
143
|
+
postal_cntry_cd = ETL.parse_string row[:postal_cntry_cd], length: 2
|
144
|
+
ph[:phoneType] = phone_typ_cd unless phone_typ_cd.empty?
|
145
|
+
ph[:phoneNumber] = phone_nbr unless phone_nbr.empty?
|
146
|
+
ph[:extension] = phone_extn_nbr unless phone_extn_nbr.empty?
|
147
|
+
ph[:country] = postal_cntry_cd unless postal_cntry_cd.empty?
|
148
|
+
ph[:default] = true
|
149
|
+
ph[:active] = true
|
150
|
+
|
151
|
+
unless phone_typ_cd.empty? || phone_nbr.empty?
|
152
|
+
record.phones do |phones|
|
153
|
+
phones.phone ph
|
154
|
+
end # phones
|
155
|
+
end
|
156
|
+
|
157
|
+
em = {}
|
158
|
+
email_typ_cd = GRM.parse_email_type( row[:email_typ_cd] )
|
159
|
+
email_addr = GRM.parse_email_address( row[:email_addr] )
|
160
|
+
em[:emailType] = email_typ_cd unless email_typ_cd.empty?
|
161
|
+
em[:emailAddress] = email_addr unless email_addr.empty?
|
162
|
+
em[:default] = true
|
163
|
+
em[:active] = true
|
164
|
+
|
165
|
+
unless email_typ_cd.empty? || email_addr.empty?
|
166
|
+
record.emails do |emails|
|
167
|
+
emails.email em unless email_addr.empty?
|
168
|
+
end # emails
|
169
|
+
end
|
170
|
+
|
171
|
+
ea = {}
|
172
|
+
visa_type = ETL.parse_string( row[:visa_type], length: 30 )
|
173
|
+
county = ETL.parse_string( row[:county], length: 30 )
|
174
|
+
age_by_fiscal_year = ETL.parse_integer( row[:age_by_fiscal_year], length: 3 )
|
175
|
+
race = ETL.parse_string( row[:race], length: 30 )
|
176
|
+
education_level = ETL.parse_string( row[:education_level], length: 30 )
|
177
|
+
degree = GRM.parse_degree( row[:degree] )
|
178
|
+
major = ETL.parse_string( row[:major], length: 30 )
|
179
|
+
is_handicapped = ETL.parse_boolean row[:is_handicapped]
|
180
|
+
handicap_type = ETL.parse_string( row[:handicap_type], length: 30 )
|
181
|
+
is_veteran = ETL.parse_boolean( row[:is_veteran] )
|
182
|
+
veteran_type = ETL.parse_string( row[:veteran_type], length: 30 )
|
183
|
+
has_visa = ETL.parse_boolean( row[:has_visa] )
|
184
|
+
visa_code = ETL.parse_string( row[:visa_code], length: 20 )
|
185
|
+
visa_renewal_date = ETL.parse_string( row[:visa_renewal_date], length: 19 )
|
186
|
+
office_location = ETL.parse_string( row[:office_location], length: 30 )
|
187
|
+
secondry_office_location = ETL.parse_string( row[:secondry_office_location], length: 30 )
|
188
|
+
school = ETL.parse_string( row[:school], length: 50 )
|
189
|
+
year_graduated = GRM.parse_year( row[:year_graduated] )
|
190
|
+
directory_department = ETL.parse_string( row[:directory_department], length: 30 )
|
191
|
+
directory_title = ETL.parse_string( row[:directory_title], length: 50 )
|
192
|
+
primary_title = ETL.parse_string( row[:primary_title], length: 51 )
|
193
|
+
vacation_accural = ETL.parse_boolean( row[:vacation_accural] )
|
194
|
+
is_on_sabbatical = ETL.parse_boolean( row[:is_on_sabbatical] )
|
195
|
+
id_provided = ETL.parse_string( row[:id_provided], length: 30 )
|
196
|
+
id_verified = ETL.parse_string( row[:id_verified], length: 30 )
|
197
|
+
citizenship_type_code = GRM.parse_citizenship_type( row[:citizenship_type_code] )
|
198
|
+
multi_campus_principal_id = ETL.parse_string( row[:multi_campus_principal_id], length: 40 )
|
199
|
+
multi_campus_principal_name = ETL.parse_string( row[:multi_campus_principal_name], length: 100 )
|
200
|
+
salary_anniversary_date = ETL.parse_string( row[:salary_anniversary_date], length: 10 )
|
201
|
+
ea[:visaType] = visa_type unless visa_type.empty?
|
202
|
+
ea[:county] = county unless county.empty?
|
203
|
+
ea[:ageByFiscalYear] = age_by_fiscal_year unless age_by_fiscal_year.nil?
|
204
|
+
ea[:race] = race unless race.empty?
|
205
|
+
ea[:educationLevel] = education_level unless education_level.empty?
|
206
|
+
ea[:degree] = degree unless degree.empty?
|
207
|
+
ea[:major] = major unless major.empty?
|
208
|
+
ea[:handicapped] = is_handicapped unless is_handicapped.nil?
|
209
|
+
ea[:handicapType] = handicap_type unless handicap_type.empty?
|
210
|
+
ea[:veteran] = is_veteran unless is_veteran.nil?
|
211
|
+
ea[:veteranType] = veteran_type unless veteran_type.empty?
|
212
|
+
ea[:visa] = has_visa unless has_visa.nil?
|
213
|
+
ea[:visaCode] = visa_code unless visa_code.empty?
|
214
|
+
ea[:visaRenewalDate] = visa_renewal_date unless visa_renewal_date.empty?
|
215
|
+
ea[:officeLocation] = office_location unless office_location.empty?
|
216
|
+
ea[:secondaryOfficeLocation] = secondry_office_location unless secondry_office_location.empty?
|
217
|
+
ea[:school] = school unless school.empty?
|
218
|
+
ea[:yearGraduated] = year_graduated unless year_graduated.empty?
|
219
|
+
ea[:directoryDepartment] = directory_department unless directory_department.empty?
|
220
|
+
ea[:directoryTitle] = directory_title unless directory_title.empty?
|
221
|
+
ea[:primaryTitle] = primary_title unless primary_title.empty?
|
222
|
+
ea[:vacationAccrual] = vacation_accural unless vacation_accural.nil?
|
223
|
+
ea[:onSabbatical] = is_on_sabbatical unless is_on_sabbatical.nil?
|
224
|
+
ea[:idProvided] = id_provided unless id_provided.empty?
|
225
|
+
ea[:idVerified] = id_verified unless id_verified.empty?
|
226
|
+
ea[:citizenshipType] = citizenship_type_code unless citizenship_type_code.empty?
|
227
|
+
ea[:multiCampusPrincipalId] = multi_campus_principal_id unless multi_campus_principal_id.empty?
|
228
|
+
ea[:multiCampusPrincipalName] = multi_campus_principal_name unless multi_campus_principal_name.empty?
|
229
|
+
ea[:salaryAnniversaryDate] = salary_anniversary_date unless salary_anniversary_date.empty?
|
230
|
+
|
231
|
+
record.kcExtendedAttributes ea
|
232
|
+
|
233
|
+
ap = {}
|
234
|
+
unit_number = ETL.parse_string( row[:unit_number], length: 8 )
|
235
|
+
appointment_type_code = ETL.parse_string( row[:appointment_type_code], length: 3 )
|
236
|
+
job_code = ETL.parse_string( row[:job_code], length: 6 )
|
237
|
+
salary = ETL.parse_float( row[:salary], length: 15 )
|
238
|
+
appointment_start_date = ETL.parse_string( row[:appointment_start_date] )
|
239
|
+
appointment_end_date = ETL.parse_string( row[:appointment_end_date] )
|
240
|
+
job_title = ETL.parse_string( row[:job_title], length: 50 )
|
241
|
+
prefered_job_title = ETL.parse_string( row[:prefered_job_title], length: 51 )
|
242
|
+
ap[:unitNumber] = unit_number unless unit_number.empty?
|
243
|
+
ap[:appointmentType] = appointment_type_code unless appointment_type_code.empty?
|
244
|
+
ap[:jobCode] = job_code unless job_code.empty?
|
245
|
+
ap[:salary] = salary unless salary.nil?
|
246
|
+
ap[:startDate] = appointment_start_date unless appointment_start_date.empty?
|
247
|
+
ap[:endDate] = appointment_end_date unless appointment_end_date.empty?
|
248
|
+
ap[:jobTitle] = job_title unless job_title.empty?
|
249
|
+
ap[:preferedJobTitle] = prefered_job_title unless prefered_job_title.empty?
|
250
|
+
|
251
|
+
unless unit_number.empty? || job_code.empty?
|
252
|
+
record.appointments do |appointments|
|
253
|
+
appointments.appointment ap
|
254
|
+
end # appointments
|
255
|
+
end
|
256
|
+
end # record
|
257
|
+
|
258
|
+
rescue TextParseError => e
|
259
|
+
puts e.message
|
260
|
+
end
|
261
|
+
end # row
|
262
|
+
end # record
|
263
|
+
end # hrmanifest
|
264
|
+
end # file
|
265
|
+
end # csv
|
266
|
+
puts "\nXML file written to #{opt[:xml_filename]}\n\n"
|
267
|
+
|
268
|
+
# validate the resulting XML file against the official XSD schema
|
269
|
+
uri = URI 'https://raw.githubusercontent.com/rSmart/ce-tech-docs/master/hrmanifest.xsd'
|
270
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
271
|
+
Tempfile.open "hrmanifest.xsd" do |file|
|
272
|
+
request = Net::HTTP::Get.new uri
|
273
|
+
http.request request do |response|
|
274
|
+
response.read_body do |segment|
|
275
|
+
file.write(segment)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
file.rewind
|
279
|
+
xsd = Nokogiri::XML::Schema file
|
280
|
+
doc = Nokogiri::XML File.read opt[:xml_filename]
|
281
|
+
xml_errors = xsd.validate doc
|
282
|
+
if xml_errors.empty?
|
283
|
+
puts "Congratulations! The XML file passes XSD schema validation! w00t!"
|
284
|
+
else
|
285
|
+
puts "The XML file does NOT pass XSD schema validation!:"
|
286
|
+
xml_errors.each do |error|
|
287
|
+
puts error.message
|
288
|
+
end
|
289
|
+
exit 1
|
290
|
+
end
|
291
|
+
end # file
|
292
|
+
end
|
data/lib/rsmart_toolbox.rb
CHANGED
data/lib/rsmart_toolbox/etl.rb
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
require "rsmart_toolbox"
|
18
18
|
|
19
|
-
module
|
19
|
+
module Rsmart::ETL
|
20
20
|
|
21
21
|
class TextParseError < StandardError
|
22
22
|
end
|
@@ -76,7 +76,7 @@ module RsmartToolbox::ETL
|
|
76
76
|
if b.empty?
|
77
77
|
return nil
|
78
78
|
end
|
79
|
-
raise
|
79
|
+
raise Rsmart::ETL::error TextParseError.new "invalid value for Boolean: '#{str}'"
|
80
80
|
end
|
81
81
|
|
82
82
|
# Simply here to help ensure we consistently apply the same encoding options.
|
@@ -116,7 +116,7 @@ module RsmartToolbox::ETL
|
|
116
116
|
opt[:strict] = true if opt[:strict].nil?
|
117
117
|
retval = encode str.to_s.strip
|
118
118
|
if opt[:required] && retval.empty?
|
119
|
-
raise
|
119
|
+
raise Rsmart::ETL::error TextParseError.new "Required data element '#{opt[:name]}' not found: '#{str}'"
|
120
120
|
end
|
121
121
|
if opt[:default] && retval.empty?
|
122
122
|
retval = opt[:default]
|
@@ -124,12 +124,12 @@ module RsmartToolbox::ETL
|
|
124
124
|
if opt[:length] && retval.length > opt[:length].to_i
|
125
125
|
detail = "#{opt[:name]}.length > #{opt[:length]}: '#{str}'-->'#{str[0..(opt[:length] - 1)]}'"
|
126
126
|
if opt[:strict]
|
127
|
-
raise
|
127
|
+
raise Rsmart::ETL::error TextParseError.new "Data exceeds maximum field length: #{detail}"
|
128
128
|
end
|
129
|
-
|
129
|
+
Rsmart::ETL::warning "Data will be truncated: #{detail}"
|
130
130
|
end
|
131
131
|
if opt[:valid_values] && ! valid_value(retval, opt[:valid_values], opt)
|
132
|
-
raise
|
132
|
+
raise Rsmart::ETL::error TextParseError.new "Illegal #{opt[:name]}: value '#{str}' not found in: #{opt[:valid_values]}"
|
133
133
|
end
|
134
134
|
return escape_single_quotes retval
|
135
135
|
end
|
@@ -189,8 +189,8 @@ module RsmartToolbox::ETL
|
|
189
189
|
def self.parse_actv_ind!(row, insert_str, values_str, opt={})
|
190
190
|
# `ACTV_IND` varchar(1) COLLATE utf8_bin DEFAULT 'Y',
|
191
191
|
opt[:name] = "actv_ind" if opt[:name].nil?
|
192
|
-
actv_ind =
|
193
|
-
|
192
|
+
actv_ind = Rsmart::ETL::parse_actv_ind row[ to_symbol( opt[:name] ) ]
|
193
|
+
Rsmart::ETL::mutate_sql_stmt! insert_str, opt[:name], values_str, actv_ind
|
194
194
|
end
|
195
195
|
|
196
196
|
# Parse common command line options for CSV --> SQL transformations.
|
@@ -16,28 +16,28 @@
|
|
16
16
|
|
17
17
|
require "rsmart_toolbox/etl"
|
18
18
|
|
19
|
-
module
|
19
|
+
module Rsmart::ETL::GRM
|
20
20
|
|
21
21
|
def self.parse_rolodex_id!(row, insert_str, values_str, opt={})
|
22
22
|
# `ROLODEX_ID` decimal(6,0) NOT NULL DEFAULT '0',
|
23
23
|
opt[:name] = "ROLODEX_ID" if opt[:name].nil?
|
24
24
|
opt[:required] = true if opt[:required].nil?
|
25
25
|
opt[:length] = 6 if opt[:length].nil?
|
26
|
-
|
26
|
+
Rsmart::ETL::parse_integer! row, insert_str, values_str, opt
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.parse_country_code!(row, insert_str, values_str, opt={})
|
30
30
|
# `COUNTRY_CODE` char(3) COLLATE utf8_bin DEFAULT NULL,
|
31
31
|
opt[:name] = "COUNTRY_CODE" if opt[:name].nil?
|
32
32
|
opt[:length] = 3 if opt[:length].nil?
|
33
|
-
|
33
|
+
Rsmart::ETL::parse_string! row, insert_str, values_str, opt
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.parse_state!(row, insert_str, values_str, opt={})
|
37
37
|
# `STATE` varchar(30) COLLATE utf8_bin DEFAULT NULL,
|
38
38
|
opt[:name] = "STATE" if opt[:name].nil?
|
39
39
|
opt[:length] = 30 if opt[:length].nil?
|
40
|
-
|
40
|
+
Rsmart::ETL::parse_string! row, insert_str, values_str, opt
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.parse_sponsor_code!(row, insert_str, values_str, opt={})
|
@@ -45,14 +45,14 @@ module RsmartToolbox::ETL::GRM
|
|
45
45
|
opt[:name] = "SPONSOR_CODE" if opt[:name].nil?
|
46
46
|
opt[:required] = true if opt[:required].nil?
|
47
47
|
opt[:length] = 6 if opt[:length].nil?
|
48
|
-
|
48
|
+
Rsmart::ETL::parse_string! row, insert_str, values_str, opt
|
49
49
|
end
|
50
50
|
|
51
51
|
def self.parse_postal_code!(row, insert_str, values_str, opt={})
|
52
52
|
# `POSTAL_CODE` varchar(15) COLLATE utf8_bin DEFAULT NULL,
|
53
53
|
opt[:name] = "POSTAL_CODE" if opt[:name].nil?
|
54
54
|
opt[:length] = 15 if opt[:length].nil?
|
55
|
-
|
55
|
+
Rsmart::ETL::parse_string! row, insert_str, values_str, opt
|
56
56
|
end
|
57
57
|
|
58
58
|
def self.parse_owned_by_unit!(row, insert_str, values_str, opt={})
|
@@ -60,7 +60,7 @@ module RsmartToolbox::ETL::GRM
|
|
60
60
|
opt[:name] = "OWNED_BY_UNIT" if opt[:name].nil?
|
61
61
|
opt[:required] = true if opt[:required].nil?
|
62
62
|
opt[:length] = 8 if opt[:length].nil?
|
63
|
-
|
63
|
+
Rsmart::ETL::parse_string! row, insert_str, values_str, opt
|
64
64
|
end
|
65
65
|
|
66
66
|
def self.parse_email_address(str, opt={})
|
@@ -68,14 +68,14 @@ module RsmartToolbox::ETL::GRM
|
|
68
68
|
opt[:name] = "EMAIL_ADDRESS" if opt[:name].nil?
|
69
69
|
opt[:length] = 60 if opt[:length].nil?
|
70
70
|
opt[:valid_values] = /^(([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?))?$/ if opt[:valid_values].nil?
|
71
|
-
return
|
71
|
+
return Rsmart::ETL::parse_string str, opt
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.parse_email_address!(row, insert_str, values_str, opt={})
|
75
75
|
# `EMAIL_ADDRESS` varchar(60) COLLATE utf8_bin DEFAULT NULL,
|
76
76
|
opt[:name] = "EMAIL_ADDRESS" if opt[:name].nil?
|
77
|
-
email_address = parse_email_address row[
|
78
|
-
|
77
|
+
email_address = parse_email_address row[ Rsmart::ETL::to_symbol( opt[:name] ) ]
|
78
|
+
Rsmart::ETL::mutate_sql_stmt! insert_str, opt[:name], values_str, email_address
|
79
79
|
end
|
80
80
|
|
81
81
|
def self.parse_principal_id(str, opt={})
|
@@ -83,7 +83,7 @@ module RsmartToolbox::ETL::GRM
|
|
83
83
|
opt[:name] = "PRNCPL_ID" if opt[:name].nil?
|
84
84
|
opt[:required] = true if opt[:required].nil?
|
85
85
|
opt[:length] = 40 if opt[:length].nil?
|
86
|
-
|
86
|
+
Rsmart::ETL::parse_string str, opt
|
87
87
|
end
|
88
88
|
|
89
89
|
def self.parse_principal_name(str, opt={})
|
@@ -91,9 +91,9 @@ module RsmartToolbox::ETL::GRM
|
|
91
91
|
opt[:name] = "PRNCPL_NM" if opt[:name].nil?
|
92
92
|
opt[:length] = 100 if opt[:length].nil?
|
93
93
|
opt[:required] = true if opt[:required].nil?
|
94
|
-
prncpl_nm =
|
94
|
+
prncpl_nm = Rsmart::ETL::parse_string str, opt
|
95
95
|
unless prncpl_nm =~ /^([a-z0-9\@\.\_\-]+)$/
|
96
|
-
raise
|
96
|
+
raise Rsmart::ETL::error TextParseError.new "Illegal prncpl_nm found: '#{prncpl_nm}'"
|
97
97
|
end
|
98
98
|
return prncpl_nm
|
99
99
|
end
|
@@ -102,14 +102,14 @@ module RsmartToolbox::ETL::GRM
|
|
102
102
|
# `EMP_STAT_CD` varchar(40) COLLATE utf8_bin DEFAULT NULL,
|
103
103
|
opt[:name] = "EMP_STAT_CD" if opt[:name].nil?
|
104
104
|
opt[:valid_values] = /^(A|D|L|N|P|R|S|T)$/i if opt[:valid_values].nil?
|
105
|
-
return
|
105
|
+
return Rsmart::ETL::parse_flag str, opt
|
106
106
|
end
|
107
107
|
|
108
108
|
def self.parse_emp_typ_cd(str, opt={})
|
109
109
|
# `EMP_TYP_CD` varchar(40) COLLATE utf8_bin DEFAULT NULL,
|
110
110
|
opt[:name] = "EMP_TYP_CD" if opt[:name].nil?
|
111
111
|
opt[:valid_values] = /^(N|O|P)$/i if opt[:valid_values].nil?
|
112
|
-
return
|
112
|
+
return Rsmart::ETL::parse_flag str, opt
|
113
113
|
end
|
114
114
|
|
115
115
|
def self.parse_address_type_code(str, opt={})
|
@@ -117,14 +117,14 @@ module RsmartToolbox::ETL::GRM
|
|
117
117
|
opt[:name] = "TODO_address_type_code" if opt[:name].nil?
|
118
118
|
opt[:length] = 3 if opt[:length].nil?
|
119
119
|
opt[:valid_values] = /^(HM|OTH|WRK)$/i if opt[:valid_values].nil?
|
120
|
-
return
|
120
|
+
return Rsmart::ETL::parse_flag str, opt
|
121
121
|
end
|
122
122
|
|
123
123
|
def self.parse_name_code(str, opt={})
|
124
124
|
opt[:name] = "NM_TYP_CD" if opt[:name].nil?
|
125
125
|
opt[:length] = 4 if opt[:length].nil?
|
126
126
|
opt[:valid_values] = /^(OTH|PRFR|PRM)$/i if opt[:valid_values].nil?
|
127
|
-
return
|
127
|
+
return Rsmart::ETL::parse_flag str, opt
|
128
128
|
end
|
129
129
|
|
130
130
|
def self.parse_prefix(str, opt={})
|
@@ -132,7 +132,7 @@ module RsmartToolbox::ETL::GRM
|
|
132
132
|
opt[:length] = 3 if opt[:length].nil?
|
133
133
|
opt[:valid_values] = /^(Ms|Mrs|Mr|Dr)?$/ if opt[:valid_values].nil?
|
134
134
|
opt[:upcase] = false if opt[:upcase].nil?
|
135
|
-
return
|
135
|
+
return Rsmart::ETL::parse_flag str, opt
|
136
136
|
end
|
137
137
|
|
138
138
|
def self.parse_suffix(str, opt={})
|
@@ -140,7 +140,7 @@ module RsmartToolbox::ETL::GRM
|
|
140
140
|
opt[:length] = 3 if opt[:length].nil?
|
141
141
|
opt[:valid_values] = /^(Jr|Sr|Mr|Md)?$/ if opt[:valid_values].nil?
|
142
142
|
opt[:upcase] = false if opt[:upcase].nil?
|
143
|
-
return
|
143
|
+
return Rsmart::ETL::parse_flag str, opt
|
144
144
|
end
|
145
145
|
|
146
146
|
def self.parse_phone_type(str, opt={})
|
@@ -148,7 +148,7 @@ module RsmartToolbox::ETL::GRM
|
|
148
148
|
opt[:name] = "TODO_phone_type" if opt[:name].nil?
|
149
149
|
opt[:length] = 3 if opt[:length].nil?
|
150
150
|
opt[:valid_values] = /^(FAX|HM|MBL|OTH|WRK)$/i if opt[:valid_values].nil?
|
151
|
-
return
|
151
|
+
return Rsmart::ETL::parse_flag str, opt
|
152
152
|
end
|
153
153
|
|
154
154
|
def self.parse_phone_number(str, opt={})
|
@@ -156,26 +156,26 @@ module RsmartToolbox::ETL::GRM
|
|
156
156
|
opt[:name] = "PHONE_NBR" if opt[:name].nil?
|
157
157
|
opt[:length] = 12 if opt[:length].nil?
|
158
158
|
opt[:valid_values] = /^(\d{3}-\d{3}-\d{4})?$/ if opt[:valid_values].nil?
|
159
|
-
return
|
159
|
+
return Rsmart::ETL::parse_string str, opt
|
160
160
|
end
|
161
161
|
|
162
162
|
def self.parse_email_type(str, opt={})
|
163
163
|
opt[:name] = "EMAIL_TYP_CD" if opt[:name].nil?
|
164
164
|
opt[:length] = 3 if opt[:length].nil?
|
165
165
|
opt[:valid_values] = /^(HM|OTH|WRK)$/i if opt[:valid_values].nil?
|
166
|
-
return
|
166
|
+
return Rsmart::ETL::parse_flag str, opt
|
167
167
|
end
|
168
168
|
|
169
169
|
def self.parse_year(str, opt={})
|
170
170
|
opt[:length] = 4 if opt[:length].nil?
|
171
171
|
opt[:valid_values] = /^(\d{4})?$/ if opt[:valid_values].nil?
|
172
|
-
return
|
172
|
+
return Rsmart::ETL::parse_string str, opt
|
173
173
|
end
|
174
174
|
|
175
175
|
def self.parse_citizenship_type(str, opt={})
|
176
176
|
opt[:name] = "CITIZENSHIP_TYPE_CODE" if opt[:name].nil?
|
177
177
|
opt[:valid_values] = /^([1-4])$/ if opt[:valid_values].nil?
|
178
|
-
return
|
178
|
+
return Rsmart::ETL::parse_flag str, opt
|
179
179
|
end
|
180
180
|
|
181
181
|
def self.parse_degree(str, opt={})
|
@@ -184,7 +184,7 @@ module RsmartToolbox::ETL::GRM
|
|
184
184
|
opt[:length] = 5 if opt[:length].nil?
|
185
185
|
opt[:valid_values] = /^(AS|BA|BComm|BEd|BS|DA|DC|DD|DDS|DEng|DFA|DH|DHA|DMin|DPA|DSN|DVM|DVS|HS|JD|LLD|LLM|MA|MAEd|MArch|MBA|MD|MDS|MDiv|MEE|MEd|MEng|MFA|MIS|MLS|MPA|MPE|MPH|MPd|MPhil|MS|MSEd|MST|MSW|MTh|PhD|PharD|ScD|ThD|UKNW)?$/ if opt[:valid_values].nil?
|
186
186
|
opt[:upcase] = false if opt[:upcase].nil?
|
187
|
-
return
|
187
|
+
return Rsmart::ETL::parse_flag str, opt
|
188
188
|
end
|
189
189
|
|
190
190
|
end
|
data/rsmart_toolbox.gemspec
CHANGED
@@ -21,10 +21,10 @@ require 'rsmart_toolbox/version'
|
|
21
21
|
|
22
22
|
Gem::Specification.new do |spec|
|
23
23
|
spec.name = "rsmart_toolbox"
|
24
|
-
spec.version =
|
24
|
+
spec.version = Rsmart::VERSION
|
25
25
|
spec.authors = ["Lance Speelmon"]
|
26
26
|
spec.email = ["lspeelmon@rsmart.com"]
|
27
|
-
spec.summary = %q{Client library and command-line
|
27
|
+
spec.summary = %q{Client library and command-line tools to help interact with rSmart's cloud APIs.}
|
28
28
|
# spec.description = %q{TODO: Write a longer description. Optional.}
|
29
29
|
spec.homepage = "https://github.com/rSmart/rsmart_toolbox"
|
30
30
|
spec.metadata = { "issue_tracker" => "https://github.com/rSmart/rsmart_toolbox/issues" }
|
@@ -35,9 +35,13 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
36
36
|
spec.require_paths = ["lib"]
|
37
37
|
|
38
|
+
spec.add_runtime_dependency 'builder', '~> 3.2.2'
|
39
|
+
spec.add_runtime_dependency 'nokogiri', '~> 1.6.3.1'
|
40
|
+
|
38
41
|
spec.required_ruby_version = '>= 1.9'
|
39
42
|
spec.add_development_dependency "bundler", "~> 1.6"
|
40
43
|
spec.add_development_dependency "rake", "~> 10.0"
|
41
44
|
spec.add_development_dependency "rspec", "~> 3.0"
|
42
|
-
spec.add_development_dependency "simplecov"
|
45
|
+
# spec.add_development_dependency "simplecov"
|
46
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
43
47
|
end
|
@@ -17,10 +17,10 @@
|
|
17
17
|
require 'spec_helper'
|
18
18
|
require 'rsmart_toolbox/etl/grm'
|
19
19
|
|
20
|
-
GRM =
|
21
|
-
TextParseError =
|
20
|
+
GRM = Rsmart::ETL::GRM
|
21
|
+
TextParseError = Rsmart::ETL::TextParseError
|
22
22
|
|
23
|
-
RSpec.describe "
|
23
|
+
RSpec.describe "Rsmart::ETL::GRM" do
|
24
24
|
|
25
25
|
describe "#parse_rolodex_id!" do
|
26
26
|
# `ROLODEX_ID` decimal(6,0) NOT NULL DEFAULT '0',
|
@@ -17,9 +17,9 @@
|
|
17
17
|
require 'spec_helper'
|
18
18
|
require 'rsmart_toolbox/etl'
|
19
19
|
|
20
|
-
ETL =
|
20
|
+
ETL = Rsmart::ETL
|
21
21
|
|
22
|
-
RSpec.describe "
|
22
|
+
RSpec.describe "Rsmart::ETL" do
|
23
23
|
|
24
24
|
describe "#error" do
|
25
25
|
it "it returns a TextParseError when passed a String" do
|
data/spec/rsmart_toolbox_spec.rb
CHANGED
@@ -17,11 +17,11 @@
|
|
17
17
|
require 'spec_helper'
|
18
18
|
require 'rsmart_toolbox'
|
19
19
|
|
20
|
-
RSpec.describe "
|
20
|
+
RSpec.describe "Rsmart" do
|
21
21
|
|
22
22
|
it "has a VERSION number" do
|
23
|
-
expect(
|
24
|
-
expect(
|
23
|
+
expect( Rsmart::VERSION ).not_to be_nil
|
24
|
+
expect( Rsmart::VERSION ).to match /^(\d+)\.*(\d+)\.*(\d+)*\.*(\d+)*$/
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -14,7 +14,8 @@
|
|
14
14
|
# You should have received a copy of the GNU Affero General Public License
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
|
17
|
-
require 'simplecov'
|
17
|
+
# require 'simplecov'
|
18
|
+
require 'codeclimate-test-reporter'
|
18
19
|
|
19
20
|
RSpec.configure do |config|
|
20
21
|
# capture original references for later
|
@@ -34,6 +35,8 @@ RSpec.configure do |config|
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
SimpleCov.start do
|
38
|
-
|
39
|
-
end
|
38
|
+
# SimpleCov.start do
|
39
|
+
# add_filter "/spec"
|
40
|
+
# end
|
41
|
+
|
42
|
+
CodeClimate::TestReporter.start
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsmart_toolbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lance Speelmon
|
@@ -30,8 +30,36 @@ cert_chain:
|
|
30
30
|
sKRWzEtHFamxQaIspOja5O4oQKiCbWa90fEuIoCtwyy1rQtL9VKoDTs4vZASXNuc
|
31
31
|
F/lEyekXSjN36uTtlt4LkKLn/k7k5gRbt4+C9Q==
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-08-
|
33
|
+
date: 2014-08-07 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: builder
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 3.2.2
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 3.2.2
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: nokogiri
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.6.3.1
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.6.3.1
|
35
63
|
- !ruby/object:Gem::Dependency
|
36
64
|
name: bundler
|
37
65
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,7 +103,7 @@ dependencies:
|
|
75
103
|
- !ruby/object:Gem::Version
|
76
104
|
version: '3.0'
|
77
105
|
- !ruby/object:Gem::Dependency
|
78
|
-
name:
|
106
|
+
name: codeclimate-test-reporter
|
79
107
|
requirement: !ruby/object:Gem::Requirement
|
80
108
|
requirements:
|
81
109
|
- - ">="
|
@@ -91,15 +119,18 @@ dependencies:
|
|
91
119
|
description:
|
92
120
|
email:
|
93
121
|
- lspeelmon@rsmart.com
|
94
|
-
executables:
|
122
|
+
executables:
|
123
|
+
- transform_CSV_to_HR_XML.rb
|
95
124
|
extensions: []
|
96
125
|
extra_rdoc_files: []
|
97
126
|
files:
|
98
127
|
- ".gitignore"
|
128
|
+
- ".travis.yml"
|
99
129
|
- Gemfile
|
100
130
|
- LICENSE.txt
|
101
131
|
- README.md
|
102
132
|
- Rakefile
|
133
|
+
- bin/transform_CSV_to_HR_XML.rb
|
103
134
|
- lib/rsmart_toolbox.rb
|
104
135
|
- lib/rsmart_toolbox/etl.rb
|
105
136
|
- lib/rsmart_toolbox/etl/grm.rb
|
@@ -133,7 +164,7 @@ rubyforge_project:
|
|
133
164
|
rubygems_version: 2.4.1
|
134
165
|
signing_key:
|
135
166
|
specification_version: 4
|
136
|
-
summary: Client library and command-line
|
167
|
+
summary: Client library and command-line tools to help interact with rSmart's cloud
|
137
168
|
APIs.
|
138
169
|
test_files:
|
139
170
|
- spec/rsmart_toolbox/etl/grm_spec.rb
|
metadata.gz.sig
CHANGED
Binary file
|