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,663 @@
1
+ # encoding: utf-8
2
+
3
+ require 'zip'
4
+ require 'securerandom'
5
+ require "progress"
6
+
7
+ module MoveToGo
8
+ # The root model for Go import. This class is the container for everything else.
9
+ class RootModel
10
+ # the migrator_coworker is a special coworker that is set as
11
+ # responsible for objects that requires a coworker, eg a history.
12
+ attr_accessor :migrator_coworker
13
+
14
+ attr_accessor :settings, :organizations, :coworkers, :deals, :histories
15
+
16
+ # The configuration is used to set run-time properties for
17
+ # move-to-go. This should not be confused with the model's
18
+ # settings. Sets the following properties:
19
+ #
20
+ # ALLOW_DEALS_WITHOUT_RESPONSIBLE - if set to true, deals
21
+ # without a responsible will NOT have the import user set as
22
+ # default.
23
+ attr_accessor :configuration
24
+
25
+ attr_reader :documents, :persons
26
+
27
+ def serialize_variables
28
+ [
29
+ {:id => :settings, :type => :settings},
30
+ {:id => :coworkers, :type => :coworkers},
31
+ {:id => :organizations, :type => :organizations},
32
+ {:id => :deals, :type => :deals},
33
+ {:id => :histories, :type => :histories},
34
+ {:id => :documents, :type => :documents},
35
+ ]
36
+ end
37
+
38
+ def serialize_name
39
+ "GoImport"
40
+ end
41
+
42
+ include SerializeHelper
43
+
44
+ def initialize()
45
+ @settings = Settings.new
46
+ @organizations = {}
47
+ @coworkers = {}
48
+ @migrator_coworker = Coworker.new
49
+ @migrator_coworker.integration_id = "migrator"
50
+ @migrator_coworker.first_name = "Migrator"
51
+ @coworkers[@migrator_coworker.integration_id] = @migrator_coworker
52
+ @deals = {}
53
+ @histories = {}
54
+ @documents = Documents.new
55
+ @configuration = {}
56
+
57
+ configure
58
+ end
59
+
60
+ def persons
61
+ return @organizations.collect{|k, o| o.employees}.flatten.compact
62
+ end
63
+
64
+ # Adds the specifed coworker object to the model.
65
+
66
+ # @example Add a coworker from a new coworker
67
+ # coworker = MoveToGo::Coworker.new
68
+ # coworker.integration_id = "123"
69
+ # coworker.first_name="Kalle"
70
+ # coworker.last_name="Anka"
71
+ # coworker.email = "kalle.anka@vonanka.com"
72
+ # rootmodel.add_coworker(coworker)
73
+ def add_coworker(coworker)
74
+ if coworker.nil?
75
+ return nil
76
+ end
77
+
78
+ if !coworker.is_a?(Coworker)
79
+ raise ArgumentError.new("Expected a coworker")
80
+ end
81
+
82
+ if coworker.integration_id.nil? || coworker.integration_id.length == 0
83
+ raise IntegrationIdIsRequiredError, "An integration id is required for a coworker."
84
+ end
85
+
86
+ if find_coworker_by_integration_id(coworker.integration_id, false) != nil
87
+ raise AlreadyAddedError, "Already added a coworker with integration_id #{coworker.integration_id}"
88
+ end
89
+
90
+ @coworkers[coworker.integration_id] = coworker
91
+ coworker.set_is_immutable
92
+
93
+ return coworker
94
+ end
95
+
96
+ # Adds the specifed organization object to the model.
97
+ # @example Add an organization from a new organization
98
+ # organization = MoveToGo::Organization.new
99
+ # organization.integration_id = "123"
100
+ # organization.name = "Beagle Boys"
101
+ # rootmodel.add_organization(organization)
102
+ def add_organization(organization)
103
+ if organization.nil?
104
+ return nil
105
+ end
106
+
107
+ if !organization.is_a?(Organization)
108
+ raise ArgumentError.new("Expected an organization")
109
+ end
110
+
111
+ if organization.integration_id.nil? || organization.integration_id.length == 0
112
+ raise IntegrationIdIsRequiredError, "An integration id is required for an organization."
113
+ end
114
+
115
+ if find_organization_by_integration_id(organization.integration_id, false) != nil
116
+ raise AlreadyAddedError, "Already added an organization with integration_id #{organization.integration_id}"
117
+ end
118
+
119
+ @organizations[organization.integration_id] = organization
120
+ organization.set_is_immutable
121
+
122
+ return organization
123
+ end
124
+
125
+ # Adds the specifed deal object to the model.
126
+ # @example Add a deal from a new deal
127
+ # deal = MoveToGo::Deal.new
128
+ # deal.integration_id = "123"
129
+ # deal.name = "Big deal"
130
+ # rootmodel.add_deal(deal)
131
+ def add_deal(deal)
132
+ if deal.nil?
133
+ return nil
134
+ end
135
+
136
+ if !deal.is_a?(Deal)
137
+ raise ArgumentError.new("Expected a deal")
138
+ end
139
+
140
+ if deal.integration_id.nil? || deal.integration_id.length == 0
141
+ raise IntegrationIdIsRequiredError, "An integration id is required for a deal."
142
+ end
143
+
144
+ if find_deal_by_integration_id(deal.integration_id, false) != nil
145
+ raise AlreadyAddedError, "Already added a deal with integration_id #{deal.integration_id}"
146
+ end
147
+
148
+ if !configuration[:allow_deals_without_responsible] && deal.responsible_coworker.nil?
149
+ deal.responsible_coworker = @migrator_coworker
150
+ end
151
+
152
+ @deals[deal.integration_id] = deal
153
+ deal.set_is_immutable
154
+
155
+ return deal
156
+ end
157
+
158
+ def configure()
159
+ if defined?(ALLOW_DEALS_WITHOUT_RESPONSIBLE)
160
+ config_value = ALLOW_DEALS_WITHOUT_RESPONSIBLE.to_s
161
+
162
+ configuration[:allow_deals_without_responsible] =
163
+ config_value.downcase == "true" || config_value == "1"
164
+ end
165
+
166
+ if defined?(REPORT_RESULT)
167
+ config_value = REPORT_RESULT.to_s
168
+
169
+ configuration[:report_result] =
170
+ config_value.downcase == "true" || config_value == "1"
171
+ end
172
+ end
173
+
174
+ def add_sales_call(sales_call)
175
+ if sales_call.nil?
176
+ return nil
177
+ end
178
+ if !sales_call.is_a?(SalesCall)
179
+ raise ArgumentError.new("Expected a SalesCall")
180
+ end
181
+ add_history(sales_call)
182
+ end
183
+
184
+ def add_comment(comment)
185
+ if comment.nil?
186
+ return nil
187
+ end
188
+ if !comment.is_a?(Comment)
189
+ raise ArgumentError.new("Expected a Comment")
190
+ end
191
+ add_history(comment)
192
+ end
193
+
194
+ def add_talked_to(talked_to)
195
+ if talked_to.nil?
196
+ return nil
197
+ end
198
+ if !talked_to.is_a?(TalkedTo)
199
+ raise ArgumentError.new("Expected a TalkedTo")
200
+ end
201
+ add_history(talked_to)
202
+ end
203
+
204
+ def add_tried_to_reach(tried_to_reach)
205
+ if tried_to_reach.nil?
206
+ return nil
207
+ end
208
+ if !tried_to_reach.is_a?(TriedToReach)
209
+ raise ArgumentError.new("Expected a TriedToReach")
210
+ end
211
+ add_history(tried_to_reach)
212
+ end
213
+
214
+ def add_client_visit(client_visit)
215
+ if client_visit.nil?
216
+ return nil
217
+ end
218
+ if !client_visit.is_a?(ClientVisit)
219
+ raise ArgumentError.new("Expected a ClientVisit")
220
+ end
221
+ add_history(client_visit)
222
+ end
223
+
224
+ # Adds the specifed history object to the model.
225
+ #
226
+ # If no integration_id has been specifed move-to-go generate
227
+ # one.
228
+ #
229
+ # @example Add a comment from a new comment
230
+ # comment = MoveToGo::Comment.new
231
+ # comment.integration_id = "123"
232
+ # comment.text = "This is a history"
233
+ # rootmodel.add_comment(comment)
234
+ def add_history(history)
235
+ if history.nil?
236
+ return nil
237
+ end
238
+
239
+ if !history.is_a?(History)
240
+ raise ArgumentError.new("Expected a history")
241
+ end
242
+
243
+ if history.integration_id.nil? || history.integration_id.length == 0
244
+ history.integration_id = @histories.length.to_s
245
+ end
246
+
247
+ if find_history_by_integration_id(history.integration_id, false) != nil
248
+ raise AlreadyAddedError, "Already added a history with integration_id #{history.integration_id}"
249
+ end
250
+
251
+ if history.created_by.nil?
252
+ history.created_by = @migrator_coworker
253
+ end
254
+
255
+ @histories[history.integration_id] = history
256
+ history.set_is_immutable
257
+
258
+ return history
259
+ end
260
+
261
+ def add_link(link)
262
+ @documents = Documents.new if @documents == nil
263
+
264
+ return @documents.add_link(link)
265
+ end
266
+
267
+ def add_file(file)
268
+ @documents = Documents.new if @documents == nil
269
+
270
+ return @documents.add_file(file)
271
+ end
272
+
273
+ def find_coworker_by_integration_id(integration_id, report_result=!!configuration[:report_result])
274
+ if @coworkers.has_key?(integration_id)
275
+ return @coworkers[integration_id]
276
+ else
277
+ report_failed_to_find_object("coworker", ":#{integration_id}") if report_result
278
+ return nil
279
+ end
280
+ end
281
+
282
+ def find_organization_by_integration_id(integration_id, report_result=!!configuration[:report_result])
283
+ if @organizations.has_key?(integration_id)
284
+ return @organizations[integration_id]
285
+ else
286
+ report_failed_to_find_object("organization", ":#{integration_id}") if report_result
287
+ return nil
288
+ end
289
+
290
+ end
291
+
292
+ def find_person_by_integration_id(integration_id, report_result=!!configuration[:report_result])
293
+ return nil if @organizations.nil?
294
+ @organizations.each do |key, organization|
295
+ person = organization.find_employee_by_integration_id(integration_id)
296
+ return person if person
297
+ end
298
+ report_failed_to_find_object("person", ":#{integration_id}") if report_result
299
+ return nil
300
+ end
301
+
302
+ def find_history_by_integration_id(integration_id, report_result=!!configuration[:report_result])
303
+ if @histories.has_key?(integration_id)
304
+ return @histories[integration_id]
305
+ else
306
+ report_failed_to_find_object("history", ":#{integration_id}") if report_result
307
+ return nil
308
+ end
309
+ end
310
+
311
+ # find deals for organization using {Organization#integration_id}
312
+ def find_deals_for_organization(organization)
313
+ deals = []
314
+
315
+ deals = @deals.values.select do |deal|
316
+ !deal.customer.nil? && deal.customer.integration_id == organization.integration_id
317
+ end
318
+ return deals
319
+ end
320
+
321
+ def find_deal_by_integration_id(integration_id, report_result=!!configuration[:report_result])
322
+ if @deals.has_key?(integration_id)
323
+ return @deals[integration_id]
324
+ else
325
+ report_failed_to_find_object("deal", ":#{integration_id}") if report_result
326
+ return nil
327
+ end
328
+ end
329
+
330
+ # Finds a organization based on one of its property.
331
+ # Returns the first found matching organization
332
+ # Method is much slower then using find_organization_by_integration_id
333
+ # @example Finds a organization on its name
334
+ # rm.find_organization {|org| org.name == "Lundalogik" }
335
+ def find_organization(report_result=!!configuration[:report_result], &block)
336
+ result = find(@organizations.values.flatten, &block)
337
+ report_failed_to_find_object("organization") if result.nil? and report_result
338
+ return result
339
+ end
340
+
341
+ # Finds organizations based on one of their property.
342
+ # Returns all matching organizations
343
+ # @example Selects organizations on their names
344
+ # rm.select_organizations {|org| org.name == "Lundalogik" }
345
+ def select_organizations(report_result=!!configuration[:report_result], &block)
346
+ result = select(@organizations.values.flatten, &block)
347
+ report_failed_to_find_object("organization") if result.empty? and report_result
348
+ return result
349
+ end
350
+
351
+ # Finds a person based on one of its property.
352
+ # Returns the first found matching person
353
+ # @example Finds a person on its name
354
+ # rm.find_person {|person| person.first_name == "Kalle" }
355
+ def find_person(report_result=!!configuration[:report_result], &block)
356
+ result = find(persons, &block)
357
+ report_failed_to_find_object("person") if result.nil? and report_result
358
+ return result
359
+ end
360
+
361
+ # Finds persons based on one of their property.
362
+ # Returns all matching persons
363
+ # @example Selects persons on their names
364
+ # rm.select_person {|p| p.first_name == "Kalle" }
365
+ def select_persons(report_result=!!configuration[:report_result], &block)
366
+ result = select(persons, &block)
367
+ report_failed_to_find_object("person") if result.empty? and report_result
368
+ return result
369
+ end
370
+
371
+ # Finds a deal based on one of its property.
372
+ # Returns the first found matching deal
373
+ # Method is much slower then using find_deal_by_integration_id
374
+ # @example Finds a deal on its name
375
+ # rm.find_deal {|deal| deal.value == 120000 }
376
+ def find_deal(report_result=!!configuration[:report_result], &block)
377
+ result = find(@deals.values.flatten, &block)
378
+ report_failed_to_find_object("person") if result.nil? and report_result
379
+ return result
380
+ end
381
+
382
+ # Finds deals based on one of their property.
383
+ # Returns all matching deals
384
+ # @example Selects deals on their names
385
+ # rm.select_deals {|deal| deal.name == "Big Deal" }
386
+ def select_deals(report_result=!!configuration[:report_result], &block)
387
+ result = select(@deals.values.flatten, &block)
388
+ report_failed_to_find_object("deal") if result.empty? and report_result
389
+ return result
390
+ end
391
+
392
+ # Finds a coworker based on one of its property.
393
+ # Returns the first found matching coworker
394
+ # @example Finds a coworker on its name
395
+ # rm.find_coworker {|coworker| coworker.email == "kalle@kula.se" }
396
+ def find_coworker(report_result=!!configuration[:report_result], &block)
397
+ result = find(@coworkers.values.flatten, &block)
398
+ report_failed_to_find_object("coworker") if result.nil? and report_result
399
+ return result
400
+ end
401
+
402
+ # Finds coworkers based on one of their property.
403
+ # Returns all matching coworkers
404
+ # @example Selects coworkers on their names
405
+ # rm.select_coworkers {|coworker| coworker.email == "kalle@kula.se" }
406
+ def select_coworkers(report_result=!!configuration[:report_result], &block)
407
+ result = select(@coworkers, &block)
408
+ report_failed_to_find_object("coworker") if result.empty? and report_result
409
+ return result
410
+ end
411
+
412
+
413
+ # Finds a history based on one of its property.
414
+ # Returns the first found matching history
415
+ # @example Finds a history on its name
416
+ # rm.find_history {|history| history.text == "hello!" }
417
+ def find_history(report_result=!!configuration[:report_result], &block)
418
+ result = find(@histories.values.flatten, &block)
419
+ report_failed_to_find_object("history") if result.nil? and report_result
420
+ return result
421
+ end
422
+
423
+ # Finds a document based on one of its property.
424
+ # Returns the first found matching document
425
+ # @example Finds a document on its name
426
+ # rm.find_document(:file) {|document| document.name == "Important Tender" }
427
+ def find_document(type, report_result=!!configuration[:report_result], &block)
428
+ result = find(@documents.files, &block) if type == :file
429
+ result = find(@documents.links, &block) if type == :link
430
+ report_failed_to_find_object("document") if result.nil? and report_result
431
+ return result
432
+ end
433
+
434
+ # Returns a string describing problems with the data. For
435
+ # instance if integration_id for any entity is not unique.
436
+ def sanity_check
437
+ error = String.new
438
+
439
+ # dups = get_integration_id_duplicates(with_non_empty_integration_id(@coworkers))
440
+ # dups_error_items = (dups.collect{|coworker| coworker.integration_id}).compact
441
+ # if dups.length > 0
442
+ # error = "#{error}\nDuplicate coworker integration_id: #{dups_error_items.join(", ")}."
443
+ # end
444
+
445
+ # dups = get_integration_id_duplicates(with_non_empty_integration_id(@organizations))
446
+ # dups_error_items = (dups.collect{|org| org.integration_id}).compact
447
+ # if dups.length > 0
448
+ # error = "#{error}\nDuplicate organization integration_id: #{dups_error_items.join(", ")}."
449
+ # end
450
+
451
+ # dups = get_integration_id_duplicates(with_non_empty_integration_id(@deals))
452
+ # dups_error_items = (dups.collect{|deal| deal.integration_id}).compact
453
+ # if dups_error_items.length > 0
454
+ # error = "#{error}\nDuplicate deal integration_id: #{dups_error_items.join(", ")}."
455
+ # end
456
+
457
+ persons = @organizations.collect{|k, o| o.employees}.flatten.compact
458
+ dups = get_integration_id_duplicates(with_non_empty_integration_id(persons))
459
+ dups_error_items = (dups.collect{|person| person.integration_id}).compact
460
+ if dups_error_items.length > 0
461
+ error = "#{error}\nDuplicate person integration_id: #{dups_error_items.join(", ")}."
462
+ end
463
+
464
+ dups = get_integration_id_duplicates(with_non_empty_integration_id(@documents.links))
465
+ dups_error_items = (dups.collect{|l| l.integration_id}).compact
466
+ if dups_error_items.length > 0
467
+ error = "#{error}\nDuplicate link integration_id: #{dups_error_items.join(", ")}."
468
+ end
469
+
470
+ return error.strip
471
+ end
472
+
473
+ def validate(ignore_invalid_files = false, max_file_size)
474
+ errors = String.new
475
+ warnings = String.new
476
+
477
+ @organizations.each do |k, o|
478
+ validation_message = o.validate()
479
+
480
+ if !validation_message.empty?
481
+ errors = "#{errors}\n#{validation_message}"
482
+ end
483
+ end
484
+
485
+ converter_deal_statuses = @settings.deal.statuses.map {|status| status.label} if @settings.deal != nil
486
+ @deals.each do |key, deal|
487
+ error, warning = deal.validate converter_deal_statuses
488
+
489
+ if !error.empty?
490
+ errors = "#{errors}\n#{error}"
491
+ end
492
+ if !warning.empty?
493
+ warnings = "#{warnings}\n#{warning}"
494
+ end
495
+ end
496
+
497
+ @histories.each do |key, history|
498
+ validation_message = history.validate
499
+
500
+ if !validation_message.empty?
501
+ errors = "#{errors}\n#{validation_message}"
502
+ end
503
+ end
504
+
505
+ @documents.links.each do |link|
506
+ validation_message = link.validate
507
+ if !validation_message.empty?
508
+ errors = "#{errors}\n#{validation_message}"
509
+ end
510
+ end
511
+
512
+ @documents.files.each do |file|
513
+ validation_message = file.validate(ignore_invalid_files, max_file_size)
514
+ if !validation_message.empty?
515
+ errors = "#{errors}\n#{validation_message}"
516
+ end
517
+ end
518
+
519
+ return [errors.strip, warnings.strip]
520
+ end
521
+
522
+ # @!visibility private
523
+ def to_rexml(doc)
524
+ element_name = serialize_name
525
+ elem = doc.add_element(element_name,{"Version"=>"v3_0"})
526
+ SerializeHelper::serialize_variables_rexml(elem, self)
527
+ end
528
+
529
+ # @!visibility private
530
+ # zip-filename is the name of the zip file to create
531
+ def save_to_zip(zip_filename, files_filename)
532
+ puts "Trying to save to zip..."
533
+ # saves the model to a zipfile that contains xml data and
534
+ # document files.
535
+
536
+ if ::File.exists?(zip_filename)
537
+ ::File.delete zip_filename
538
+ end
539
+
540
+ go_data_file = Tempfile.new('go')
541
+ puts "Creating go.xml file with data..."
542
+ if !files_filename.nil?
543
+ saved_documents = @documents
544
+ @documents = Documents.new
545
+ end
546
+ serialize_to_file(go_data_file)
547
+ create_zip(zip_filename, go_data_file, documents.files)
548
+
549
+ if !files_filename.nil?
550
+ go_files_file = Tempfile.new('go-files')
551
+ puts "Creating go.xml file with documents information..."
552
+ @organizations = []
553
+ @coworkers = []
554
+ @deals = []
555
+ @histories = []
556
+ @documents = saved_documents
557
+ serialize_to_file(go_files_file)
558
+
559
+ files_zip_filename = files_filename+".zip"
560
+ if ::File.exists?(files_zip_filename)
561
+ ::File.delete files_zip_filename
562
+ end
563
+ create_zip(files_zip_filename, go_files_file, documents.files)
564
+ end
565
+ end
566
+
567
+ def create_zip(filename, xml, files)
568
+ Zip::File.open("#{Dir.pwd}/#{filename}", Zip::File::CREATE) do |zip_file|
569
+ puts "Add go.xml file to zip '#{filename}'..."
570
+ zip_file.add('go.xml', xml)
571
+
572
+ if files.length > 0
573
+ if defined?(FILES_FOLDER) && !FILES_FOLDER.empty?()
574
+ puts "Files with relative path are imported from '#{FILES_FOLDER}'."
575
+ root_folder = FILES_FOLDER
576
+ else
577
+ puts "Files with relative path are imported from the current folder (#{Dir.pwd})."
578
+ root_folder = Dir.pwd
579
+ end
580
+
581
+ # If a file's path is absolute, then we probably dont
582
+ # have the files in the same location here. For
583
+ # example, the customer might have stored their files
584
+ # at f:\lime-easy\documents. We must replace this part
585
+ # of each file with the root_folder from above.
586
+ if defined?(FILES_FOLDER_AT_CUSTOMER) && !FILES_FOLDER_AT_CUSTOMER.empty?()
587
+ files_folder_at_customer = FILES_FOLDER_AT_CUSTOMER
588
+ puts "Files with absolute paths will have the part '#{files_folder_at_customer}' replaced with '#{root_folder}'."
589
+ else
590
+ files_folder_at_customer = ""
591
+ puts "Files with absolute paths will be imported from their origial location."
592
+ end
593
+
594
+ # 1) files/ - a folder with all files referenced from
595
+ # the source.
596
+ files.with_progress(" - Trying to add files to zip...").each do |file|
597
+ # we dont need to check that the file exists since
598
+ # we assume that rootmodel.validate has been
599
+ # called before save_to_zip.
600
+ file.add_to_zip_file(zip_file)
601
+ end
602
+ end
603
+ puts "Compressing zip file ... "
604
+ end
605
+ end
606
+
607
+ def report_rootmodel_status
608
+ #nbr_of_persons = @organizations.collect{|k, o| o.employees}.flatten.compact.length
609
+ nbr_of_documents = @documents.files.length + @documents.links.length
610
+ puts "Rootmodel contains:\n" \
611
+ " Organizations: #{@organizations.length}\n" \
612
+ " Persons: #{persons.length}\n" \
613
+ " Deals: #{@deals.length}\n" \
614
+ " History logs: #{@histories.length}\n" \
615
+ " Documents: #{nbr_of_documents}"
616
+ end
617
+
618
+ private
619
+ # returns all items from the object array with duplicate integration ids.
620
+ # To get all organizations with the same integration_id use
621
+ # @example Get all the organization duplicates with the same integration id
622
+ # rm.get_integration_id_duplicates(rm.organizations)
623
+ def get_integration_id_duplicates(objects)
624
+ uniq_items = objects.uniq {|item| item.integration_id}.compact
625
+
626
+ return (objects - uniq_items).compact
627
+ end
628
+
629
+ def with_non_empty_integration_id(objects)
630
+ return objects.select do |obj|
631
+ obj.integration_id != nil && !obj.integration_id.empty?
632
+ end
633
+ end
634
+
635
+ # Prints a warning text if a find-function returns nil
636
+ def report_failed_to_find_object(object, search_string="")
637
+ c = caller_locations(2).first
638
+ puts "Warning: #{c.label}:#{c.lineno}: Failed to find #{object}#{search_string}"
639
+ end
640
+
641
+ def find(array)
642
+ result = nil
643
+ array.each do |obj|
644
+ if yield(obj)
645
+ result = obj
646
+ break
647
+ end
648
+ end
649
+ return result
650
+ end
651
+
652
+ def select(array)
653
+ result = []
654
+ array.each do |obj|
655
+ if yield(obj)
656
+ result.push obj
657
+ end
658
+ end
659
+ return result
660
+ end
661
+
662
+ end
663
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'history'
2
+ module MoveToGo
3
+ class SalesCall < History
4
+ def initialize(opt = nil)
5
+ super(opt)
6
+
7
+ @classification = HistoryClassification::SalesCall
8
+ end
9
+ end
10
+ end