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,108 @@
1
+ require 'fileutils'
2
+ require 'open3'
3
+
4
+ module MoveToGo
5
+ class Sources
6
+ def initialize(path)
7
+ @path = path
8
+ end
9
+
10
+ def list()
11
+ Dir.entries(@path).select {
12
+ |f| f != '.' && f != '..'
13
+ }
14
+ end
15
+
16
+ def create_project_from_source(project_name, source_name)
17
+ if !source_exists?(source_name)
18
+ puts "The source '#{source_name}' doesnt exist."
19
+ return false
20
+ end
21
+
22
+ if project_exists?(project_name)
23
+ puts "A project named '#{project_name}' already exists"
24
+ return false
25
+ end
26
+
27
+ begin
28
+ copy_source_to_folder(source_name, project_name)
29
+
30
+ install_gems_for_project(project_name)
31
+ return true
32
+ rescue
33
+ puts "Something when wrong (errors should have been printed above)..."
34
+ FileUtils.remove_dir(project_name, true)
35
+ return false
36
+ end
37
+ end
38
+
39
+ def about_source(source_name)
40
+ if !source_exists?(source_name)
41
+ puts "The source '#{source_name}' doesnt exist."
42
+ return false
43
+ end
44
+
45
+ print_about_file_for_source(source_name)
46
+ end
47
+
48
+ private
49
+ def print_about_file_for_source(name)
50
+ about_path = ::File.expand_path("#{name}/.move-to-go/readme.txt", @path)
51
+
52
+ if ::File.exists?(about_path)
53
+ about_contents = ::File.open(about_path, "rb").read
54
+ puts about_contents
55
+ else
56
+ puts "No about text specifed for source '#{name}'."
57
+ end
58
+ end
59
+
60
+ private
61
+ def source_exists?(name)
62
+ source = list.find { |s| s.downcase == name.downcase }
63
+
64
+ return !source.nil?
65
+ end
66
+
67
+ private
68
+ def project_exists?(name)
69
+ # do we have a folder named 'name' in the current folder?
70
+ project = Dir.entries(Dir.pwd).find { |f| f.downcase == name.downcase}
71
+
72
+ return !project.nil?
73
+ end
74
+
75
+ private
76
+ def copy_source_to_folder(source_name, project_name)
77
+ puts "Trying to create project '#{project_name}' from source '#{source_name}'..."
78
+ FileUtils.cp_r ::File.expand_path(source_name, @path), project_name
79
+ end
80
+
81
+ private
82
+ def install_gems_for_project(project_name)
83
+ puts "Trying to verify that all required gems are installed..."
84
+ Dir.chdir(::File.expand_path(project_name, Dir.pwd)) do
85
+ exec_but_dont_show_unless_error('bundle install --verbose')
86
+ end
87
+ end
88
+
89
+ private
90
+ def exec_but_dont_show_unless_error(cmd)
91
+ std_out_value = []
92
+ Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
93
+ while std_line = stdout.gets
94
+ std_out_value << std_line
95
+ end
96
+
97
+ exit_status = wait_thr.value
98
+ if !exit_status.success?
99
+ puts "Command '#{cmd}' failed with #{exit_status}"
100
+ puts "Output from command:"
101
+ puts std_out_value
102
+
103
+ raise "failed exec #{cmd}"
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,52 @@
1
+ require "fileutils"
2
+ require 'open3'
3
+ module MoveToGo
4
+ class Templating
5
+ def initialize(path)
6
+ @path = path
7
+ end
8
+
9
+ def list()
10
+ Dir.entries(@path).select { |d| d != '.' && d != '..' }
11
+ end
12
+
13
+ def unpack(name, path)
14
+ template = list.find { |t| t == name }
15
+ if template
16
+ unpackedname = name
17
+
18
+ puts "Unpacking template #{name} to #{path}"
19
+ FileUtils.cp_r File.expand_path(name, @path), path
20
+
21
+ # Now make sure all gems in template are installed
22
+ puts "Making sure all needed gems are present"
23
+ Dir.chdir(File.expand_path(unpackedname, path)) do
24
+ exec_but_dont_show_unless_error('bundle install --verbose')
25
+ end
26
+ true
27
+ else
28
+ puts "Unable to find template #{name}"
29
+ false
30
+ end
31
+ end
32
+
33
+ private
34
+ def exec_but_dont_show_unless_error(cmd)
35
+ std_out_value = []
36
+ Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
37
+ while std_line = stdout.gets
38
+ std_out_value << std_line
39
+ end
40
+
41
+ exit_status = wait_thr.value
42
+ if !exit_status.success?
43
+ puts "Failed with #{exit_status}"
44
+ puts "std_out_value"
45
+ puts std_out_value
46
+
47
+ raise "failed exec #{cmd}"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/move-to-go.rb ADDED
@@ -0,0 +1,20 @@
1
+ module MoveToGo
2
+ private
3
+ def self.require_all_in(folder)
4
+ Dir.glob(::File.join(::File.dirname(::File.absolute_path(__FILE__)),folder), &method(:require))
5
+ end
6
+
7
+ require_relative 'move-to-go/errors'
8
+ require_relative 'move-to-go/serialize_helper'
9
+ require_relative 'move-to-go/model_helpers'
10
+ require_relative 'move-to-go/can_become_immutable'
11
+ MoveToGo::require_all_in 'move-to-go/model/*.rb'
12
+ require_relative 'move-to-go/csv_helper'
13
+ require_relative 'move-to-go/roo_helper'
14
+ require_relative 'move-to-go/phone_helper'
15
+ require_relative 'move-to-go/email_helper'
16
+ require_relative 'move-to-go/excel_helper'
17
+ require_relative 'move-to-go/templating'
18
+ require_relative 'move-to-go/source'
19
+ require_relative 'move-to-go/shard_helper'
20
+ 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 @@
1
+ This source converts a VISMA Administration 2000 database to LIME Go.
@@ -0,0 +1,89 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'move-to-go'
4
+ #require 'roo'
5
+ require 'dbf'
6
+ require_relative("../converter")
7
+
8
+ KUND_FILE = './database/KUND.DBF'
9
+ KONTAKT_FILE = './database/KONTAKT.DBF'
10
+
11
+ def convert_source
12
+ puts "Trying to convert VISMA Administration 2000 source to LIME Go..."
13
+
14
+ # Verify that required files exists.
15
+ if !File.exists?(KUND_FILE)
16
+ puts "You MUST put KUND.DBF in the database folder."
17
+ raise
18
+ end
19
+
20
+ if !File.exists?(KONTAKT_FILE)
21
+ puts "You MUST put KONTAKT.DBF in the database folder."
22
+ raise
23
+ end
24
+
25
+ puts "Trying to read data from VISMA files..."
26
+ organization_rows = DBF::Table.new(KUND_FILE)
27
+ person_rows = DBF::Table.new(KONTAKT_FILE)
28
+
29
+ rootmodel = MoveToGo::RootModel.new
30
+ converter = Converter.new
31
+
32
+ converter.configure rootmodel
33
+
34
+ # Then create organizations, they are only referenced by
35
+ # coworkers.
36
+ puts "Trying to process Organization..."
37
+ organization_rows.each do |row|
38
+ if not row.nil?
39
+ if not row["NAMN"] == ""
40
+ organization = converter.to_organization(row, rootmodel)
41
+ rootmodel.add_organization(organization)
42
+ converter.organization_hook(row, organization, rootmodel) if defined? converter.organization_hook
43
+ end
44
+ end
45
+ end
46
+ puts "Processed #{rootmodel.organizations.length} Organizations."
47
+
48
+ # Add people and link them to their organizations
49
+ puts "Trying to process Persons..."
50
+ imported_person_count = 0
51
+ person_rows.each do |row|
52
+ # People are special since they are not added directly to
53
+ # the root model
54
+ if not row.nil?
55
+ if not row["KUNDNR"] == "" and not row["NAMN"] == ""
56
+ converter.import_person_to_organization(row, rootmodel)
57
+ imported_person_count = imported_person_count + 1
58
+ end
59
+ end
60
+ end
61
+ puts "Processed #{imported_person_count} Persons."
62
+
63
+ # History must be owned by a coworker and then should reference
64
+ # organization or deal and might reference a person
65
+ puts "Trying to process History..."
66
+ imported_history_count = 0
67
+ organization_rows.each do |row|
68
+ if not row.nil?
69
+ if row['ANTECK_1'].length > 0
70
+
71
+ comment = MoveToGo::Comment.new()
72
+
73
+ organization = rootmodel.find_organization_by_integration_id(row['KUNDNR'])
74
+ unless organization.nil?
75
+ comment.organization = organization
76
+ end
77
+ comment.created_by = rootmodel.migrator_coworker
78
+ comment.text = row['ANTECK_1']
79
+
80
+ rootmodel.add_history(comment)
81
+ imported_history_count = imported_history_count + 1
82
+ end
83
+ end
84
+ end
85
+ puts "Processed #{imported_history_count} History."
86
+
87
+ return rootmodel
88
+ end
89
+
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rspec'
4
+ gem 'move-to-go'
5
+ gem 'dbf'
@@ -0,0 +1,120 @@
1
+ require 'move-to-go'
2
+ require 'dbf'
3
+
4
+ # Customize this file to suit your input for a
5
+ # VISMA Administration 2000 database.
6
+ #
7
+ # You must put KUND.DBS and KONTAKTER.DBS in the database folder.
8
+ #
9
+ # Documentation move-to-go can be found at
10
+ # http://rubygems.org/gems/move-to-go
11
+ #
12
+ # move-to-go contains all objects in LIME Go such as organizations,
13
+ # people, deals, etc. What properties each object has is described in
14
+ # the documentation.
15
+ #
16
+ # Generate the xml-file that should be sent to LIME Go with the command:
17
+ # move-to-go run
18
+
19
+ # If you are importing files then you must set the FILES_FOLDER
20
+ # constant. FILES_FOLDER should point to the folder where the files
21
+ # are stored. FILES_FOLDER can be relative to the project directory
22
+ # or absolute. Note that you need to escape \ with a \ so in order to
23
+ # write \ use \\.
24
+ FILES_FOLDER = "./files"
25
+
26
+ # If you are importing files with an absolute path (eg
27
+ # m:\documents\readme.doc) then you probably wont have files at that
28
+ # location on the computer where "move-to-go run" is executed. Set
29
+ # FILES_FOLDER_AT_CUSTOMER to the folder where documents are stored at
30
+ # the customers site. Ie, in this example m:\documents.
31
+ # Note that you need to escape \ with a \ so in order to write \ use
32
+ # \\.
33
+ FILES_FOLDER_AT_CUSTOMER = "m:\\documents\\"
34
+
35
+ class Converter
36
+ def configure(rootmodel)
37
+ # Add custom field to your model here. Custom fields can be
38
+ # added to organization, deal and person. Valid types are
39
+ # :String and :Link. If no type is specified :String is used
40
+ # as default.
41
+
42
+ #Creates a custom field to add invoicing data
43
+ rootmodel.settings.with_organization do |org|
44
+ org.set_custom_field( { :integrationid => 'ackoms', :title => 'Fakturerat', :type => :String } )
45
+ end
46
+ end
47
+
48
+ def import_person_to_organization(row, rootmodel)
49
+ organization = rootmodel.find_organization_by_integration_id(row['KUNDNR'])
50
+
51
+ if !organization.nil?
52
+ organization.add_employee(to_person(row, rootmodel))
53
+ end
54
+ end
55
+
56
+ def to_organization(row, rootmodel)
57
+ organization = MoveToGo::Organization.new()
58
+
59
+ #Add tags:
60
+ organization.set_tag "Kund"
61
+
62
+ organization.name = row['NAMN']
63
+ # Integrationid must be set to be able to import the same file
64
+ # more than once without creating duplicates
65
+ organization.integration_id = row['KUNDNR']
66
+
67
+ #address
68
+ organization.with_postal_address do |address|
69
+ address.street = row['POSTADR']
70
+ address.zip_code = row['POSTNR']
71
+ address.city = row['ORT']
72
+ end
73
+
74
+ organization.email = row['EPOST']
75
+ organization.organization_number = row['ORGNR']
76
+ organization.central_phone_number = row['TEL']
77
+
78
+ # Sets the organization's relation. Relation must be a value
79
+ # from MoveToGo::Relation.
80
+ organization.relation = MoveToGo::Relation::IsACustomer
81
+
82
+ #Fill data to custom fields
83
+ organization.set_custom_value("ackoms", row["ACKOMS"])
84
+
85
+ return organization
86
+ end
87
+
88
+ def to_person(row, rootmodel)
89
+ person = MoveToGo::Person.new()
90
+
91
+ # *** TODO:
92
+ #
93
+ # Set person properties from the row.
94
+
95
+ person.parse_name_to_firstname_lastname_se(row['NAMN'])
96
+ if MoveToGo::EmailHelper.is_valid?(row['EPOST'])
97
+ person.email = row['EPOST']
98
+ end
99
+ person.mobile_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['MBTEL'], [",", "/", "\\"])
100
+ person.direct_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['TEL'], [",", "/", "\\"])
101
+
102
+ return person
103
+ end
104
+
105
+ # HOOKS
106
+ #
107
+ # Sometimes you need to add exra information to the rootmodel, this can be done
108
+ # with hooks, below is an example of an organization hook that adds a comment to
109
+ # an organization if a field has a specific value
110
+ #def organization_hook(row, organization, rootmodel)
111
+ # if not row['fieldname'].empty?
112
+ # comment = MoveToGo::Comment.new
113
+ # comment.text = row['fieldname']
114
+ # comment.organization = organization
115
+ # comment.created_by = rootmodel.migrator_coworker
116
+ # rootmodel.add_history(comment)
117
+ # end
118
+ #end
119
+
120
+ end
@@ -0,0 +1,235 @@
1
+ require 'move-to-go'
2
+ require_relative("../converter")
3
+
4
+ REPORT_RESULT = true
5
+ COWORKER_FILE = "data/coworkers.csv"
6
+ ORGANIZATION_FILE = "data/contacts.csv"
7
+ LEADS_FILE = "data/leads.csv"
8
+ PERSON_FILE = "data/contacts.csv"
9
+ DEAL_FILE = "data/deals.csv"
10
+ HISTORY_FILE = "data/histories.csv"
11
+ SOURCE_ENCODING = "utf-8"
12
+
13
+
14
+
15
+ def process_rows(file_name, source_encoding)
16
+ data = File.read(file_name, :encoding => source_encoding)
17
+ rows = MoveToGo::CsvHelper::text_to_hashes(data)
18
+ rows.each do |row|
19
+ yield row
20
+ end
21
+ end
22
+
23
+ def convert_source
24
+ puts "Trying to convert Base CRM source to LIME Go..."
25
+
26
+ converter = Converter.new
27
+ ignored_histories = 0
28
+ ignored_persons = 0
29
+
30
+ # A rootmodel is used to represent all entitite/models that is
31
+ # exported
32
+ rootmodel = MoveToGo::RootModel.new
33
+
34
+ converter.configure(rootmodel)
35
+ source_encoding = defined?(SOURCE_ENCODING) ? SOURCE_ENCODING : 'ISO-8859-1'
36
+
37
+ # coworkers
38
+ # start with these since they are referenced
39
+ # from everywhere....
40
+ if defined?(COWORKER_FILE) && !COWORKER_FILE.nil? && !COWORKER_FILE.empty?
41
+ process_rows(COWORKER_FILE, source_encoding) do |row|
42
+ coworker = converter.to_coworker(row)
43
+ coworker.integration_id = "#{row['first_name']} #{row['last_name']}"
44
+ coworker.first_name = row['first_name']
45
+ coworker.last_name = row['last_name']
46
+ coworker.email = row['email']
47
+ rootmodel.add_coworker(coworker)
48
+ end
49
+ end
50
+
51
+ # organizations
52
+ if defined?(ORGANIZATION_FILE) && !ORGANIZATION_FILE.nil? && !ORGANIZATION_FILE.empty?
53
+ process_rows(ORGANIZATION_FILE, source_encoding) do |row|
54
+ next if row["is_organisation"] == "false"
55
+ organization = converter.to_organization(row, rootmodel)
56
+ organization = MoveToGo::Organization.new
57
+ organization.integration_id = row['id']
58
+ organization.name = row['name']
59
+ organization.email = row['email']
60
+ organization.web_site = row['website']
61
+ organization.central_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['phone']) if not row['phone'].nil?
62
+
63
+ organization.with_visit_address do |address|
64
+ address.street = row['address']
65
+ address.zip_code = row['zip']
66
+ address.city = row['city']
67
+ end
68
+
69
+ organization.with_postal_address do |address|
70
+ address.street = row['address']
71
+ address.zip_code = row['zip']
72
+ address.city = row['city']
73
+ end
74
+
75
+ case row['prospect_status']
76
+ when "current"
77
+ organization.relation = MoveToGo::Relation::WorkingOnIt
78
+ else
79
+ organization.relation = MoveToGo::Relation::BeenInTouch
80
+ end
81
+
82
+ case row['customer_status']
83
+ when "current"
84
+ organization.relation = MoveToGo::Relation::IsACustomer
85
+ when "past"
86
+ organization.relation = MoveToGo::Relation::WasACustomer
87
+ else
88
+ organization.relation = MoveToGo::Relation::BeenInTouch
89
+ end
90
+
91
+ coworker = rootmodel.find_coworker_by_integration_id row['owner']
92
+ organization.responsible_coworker = coworker
93
+ tags = row['tags'].split(",")
94
+ tags.each do |tag|
95
+ organization.set_tag(tag)
96
+ end
97
+
98
+ rootmodel.add_organization(organization)
99
+ end
100
+ end
101
+
102
+ # persons
103
+ # depends on organizations
104
+ if defined?(PERSON_FILE) && !PERSON_FILE.nil? && !PERSON_FILE.empty?
105
+ process_rows(PERSON_FILE, source_encoding) do |row|
106
+ # adds it self to the employer
107
+ next if row["is_organisation"] == "true"
108
+ person = converter.to_person(row, rootmodel)
109
+
110
+ person.integration_id = row['id']
111
+
112
+ person.first_name = row['first_name']
113
+ person.last_name = row['last_name']
114
+
115
+ person.direct_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['phone'])
116
+ person.mobile_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['mobile'])
117
+ person.email = row['email']
118
+
119
+ organization = rootmodel.find_organization {|org|
120
+ org.name == row["organisation_name"]
121
+ }
122
+ if not organization.nil?
123
+ organization.add_employee(person)
124
+ else
125
+ puts "No organization for person '#{person.first_name} #{person.last_name}, #{person.integration_id}' could be found. Person will not be imported!"
126
+ ignored_persons += 1
127
+ end
128
+ end
129
+ end
130
+
131
+ # leads
132
+ if defined?(LEADS_FILE) && !LEADS_FILE.nil? && !LEADS_FILE.empty?
133
+ process_rows(LEADS_FILE, source_encoding) do |row|
134
+ organization = converter.to_organization_from_lead(row, rootmodel)
135
+
136
+ organization.integration_id = "l#{row['id']}"
137
+ organization.name = row['company_name']
138
+ organization.relation = MoveToGo::Relation::WorkingOnIt
139
+
140
+ organization.central_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['phone']) if not row['phone'].nil?
141
+
142
+ organization.with_visit_address do |address|
143
+ address.street = row['street']
144
+ address.city = row['city']
145
+ end
146
+
147
+ coworker = rootmodel.find_coworker_by_integration_id row['owner']
148
+ organization.responsible_coworker = coworker
149
+
150
+ if not row['tags'].nil?
151
+ tags = row['tags'].split(",")
152
+ tags.each do |tag|
153
+ organization.set_tag(tag)
154
+ end
155
+ end
156
+
157
+ person = MoveToGo::Person.new
158
+
159
+ person.integration_id = "p#{row['id']}"
160
+ person.first_name = row['first_name']
161
+ person.last_name = row['last_name']
162
+ person.direct_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['phone']) if not row['phone'].nil?
163
+ person.mobile_phone_number = MoveToGo::PhoneHelper.parse_numbers(row['mobile']) if not row['mobile'].nil?
164
+ person.email = row['email']
165
+
166
+ organization.add_employee(person)
167
+
168
+ if row['description']
169
+ comment = MoveToGo::Comment.new()
170
+
171
+ comment.text = row['description']
172
+ comment.person = person
173
+ comment.organization = organization
174
+ comment.created_by = coworker
175
+
176
+ rootmodel.add_comment(comment)
177
+ end
178
+ rootmodel.add_organization(organization)
179
+ end
180
+ end
181
+
182
+ # deals
183
+ if defined?(DEAL_FILE) && !DEAL_FILE.nil? && !DEAL_FILE.empty?
184
+ process_rows(DEAL_FILE, source_encoding) do |row|
185
+ deal = converter.to_deal(row, rootmodel)
186
+ deal.integration_id = row['id']
187
+ deal.name = row['name']
188
+
189
+ deal.value = row['scope']
190
+ deal.customer = rootmodel.find_organization_by_integration_id(row['company_id'])
191
+ deal.customer_contact = rootmodel.find_person_by_integration_id(row['main_contact_id'])
192
+ deal.responsible_coworker = rootmodel.find_coworker_by_integration_id(row['owner'])
193
+
194
+ values = row['tags'].split(",")
195
+ values.each do |value|
196
+ deal.set_tag(value)
197
+ end
198
+ rootmodel.add_deal(deal)
199
+ end
200
+ end
201
+
202
+ # historys
203
+ if defined?(HISTORY_FILE) && !HISTORY_FILE.nil? && !HISTORY_FILE.empty?
204
+ process_rows(HISTORY_FILE, source_encoding) do |row|
205
+ history = MoveToGo::Comment.new()
206
+ history.integration_id = row['id']
207
+ history.text = row['content']
208
+ history.created_by = rootmodel.find_coworker_by_integration_id(row["owner"])
209
+ notable_id = row['noteable_id']
210
+ case row["noteable_type"]
211
+ when "Deal"
212
+ deal = rootmodel.find_deal_by_integration_id(notable_id)
213
+ history.deal = deal
214
+ when "Lead"
215
+ history.person = rootmodel.find_person_by_integration_id("p#{notable_id}")
216
+ history.organization = rootmodel.find_organization_by_integration_id("l#{notable_id}")
217
+ when "Contact"
218
+ puts "Ignoreing history for unbound person: #{row['owner']}"
219
+ ignored_histories += 1
220
+ next
221
+ else
222
+ org = rootmodel.find_organization_by_integration_id(notable_id)
223
+ if org.nil?
224
+ person = rootmodel.find_person_by_integration_id(notable_id)
225
+ org = person.organization
226
+ history.person = person
227
+ end
228
+ history.organization = org
229
+ end
230
+ rootmodel.add_history(history)
231
+ end
232
+ end
233
+ puts "Ignored #{ignored_persons} persons and #{ignored_histories} histories"
234
+ return rootmodel
235
+ end
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'thor'
4
+ gem 'move-to-go'
5
+ gem 'rspec'
@@ -0,0 +1,9 @@
1
+ # Base CRM migration
2
+
3
+ 1. Export your Base CRM data with the built in export in Base CRM
4
+ 2. Put the exported data into the `data` folder
5
+ 3. Coworkers has to be entered manually into the coworkers file. A template file is provided
6
+ 4. All mappings are done in `runner.rb` but special unique things can be configured in `converter.rb`
7
+
8
+ Note: In Base CRM you can have contacts persons without a corresponding organization.
9
+ This is not allowed in LIME Go and these persons and notes just linked to them will be ignored.