go_import 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. data/bin/go-import +96 -0
  2. data/lib/go_import/csv_helper.rb +47 -0
  3. data/lib/go_import/email_helper.rb +10 -0
  4. data/lib/go_import/errors.rb +22 -0
  5. data/lib/go_import/excel_helper.rb +10 -0
  6. data/lib/go_import/global_phone.json +6571 -0
  7. data/lib/go_import/model/address.rb +61 -0
  8. data/lib/go_import/model/class_settings.rb +50 -0
  9. data/lib/go_import/model/coworker.rb +76 -0
  10. data/lib/go_import/model/coworker_reference.rb +33 -0
  11. data/lib/go_import/model/customfield.rb +87 -0
  12. data/lib/go_import/model/deal.rb +172 -0
  13. data/lib/go_import/model/deal_class_settings.rb +73 -0
  14. data/lib/go_import/model/deal_state.rb +15 -0
  15. data/lib/go_import/model/deal_status.rb +23 -0
  16. data/lib/go_import/model/deal_status_reference.rb +47 -0
  17. data/lib/go_import/model/deal_status_setting.rb +49 -0
  18. data/lib/go_import/model/documents.rb +51 -0
  19. data/lib/go_import/model/link.rb +70 -0
  20. data/lib/go_import/model/note.rb +97 -0
  21. data/lib/go_import/model/note_classification.rb +25 -0
  22. data/lib/go_import/model/organization.rb +219 -0
  23. data/lib/go_import/model/person.rb +151 -0
  24. data/lib/go_import/model/referencetosource.rb +46 -0
  25. data/lib/go_import/model/relation.rb +23 -0
  26. data/lib/go_import/model/rootmodel.rb +359 -0
  27. data/lib/go_import/model/settings.rb +61 -0
  28. data/lib/go_import/model/tag.rb +35 -0
  29. data/lib/go_import/model_helpers.rb +54 -0
  30. data/lib/go_import/phone_helper.rb +74 -0
  31. data/lib/go_import/roo_helper.rb +80 -0
  32. data/lib/go_import/serialize_helper.rb +186 -0
  33. data/lib/go_import/source.rb +87 -0
  34. data/lib/go_import/templating.rb +52 -0
  35. data/lib/go_import.rb +19 -0
  36. data/sources/csv/.gitignore +14 -0
  37. data/sources/csv/.go_import/runner.rb +62 -0
  38. data/sources/csv/Gemfile +5 -0
  39. data/sources/csv/Rakefile.rb +7 -0
  40. data/sources/csv/converter.rb +179 -0
  41. data/sources/csv/data/coworkers.csv +2 -0
  42. data/sources/csv/data/deals.csv +2 -0
  43. data/sources/csv/data/organizations.csv +2 -0
  44. data/sources/csv/data/persons.csv +2 -0
  45. data/sources/csv/spec/exporter_spec.rb +17 -0
  46. data/sources/csv/spec/sample_data/coworkers.csv +2 -0
  47. data/sources/csv/spec/sample_data/deals.csv +2 -0
  48. data/sources/csv/spec/sample_data/organizations.csv +2 -0
  49. data/sources/csv/spec/sample_data/persons.csv +2 -0
  50. data/sources/csv/spec/spec_helper.rb +30 -0
  51. data/sources/easy/.gitignore +14 -0
  52. data/sources/easy/.go_import/runner.rb +115 -0
  53. data/sources/easy/Export/readme.txt +6 -0
  54. data/sources/easy/Gemfile +5 -0
  55. data/sources/easy/Rakefile.rb +7 -0
  56. data/sources/easy/converter.rb +435 -0
  57. data/sources/easy/spec/exporter_spec.rb +10 -0
  58. data/sources/easy/spec/sample_data/Company.txt +649 -0
  59. data/sources/easy/spec/spec_helper.rb +30 -0
  60. data/sources/excel/.gitignore +14 -0
  61. data/sources/excel/.go_import/runner.rb +116 -0
  62. data/sources/excel/Gemfile +6 -0
  63. data/sources/excel/Rakefile.rb +7 -0
  64. data/sources/excel/converter.rb +130 -0
  65. data/sources/excel/spec/sample_data/sample.xlsx +0 -0
  66. data/sources/excel/spec/spec_helper.rb +26 -0
  67. data/sources/excel/spec/tomodel_spec.rb +18 -0
  68. data/sources/excel/template.xlsx +0 -0
  69. data/spec/address_spec.rb +49 -0
  70. data/spec/class_settings_spec.rb +37 -0
  71. data/spec/coworker_spec.rb +94 -0
  72. data/spec/custom_field_spec.rb +22 -0
  73. data/spec/deal_class_settings_spec.rb +104 -0
  74. data/spec/deal_spec.rb +182 -0
  75. data/spec/deal_status_reference_spec.rb +17 -0
  76. data/spec/documents_spec.rb +37 -0
  77. data/spec/helpers/csv_helper_spec.rb +29 -0
  78. data/spec/helpers/email_helper_spec.rb +32 -0
  79. data/spec/helpers/phone_helper_spec.rb +97 -0
  80. data/spec/helpers/roo_helper_spec.rb +10 -0
  81. data/spec/helpers/serialize_helper_spec.rb +249 -0
  82. data/spec/helpers/xsd_validate_spec.rb +55 -0
  83. data/spec/link_spec.rb +106 -0
  84. data/spec/note_spec.rb +110 -0
  85. data/spec/organization_spec.rb +151 -0
  86. data/spec/person_spec.rb +132 -0
  87. data/spec/rootmodel_spec.rb +371 -0
  88. data/spec/spec_helper.rb +30 -0
  89. data/spec/templating_spec.rb +12 -0
  90. metadata +306 -0
