move-to-go 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/move-to-go +210 -0
- data/lib/move-to-go/can_become_immutable.rb +29 -0
- data/lib/move-to-go/csv_helper.rb +47 -0
- data/lib/move-to-go/email_helper.rb +14 -0
- data/lib/move-to-go/errors.rb +31 -0
- data/lib/move-to-go/excel_helper.rb +10 -0
- data/lib/move-to-go/global_phone.json +6571 -0
- data/lib/move-to-go/model/address.rb +63 -0
- data/lib/move-to-go/model/class_settings.rb +50 -0
- data/lib/move-to-go/model/clientvisit.rb +10 -0
- data/lib/move-to-go/model/comment.rb +10 -0
- data/lib/move-to-go/model/coworker.rb +82 -0
- data/lib/move-to-go/model/coworker_reference.rb +33 -0
- data/lib/move-to-go/model/customfield.rb +87 -0
- data/lib/move-to-go/model/deal.rb +216 -0
- data/lib/move-to-go/model/deal_class_settings.rb +97 -0
- data/lib/move-to-go/model/deal_state.rb +15 -0
- data/lib/move-to-go/model/deal_status.rb +23 -0
- data/lib/move-to-go/model/deal_status_reference.rb +47 -0
- data/lib/move-to-go/model/deal_status_setting.rb +49 -0
- data/lib/move-to-go/model/documents.rb +76 -0
- data/lib/move-to-go/model/file.rb +193 -0
- data/lib/move-to-go/model/history.rb +148 -0
- data/lib/move-to-go/model/history_classification.rb +26 -0
- data/lib/move-to-go/model/link.rb +82 -0
- data/lib/move-to-go/model/organization.rb +250 -0
- data/lib/move-to-go/model/person.rb +164 -0
- data/lib/move-to-go/model/referencetosource.rb +58 -0
- data/lib/move-to-go/model/relation.rb +23 -0
- data/lib/move-to-go/model/rootmodel.rb +663 -0
- data/lib/move-to-go/model/salescall.rb +10 -0
- data/lib/move-to-go/model/settings.rb +61 -0
- data/lib/move-to-go/model/tag.rb +35 -0
- data/lib/move-to-go/model/talkedto.rb +10 -0
- data/lib/move-to-go/model/triedtoreach.rb +10 -0
- data/lib/move-to-go/model_helpers.rb +97 -0
- data/lib/move-to-go/phone_helper.rb +75 -0
- data/lib/move-to-go/roo_helper.rb +82 -0
- data/lib/move-to-go/serialize_helper.rb +199 -0
- data/lib/move-to-go/shard_helper.rb +96 -0
- data/lib/move-to-go/source.rb +108 -0
- data/lib/move-to-go/templating.rb +52 -0
- data/lib/move-to-go.rb +20 -0
- data/sources/VISMA/.gitignore +14 -0
- data/sources/VISMA/.move-to-go/readme.txt +1 -0
- data/sources/VISMA/.move-to-go/runner.rb +89 -0
- data/sources/VISMA/Database/KONTAKT.DBF +0 -0
- data/sources/VISMA/Database/KUND.DBF +0 -0
- data/sources/VISMA/Gemfile +5 -0
- data/sources/VISMA/converter.rb +120 -0
- data/sources/base-crm/.move-to-go/runner.rb +235 -0
- data/sources/base-crm/Gemfile +5 -0
- data/sources/base-crm/README.md +9 -0
- data/sources/base-crm/converter.rb +56 -0
- data/sources/base-crm/data/contacts.csv +13 -0
- data/sources/base-crm/data/coworkers.csv +3 -0
- data/sources/base-crm/data/deals.csv +5 -0
- data/sources/base-crm/data/histories.csv +6 -0
- data/sources/base-crm/data/leads.csv +4 -0
- data/sources/base-crm/data/tasks.csv +5 -0
- data/sources/csv/.gitignore +14 -0
- data/sources/csv/.move-to-go/readme.txt +1 -0
- data/sources/csv/.move-to-go/runner.rb +65 -0
- data/sources/csv/Gemfile +5 -0
- data/sources/csv/converter.rb +218 -0
- data/sources/csv/data/coworkers.csv +2 -0
- data/sources/csv/data/deals.csv +2 -0
- data/sources/csv/data/organizations.csv +2 -0
- data/sources/csv/data/persons.csv +2 -0
- data/sources/custom/.gitignore +14 -0
- data/sources/custom/.move-to-go/readme.txt +1 -0
- data/sources/custom/.move-to-go/runner.rb +30 -0
- data/sources/custom/Gemfile +4 -0
- data/sources/custom/converter.rb +45 -0
- data/sources/excel/.gitignore +14 -0
- data/sources/excel/.move-to-go/readme.txt +3 -0
- data/sources/excel/.move-to-go/runner.rb +140 -0
- data/sources/excel/Gemfile +7 -0
- data/sources/excel/converter.rb +188 -0
- data/sources/excel/files/avtal.docx +0 -0
- data/sources/excel/files/more/avtal.docx +0 -0
- data/sources/excel/files/more/offert-2.pdf +0 -0
- data/sources/excel/files/offert-2.docx +0 -0
- data/sources/excel/files/offert.docx +0 -0
- data/sources/excel/sample-data.xlsx +0 -0
- data/sources/excel-basic/.gitignore +14 -0
- data/sources/excel-basic/.move-to-go/readme.txt +3 -0
- data/sources/excel-basic/.move-to-go/runner.rb +139 -0
- data/sources/excel-basic/Exempelfil.xlsx +0 -0
- data/sources/excel-basic/Gemfile +6 -0
- data/sources/excel-basic/converter.rb +175 -0
- data/sources/excel-basic/files/avtal.docx +0 -0
- data/sources/excel-basic/files/more/avtal.docx +0 -0
- data/sources/excel-basic/files/more/offert-2.pdf +0 -0
- data/sources/excel-basic/files/offert-2.docx +0 -0
- data/sources/excel-basic/files/offert.docx +0 -0
- data/sources/lime-crm-basic/.gitignore +14 -0
- data/sources/lime-crm-basic/.move-to-go/readme.txt +1 -0
- data/sources/lime-crm-basic/.move-to-go/runner.rb +524 -0
- data/sources/lime-crm-basic/Gemfile +6 -0
- data/sources/lime-crm-basic/converter.rb +396 -0
- data/sources/lime-easy/.gitignore +14 -0
- data/sources/lime-easy/.move-to-go/readme.txt +1 -0
- data/sources/lime-easy/.move-to-go/runner.rb +348 -0
- data/sources/lime-easy/Export/readme.txt +6 -0
- data/sources/lime-easy/Gemfile +5 -0
- data/sources/lime-easy/converter.rb +362 -0
- data/sources/salesforce/.gitignore +14 -0
- data/sources/salesforce/.move-to-go/readme.txt +1 -0
- data/sources/salesforce/.move-to-go/runner.rb +404 -0
- data/sources/salesforce/Gemfile +6 -0
- data/sources/salesforce/Gemfile.lock +48 -0
- data/sources/salesforce/converter.rb +113 -0
- data/sources/salesforce/export/readme.txt +3 -0
- data/spec/address_spec.rb +49 -0
- data/spec/class_settings_spec.rb +37 -0
- data/spec/coworker_spec.rb +94 -0
- data/spec/custom_field_spec.rb +22 -0
- data/spec/deal_class_settings_spec.rb +116 -0
- data/spec/deal_spec.rb +232 -0
- data/spec/deal_status_reference_spec.rb +17 -0
- data/spec/documents_spec.rb +64 -0
- data/spec/file_spec.rb +178 -0
- data/spec/helpers/csv_helper_spec.rb +45 -0
- data/spec/helpers/email_helper_spec.rb +37 -0
- data/spec/helpers/phone_helper_spec.rb +119 -0
- data/spec/helpers/roo_helper_spec.rb +10 -0
- data/spec/helpers/serialize_helper_spec.rb +253 -0
- data/spec/helpers/shard_helper_spec.rb +141 -0
- data/spec/helpers/xsd_validate_spec.rb +57 -0
- data/spec/history_spec.rb +150 -0
- data/spec/link_spec.rb +107 -0
- data/spec/organization_spec.rb +221 -0
- data/spec/person_spec.rb +129 -0
- data/spec/rootmodel_spec.rb +993 -0
- data/spec/spec_helper.rb +30 -0
- metadata +362 -0
@@ -0,0 +1,404 @@
|
|
1
|
+
|
2
|
+
require 'zip'
|
3
|
+
|
4
|
+
require 'move-to-go'
|
5
|
+
require_relative("../converter")
|
6
|
+
|
7
|
+
# EXPORT_FOLDER and other constants should be defined ../converter.rb
|
8
|
+
|
9
|
+
USER_FILE = "User.csv"
|
10
|
+
ORGANIZATION_ACCOUNT_FILE = "Account.csv"
|
11
|
+
ORGANIZATION_LEAD_FILE = "Lead.csv"
|
12
|
+
PERSON_FILE = "Contact.csv"
|
13
|
+
DEAL_FILE = "Opportunity.csv"
|
14
|
+
NOTE_FILE = "Note.csv"
|
15
|
+
|
16
|
+
def process_rows(filename)
|
17
|
+
if !File.exists?(filename)
|
18
|
+
puts "Error: Cant find the file '#{filename}'."
|
19
|
+
raise
|
20
|
+
end
|
21
|
+
|
22
|
+
f = File.open(filename, 'r')
|
23
|
+
data = f.read.encode("UTF-8", "ISO-8859-1")
|
24
|
+
rows = MoveToGo::CsvHelper::text_to_hashes(data, ',')
|
25
|
+
rows.each do |row|
|
26
|
+
yield row
|
27
|
+
end
|
28
|
+
f.close
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_salesforce_export_zipfile()
|
32
|
+
if defined?(EXPORT_FOLDER)
|
33
|
+
if EXPORT_FOLDER.nil? || EXPORT_FOLDER.empty?
|
34
|
+
puts "EXPORT_FOLDER is empty, using 'export' as default."
|
35
|
+
export_folder = File.expand_path("export", Dir.pwd)
|
36
|
+
else
|
37
|
+
export_folder = File.expand_path(EXPORT_FOLDER, Dir.pwd)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
puts "EXPORT_FOLDER is not defined, using 'export' as default."
|
41
|
+
export_folder = File.expand_path("export", Dir.pwd)
|
42
|
+
end
|
43
|
+
|
44
|
+
puts "Searching '#{export_folder}' for Salesforce export zip file..."
|
45
|
+
|
46
|
+
if defined?(EXPORT_FILE)
|
47
|
+
if EXPORT_FILE.nil? || EXPORT_FILE.empty?
|
48
|
+
export_zip_files = Dir.glob(File.join(export_folder, "*.zip"))
|
49
|
+
else
|
50
|
+
export_zip_files = Dir.glob(File.join(export_folder, EXPORT_FILE))
|
51
|
+
end
|
52
|
+
else
|
53
|
+
export_zip_files = Dir.glob(File.join(export_folder, "*.zip"))
|
54
|
+
end
|
55
|
+
|
56
|
+
if export_zip_files.length == 0
|
57
|
+
puts "No zip file found, please copy your Salesforce export zipfile to '#{export_folder}'."
|
58
|
+
return nil
|
59
|
+
elsif export_zip_files.length > 1
|
60
|
+
puts "More than one zip file found in '#{export_folder}', either remove all but one or set the EXPORT_FILE in converter.rb"
|
61
|
+
return nil
|
62
|
+
elsif export_zip_files.length == 1
|
63
|
+
puts "Found zipfile to import from. Using: '#{export_zip_files[0]}'."
|
64
|
+
return export_zip_files[0]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_coworker(row)
|
69
|
+
coworker = nil
|
70
|
+
|
71
|
+
if row['IsActive'] == '1' && row['UserType'] == 'Standard'
|
72
|
+
coworker = MoveToGo::Coworker.new
|
73
|
+
|
74
|
+
coworker.email = row['Email']
|
75
|
+
coworker.integration_id = row['Id']
|
76
|
+
coworker.first_name = row['FirstName']
|
77
|
+
coworker.last_name = row['LastName']
|
78
|
+
coworker.direct_phone_number = row['Phone']
|
79
|
+
coworker.mobile_phone_number = row['MobilePhone']
|
80
|
+
end
|
81
|
+
|
82
|
+
return coworker
|
83
|
+
end
|
84
|
+
|
85
|
+
def account_to_organization(row, rootmodel)
|
86
|
+
if row['IsDeleted'] != '0'
|
87
|
+
return nil
|
88
|
+
end
|
89
|
+
|
90
|
+
organization = MoveToGo::Organization.new
|
91
|
+
|
92
|
+
organization.relation = MoveToGo::Relation::IsACustomer
|
93
|
+
organization.integration_id = row['Id']
|
94
|
+
organization.name = row['Name']
|
95
|
+
organization.set_tag(row['Type'])
|
96
|
+
|
97
|
+
organization.central_phone_number = row['Phone']
|
98
|
+
organization.web_site = row['Website']
|
99
|
+
|
100
|
+
organization.with_postal_address do |address|
|
101
|
+
address.street = row['BillingStreet']
|
102
|
+
address.zip_code = row['BillingPostalCode']
|
103
|
+
address.city = row['BillingCity']
|
104
|
+
address.country_code = get_country_code(row['BillingCountry'])
|
105
|
+
end
|
106
|
+
|
107
|
+
organization.with_visit_address do |address|
|
108
|
+
address.street = row['ShippingStreet']
|
109
|
+
address.zip_code = row['ShippingPostalCode']
|
110
|
+
address.city = row['ShippingCity']
|
111
|
+
address.country_code = get_country_code(row['ShippingCountry'])
|
112
|
+
end
|
113
|
+
|
114
|
+
organization.set_tag row['Industry']
|
115
|
+
|
116
|
+
organization.responsible_coworker =
|
117
|
+
rootmodel.find_coworker_by_integration_id(row['OwnerId'])
|
118
|
+
|
119
|
+
converter.organization_hook(row, organization, rootmodel) if defined? converter.organization_hook
|
120
|
+
|
121
|
+
return organization
|
122
|
+
end
|
123
|
+
|
124
|
+
def lead_to_organization(row, rootmodel, converter)
|
125
|
+
if row['IsDeleted'] != '0'
|
126
|
+
return nil
|
127
|
+
end
|
128
|
+
|
129
|
+
if row['IsConverted'] == '1'
|
130
|
+
return nil
|
131
|
+
end
|
132
|
+
|
133
|
+
organization = MoveToGo::Organization.new
|
134
|
+
|
135
|
+
if converter.respond_to?(:get_relation_for_lead)
|
136
|
+
relation = converter.get_relation_for_lead
|
137
|
+
|
138
|
+
if !relation.nil?
|
139
|
+
organization.relation = relation
|
140
|
+
else
|
141
|
+
organization.relation = MoveToGo::Relation::WorkingOnIt
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
use_default_lead_tag = true
|
146
|
+
if converter.respond_to?(:get_tags_for_lead)
|
147
|
+
tags = converter.get_tags_for_lead(row['Status'])
|
148
|
+
|
149
|
+
if !tags.nil?
|
150
|
+
if tags.is_a?(String)
|
151
|
+
organization.set_tag tags
|
152
|
+
use_default_lead_tag = false
|
153
|
+
elsif tags.is_a?(Array)
|
154
|
+
tags.each do |tag|
|
155
|
+
organization.set_tag tag
|
156
|
+
end
|
157
|
+
use_default_lead_tag = false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
if use_default_lead_tag == true
|
162
|
+
organization.set_tag 'lead'
|
163
|
+
organization.set_tag row['Status']
|
164
|
+
end
|
165
|
+
|
166
|
+
organization.responsible_coworker =
|
167
|
+
rootmodel.find_coworker_by_integration_id(row['OwnerId'])
|
168
|
+
|
169
|
+
organization.name = row['Company']
|
170
|
+
organization.with_postal_address do |address|
|
171
|
+
address.street = row['Street']
|
172
|
+
address.zip_code = row['PostalCode']
|
173
|
+
address.city = row['City']
|
174
|
+
address.country_code = get_country_code(row['Country'])
|
175
|
+
end
|
176
|
+
organization.web_site = row['WebSite']
|
177
|
+
|
178
|
+
organization.set_tag row['Industry']
|
179
|
+
|
180
|
+
person = MoveToGo::Person.new
|
181
|
+
organization.add_employee(person)
|
182
|
+
person.first_name = row['FirstName']
|
183
|
+
person.last_name = row['LastName']
|
184
|
+
person.position = row['Title']
|
185
|
+
person.direct_phone_number = row['Phone']
|
186
|
+
person.mobile_phone_number = row['MobilePhone']
|
187
|
+
person.email = row['Email']
|
188
|
+
|
189
|
+
return organization
|
190
|
+
end
|
191
|
+
|
192
|
+
def get_country_code(country)
|
193
|
+
country_code = ''
|
194
|
+
|
195
|
+
case country.downcase
|
196
|
+
when 'sverige'
|
197
|
+
country_code = 'se'
|
198
|
+
when 'sweden'
|
199
|
+
country_code = 'se'
|
200
|
+
when 'norge'
|
201
|
+
country_code = 'no'
|
202
|
+
when 'norway'
|
203
|
+
country_code = 'no'
|
204
|
+
when 'danmark'
|
205
|
+
country_code = 'dk'
|
206
|
+
when 'denmark'
|
207
|
+
country_code = 'dk'
|
208
|
+
end
|
209
|
+
|
210
|
+
return country_code
|
211
|
+
end
|
212
|
+
|
213
|
+
def add_person_to_organization(row, rootmodel)
|
214
|
+
if row['IsDeleted'] != '0'
|
215
|
+
return
|
216
|
+
end
|
217
|
+
|
218
|
+
org = rootmodel.find_organization_by_integration_id(row['AccountId'])
|
219
|
+
if !org.nil?
|
220
|
+
person = MoveToGo::Person.new
|
221
|
+
org.add_employee(person)
|
222
|
+
|
223
|
+
person.integration_id = row['Id']
|
224
|
+
person.first_name = row['FirstName']
|
225
|
+
person.last_name = row['LastName']
|
226
|
+
|
227
|
+
person.direct_phone_number = row['Phone']
|
228
|
+
person.fax_phone_number = row['Fax']
|
229
|
+
person.mobile_phone_number = row['MobilePhone']
|
230
|
+
person.home_phone_number = row['HomePhone']
|
231
|
+
person.position = row['Title']
|
232
|
+
person.email = row['Email']
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_deal(row, rootmodel, converter)
|
237
|
+
if row['IsDeleted'] != '0'
|
238
|
+
return nil
|
239
|
+
end
|
240
|
+
|
241
|
+
deal = MoveToGo::Deal.new
|
242
|
+
|
243
|
+
deal.integration_id = row['Id']
|
244
|
+
deal.customer = rootmodel.find_organization_by_integration_id(row['AccountId'])
|
245
|
+
deal.responsible_coworker = rootmodel.find_coworker_by_integration_id(row['OwnerId'])
|
246
|
+
deal.customer_contact =
|
247
|
+
rootmodel.find_person_by_integration_id(row['PrimaryPartnerAccountId'])
|
248
|
+
deal.name = row['Name']
|
249
|
+
deal.description = row['Description']
|
250
|
+
deal.value = row['Amount']
|
251
|
+
deal.probability = row['Probability']
|
252
|
+
|
253
|
+
deal.set_tag row['Type']
|
254
|
+
|
255
|
+
if converter.respond_to?(:get_deal_status_from_salesforce_stage)
|
256
|
+
status = converter.get_deal_status_from_salesforce_stage(row['StageName'])
|
257
|
+
|
258
|
+
if !status.nil?
|
259
|
+
deal.status = status
|
260
|
+
else
|
261
|
+
deal.status = row['StageName']
|
262
|
+
end
|
263
|
+
else
|
264
|
+
deal.status = row['StageName']
|
265
|
+
end
|
266
|
+
|
267
|
+
return deal
|
268
|
+
end
|
269
|
+
|
270
|
+
def to_history(row, rootmodel)
|
271
|
+
if row['IsDeleted'] != '0'
|
272
|
+
return nil
|
273
|
+
end
|
274
|
+
|
275
|
+
history = MoveToGo::History.new
|
276
|
+
|
277
|
+
history.integration_id = row['Id']
|
278
|
+
history.text = row['Title'] + ' ' + row['Body']
|
279
|
+
|
280
|
+
history.date = row['CreatedDate']
|
281
|
+
|
282
|
+
history.created_by = rootmodel.find_coworker_by_integration_id(row['CreatedById'])
|
283
|
+
history.organization = rootmodel.find_organization_by_integration_id(row['AccountId'])
|
284
|
+
|
285
|
+
# TODO: we should probably set the classification in the same was
|
286
|
+
# a a deal's status is set.
|
287
|
+
|
288
|
+
return history
|
289
|
+
end
|
290
|
+
|
291
|
+
def add_opportunity_stages_as_deal_status_to_model(rootmodel)
|
292
|
+
puts "Trying to create deal statuses..."
|
293
|
+
|
294
|
+
default_status = ''
|
295
|
+
statuses = []
|
296
|
+
process_rows(DEAL_FILE) do |row|
|
297
|
+
status = {
|
298
|
+
:label => row['StageName'],
|
299
|
+
:integration_id => row['StageName'],
|
300
|
+
:sort_order => row['StageSortOrder']
|
301
|
+
}
|
302
|
+
|
303
|
+
if row['IsClosed'] == '1'
|
304
|
+
if row['IsWon'] == '1'
|
305
|
+
status[:assessment] = MoveToGo::DealState::PositiveEndState
|
306
|
+
else
|
307
|
+
status[:assessment] = MoveToGo::DealState::NegativeEndState
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
if !statuses.any? {|s| s[:label] == status[:label]}
|
312
|
+
statuses.push status
|
313
|
+
|
314
|
+
if row['StageSortOrder'] == '1'
|
315
|
+
default_status = status[:label]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
statuses.sort! { |s1, s2| s1[:sort_order] <=> s2[:sort_order] }
|
321
|
+
rootmodel.settings.with_deal do |deal|
|
322
|
+
statuses.each do |status|
|
323
|
+
deal.add_status({ :label => status[:label],
|
324
|
+
:integration_id => status[:integration_id],
|
325
|
+
:assessment => status[:assessment]
|
326
|
+
})
|
327
|
+
end
|
328
|
+
|
329
|
+
deal.default_status = default_status
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def convert_source
|
334
|
+
puts "Trying to convert Salesforce to LIME Go..."
|
335
|
+
|
336
|
+
converter = Converter.new
|
337
|
+
|
338
|
+
salesforce_export_zipfile = get_salesforce_export_zipfile()
|
339
|
+
|
340
|
+
if salesforce_export_zipfile.nil? then
|
341
|
+
puts "Could find Salesforce export zip file."
|
342
|
+
raise
|
343
|
+
end
|
344
|
+
|
345
|
+
rootmodel = MoveToGo::RootModel.new
|
346
|
+
if converter.respond_to?(:configure)
|
347
|
+
converter.configure(rootmodel)
|
348
|
+
end
|
349
|
+
|
350
|
+
# We know have the Salesforce export zip file in
|
351
|
+
# export_zip_files[0]. We should unzip the file to a temp folder
|
352
|
+
# and return the path.
|
353
|
+
working_folder = Dir.mktmpdir("move-to-go")
|
354
|
+
puts "upzip '#{salesforce_export_zipfile}' to '#{working_folder.to_s}'..."
|
355
|
+
|
356
|
+
Dir.chdir(working_folder) do
|
357
|
+
Zip::File.open(salesforce_export_zipfile) do |zip_file|
|
358
|
+
zip_file.each do |entry|
|
359
|
+
if entry.to_s.include?("/") then
|
360
|
+
# puts "DIR"
|
361
|
+
else
|
362
|
+
entry.extract
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
add_opportunity_stages_as_deal_status_to_model(rootmodel)
|
368
|
+
|
369
|
+
puts "Trying to import users..."
|
370
|
+
process_rows(USER_FILE) do |row|
|
371
|
+
rootmodel.add_coworker(to_coworker(row))
|
372
|
+
end
|
373
|
+
|
374
|
+
puts "Trying to import organizations..."
|
375
|
+
process_rows(ORGANIZATION_ACCOUNT_FILE) do |row|
|
376
|
+
rootmodel.add_organization(account_to_organization(row, rootmodel))
|
377
|
+
end
|
378
|
+
process_rows(ORGANIZATION_LEAD_FILE) do |row|
|
379
|
+
rootmodel.add_organization(lead_to_organization(row, rootmodel, converter))
|
380
|
+
end
|
381
|
+
|
382
|
+
puts "Trying to import persons..."
|
383
|
+
process_rows(PERSON_FILE) do |row|
|
384
|
+
add_person_to_organization(row, rootmodel)
|
385
|
+
end
|
386
|
+
|
387
|
+
puts "Trying to import deals..."
|
388
|
+
process_rows(DEAL_FILE) do |row|
|
389
|
+
rootmodel.add_deal(to_deal(row, rootmodel, converter))
|
390
|
+
end
|
391
|
+
|
392
|
+
puts "Trying to import history..."
|
393
|
+
process_rows(NOTE_FILE) do |row|
|
394
|
+
rootmodel.add_history(to_history(row, rootmodel))
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
puts "Trying to remove '#{working_folder}'."
|
399
|
+
FileUtils.rm_rf(working_folder)
|
400
|
+
|
401
|
+
return rootmodel
|
402
|
+
|
403
|
+
end
|
404
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.2.5)
|
5
|
+
global_phone (1.0.1)
|
6
|
+
move-to-go (3.0.18)
|
7
|
+
bundler
|
8
|
+
global_phone
|
9
|
+
iso_country_codes
|
10
|
+
nokogiri
|
11
|
+
roo
|
12
|
+
sixarm_ruby_email_address_validation
|
13
|
+
thor
|
14
|
+
iso_country_codes (0.6.1)
|
15
|
+
mini_portile (0.6.1)
|
16
|
+
nokogiri (1.6.4.1-x86-mingw32)
|
17
|
+
mini_portile (~> 0.6.0)
|
18
|
+
roo (1.13.2)
|
19
|
+
nokogiri
|
20
|
+
rubyzip
|
21
|
+
spreadsheet (> 0.6.4)
|
22
|
+
rspec (3.1.0)
|
23
|
+
rspec-core (~> 3.1.0)
|
24
|
+
rspec-expectations (~> 3.1.0)
|
25
|
+
rspec-mocks (~> 3.1.0)
|
26
|
+
rspec-core (3.1.7)
|
27
|
+
rspec-support (~> 3.1.0)
|
28
|
+
rspec-expectations (3.1.2)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.1.0)
|
31
|
+
rspec-mocks (3.1.3)
|
32
|
+
rspec-support (~> 3.1.0)
|
33
|
+
rspec-support (3.1.2)
|
34
|
+
ruby-ole (1.2.11.7)
|
35
|
+
rubyzip (1.1.6)
|
36
|
+
sixarm_ruby_email_address_validation (2.0.0)
|
37
|
+
spreadsheet (1.0.0)
|
38
|
+
ruby-ole (>= 1.0)
|
39
|
+
thor (0.19.1)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
x86-mingw32
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
move-to-go
|
46
|
+
rspec
|
47
|
+
rubyzip
|
48
|
+
thor
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'move-to-go'
|
2
|
+
|
3
|
+
# This converter will convert a full export from Salesforce to LIME
|
4
|
+
# Go. Export data according to
|
5
|
+
# https://help.salesforce.com/apex/HTViewHelpDoc?id=admin_exportdata.htm
|
6
|
+
|
7
|
+
# You need to customize this script to suit your Salesforce export.
|
8
|
+
|
9
|
+
# You should save the zipfile from Salesforce in the
|
10
|
+
# EXPORT_FOLDER. You dont have to unzip the file, just put it in the folder.
|
11
|
+
EXPORT_FOLDER = "export"
|
12
|
+
|
13
|
+
# If you put more than one zip in the folder you must name the file
|
14
|
+
# you want to import to LIME GO.
|
15
|
+
# EXPORT_FILE = ""
|
16
|
+
|
17
|
+
# move-to-go will NOT use any unzipped files from the EXPORT_FOLDER. It
|
18
|
+
# will instead extract the zipfile to a temporary folder.
|
19
|
+
|
20
|
+
|
21
|
+
# If you are importing files then you must set the FILES_FOLDER
|
22
|
+
# constant. FILES_FOLDER should point to the folder where the files
|
23
|
+
# are stored. FILES_FOLDER can be relative to the project directory
|
24
|
+
# or absolute. Note that you need to escape \ with a \ so in order to
|
25
|
+
# write \ use \\.
|
26
|
+
FILES_FOLDER = "./files"
|
27
|
+
|
28
|
+
# If you are importing files with an absolute path (eg
|
29
|
+
# m:\documents\readme.doc) then you probably wont have files at that
|
30
|
+
# location on the computer where "move-to-go run" is executed. Set
|
31
|
+
# FILES_FOLDER_AT_CUSTOMER to the folder where documents are stored at
|
32
|
+
# the customers site. Ie, in this example m:\documents.
|
33
|
+
# Note that you need to escape \ with a \ so in order to write \ use
|
34
|
+
# \\.
|
35
|
+
FILES_FOLDER_AT_CUSTOMER = "m:\\documents\\"
|
36
|
+
|
37
|
+
class Converter
|
38
|
+
# Configure your root model, add custom fields and deal statuses.
|
39
|
+
def configure(rootmodel)
|
40
|
+
# add custom field and deal statuses to your model
|
41
|
+
# here. Custom fields can be added to organization, deal and
|
42
|
+
# person. Valid types are :String and :Link. If no type is
|
43
|
+
# specified :String is used as default.
|
44
|
+
|
45
|
+
# You dont have to add the Stages for Opportunities here since
|
46
|
+
# they are automagically added.
|
47
|
+
|
48
|
+
|
49
|
+
# rootmodel.settings.with_organization do |organization|
|
50
|
+
# organization.set_custom_field( { :integrationid => 'external_url', :title => 'Link to external system', :type => :Link } )
|
51
|
+
# end
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_deal_status_from_salesforce_stage(salesforce_deal_stage)
|
55
|
+
# When deals are added to LIME Go this method is called for
|
56
|
+
# each deal. The deal's stage from Salesforce is supplied as
|
57
|
+
# an argument and this method should return a status for the
|
58
|
+
# deal in LIME Go. The returned value is probably a label of a
|
59
|
+
# deal status that has been added in the configure(rootmodel)
|
60
|
+
# method. If nil is returned, the default status will be the
|
61
|
+
# same as in Salesforce (ie salesforce_deal_stage)
|
62
|
+
|
63
|
+
# deal_status = nil
|
64
|
+
|
65
|
+
# case salesforce_deal_stage
|
66
|
+
# when 'Prospecting'
|
67
|
+
# deal_status = '1. Kvalificering'
|
68
|
+
# when 'Closed Won'
|
69
|
+
# deal_status = 'Vunnen'
|
70
|
+
# end
|
71
|
+
|
72
|
+
# return deal_status
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_relation_for_lead()
|
76
|
+
# Returns the relation that converted leads should have. By
|
77
|
+
# default leads will get the relation WorkingOnIt.
|
78
|
+
|
79
|
+
return MoveToGo::Relation::WorkingOnIt
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_tags_for_lead(lead_status)
|
83
|
+
# Returns the tag or tags that converted leads should
|
84
|
+
# have. Return either a string or an array of
|
85
|
+
# strings. lead_status is the status value from Salesforce.
|
86
|
+
|
87
|
+
# If no tag is returned, the default is 'lead' and the status.
|
88
|
+
|
89
|
+
# if lead_status == 'Qualified'
|
90
|
+
# return ['lead', 'qualified']
|
91
|
+
# else
|
92
|
+
# return 'lead'
|
93
|
+
# end
|
94
|
+
|
95
|
+
# return nil
|
96
|
+
end
|
97
|
+
|
98
|
+
# HOOKS
|
99
|
+
#
|
100
|
+
# Sometimes you need to add exra information to the rootmodel, this can be done
|
101
|
+
# with hooks, below is an example of an organization hook that adds a comment to
|
102
|
+
# an organization if a field has a specific value
|
103
|
+
#def organization_hook(row, organization, rootmodel)
|
104
|
+
# if not row['fieldname'].empty?
|
105
|
+
# comment = MoveToGo::Comment.new
|
106
|
+
# comment.text = row['fieldname']
|
107
|
+
# comment.organization = organization
|
108
|
+
# comment.created_by = rootmodel.migrator_coworker
|
109
|
+
# rootmodel.add_comment(comment)
|
110
|
+
# end
|
111
|
+
#end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require 'move-to-go'
|
3
|
+
|
4
|
+
describe MoveToGo::Address do
|
5
|
+
describe "Parse line with swedish zip and city into zipcode" do
|
6
|
+
let (:zip_code) {
|
7
|
+
address = MoveToGo::Address.new
|
8
|
+
line = "114 45 STOCKHOLM"
|
9
|
+
address.parse_zip_and_address_se(line).zip_code
|
10
|
+
}
|
11
|
+
it "should have zipcode equal to '114 45'" do
|
12
|
+
zip_code.should eq '114 45'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "Parse line with swedish zip and city into city" do
|
17
|
+
let (:city){
|
18
|
+
address = MoveToGo::Address.new
|
19
|
+
line = "114 45 STOCKHOLM"
|
20
|
+
address.parse_zip_and_address_se(line).city
|
21
|
+
}
|
22
|
+
it "should have city equal to 'STOCKHOLM'" do
|
23
|
+
city.should eq 'STOCKHOLM'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "Parse line with non-swedish zip and city assuming swedish format" do
|
28
|
+
describe "praha example" do
|
29
|
+
let (:parse_result){
|
30
|
+
address = MoveToGo::Address.new
|
31
|
+
line = "CZ-140 00 PRAHA 4"
|
32
|
+
address.parse_zip_and_address_se(line)
|
33
|
+
}
|
34
|
+
it "should be nil" do
|
35
|
+
parse_result.should == nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
describe "finnish example" do
|
39
|
+
let (:parse_result){
|
40
|
+
address = MoveToGo::Address.new
|
41
|
+
line = "0511 HELSINKI"
|
42
|
+
address.parse_zip_and_address_se(line)
|
43
|
+
}
|
44
|
+
it "should be nil" do
|
45
|
+
parse_result.should == nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'move-to-go'
|
3
|
+
|
4
|
+
describe "ClassSettings" do
|
5
|
+
let(:class_settings) {
|
6
|
+
MoveToGo::ClassSettings.new
|
7
|
+
}
|
8
|
+
|
9
|
+
it "can set custom field and if there is already an existing custom field, then it is overwritten." do
|
10
|
+
class_settings.set_custom_field({:integration_id => "link_to_bi_system", :title => "Link to BI system"})
|
11
|
+
class_settings.set_custom_field({:integration_id => "link_to_bi_system", :title => "Link to BI system 2"})
|
12
|
+
class_settings.custom_fields.length.should eq 1
|
13
|
+
class_settings.custom_fields[0].title.should eq "Link to BI system 2"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should not allow new custom fields without id and integration id" do
|
17
|
+
begin
|
18
|
+
class_settings.set_custom_field({:integration_id => "", :id => "", :title => "Link to BI system"})
|
19
|
+
rescue
|
20
|
+
end
|
21
|
+
|
22
|
+
class_settings.custom_fields.length.should eq 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow new custom field with integration_id" do
|
26
|
+
class_settings.set_custom_field({:integration_id => "link_to_bi_system", :title => "Link to BI system"})
|
27
|
+
class_settings.custom_fields.length.should eq 1
|
28
|
+
class_settings.custom_fields[0].title.should eq "Link to BI system"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow new custom field with id" do
|
32
|
+
class_settings.set_custom_field({:id => "123", :title => "Link to BI system"})
|
33
|
+
class_settings.custom_fields.length.should eq 1
|
34
|
+
class_settings.custom_fields[0].title.should eq "Link to BI system"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|