move-to-go 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/bin/move-to-go +210 -0
  3. data/lib/move-to-go/can_become_immutable.rb +29 -0
  4. data/lib/move-to-go/csv_helper.rb +47 -0
  5. data/lib/move-to-go/email_helper.rb +14 -0
  6. data/lib/move-to-go/errors.rb +31 -0
  7. data/lib/move-to-go/excel_helper.rb +10 -0
  8. data/lib/move-to-go/global_phone.json +6571 -0
  9. data/lib/move-to-go/model/address.rb +63 -0
  10. data/lib/move-to-go/model/class_settings.rb +50 -0
  11. data/lib/move-to-go/model/clientvisit.rb +10 -0
  12. data/lib/move-to-go/model/comment.rb +10 -0
  13. data/lib/move-to-go/model/coworker.rb +82 -0
  14. data/lib/move-to-go/model/coworker_reference.rb +33 -0
  15. data/lib/move-to-go/model/customfield.rb +87 -0
  16. data/lib/move-to-go/model/deal.rb +216 -0
  17. data/lib/move-to-go/model/deal_class_settings.rb +97 -0
  18. data/lib/move-to-go/model/deal_state.rb +15 -0
  19. data/lib/move-to-go/model/deal_status.rb +23 -0
  20. data/lib/move-to-go/model/deal_status_reference.rb +47 -0
  21. data/lib/move-to-go/model/deal_status_setting.rb +49 -0
  22. data/lib/move-to-go/model/documents.rb +76 -0
  23. data/lib/move-to-go/model/file.rb +193 -0
  24. data/lib/move-to-go/model/history.rb +148 -0
  25. data/lib/move-to-go/model/history_classification.rb +26 -0
  26. data/lib/move-to-go/model/link.rb +82 -0
  27. data/lib/move-to-go/model/organization.rb +250 -0
  28. data/lib/move-to-go/model/person.rb +164 -0
  29. data/lib/move-to-go/model/referencetosource.rb +58 -0
  30. data/lib/move-to-go/model/relation.rb +23 -0
  31. data/lib/move-to-go/model/rootmodel.rb +663 -0
  32. data/lib/move-to-go/model/salescall.rb +10 -0
  33. data/lib/move-to-go/model/settings.rb +61 -0
  34. data/lib/move-to-go/model/tag.rb +35 -0
  35. data/lib/move-to-go/model/talkedto.rb +10 -0
  36. data/lib/move-to-go/model/triedtoreach.rb +10 -0
  37. data/lib/move-to-go/model_helpers.rb +97 -0
  38. data/lib/move-to-go/phone_helper.rb +75 -0
  39. data/lib/move-to-go/roo_helper.rb +82 -0
  40. data/lib/move-to-go/serialize_helper.rb +199 -0
  41. data/lib/move-to-go/shard_helper.rb +96 -0
  42. data/lib/move-to-go/source.rb +108 -0
  43. data/lib/move-to-go/templating.rb +52 -0
  44. data/lib/move-to-go.rb +20 -0
  45. data/sources/VISMA/.gitignore +14 -0
  46. data/sources/VISMA/.move-to-go/readme.txt +1 -0
  47. data/sources/VISMA/.move-to-go/runner.rb +89 -0
  48. data/sources/VISMA/Database/KONTAKT.DBF +0 -0
  49. data/sources/VISMA/Database/KUND.DBF +0 -0
  50. data/sources/VISMA/Gemfile +5 -0
  51. data/sources/VISMA/converter.rb +120 -0
  52. data/sources/base-crm/.move-to-go/runner.rb +235 -0
  53. data/sources/base-crm/Gemfile +5 -0
  54. data/sources/base-crm/README.md +9 -0
  55. data/sources/base-crm/converter.rb +56 -0
  56. data/sources/base-crm/data/contacts.csv +13 -0
  57. data/sources/base-crm/data/coworkers.csv +3 -0
  58. data/sources/base-crm/data/deals.csv +5 -0
  59. data/sources/base-crm/data/histories.csv +6 -0
  60. data/sources/base-crm/data/leads.csv +4 -0
  61. data/sources/base-crm/data/tasks.csv +5 -0
  62. data/sources/csv/.gitignore +14 -0
  63. data/sources/csv/.move-to-go/readme.txt +1 -0
  64. data/sources/csv/.move-to-go/runner.rb +65 -0
  65. data/sources/csv/Gemfile +5 -0
  66. data/sources/csv/converter.rb +218 -0
  67. data/sources/csv/data/coworkers.csv +2 -0
  68. data/sources/csv/data/deals.csv +2 -0
  69. data/sources/csv/data/organizations.csv +2 -0
  70. data/sources/csv/data/persons.csv +2 -0
  71. data/sources/custom/.gitignore +14 -0
  72. data/sources/custom/.move-to-go/readme.txt +1 -0
  73. data/sources/custom/.move-to-go/runner.rb +30 -0
  74. data/sources/custom/Gemfile +4 -0
  75. data/sources/custom/converter.rb +45 -0
  76. data/sources/excel/.gitignore +14 -0
  77. data/sources/excel/.move-to-go/readme.txt +3 -0
  78. data/sources/excel/.move-to-go/runner.rb +140 -0
  79. data/sources/excel/Gemfile +7 -0
  80. data/sources/excel/converter.rb +188 -0
  81. data/sources/excel/files/avtal.docx +0 -0
  82. data/sources/excel/files/more/avtal.docx +0 -0
  83. data/sources/excel/files/more/offert-2.pdf +0 -0
  84. data/sources/excel/files/offert-2.docx +0 -0
  85. data/sources/excel/files/offert.docx +0 -0
  86. data/sources/excel/sample-data.xlsx +0 -0
  87. data/sources/excel-basic/.gitignore +14 -0
  88. data/sources/excel-basic/.move-to-go/readme.txt +3 -0
  89. data/sources/excel-basic/.move-to-go/runner.rb +139 -0
  90. data/sources/excel-basic/Exempelfil.xlsx +0 -0
  91. data/sources/excel-basic/Gemfile +6 -0
  92. data/sources/excel-basic/converter.rb +175 -0
  93. data/sources/excel-basic/files/avtal.docx +0 -0
  94. data/sources/excel-basic/files/more/avtal.docx +0 -0
  95. data/sources/excel-basic/files/more/offert-2.pdf +0 -0
  96. data/sources/excel-basic/files/offert-2.docx +0 -0
  97. data/sources/excel-basic/files/offert.docx +0 -0
  98. data/sources/lime-crm-basic/.gitignore +14 -0
  99. data/sources/lime-crm-basic/.move-to-go/readme.txt +1 -0
  100. data/sources/lime-crm-basic/.move-to-go/runner.rb +524 -0
  101. data/sources/lime-crm-basic/Gemfile +6 -0
  102. data/sources/lime-crm-basic/converter.rb +396 -0
  103. data/sources/lime-easy/.gitignore +14 -0
  104. data/sources/lime-easy/.move-to-go/readme.txt +1 -0
  105. data/sources/lime-easy/.move-to-go/runner.rb +348 -0
  106. data/sources/lime-easy/Export/readme.txt +6 -0
  107. data/sources/lime-easy/Gemfile +5 -0
  108. data/sources/lime-easy/converter.rb +362 -0
  109. data/sources/salesforce/.gitignore +14 -0
  110. data/sources/salesforce/.move-to-go/readme.txt +1 -0
  111. data/sources/salesforce/.move-to-go/runner.rb +404 -0
  112. data/sources/salesforce/Gemfile +6 -0
  113. data/sources/salesforce/Gemfile.lock +48 -0
  114. data/sources/salesforce/converter.rb +113 -0
  115. data/sources/salesforce/export/readme.txt +3 -0
  116. data/spec/address_spec.rb +49 -0
  117. data/spec/class_settings_spec.rb +37 -0
  118. data/spec/coworker_spec.rb +94 -0
  119. data/spec/custom_field_spec.rb +22 -0
  120. data/spec/deal_class_settings_spec.rb +116 -0
  121. data/spec/deal_spec.rb +232 -0
  122. data/spec/deal_status_reference_spec.rb +17 -0
  123. data/spec/documents_spec.rb +64 -0
  124. data/spec/file_spec.rb +178 -0
  125. data/spec/helpers/csv_helper_spec.rb +45 -0
  126. data/spec/helpers/email_helper_spec.rb +37 -0
  127. data/spec/helpers/phone_helper_spec.rb +119 -0
  128. data/spec/helpers/roo_helper_spec.rb +10 -0
  129. data/spec/helpers/serialize_helper_spec.rb +253 -0
  130. data/spec/helpers/shard_helper_spec.rb +141 -0
  131. data/spec/helpers/xsd_validate_spec.rb +57 -0
  132. data/spec/history_spec.rb +150 -0
  133. data/spec/link_spec.rb +107 -0
  134. data/spec/organization_spec.rb +221 -0
  135. data/spec/person_spec.rb +129 -0
  136. data/spec/rootmodel_spec.rb +993 -0
  137. data/spec/spec_helper.rb +30 -0
  138. metadata +362 -0