@@ -0,0 +1,30 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ #require File.expand_path("../../config/environment", __FILE__)
3
+ #require 'rspec/rails'
4
+ #require 'rspec/autorun'
5
+
6
+ # Requires supporting ruby files with custom matchers and macros, etc,
7
+ # in spec/support/ and its subdirectories.
8
+ #Dir[File.join(File.dirname(File.absolute_path(__FILE__)),"support/**/*.rb")].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ # ## Mock Framework
12
+ #
13
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
14
+ #
15
+ # config.mock_with :mocha
16
+ # config.mock_with :flexmock
17
+ # config.mock_with :rr
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = "random"
24
+
25
+ # Allow both should and expect syntax
26
+ # http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
27
+ config.expect_with :rspec do |c|
28
+ c.syntax = [:should, :expect]
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile ~/.gitignore_global
6
+
7
+ # Ignore bundler config
8
+ /.bundle
9
+ # Ignore built gems
10
+ /*.gem
11
+ # Ignore all logfiles and tempfiles.
12
+ /tmp
13
+ /spec/tmp
14
+ pkg
@@ -0,0 +1,115 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'go_import'
4
+ require_relative("../converter")
5
+
6
+ def convert_source
7
+ puts "Trying to convert LIME Easy source to LIME Go..."
8
+
9
+ converter = Converter.new
10
+
11
+ # *** TODO:
12
+ #
13
+ # Modify the name of the sheets. Or add/remove sheets based on
14
+ # your Excel file.
15
+
16
+ # First we read each sheet from the excel file into separate
17
+ # variables
18
+ excel_workbook = GoImport::ExcelHelper.Open(EXCEL_FILE)
19
+
20
+ if defined?(COWORKER_SHEET)
21
+ if excel_workbook.has_sheet?(COWORKER_SHEET)
22
+ coworker_rows = excel_workbook.rows_for_sheet COWORKER_SHEET
23
+ else
24
+ puts "Warning: can't find sheet '#{COWORKER_SHEET}'"
25
+ end
26
+ end
27
+
28
+ if defined?(ORGANIZATION_SHEET)
29
+ if excel_workbook.has_sheet?(ORGANIZATION_SHEET)
30
+ organization_rows = excel_workbook.rows_for_sheet ORGANIZATION_SHEET
31
+ else
32
+ puts "Warning: can't find sheet '#{ORGANIZATION_SHEET}'"
33
+ end
34
+ end
35
+
36
+ if defined?(PERSON_SHEET)
37
+ if excel_workbook.has_sheet?(PERSON_SHEET)
38
+ person_rows = excel_workbook.rows_for_sheet PERSON_SHEET
39
+ else
40
+ puts "Warning: can't find sheet '#{PERSON_SHEET}'"
41
+ end
42
+ end
43
+
44
+ if defined?(DEAL_SHEET)
45
+ if excel_workbook.has_sheet?(DEAL_SHEET)
46
+ deal_rows = excel_workbook.rows_for_sheet DEAL_SHEET
47
+ else
48
+ puts "Warning: can't find sheet '#{DEAL_SHEET}'"
49
+ end
50
+ end
51
+
52
+ if defined?(NOTE_SHEET)
53
+ if excel_workbook.has_sheet?(NOTE_SHEET)
54
+ note_rows = excel_workbook.rows_for_sheet NOTE_SHEET
55
+ else
56
+ puts "Warning: can't find sheet '#{NOTE_SHEET}'"
57
+ end
58
+ end
59
+
60
+ # Then we create a rootmodel that will contain all data that
61
+ # should be exported to LIME Go.
62
+ rootmodel = GoImport::RootModel.new
63
+
64
+ # And configure the model if we have any custom fields
65
+ converter.configure rootmodel
66
+
67
+ # Now start to read data from the excel file and add to the
68
+ # rootmodel. We begin with coworkers since they are referenced
69
+ # from everywhere (orgs, deals, notes)
70
+ if defined?(coworker_rows) && !coworker_rows.nil?
71
+ puts "Trying to convert coworkers..."
72
+ coworker_rows.each do |row|
73
+ rootmodel.add_coworker(converter.to_coworker(row))
74
+ end
75
+ end
76
+
77
+ # Then create organizations, they are only referenced by
78
+ # coworkers.
79
+ if defined?(organization_rows) && !organization_rows.nil?
80
+ puts "Trying to convert organizations..."
81
+ organization_rows.each do |row|
82
+ rootmodel.add_organization(converter.to_organization(row, rootmodel))
83
+ end
84
+ end
85
+
86
+ # Add people and link them to their organizations
87
+ if defined?(person_rows) && !person_rows.nil?
88
+ puts "Trying to convert persons..."
89
+ person_rows.each do |row|
90
+ # People are special since they are not added directly to
91
+ # the root model
92
+ converter.import_person_to_organization(row, rootmodel)
93
+ end
94
+ end
95
+
96
+ # Deals can connected to coworkers, organizations and people.
97
+ if defined?(deal_rows) && !deal_rows.nil?
98
+ puts "Trying to convert deals..."
99
+ deal_rows.each do |row|
100
+ rootmodel.add_deal(converter.to_deal(row, rootmodel))
101
+ end
102
+ end
103
+
104
+ # Notes must be owned by a coworker and the be added to
105
+ # organizations and notes and might refernce a person
106
+ if defined?(note_rows) && !note_rows.nil?
107
+ puts "Trying to convert notes..."
108
+ note_rows.each do |row|
109
+ rootmodel.add_note(converter.to_note(row, rootmodel))
110
+ end
111
+ end
112
+
113
+ return rootmodel
114
+ end
115
+
@@ -0,0 +1,6 @@
1
+ Export all data from KONTAKT.mdb to this folder.
2
+
3
+ Export data using the magical tool called PowerSellMigrationExport.exe
4
+ that can be found in K:\Lundalogik\LIME Easy\Tillbeh�r\Migrationsexport.
5
+
6
+ Yay!
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'thor'
4
+ #gem 'go_import'
5
+ gem 'rspec'
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+ task :test => :spec
@@ -0,0 +1,435 @@
1
+ # encoding: UTF-8
2
+ require 'go_import'
3
+
4
+ # Customize this file to suit your input files.
5
+ #
6
+ # Documentation go_import can be found at
7
+ # http://rubygems.org/gems/go_import
8
+ #
9
+ # go_import contains all objects in LIME Go such as organization,
10
+ # people, deals, etc. What properties each object has is described in
11
+ # the documentation.
12
+
13
+ # *** TODO:
14
+ #
15
+ # You must customize this template so it works with your LIME Easy
16
+ # database. Modify each to_* method and set properties on the LIME Go
17
+ # objects.
18
+ #
19
+ # Follow these steps:
20
+ #
21
+ # 1) Export all data from KONTAKT.mdb to a folder named Export located
22
+ # in the folder created by go_import unpack_template. Export data
23
+ # using the magical tool called PowerSellMigrationExport.exe that can
24
+ # be found in K:\Lundalogik\LIME Easy\Tillbeh�r\Migrationsexport.
25
+ #
26
+ # 2) Modify this file (the to_* methods) according to your customer's
27
+ # KONTAKT.mdb and wishes.
28
+ #
29
+ # 3) Run easy-to-go.bat in a command prompt.
30
+ #
31
+ # 4) Upload go.xml to LIME Go. First test your import on staging and
32
+ # when your customer has approved the import, run it on production.
33
+ class Exporter
34
+ # Turns a user from the User.txt Easy Export file into
35
+ # a go_import coworker.
36
+ def to_coworker(row)
37
+ coworker = GoImport::Coworker.new
38
+ # integration_id is typically the userId in Easy
39
+ # Must be set to be able to import the same file more
40
+ # than once without creating duplicates
41
+
42
+ # NOTE: You shouldn't have to modify this method
43
+
44
+ coworker.integration_id = row['PowerSellUserID']
45
+ coworker.parse_name_to_firstname_lastname_se(row['Name'])
46
+
47
+ return coworker
48
+ end
49
+
50
+ # Turns a row from the Easy exported Company.txt file into a
51
+ # go_import organization.
52
+ def to_organization(row, coworkers)
53
+ organization = GoImport::Organization.new
54
+ # integration_id is typically the company Id in Easy
55
+ # Must be set to be able to import the same file more
56
+ # than once without creating duplicates
57
+
58
+ # Easy standard fields
59
+ organization.integration_id = row['PowerSellCompanyID']
60
+ organization.name = row['Company name']
61
+ organization.central_phone_number = row['Telephone']
62
+
63
+ # *** TODO: Customize below this line (address, superfield,
64
+ # relation, etc)
65
+
66
+ # NOTE!! if a bisnode-id is present maybe you want to consider
67
+ # not setting this (because if you set the address LIME Go
68
+ # will NOT automagically update the address from PAR)
69
+ # Addresses consists of several parts in Go. Lots of other
70
+ # systems have the address all in one line, to be able to
71
+ # match when importing it is way better to split the addresses
72
+ organization.with_postal_address do |address|
73
+ address.street = row['street']
74
+ address.zip_code = row['zip']
75
+ address.city = row['city']
76
+ address.location = row['location']
77
+ end
78
+
79
+ # Easy superfields
80
+
81
+ # Same as postal address
82
+ organization.with_visit_address do |addr|
83
+ addr.street = row['visit street']
84
+ addr.zip_code = row['visit zip']
85
+ addr.city = row['visit city']
86
+ end
87
+
88
+ organization.email = row['e-mail']
89
+ organization.organization_number = row['orgnr']
90
+
91
+ # Set Bisnode Id if present
92
+ bisnode_id = row['Bisnode-id']
93
+
94
+ if bisnode_id && !bisnode_id.empty?
95
+ organization.with_source do |source|
96
+ source.par_se(bisnode_id)
97
+ end
98
+ end
99
+
100
+ # Only set other Bisnode fields if the Bisnode Id is empty
101
+ if bisnode_id.empty?
102
+ organization.web_site = row['website']
103
+ end
104
+
105
+ # Responsible coworker for the organization.
106
+ # For instance responsible sales rep.
107
+ coworker_id = coworkers[row['idUser-Responsible']]
108
+ organization.responsible_coworker = @rootmodel.find_coworker_by_integration_id(coworker_id)
109
+
110
+ # Tags are set and defined at the same place
111
+ # Setting a tag: Imported is useful for the user
112
+ organization.set_tag("Imported")
113
+
114
+ # Option fields are normally translated into tags
115
+ # The option field customer category for instance,
116
+ # has the options "A-customer", "B-customer", and "C-customer"
117
+ organization.set_tag(row['customer category'])
118
+
119
+ # Relation
120
+ # let's say that there is a option field in Easy called 'Customer relation'
121
+ # with the options '1.Customer', '2.Prospect' '3.Partner' and '4.Lost customer'
122
+ if row['Customer relation'] == '1.Customer'
123
+ # We have made a deal with this organization.
124
+ organization.relation = GoImport::Relation::IsACustomer
125
+ elsif row['Customer relation'] == '3.Partner'
126
+ # We have made a deal with this organization.
127
+ organization.relation = GoImport::Relation::IsACustomer
128
+ elsif row['Customer relation'] == '2.Prospect'
129
+ # Something is happening with this organization, we might have
130
+ # booked a meeting with them or created a deal, etc.
131
+ organization.relation = GoImport::Relation::WorkingOnIt
132
+ elsif row['Customer relation'] == '4.Lost customer'
133
+ # We had something going with this organization but we
134
+ # couldn't close the deal and we don't think they will be a
135
+ # customer to us in the foreseeable future.
136
+ organization.relation = GoImport::Relation::BeenInTouch
137
+ else
138
+ organization.relation = GoImport::Relation::NoRelation
139
+ end
140
+
141
+ return organization
142
+ end
143
+
144
+ # Turns a row from the Easy exported Company-Person.txt file into
145
+ # a go_import model that is used to generate xml
146
+ def to_person(row)
147
+ person = GoImport::Person.new
148
+
149
+ # Easy standard fields created in configure method Easy
150
+ # persons don't have a globally unique Id, they are only
151
+ # unique within the scope of the company, so we combine the
152
+ # referenceId and the companyId to make a globally unique
153
+ # integration_id
154
+ person.integration_id = "#{row['PowerSellReferenceID']}-#{row['PowerSellCompanyID']}"
155
+ person.first_name = row['First name']
156
+ person.last_name = row['Last name']
157
+
158
+ # set employer connection
159
+ employer = @rootmodel.find_organization_by_integration_id(row['PowerSellCompanyID'])
160
+ if employer
161
+ employer.add_employee person
162
+ end
163
+
164
+ # *** TODO: Customize below this line (superfields, tags, etc)
165
+
166
+ # Easy superfields
167
+ person.direct_phone_number = row['Direktnummer']
168
+ person.mobile_phone_number = row['Mobil']
169
+ person.email = row['e-mail']
170
+ person.position = row['position']
171
+
172
+ # Populate a Go custom field
173
+ person.set_custom_value("shoe_size", row['shoe size'])
174
+
175
+ # Tags
176
+ person.set_tag("Imported")
177
+
178
+ # Checkbox fields
179
+ # Xmas card field is a checkbox in Easy
180
+ if row['Xmas card'] == "1"
181
+ person.set_tag("Xmas card")
182
+ end
183
+
184
+ # Multioption fields or "Set"- fields
185
+ if row['intrests']
186
+ intrests = row['intrests'].split(';')
187
+ intrests.each do |intrest|
188
+ person.set_tag(intrest)
189
+ end
190
+ end
191
+ end
192
+
193
+ # Turns a row from the Easy exported Project.txt file into
194
+ # a go_import model that is used to generate xml.
195
+ # Uses includes hash to lookup organizations to connect
196
+ # Uses coworkers hash to lookup coworkers to connect
197
+ def to_deal(row, includes, coworkers)
198
+ deal = GoImport::Deal.new
199
+ # Easy standard fields
200
+ deal.integration_id = row['PowerSellProjectID']
201
+ deal.name = row['Name']
202
+ deal.description = row['Description']
203
+
204
+ # Easy superfields
205
+ deal.order_date = row['order date']
206
+
207
+ coworker_id = coworkers[row['isUser-Ansvarig']]
208
+ deal.responsible_coworker = @rootmodel.find_coworker_by_integration_id(coworker_id)
209
+
210
+ # Should be integer
211
+ # The currency used in Easy should match the one used in Go
212
+ deal.value = row['value']
213
+
214
+ # should be between 0 - 100
215
+ # remove everything that is not an intiger
216
+ deal.probability = row['probability'].gsub(/[^\d]/,"").to_i unless row['probability'].nil?
217
+
218
+ # Sets the deal's status to the value of the Easy field. This
219
+ # assumes that the status is already created in LIME Go. To
220
+ # create statuses during import add them to the settings
221
+ # during configure.
222
+ if !row['Status'].empty?
223
+ deal.status = row['Status']
224
+ end
225
+
226
+ # Tags
227
+ deal.set_tag("Imported")
228
+
229
+ # Make the deal - organization connection
230
+ if includes
231
+ organization_id = includes[row['PowerSellProjectID']]
232
+ organization = @rootmodel.find_organization_by_integration_id(organization_id)
233
+ if organization
234
+ deal.customer = organization
235
+ end
236
+ end
237
+
238
+ return deal
239
+ end
240
+
241
+ # Turns a row from the Easy exported Company-History.txt file into
242
+ # a go_import model that is used to generate xml.
243
+ # Uses coworkers hash to lookup coworkers to connect
244
+ # Uses people hash to lookup persons to connect
245
+ def to_organization_note(row, coworkers, people)
246
+ organization = @rootmodel.find_organization_by_integration_id(row['PowerSellCompanyID'])
247
+
248
+ coworker_id = coworkers[row['idUser']]
249
+ coworker = @rootmodel.find_coworker_by_integration_id(coworker_id)
250
+
251
+ if organization && coworker
252
+ note = GoImport::Note.new()
253
+ note.organization = organization
254
+ note.created_by = coworker
255
+ note.person = organization.find_employee_by_integration_id(people[row['idPerson']])
256
+ note.date = row['Date']
257
+ note.text = "#{row['Category']}: #{row['History']}"
258
+
259
+ return note.text.empty? ? nil : note
260
+ end
261
+
262
+ return nil
263
+ end
264
+
265
+ # Turns a row from the Easy exported Project-History.txt file into
266
+ # a go_import model that is used to generate xml
267
+ # Uses coworkers hash to lookup coworkers to connect
268
+ def to_deal_note(row, coworkers)
269
+ # TODO: This could be improved to read a person from an
270
+ # organization connected to this deal if any, but since it is
271
+ # a many to many connection between organizations and deals
272
+ # it's not a straight forward task
273
+ deal = @rootmodel.find_deal_by_integration_id(row['PowerSellProjectID'])
274
+
275
+ coworker_id = coworkers[row['idUser']]
276
+ coworker = @rootmodel.find_coworker_by_integration_id(coworker_id)
277
+
278
+ if deal && coworker
279
+ note = GoImport::Note.new()
280
+ note.deal = deal
281
+ note.created_by = coworker
282
+ note.date = row['Date']
283
+ # Raw history looks like this <category>: <person>: <text>
284
+ note.text = row['RawHistory']
285
+
286
+ return note.text.empty? ? nil : note
287
+ end
288
+
289
+ return nil
290
+ end
291
+
292
+ def configure(model)
293
+ # add custom field to your model here. Custom fields can be
294
+ # added to organization, deal and person. Valid types are
295
+ # :String and :Link. If no type is specified :String is used
296
+ # as default.
297
+ model.settings.with_person do |person|
298
+ person.set_custom_field( { :integration_id => 'shoe_size', :title => 'Shoe size', :type => :String} )
299
+ end
300
+
301
+ model.settings.with_deal do |deal|
302
+ # assessment is default DealState::NoEndState
303
+ deal.add_status( {:label => '1. Kvalificering' })
304
+ deal.add_status( {:label => '2. Deal closed', :assessment => GoImport::DealState::PositiveEndState })
305
+ deal.add_status( {:label => '4. Deal lost', :assessment => GoImport::DealState::NegativeEndState })
306
+ end
307
+ end
308
+
309
+ def process_rows(file_name)
310
+ data = File.open(file_name, 'r').read.encode('UTF-8',"ISO-8859-1").strip().gsub('"', '')
311
+ data = '"' + data.gsub("\t", "\"\t\"") + '"'
312
+ data = data.gsub("\n", "\"\n\"")
313
+
314
+ rows = GoImport::CsvHelper::text_to_hashes(data, "\t", "\n", '"')
315
+ rows.each do |row|
316
+ yield row
317
+ end
318
+ end
319
+
320
+ def to_model(coworkers_filename, organization_filename, persons_filename, orgnotes_filename, includes_filename, deals_filename, dealnotes_filename)
321
+ # A rootmodel is used to represent all entitite/models
322
+ # that is exported
323
+ @rootmodel = GoImport::RootModel.new
324
+ coworkers = Hash.new
325
+ includes = Hash.new
326
+ people = Hash.new
327
+
328
+ configure @rootmodel
329
+
330
+ # coworkers
331
+ # start with these since they are referenced
332
+ # from everywhere....
333
+ if coworkers_filename && !coworkers_filename.empty?
334
+ process_rows coworkers_filename do |row|
335
+ coworkers[row['userIndex']] = row['userId']
336
+ @rootmodel.add_coworker(to_coworker(row))
337
+ end
338
+ end
339
+
340
+ # organizations
341
+ if organization_filename && !organization_filename.empty?
342
+ process_rows organization_filename do |row|
343
+ @rootmodel.add_organization(to_organization(row, coworkers))
344
+ end
345
+ end
346
+
347
+ # persons
348
+ # depends on organizations
349
+ if persons_filename && !persons_filename.empty?
350
+ process_rows persons_filename do |row|
351
+ people[row['personIndex']] = "#{row['PowerSellReferenceID']}-#{row['PowerSellCompanyID']}"
352
+ # adds it self to the employer
353
+ to_person(row)
354
+ end
355
+ end
356
+
357
+ # organization notes
358
+ if orgnotes_filename && !orgnotes_filename.empty?
359
+ process_rows orgnotes_filename do |row|
360
+ # adds itself if applicable
361
+ @rootmodel.add_note(to_organization_note(row, coworkers, people))
362
+ end
363
+ end
364
+
365
+ # Organization - Deal connection
366
+ # Reads the includes.txt and creats a hash
367
+ # that connect organizations to deals
368
+ if includes_filename && !includes_filename.empty?
369
+ process_rows includes_filename do |row|
370
+ includes[row['PowerSellProjectID']] = row['PowerSellCompanyID']
371
+ end
372
+ end
373
+
374
+ # deals
375
+ # deals can reference coworkers (responsible), organizations
376
+ # and persons (contact)
377
+ if deals_filename && !deals_filename.empty?
378
+ process_rows deals_filename do |row|
379
+ @rootmodel.add_deal(to_deal(row, includes, coworkers))
380
+ end
381
+ end
382
+
383
+ # deal notes
384
+ if dealnotes_filename && !dealnotes_filename.empty?
385
+ process_rows dealnotes_filename do |row|
386
+ # adds itself if applicable
387
+ @rootmodel.add_note(to_deal_note(row, coworkers))
388
+ end
389
+ end
390
+
391
+ return @rootmodel
392
+ end
393
+
394
+ def save_xml(file)
395
+ File.open(file,'w') do |f|
396
+ f.write(GoImport::SerializeHelper::serialize(to_xml_model))
397
+ end
398
+ end
399
+ end
400
+
401
+ require "thor"
402
+ require "fileutils"
403
+ require 'pathname'
404
+
405
+ class Cli < Thor
406
+ desc "to_go", "Generates a Go XML file"
407
+ method_option :output, :desc => "Path to file where xml will be output", :default => "export.xml", :type => :string, :required => true
408
+ method_option :coworkers, :desc => "Path to coworkers csv file", :type => :string, :required => true
409
+ method_option :organizations, :desc => "Path to organization csv file", :type => :string, :required => true
410
+ method_option :persons, :desc => "Path to persons csv file", :type => :string, :required => true
411
+ method_option :orgnotes, :desc => "Path to organization notes file", :type => :string, :required => true
412
+ method_option :includes, :desc => "Path to include file", :type => :string, :required => true
413
+ method_option :deals, :desc => "Path to deals csv file", :type => :string, :required => true
414
+ method_option :dealnotes, :desc => "Path to deal notes file", :type => :string, :required => true
415
+ def to_go
416
+ output = options.output
417
+ exporter = Exporter.new()
418
+ model = exporter.to_model(options.coworkers, options.organizations, options.persons, options.orgnotes, options.includes, options.deals, options.dealnotes)
419
+ error = model.sanity_check
420
+ if error.empty?
421
+ validation_errors = model.validate
422
+
423
+ if validation_errors.empty?
424
+ model.serialize_to_file(output)
425
+ puts "Generated Go XML file: '#{output}'."
426
+ else
427
+ puts "Could not generate file due to"
428
+ puts validation_errors
429
+ end
430
+ else
431
+ puts "Could not generate file due to"
432
+ puts error
433
+ end
434
+ end
435
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ require 'tomodel'
3
+
4
+ describe 'Exporter' do
5
+ before(:all) do
6
+ exporter = Exporter.new
7
+ organizations_file = File.join(File.dirname(__FILE__), 'sample_data', 'company.txt')
8
+ @model = exporter.to_model(nil, organizations_file, nil, nil, nil, nil, nil)
9
+ end
10
+ end