go_import 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/go-import +96 -0
- data/lib/go_import/csv_helper.rb +47 -0
- data/lib/go_import/email_helper.rb +10 -0
- data/lib/go_import/errors.rb +22 -0
- data/lib/go_import/excel_helper.rb +10 -0
- data/lib/go_import/global_phone.json +6571 -0
- data/lib/go_import/model/address.rb +61 -0
- data/lib/go_import/model/class_settings.rb +50 -0
- data/lib/go_import/model/coworker.rb +76 -0
- data/lib/go_import/model/coworker_reference.rb +33 -0
- data/lib/go_import/model/customfield.rb +87 -0
- data/lib/go_import/model/deal.rb +172 -0
- data/lib/go_import/model/deal_class_settings.rb +73 -0
- data/lib/go_import/model/deal_state.rb +15 -0
- data/lib/go_import/model/deal_status.rb +23 -0
- data/lib/go_import/model/deal_status_reference.rb +47 -0
- data/lib/go_import/model/deal_status_setting.rb +49 -0
- data/lib/go_import/model/documents.rb +51 -0
- data/lib/go_import/model/link.rb +70 -0
- data/lib/go_import/model/note.rb +97 -0
- data/lib/go_import/model/note_classification.rb +25 -0
- data/lib/go_import/model/organization.rb +219 -0
- data/lib/go_import/model/person.rb +151 -0
- data/lib/go_import/model/referencetosource.rb +46 -0
- data/lib/go_import/model/relation.rb +23 -0
- data/lib/go_import/model/rootmodel.rb +359 -0
- data/lib/go_import/model/settings.rb +61 -0
- data/lib/go_import/model/tag.rb +35 -0
- data/lib/go_import/model_helpers.rb +54 -0
- data/lib/go_import/phone_helper.rb +74 -0
- data/lib/go_import/roo_helper.rb +80 -0
- data/lib/go_import/serialize_helper.rb +186 -0
- data/lib/go_import/source.rb +87 -0
- data/lib/go_import/templating.rb +52 -0
- data/lib/go_import.rb +19 -0
- data/sources/csv/.gitignore +14 -0
- data/sources/csv/.go_import/runner.rb +62 -0
- data/sources/csv/Gemfile +5 -0
- data/sources/csv/Rakefile.rb +7 -0
- data/sources/csv/converter.rb +179 -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/csv/spec/exporter_spec.rb +17 -0
- data/sources/csv/spec/sample_data/coworkers.csv +2 -0
- data/sources/csv/spec/sample_data/deals.csv +2 -0
- data/sources/csv/spec/sample_data/organizations.csv +2 -0
- data/sources/csv/spec/sample_data/persons.csv +2 -0
- data/sources/csv/spec/spec_helper.rb +30 -0
- data/sources/easy/.gitignore +14 -0
- data/sources/easy/.go_import/runner.rb +115 -0
- data/sources/easy/Export/readme.txt +6 -0
- data/sources/easy/Gemfile +5 -0
- data/sources/easy/Rakefile.rb +7 -0
- data/sources/easy/converter.rb +435 -0
- data/sources/easy/spec/exporter_spec.rb +10 -0
- data/sources/easy/spec/sample_data/Company.txt +649 -0
- data/sources/easy/spec/spec_helper.rb +30 -0
- data/sources/excel/.gitignore +14 -0
- data/sources/excel/.go_import/runner.rb +116 -0
- data/sources/excel/Gemfile +6 -0
- data/sources/excel/Rakefile.rb +7 -0
- data/sources/excel/converter.rb +130 -0
- data/sources/excel/spec/sample_data/sample.xlsx +0 -0
- data/sources/excel/spec/spec_helper.rb +26 -0
- data/sources/excel/spec/tomodel_spec.rb +18 -0
- data/sources/excel/template.xlsx +0 -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 +104 -0
- data/spec/deal_spec.rb +182 -0
- data/spec/deal_status_reference_spec.rb +17 -0
- data/spec/documents_spec.rb +37 -0
- data/spec/helpers/csv_helper_spec.rb +29 -0
- data/spec/helpers/email_helper_spec.rb +32 -0
- data/spec/helpers/phone_helper_spec.rb +97 -0
- data/spec/helpers/roo_helper_spec.rb +10 -0
- data/spec/helpers/serialize_helper_spec.rb +249 -0
- data/spec/helpers/xsd_validate_spec.rb +55 -0
- data/spec/link_spec.rb +106 -0
- data/spec/note_spec.rb +110 -0
- data/spec/organization_spec.rb +151 -0
- data/spec/person_spec.rb +132 -0
- data/spec/rootmodel_spec.rb +371 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/templating_spec.rb +12 -0
- metadata +306 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rexml/document"
|
3
|
+
|
4
|
+
module GoImport
|
5
|
+
module SerializeHelper
|
6
|
+
def serialize()
|
7
|
+
SerializeHelper::serialize(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialize_to_file(file)
|
11
|
+
SerializeHelper::serialize_to_file(file, self)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @!visibility private
|
15
|
+
def self.serialize_variables_rexml(elem, obj)
|
16
|
+
if (obj.respond_to?(:serialize_variables))
|
17
|
+
obj.serialize_variables.each do |serialize_variable|
|
18
|
+
element_name = serialize_variable[:id].to_s.gsub(/^\@/,'').split('_').map do |m|
|
19
|
+
m.capitalize
|
20
|
+
end.join('')
|
21
|
+
|
22
|
+
raw_var = obj.instance_variable_get("@#{serialize_variable[:id].to_s}")
|
23
|
+
if raw_var != nil
|
24
|
+
element = elem.add_element(element_name)
|
25
|
+
if (raw_var.respond_to?(:serialize_variables))
|
26
|
+
SerializeHelper::serialize_variables_rexml(element, raw_var)
|
27
|
+
elsif (raw_var.is_a?(Array))
|
28
|
+
raw_var.each do |raw_var_elem|
|
29
|
+
SerializeHelper::serialize_rexml(element, raw_var_elem)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
element.text = raw_var.to_s.encode('UTF-8')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return
|
37
|
+
end
|
38
|
+
raise "Do not know how to handle #{obj.class} !!"
|
39
|
+
end
|
40
|
+
|
41
|
+
# @!visibility private
|
42
|
+
def self.serialize_rexml(elem, obj)
|
43
|
+
if obj.respond_to?(:to_rexml)
|
44
|
+
obj.to_rexml(elem)
|
45
|
+
elsif (obj.respond_to?(:serialize_variables))
|
46
|
+
element_name = obj.serialize_name
|
47
|
+
SerializeHelper::serialize_variables_rexml(elem.add_element(element_name), obj)
|
48
|
+
else
|
49
|
+
elem.text = obj.to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @!visibility private
|
54
|
+
def self.serialize(obj, indent= 2)
|
55
|
+
# indent -1 to avoid indent
|
56
|
+
if obj.respond_to?(:to_rexml)
|
57
|
+
doc = REXML::Document.new()
|
58
|
+
SerializeHelper::serialize_rexml(doc, obj)
|
59
|
+
doc.write( xml_str = "" , indent, true)
|
60
|
+
xml_str
|
61
|
+
elsif (obj.respond_to?(:serialize_variables))
|
62
|
+
element_name = obj.serialize_name
|
63
|
+
doc = REXML::Document.new()
|
64
|
+
SerializeHelper::serialize_variables_rexml(doc.add_element(element_name), obj)
|
65
|
+
doc.write( xml_str = "", indent, true)
|
66
|
+
xml_str
|
67
|
+
else
|
68
|
+
obj.to_s.encode(:xml => :text)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @!visibility private
|
73
|
+
def self.serialize_to_file(file, obj)
|
74
|
+
File.open(file, 'w') do |f|
|
75
|
+
f.write(SerializeHelper::serialize(obj))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# @!visibility private
|
80
|
+
def symbol_to_name(symbol)
|
81
|
+
symbol.to_s.split('_').join(' ').capitalize
|
82
|
+
end
|
83
|
+
|
84
|
+
# @!visibility private
|
85
|
+
def map_symbol_to_row(symbol,type)
|
86
|
+
{
|
87
|
+
:id => symbol.to_s,
|
88
|
+
:name => symbol == :id ? 'Go id' : symbol_to_name(symbol),
|
89
|
+
:type =>type
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
# @!visibility private
|
94
|
+
def map_to_row(p)
|
95
|
+
case p[:type]
|
96
|
+
when :string then
|
97
|
+
map_symbol_to_row(p[:id],p[:type])
|
98
|
+
when :bool then
|
99
|
+
map_symbol_to_row(p[:id],p[:type])
|
100
|
+
when :date then
|
101
|
+
map_symbol_to_row(p[:id],p[:type])
|
102
|
+
when :notes then
|
103
|
+
{
|
104
|
+
:id => p[:id].to_s,
|
105
|
+
:name => symbol_to_name(p[:id]),
|
106
|
+
:type => p[:type],
|
107
|
+
:models => SerializeHelper.get_import_rows(:note)
|
108
|
+
}
|
109
|
+
when :tags then
|
110
|
+
{
|
111
|
+
:id => p[:id].to_s,
|
112
|
+
:type => p[:type],
|
113
|
+
:name => symbol_to_name(p[:id]),
|
114
|
+
}
|
115
|
+
when :persons then
|
116
|
+
{
|
117
|
+
:id => p[:id].to_s,
|
118
|
+
:type => p[:type],
|
119
|
+
:name => symbol_to_name(p[:id]),
|
120
|
+
:models => SerializeHelper.get_import_rows(:person)
|
121
|
+
}
|
122
|
+
when :custom_fields then
|
123
|
+
{
|
124
|
+
:id => p[:id].to_s,
|
125
|
+
:type => p[:type],
|
126
|
+
:name => symbol_to_name(p[:id]),
|
127
|
+
:models => SerializeHelper.get_import_rows(:custom_field)
|
128
|
+
}
|
129
|
+
when :custom_values then
|
130
|
+
{
|
131
|
+
:id => p[:id].to_s,
|
132
|
+
:type => p[:type],
|
133
|
+
:name => symbol_to_name(p[:id]),
|
134
|
+
:models => SerializeHelper.get_import_rows(:custom_value)
|
135
|
+
}
|
136
|
+
else
|
137
|
+
{
|
138
|
+
:id => p[:id].to_s,
|
139
|
+
:name => symbol_to_name(p[:id]),
|
140
|
+
:type => p[:type],
|
141
|
+
:model => SerializeHelper.get_import_rows(p[:type])
|
142
|
+
}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# What fields/rows on the class is supposed to be used by the Gem to generate the xml
|
147
|
+
# This method uses #serialize_variables.
|
148
|
+
def get_import_rows
|
149
|
+
serialize_variables.map do |p|
|
150
|
+
map_to_row p
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# @!visibility private
|
155
|
+
def self.get_import_rows(type)
|
156
|
+
case type
|
157
|
+
when :person then
|
158
|
+
Person.new
|
159
|
+
when :source_ref then
|
160
|
+
ReferenceToSource.new
|
161
|
+
when :note then
|
162
|
+
Note.new
|
163
|
+
when :address then
|
164
|
+
Address.new
|
165
|
+
when :organization then
|
166
|
+
Organization.new
|
167
|
+
when :coworker_reference then
|
168
|
+
CoworkerReference.new
|
169
|
+
when :organization_reference then
|
170
|
+
OrganizationReference.new
|
171
|
+
when :custom_field then
|
172
|
+
CustomField.new
|
173
|
+
when :custom_value then
|
174
|
+
CustomValue.new
|
175
|
+
when :custom_field_reference then
|
176
|
+
CustomFieldReference.new
|
177
|
+
when :settings then
|
178
|
+
Settings.new
|
179
|
+
when :class_settings then
|
180
|
+
ClassSettings.new
|
181
|
+
else
|
182
|
+
raise "Unknown type: #{type}"
|
183
|
+
end.get_import_rows
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module GoImport
|
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
|
+
private
|
40
|
+
def source_exists?(name)
|
41
|
+
source = list.find { |s| s.downcase == name.downcase }
|
42
|
+
|
43
|
+
return !source.nil?
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def project_exists?(name)
|
48
|
+
# do we have a folder named 'name' in the current folder?
|
49
|
+
project = Dir.entries(Dir.pwd).find { |f| f.downcase == name.downcase}
|
50
|
+
|
51
|
+
return !project.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def copy_source_to_folder(source_name, project_name)
|
56
|
+
puts "Trying to create project '#{project_name}' from source '#{source_name}'..."
|
57
|
+
FileUtils.cp_r File.expand_path(source_name, @path), project_name
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def install_gems_for_project(project_name)
|
62
|
+
puts "Trying to verify that all required gems are installed..."
|
63
|
+
Dir.chdir(File.expand_path(project_name, Dir.pwd)) do
|
64
|
+
exec_but_dont_show_unless_error('bundle install --verbose')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def exec_but_dont_show_unless_error(cmd)
|
70
|
+
std_out_value = []
|
71
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
72
|
+
while std_line = stdout.gets
|
73
|
+
std_out_value << std_line
|
74
|
+
end
|
75
|
+
|
76
|
+
exit_status = wait_thr.value
|
77
|
+
if !exit_status.success?
|
78
|
+
puts "Command '#{cmd}' failed with #{exit_status}"
|
79
|
+
puts "Output from command:"
|
80
|
+
puts std_out_value
|
81
|
+
|
82
|
+
raise "failed exec #{cmd}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require 'open3'
|
3
|
+
module GoImport
|
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/go_import.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module GoImport
|
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 'go_import/errors'
|
8
|
+
require 'go_import/serialize_helper'
|
9
|
+
require 'go_import/model_helpers'
|
10
|
+
#FruitToLime::require_all_in 'go_import/model/*.rb'
|
11
|
+
GoImport::require_all_in 'go_import/model/*.rb'
|
12
|
+
require 'go_import/csv_helper'
|
13
|
+
require 'go_import/roo_helper'
|
14
|
+
require 'go_import/phone_helper'
|
15
|
+
require 'go_import/email_helper'
|
16
|
+
require 'go_import/excel_helper'
|
17
|
+
require 'go_import/templating'
|
18
|
+
require 'go_import/source'
|
19
|
+
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,62 @@
|
|
1
|
+
|
2
|
+
require 'go_import'
|
3
|
+
require_relative("../converter")
|
4
|
+
|
5
|
+
# COWORKER_FILE and other file names should be defined ../converter.rb
|
6
|
+
|
7
|
+
def process_rows(file_name)
|
8
|
+
data = File.open(file_name, 'r').read.encode('UTF-8',"ISO-8859-1")
|
9
|
+
rows = GoImport::CsvHelper::text_to_hashes(data)
|
10
|
+
rows.each do |row|
|
11
|
+
yield row
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def convert_source
|
16
|
+
puts "Trying to convert CSV source to LIME Go..."
|
17
|
+
|
18
|
+
converter = Converter.new
|
19
|
+
|
20
|
+
# A rootmodel is used to represent all entitite/models that is
|
21
|
+
# exported
|
22
|
+
rootmodel = GoImport::RootModel.new
|
23
|
+
|
24
|
+
converter.configure(rootmodel)
|
25
|
+
|
26
|
+
# coworkers
|
27
|
+
# start with these since they are referenced
|
28
|
+
# from everywhere....
|
29
|
+
if defined?(COWORKER_FILE) && !COWORKER_FILE.nil? && !COWORKER_FILE.empty?
|
30
|
+
process_rows COWORKER_FILE do |row|
|
31
|
+
rootmodel.add_coworker(converter.to_coworker(row))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# organizations
|
36
|
+
if defined?(ORGANIZATION_FILE) && !ORGANIZATION_FILE.nil? && !ORGANIZATION_FILE.empty?
|
37
|
+
process_rows ORGANIZATION_FILE do |row|
|
38
|
+
rootmodel.add_organization(converter.to_organization(row, rootmodel))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# persons
|
43
|
+
# depends on organizations
|
44
|
+
if defined?(PERSON_FILE) && !PERSON_FILE.nil? && !PERSON_FILE.empty?
|
45
|
+
process_rows PERSON_FILE do |row|
|
46
|
+
# adds it self to the employer
|
47
|
+
converter.to_person(row, rootmodel)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# deals
|
52
|
+
# deals can reference coworkers (responsible), organizations
|
53
|
+
# and persons (contact)
|
54
|
+
if defined?(DEAL_FILE) && !DEAL_FILE.nil? && !DEAL_FILE.empty?
|
55
|
+
process_rows DEAL_FILE do |row|
|
56
|
+
rootmodel.add_deal(converter.to_deal(row, rootmodel))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
return rootmodel
|
61
|
+
end
|
62
|
+
|
data/sources/csv/Gemfile
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'go_import'
|
2
|
+
|
3
|
+
# This converter will convert one or more CVS files into a LIME Go XML
|
4
|
+
# file.
|
5
|
+
|
6
|
+
# You need to customize this script to suit your CVS file(s).
|
7
|
+
|
8
|
+
# First we set the file names of your CVS files. If you dont need to
|
9
|
+
# import all kind of objects, just leave the filename empty or remove
|
10
|
+
# the line.
|
11
|
+
COWORKER_FILE = "data/coworkers.csv"
|
12
|
+
ORGANIZATION_FILE = "data/organizations.csv"
|
13
|
+
PERSON_FILE = "data/persons.csv"
|
14
|
+
DEAL_FILE = "data/deals.csv"
|
15
|
+
|
16
|
+
# Ie if you dont want to import deals, set DEAL_FILE = ""
|
17
|
+
|
18
|
+
class Converter
|
19
|
+
# Configure your root model, add custom fields and deal statuses.
|
20
|
+
def configure(rootmodel)
|
21
|
+
# add custom field to your model here. Custom fields can be
|
22
|
+
# added to organization, deal and person. Valid types are
|
23
|
+
# :String and :Link. If no type is specified :String is used
|
24
|
+
# as default.
|
25
|
+
rootmodel.settings.with_organization do |organization|
|
26
|
+
organization.set_custom_field( { :integrationid => 'external_url', :title => 'Link to external system', :type => :Link } )
|
27
|
+
end
|
28
|
+
|
29
|
+
rootmodel.settings.with_deal do |deal|
|
30
|
+
deal.add_status({:label => "1. Kvalificering", :integration_id => "qualification"})
|
31
|
+
deal.add_status({:label => "Vunnen", :integration_id => "won",
|
32
|
+
:assessment => GoImport::DealState::PositiveEndState })
|
33
|
+
deal.add_status({:label => "Lost", :integration_id => "Lost",
|
34
|
+
:assessment => GoImport::DealState::NegativeEndState })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Turns a row from the organization csv file into a
|
39
|
+
# GoImport::Organization.
|
40
|
+
# Use rootmodel to locate other related stuff such coworker
|
41
|
+
def to_organization(row, rootmodel)
|
42
|
+
organization = GoImport::Organization.new
|
43
|
+
# Integrationid is typically the id in the system that
|
44
|
+
# we are getting the csv from. Must be set to be able
|
45
|
+
# to import the same file more than once without
|
46
|
+
# creating duplicates
|
47
|
+
organization.integration_id = row['id']
|
48
|
+
organization.name = row['name']
|
49
|
+
|
50
|
+
# Just setting all basic properties to show whats available
|
51
|
+
# Remove or fix...
|
52
|
+
organization.organization_number = 'a number' # needs clean up, should have helpers for that in lib. Swedish format.
|
53
|
+
organization.email = 'email to organizaiton, not the person'
|
54
|
+
organization.web_site = 'www.whatever.com'
|
55
|
+
organization.central_phone_number = '0000' # needs clean up, should have helpers for that in lib. Default swedish format, convert to global format
|
56
|
+
|
57
|
+
# Addresses consists of several parts in Go.
|
58
|
+
# Lots of other systems have the address all in one
|
59
|
+
# line, to be able to match when importing it is
|
60
|
+
# way better to split the addresses
|
61
|
+
organization.with_visit_address do |address|
|
62
|
+
address.street = 'visit street'
|
63
|
+
address.zip_code = 'visit zip'
|
64
|
+
address.city = 'visit city'
|
65
|
+
end
|
66
|
+
|
67
|
+
# Another example of setting address using
|
68
|
+
# helper to split '226 48 LUND' into zip and city
|
69
|
+
organization.with_postal_address do |address|
|
70
|
+
address.street = 'postal street'
|
71
|
+
address.parse_zip_and_address_se '226 48 LUND'
|
72
|
+
end
|
73
|
+
|
74
|
+
# Responsible coworker is set by first locating
|
75
|
+
# it in the root model and then setting a reference
|
76
|
+
# to him/her
|
77
|
+
# We need to be able handle missing coworkers here
|
78
|
+
coworker = rootmodel.find_coworker_by_integration_id row['responsible_id']
|
79
|
+
organization.responsible_coworker = coworker.to_reference
|
80
|
+
|
81
|
+
# Tags are set and defined at the same place
|
82
|
+
# Setting a tag: Imported is useful for the user
|
83
|
+
organization.set_tag("Imported")
|
84
|
+
|
85
|
+
# When imported from web based ERP or similair that
|
86
|
+
# client will continue to use it can be useful to be
|
87
|
+
# able to link from Go to the same record in the ERP
|
88
|
+
# FOr instance Lime links
|
89
|
+
organization.set_custom_value("external_url", "http://something.com?key=#{row['id']}")
|
90
|
+
|
91
|
+
return organization
|
92
|
+
end
|
93
|
+
|
94
|
+
# Turns a row from the coworker csv file into a GoImport::Coworker.
|
95
|
+
def to_coworker(row)
|
96
|
+
coworker = GoImport::Coworker.new
|
97
|
+
coworker.integration_id = row['id']
|
98
|
+
coworker.first_name = row['first_name']
|
99
|
+
coworker.last_name = row['last_name']
|
100
|
+
|
101
|
+
# Other optional attributes
|
102
|
+
coworker.email = 't@e.com'
|
103
|
+
coworker.direct_phone_number = '+46121212'
|
104
|
+
coworker.mobile_phone_number = '+46324234'
|
105
|
+
coworker.home_phone_number = '+46234234'
|
106
|
+
|
107
|
+
# Tags and custom fields are set the same
|
108
|
+
# way as on organizations
|
109
|
+
|
110
|
+
return coworker
|
111
|
+
end
|
112
|
+
|
113
|
+
# Turns a row from the person csv file into a GoImport::Person.
|
114
|
+
#
|
115
|
+
# You MUST add the new person to an existing organization. Use the
|
116
|
+
# rootmodel to find the organization and then add the person with
|
117
|
+
# organization.add_employee
|
118
|
+
def to_person(row, rootmodel)
|
119
|
+
person = GoImport::Person.new
|
120
|
+
person.integration_id = row['id']
|
121
|
+
# Note that Go has separate first and last names
|
122
|
+
# Some splitting might be necessary
|
123
|
+
person.first_name = row['first_name']
|
124
|
+
person.last_name = row['last_name']
|
125
|
+
# other optional attributes
|
126
|
+
person.direct_phone_number = '+4611111'
|
127
|
+
person.fax_phone_number = '+4623234234234'
|
128
|
+
person.mobile_phone_number = '+462321212'
|
129
|
+
person.email = 'x@y.com'
|
130
|
+
person.alternative_email = 'y@x.com'
|
131
|
+
person.with_postal_address do |address|
|
132
|
+
address.street = 'postal street'
|
133
|
+
address.parse_zip_and_address_se '226 48 LUND'
|
134
|
+
end
|
135
|
+
|
136
|
+
# Tags and custom fields are set the same
|
137
|
+
# way as on organizations
|
138
|
+
|
139
|
+
# set employer connection
|
140
|
+
employer_id = row['employer_id']
|
141
|
+
employer = rootmodel.find_organization_by_integration_id employer_id
|
142
|
+
employer.add_employee person
|
143
|
+
end
|
144
|
+
|
145
|
+
# Turns a row form the deal csv file into a GoImport::Deal. Use
|
146
|
+
# the rootmodel to find objects that should be linked to the new
|
147
|
+
# deal.
|
148
|
+
def to_deal(row, rootmodel)
|
149
|
+
deal = GoImport::Deal.new
|
150
|
+
deal.integration_id = row['id']
|
151
|
+
deal.name = row['name']
|
152
|
+
# should be integer, same currency should be used in
|
153
|
+
# the system
|
154
|
+
deal.value = row['value']
|
155
|
+
|
156
|
+
# find stuff connected to deal
|
157
|
+
responsible = rootmodel.find_coworker_by_integration_id row['responsible_id']
|
158
|
+
organization = rootmodel.find_organization_by_integration_id row['customer_id']
|
159
|
+
person = organization.find_employee_by_integration_id row['customer_contact_id']
|
160
|
+
# connect the deal by references
|
161
|
+
deal.responsible_coworker = responsible.to_reference
|
162
|
+
deal.customer = organization.to_reference
|
163
|
+
deal.customer_contact = person.to_reference
|
164
|
+
|
165
|
+
# other optional attributes
|
166
|
+
deal.probability = 50 # should be between 0 - 100
|
167
|
+
deal.order_date = '2014-01-05' # Format ?
|
168
|
+
|
169
|
+
# status, set this by either label, id or integration_id (use
|
170
|
+
# appropriate method to find status)
|
171
|
+
deal.status = rootmodel.settings.deal.find_status_by_label row['status']
|
172
|
+
|
173
|
+
# or set by existing status, search by label, integration_id
|
174
|
+
# (if string) or id (if integer).
|
175
|
+
# deal.status = "Won"
|
176
|
+
|
177
|
+
return deal
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tomodel'
|
3
|
+
|
4
|
+
describe 'Exporter' do
|
5
|
+
before(:all) do
|
6
|
+
exporter = Exporter.new
|
7
|
+
organizations_file = File.join(File.dirname(__FILE__), 'sample_data', 'organizations.csv')
|
8
|
+
coworkers_file = File.join(File.dirname(__FILE__), 'sample_data', 'coworkers.csv')
|
9
|
+
persons_file = File.join(File.dirname(__FILE__), 'sample_data', 'persons.csv')
|
10
|
+
deals_file = File.join(File.dirname(__FILE__), 'sample_data', 'deals.csv')
|
11
|
+
@model = exporter.to_model(coworkers_file, organizations_file, persons_file, deals_file)
|
12
|
+
end
|
13
|
+
it "will find something with a name" do
|
14
|
+
organization = @model.organizations[0]
|
15
|
+
organization.name.length.should > 0
|
16
|
+
end
|
17
|
+
end
|