@@ -0,0 +1,348 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'move-to-go'
4
+ require 'progress'
5
+ require_relative("../converter")
6
+
7
+ EXPORT_FOLDER = 'export'
8
+ COWORKER_FILE = "#{EXPORT_FOLDER}/User.txt"
9
+ ORGANIZATION_FILE = "#{EXPORT_FOLDER}/Company.txt"
10
+ ORGANIZATION_HISTORY_FILE = "#{EXPORT_FOLDER}/Company-History.txt"
11
+ ORGANIZATION_DOCUMENT_FILE = "#{EXPORT_FOLDER}/Company-Document.txt"
12
+ PERSON_FILE = "#{EXPORT_FOLDER}/Company-Person.txt"
13
+ INCLUDE_FILE = "#{EXPORT_FOLDER}/Project-Included.txt"
14
+ DEAL_FILE = "#{EXPORT_FOLDER}/Project.txt"
15
+ DEAL_HISTORY_FILE = "#{EXPORT_FOLDER}/Project-History.txt"
16
+ PROJECT_DOCUMENT_FILE = "#{EXPORT_FOLDER}/Project-Document.txt"
17
+
18
+ def convert_source
19
+ puts "Trying to convert LIME Easy source to LIME Go..."
20
+
21
+ if !make_sure_database_has_been_exported
22
+ puts "ERROR: You must export KONTAKT.mdb to the #{EXPORT_FOLDER} folder."
23
+ raise
24
+ end
25
+
26
+ validate_constants()
27
+
28
+ converter = Converter.new
29
+ rootmodel = MoveToGo::RootModel.new
30
+
31
+ converter.configure rootmodel
32
+
33
+ includes = Hash.new
34
+
35
+ # coworkers
36
+ # start with these since they are referenced
37
+ # from everywhere....
38
+
39
+ process_rows(" - Reading Coworkers '#{COWORKER_FILE}'", COWORKER_FILE) do |row|
40
+ rootmodel.add_coworker(to_coworker(row))
41
+ end
42
+
43
+ # organizations
44
+ process_rows(" - Reading Organizations '#{ORGANIZATION_FILE}'", ORGANIZATION_FILE) do |row|
45
+ organization = init_organization(row, rootmodel)
46
+ rootmodel.add_organization(
47
+ converter.to_organization(organization, row))
48
+ converter.organization_hook(row, organization, rootmodel) if defined? converter.organization_hook
49
+ end
50
+
51
+ # persons
52
+ # depends on organizations
53
+ process_rows(" - Reading Persons '#{PERSON_FILE}'", PERSON_FILE) do |row|
54
+ # init method also adds the person to the employer
55
+ person = init_person(row, rootmodel)
56
+ converter.to_person(person, row)
57
+ end
58
+
59
+ # organization histories
60
+ process_rows(" - Reading Organization History '#{ORGANIZATION_HISTORY_FILE}'", ORGANIZATION_HISTORY_FILE) do |row|
61
+ # adds itself if applicable
62
+ rootmodel.add_history(to_organization_history(converter, row, rootmodel))
63
+ end
64
+
65
+ # Organization - Deal connection
66
+ # Reads the includes.txt and creats a hash
67
+ # that connect organizations to deals
68
+ process_rows(" - Reading Organization Deals '#{INCLUDE_FILE}'", INCLUDE_FILE) do |row|
69
+ includes[row['idProject']] = row['idCompany']
70
+ end
71
+
72
+ # deals
73
+ # deals can reference coworkers (responsible), organizations
74
+ # and persons (contact)
75
+ process_rows(" - Reading Deals '#{DEAL_FILE}'", DEAL_FILE) do |row|
76
+ deal = init_deal(row, rootmodel, includes)
77
+ rootmodel.add_deal(converter.to_deal(deal, row))
78
+ end
79
+
80
+ # deal histories
81
+ process_rows(" - Reading Deal Histories '#{DEAL_HISTORY_FILE}'", DEAL_HISTORY_FILE) do |row|
82
+ # adds itself if applicable
83
+ rootmodel.add_history(to_deal_history(converter, row, rootmodel))
84
+ end
85
+
86
+ # documents
87
+ if defined?(IMPORT_DOCUMENTS) && !IMPORT_DOCUMENTS.nil? && IMPORT_DOCUMENTS
88
+ process_rows(" - Reading Organization Documents", ORGANIZATION_DOCUMENT_FILE) do |row|
89
+ rootmodel.add_file(to_organization_document(row, rootmodel))
90
+ end
91
+
92
+ process_rows(" - Reading Project Documents", PROJECT_DOCUMENT_FILE) do |row|
93
+ rootmodel.add_file(to_deal_document(row, rootmodel))
94
+ end
95
+ end
96
+
97
+ return rootmodel
98
+ end
99
+
100
+ def to_coworker(row)
101
+ coworker = MoveToGo::Coworker.new
102
+
103
+ # integration_id is typically the userId in Easy
104
+ # Must be set to be able to import the same file more
105
+ # than once without creating duplicates
106
+ coworker.integration_id = row['idUser']
107
+ coworker.parse_name_to_firstname_lastname_se(row['Name'])
108
+ return coworker
109
+ end
110
+
111
+ def init_organization(row, rootmodel)
112
+ organization = MoveToGo::Organization.new
113
+ # integration_id is typically the company Id in Easy
114
+ # Must be set to be able to import the same file more
115
+ # than once without creating duplicates
116
+ organization.integration_id = row['idCompany']
117
+
118
+ # Easy standard fields
119
+ organization.name = row['Company name']
120
+ organization.central_phone_number = row['Telephone']
121
+
122
+ if defined?(ORGANIZATION_RESPONSIBLE_FIELD) && !ORGANIZATION_RESPONSIBLE_FIELD.nil? && !ORGANIZATION_RESPONSIBLE_FIELD.empty?
123
+ # Responsible coworker for the organization.
124
+ # For instance responsible sales rep.
125
+ coworker_id = row["idUser-#{ORGANIZATION_RESPONSIBLE_FIELD}"]
126
+ organization.responsible_coworker = rootmodel.find_coworker_by_integration_id(coworker_id)
127
+ end
128
+
129
+ return organization
130
+ end
131
+
132
+ def init_person(row, rootmodel)
133
+ person = MoveToGo::Person.new
134
+
135
+ # Easy standard fields created in configure method Easy
136
+ # persons don't have a globally unique Id, they are only
137
+ # unique within the scope of the company, so we combine the
138
+ # referenceId and the companyId to make a globally unique
139
+ # integration_id
140
+ person.integration_id = row['idPerson']
141
+ person.first_name = row['First name']
142
+ person.last_name = row['Last name']
143
+
144
+ # set employer connection
145
+ employer = rootmodel.find_organization_by_integration_id(row['idCompany'])
146
+ if employer
147
+ employer.add_employee person
148
+ end
149
+
150
+ return person
151
+ end
152
+
153
+ # Turns a row from the Easy exported Company-History.txt file into
154
+ # a move-to-go model that is used to generate xml.
155
+ def to_organization_history(converter, row, rootmodel)
156
+ organization = rootmodel.find_organization_by_integration_id(row['idCompany'])
157
+ coworker = rootmodel.find_coworker_by_integration_id(row['idUser'])
158
+
159
+ if organization && coworker
160
+ history = MoveToGo::History.new()
161
+ history.organization = organization
162
+ history.created_by = coworker
163
+ history.person = organization.find_employee_by_integration_id(row['idPerson'])
164
+ history.date = row['Date']
165
+
166
+ if converter.respond_to?(:get_history_classification_for_activity_on_company)
167
+ # we will get an InvalidHistoryClassificationError if we are
168
+ # setting and invalid classification. So no need to verify
169
+ # return value from converter.
170
+ classification =
171
+ converter.get_history_classification_for_activity_on_company(row['Category'])
172
+
173
+ if classification.nil?
174
+ classification = MoveToGo::HistoryClassification::Comment
175
+ end
176
+
177
+ history.classification = classification
178
+
179
+ history.text = row['History']
180
+ else
181
+ history.classification = MoveToGo::HistoryClassification::Comment
182
+ history.text = "#{row['Category']}: #{row['History']}"
183
+ end
184
+
185
+ return history.text.empty? ? nil : history
186
+ end
187
+
188
+ return nil
189
+ end
190
+
191
+ def to_organization_document(row, rootmodel)
192
+ file = MoveToGo::File.new()
193
+
194
+ file.integration_id = "o-#{row['idDocument']}"
195
+ file.path = row['Path']
196
+ file.name = row['Comment']
197
+
198
+ file.created_by = rootmodel.find_coworker_by_integration_id(row['idUser-Created'])
199
+ if file.created_by.nil?
200
+ file.created_by = rootmodel.migrator_coworker
201
+ end
202
+
203
+ org = rootmodel.find_organization_by_integration_id(row['idCompany'])
204
+ if org.nil?
205
+ return nil
206
+ end
207
+ file.organization = org
208
+
209
+ return file
210
+ end
211
+
212
+ def to_deal_document(row, rootmodel)
213
+ file = MoveToGo::File.new()
214
+
215
+ file.integration_id = "d-#{row['idDocument']}"
216
+ file.path = row['Path']
217
+ file.name = row['Comment']
218
+
219
+ file.created_by = rootmodel.find_coworker_by_integration_id(row['idUser-Created'])
220
+ if file.created_by.nil?
221
+ file.created_by = rootmodel.migrator_coworker
222
+ end
223
+
224
+ deal = rootmodel.find_deal_by_integration_id(row['idProject'])
225
+ if deal.nil?
226
+ return nil
227
+ end
228
+
229
+ file.deal = deal
230
+
231
+ return file
232
+ end
233
+
234
+ def init_deal(row, rootmodel, includes)
235
+ deal = MoveToGo::Deal.new
236
+
237
+ deal.integration_id = row['idProject']
238
+ deal.name = row['Name']
239
+ deal.description = row['Description']
240
+
241
+ if defined?(DEAL_RESPONSIBLE_FIELD) && !DEAL_RESPONSIBLE_FIELD.nil? && !DEAL_RESPONSIBLE_FIELD.empty?
242
+ coworker_id = row["idUser-#{DEAL_RESPONSIBLE_FIELD}"]
243
+ deal.responsible_coworker = rootmodel.find_coworker_by_integration_id(coworker_id)
244
+ end
245
+
246
+ # Make the deal - organization connection
247
+ if includes
248
+ organization_id = includes[row['idProject']]
249
+ organization = rootmodel.find_organization_by_integration_id(organization_id)
250
+ if organization
251
+ deal.customer = organization
252
+ end
253
+ end
254
+
255
+ return deal
256
+ end
257
+
258
+ # Turns a row from the Easy exported Project-History.txt file into
259
+ # a move-to-go model that is used to generate xml
260
+ def to_deal_history(converter, row, rootmodel)
261
+ # TODO: This could be improved to read a person from an
262
+ # organization connected to this deal if any, but since it is
263
+ # a many to many connection between organizations and deals
264
+ # it's not a straight forward task
265
+ deal = rootmodel.find_deal_by_integration_id(row['idProject'])
266
+ coworker = rootmodel.find_coworker_by_integration_id(row['idUser'])
267
+
268
+ if deal && coworker
269
+ history = MoveToGo::History.new()
270
+ history.deal = deal
271
+ history.created_by = coworker
272
+ history.date = row['Date']
273
+ # Raw history looks like this <category>: <person>: <text>
274
+ history.text = row['RawHistory']
275
+
276
+ if converter.respond_to?(:get_history_classification_for_activity_on_project)
277
+ # we will get an InvalidHistoryClassificationError if we are
278
+ # setting and invalid classification. So no need to verify
279
+ # return value from converter.
280
+
281
+ classification =
282
+ converter.get_history_classification_for_activity_on_project(row['Category'])
283
+
284
+ if classification.nil?
285
+ classification = MoveToGo::HistoryClassification::Comment
286
+ end
287
+
288
+ history.classification = classification
289
+ history.text = row['RawHistory'].to_s.sub("#{row['Category']}:", "")
290
+ else
291
+ history.classification = MoveToGo::HistoryClassification::Comment
292
+ history.text = row['RawHistory']
293
+ end
294
+
295
+
296
+ return history.text.empty? ? nil : history
297
+ end
298
+
299
+ return nil
300
+ end
301
+
302
+
303
+ def validate_constants()
304
+ if !defined?(ORGANIZATION_RESPONSIBLE_FIELD)
305
+ puts "WARNING: You have not defined a resposible coworker field for organization.
306
+ If you don't have such a field, you can just ignore this warning.
307
+ Otherwise you should define 'ORGANIZATION_RESPONSIBLE_FIELD' in converter.rb
308
+ with the value of the field name in Easy (e.g 'Ansvarig')."
309
+ end
310
+
311
+ if !defined?(DEAL_RESPONSIBLE_FIELD)
312
+ puts "WARNING: You have not defined a resposible coworker field for deal.
313
+ If you don't have such a field, you can just ignore this warning.
314
+ Otherwise you should define 'DEAL_RESPONSIBLE_FIELD' in converter.rb
315
+ with the value of the field name in Easy (e.g 'Ansvarig')."
316
+ end
317
+
318
+ if !defined?(IMPORT_DOCUMENTS) || IMPORT_DOCUMENTS.nil? || !IMPORT_DOCUMENTS
319
+ puts "WARNING: You are about to run the import without documents.
320
+ If that is your intention then you can ignore this warning.
321
+ Otherwise you should define 'IMPORT_DOCUMENTS' in converter.rb
322
+ with the value 'true'."
323
+ end
324
+ end
325
+
326
+
327
+ def process_rows(description, file_name)
328
+ data = File.open(file_name, 'r').read.encode('UTF-8',"ISO-8859-1").strip().gsub('"', '')
329
+ data = '"' + data.gsub("\t", "\"\t\"") + '"'
330
+ data = data.gsub("\n", "\"\n\"")
331
+
332
+ rows = MoveToGo::CsvHelper::text_to_hashes(data, "\t", "\n", '"')
333
+ rows.with_progress(description).each do |row|
334
+ yield row
335
+ end
336
+ end
337
+
338
+ def make_sure_database_has_been_exported()
339
+ return File.exists?(COWORKER_FILE) &&
340
+ File.exists?(ORGANIZATION_FILE) &&
341
+ File.exists?(ORGANIZATION_HISTORY_FILE) &&
342
+ File.exists?(ORGANIZATION_DOCUMENT_FILE) &&
343
+ File.exists?(PERSON_FILE) &&
344
+ File.exists?(INCLUDE_FILE) &&
345
+ File.exists?(DEAL_FILE) &&
346
+ File.exists?(DEAL_HISTORY_FILE) &&
347
+ File.exists?(PROJECT_DOCUMENT_FILE)
348
+ end
@@ -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 'move-to-go'
5
+ gem 'rspec'