go_import 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/go-import +45 -29
- data/lib/go_import/model/documents.rb +31 -6
- data/lib/go_import/model/file.rb +112 -0
- data/lib/go_import/model/rootmodel.rb +65 -0
- data/lib/go_import/phone_helper.rb +1 -1
- data/lib/go_import/serialize_helper.rb +3 -3
- data/lib/go_import/source.rb +2 -2
- data/sources/easy/.go_import/runner.rb +7 -2
- data/sources/easy/converter.rb +20 -2
- data/sources/excel/.go_import/runner.rb +31 -10
- data/sources/excel/converter.rb +16 -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/spec/address_spec.rb +4 -4
- data/spec/documents_spec.rb +27 -0
- data/spec/file_spec.rb +140 -0
- data/spec/link_spec.rb +0 -2
- data/spec/rootmodel_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -1
- metadata +10 -2
data/bin/go-import
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require "thor"
|
4
4
|
require "go_import"
|
5
5
|
|
6
|
+
RUNNER_DIR = ".go_import"
|
7
|
+
|
6
8
|
class GoImportCommandLine < Thor
|
7
9
|
|
8
10
|
desc "about", "About go-import"
|
@@ -43,51 +45,65 @@ class GoImportCommandLine < Thor
|
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
|
-
desc "run", "Executes the current project and create a go.
|
48
|
+
desc "run", "Executes the current project and create a go.zip file with data and files. Existing go.zip will be overwritten, use --output to specify a different filename."
|
47
49
|
option(:output,
|
48
50
|
:desc => "Name of the file where the converted source will be saved. This file should be sent to LIME Go. If the file already exist it will be replaced.",
|
49
51
|
:type => :string,
|
50
52
|
:required => false)
|
51
53
|
def run_import()
|
52
|
-
|
53
|
-
|
54
|
-
runner_dir = ".go_import"
|
55
|
-
|
56
|
-
if Dir.exists?(runner_dir) == false
|
57
|
-
puts "This doesnt look like a go-import project. Are you in the right directory or did you mess with the '#{runner_dir}' folder?"
|
58
|
-
return
|
59
|
-
end
|
60
|
-
|
61
|
-
runner_file = File.expand_path('./.go_import/runner.rb', Dir.pwd)
|
62
|
-
if File.exists?(runner_file) == false
|
63
|
-
puts "I can't run this project. Did you mess with the '#{runner_dir}' folder?"
|
54
|
+
if !is_valid_goimport_project?
|
64
55
|
return
|
65
56
|
end
|
66
57
|
|
58
|
+
runner_file = File.expand_path("./#{RUNNER_DIR}/runner.rb", Dir.pwd)
|
67
59
|
require(runner_file)
|
68
|
-
|
69
|
-
# the source must implement the convert_source method that
|
70
|
-
# returns an instance of GoImport::RootModel
|
71
60
|
model = convert_source()
|
72
61
|
|
73
|
-
|
62
|
+
if model.documents.files.length > 0 && (!defined?(FILES_FOLDER) || FILES_FOLDER.empty?())
|
63
|
+
puts "WARNING: It looks like you are importing files but FILES_FOLDER has not been set in your converter.rb."
|
64
|
+
puts "WARNING: FILES_FOLDER should be set unless you are only importing files with absolute paths."
|
65
|
+
end
|
74
66
|
|
75
|
-
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
model.serialize_to_file(go_data_filename)
|
81
|
-
puts "Source has been been converted into '#{go_data_filename}'."
|
82
|
-
else
|
83
|
-
puts "Source could not be converted due to"
|
84
|
-
puts validation_errors
|
85
|
-
end
|
67
|
+
is_ok, error_msg = can_be_serialized?(model)
|
68
|
+
if is_ok
|
69
|
+
go_data_zip = options.output.nil? == true ? "go.zip" : options.output
|
70
|
+
model.save_to_zip(go_data_zip)
|
71
|
+
puts "Source has been been converted into '#{go_data_zip}'."
|
86
72
|
else
|
87
73
|
puts "Source could not be converted due to"
|
88
|
-
puts
|
74
|
+
puts error_msg
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def can_be_serialized?(rootmodel)
|
80
|
+
is_ok = false
|
81
|
+
error = rootmodel.sanity_check
|
82
|
+
if error.empty?
|
83
|
+
error = rootmodel.validate
|
84
|
+
|
85
|
+
if error.empty?
|
86
|
+
is_ok = true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
return [is_ok, error]
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def is_valid_goimport_project?()
|
95
|
+
if Dir.exists?(RUNNER_DIR) == false
|
96
|
+
puts "This doesnt look like a go-import project. Are you in the right directory or did you mess with the '#{RUNNER_DIR}' folder?"
|
97
|
+
return false
|
98
|
+
end
|
99
|
+
|
100
|
+
runner_file = File.expand_path("./#{RUNNER_DIR}/runner.rb", Dir.pwd)
|
101
|
+
if File.exists?(runner_file) == false
|
102
|
+
puts "I can't run this project. Did you mess with the '#{RUNNER_DIR}' folder?"
|
103
|
+
return false
|
89
104
|
end
|
90
105
|
|
106
|
+
return true
|
91
107
|
end
|
92
108
|
|
93
109
|
private
|
@@ -3,15 +3,14 @@ module GoImport
|
|
3
3
|
# This class is the container for all documents, ie links and
|
4
4
|
# files.
|
5
5
|
class Documents
|
6
|
-
# *** TODO: add files when supported by the backend.
|
7
|
-
|
8
6
|
include SerializeHelper
|
9
7
|
|
10
|
-
|
8
|
+
attr_reader :links, :files
|
11
9
|
|
12
10
|
def serialize_variables
|
13
11
|
[
|
14
|
-
{:id => :links, @type => :links}
|
12
|
+
{:id => :links, @type => :links},
|
13
|
+
{:id => :files, @type => :files}
|
15
14
|
]
|
16
15
|
end
|
17
16
|
|
@@ -21,6 +20,7 @@ module GoImport
|
|
21
20
|
|
22
21
|
def initialize
|
23
22
|
@links = []
|
23
|
+
@files = []
|
24
24
|
end
|
25
25
|
|
26
26
|
def add_link(link)
|
@@ -34,10 +34,10 @@ module GoImport
|
|
34
34
|
|
35
35
|
if (!link.integration_id.nil? && link.integration_id.length > 0) &&
|
36
36
|
find_link_by_integration_id(link.integration_id) != nil
|
37
|
-
raise AlreadyAddedError, "Already added a link with integration_id #{link.integration_id}"
|
37
|
+
raise AlreadyAddedError, "Already added a link with integration_id '#{link.integration_id}'."
|
38
38
|
end
|
39
39
|
|
40
|
-
@links.push
|
40
|
+
@links.push link
|
41
41
|
|
42
42
|
return link
|
43
43
|
end
|
@@ -47,5 +47,30 @@ module GoImport
|
|
47
47
|
link.integration_id == integration_id
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
def add_file(file)
|
52
|
+
@files = [] if @files == nil
|
53
|
+
|
54
|
+
if file.nil?
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
|
58
|
+
file = File.new(file) if !file.is_a?(File)
|
59
|
+
|
60
|
+
if (!file.integration_id.nil? && file.integration_id.length > 0) &&
|
61
|
+
find_file_by_integration_id(file.integration_id) != nil
|
62
|
+
raise AlreadyAddedError, "Already added a file with integration_id '#{file.integration_id}'."
|
63
|
+
end
|
64
|
+
|
65
|
+
@files.push file
|
66
|
+
|
67
|
+
return file
|
68
|
+
end
|
69
|
+
|
70
|
+
def find_file_by_integration_id(integration_id)
|
71
|
+
return @files.find do |file|
|
72
|
+
file.integration_id == integration_id
|
73
|
+
end
|
74
|
+
end
|
50
75
|
end
|
51
76
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require_relative '../serialize_helper'
|
3
|
+
|
4
|
+
# Note that we name this class File and ruby alread have a File class.
|
5
|
+
# To refrence to this
|
6
|
+
|
7
|
+
module GoImport
|
8
|
+
class File
|
9
|
+
include SerializeHelper
|
10
|
+
attr_accessor :id, :integration_id, :path, :description
|
11
|
+
|
12
|
+
attr_reader :organization, :created_by, :deal
|
13
|
+
|
14
|
+
attr_writer :name
|
15
|
+
|
16
|
+
# zip_path is used internally when the file is stored in the
|
17
|
+
# zip file that is sent to LIME Go. You should not modify this
|
18
|
+
# property
|
19
|
+
attr_accessor :location_in_zip_file
|
20
|
+
|
21
|
+
def initialize(opt = nil)
|
22
|
+
if !opt.nil?
|
23
|
+
serialize_variables.each do |myattr|
|
24
|
+
val = opt[myattr[:id]]
|
25
|
+
instance_variable_set("@" + myattr[:id].to_s, val) if val != nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def serialize_name
|
31
|
+
"File"
|
32
|
+
end
|
33
|
+
|
34
|
+
def serialize_variables
|
35
|
+
[ :id, :integration_id, :path, :name, :description, :location_in_zip_file ].map {
|
36
|
+
|p| {
|
37
|
+
:id => p,
|
38
|
+
:type => :string
|
39
|
+
}
|
40
|
+
} +
|
41
|
+
[
|
42
|
+
{ :id => :created_by, :type => :coworker_reference },
|
43
|
+
{ :id => :organization, :type => :organization_reference },
|
44
|
+
{ :id => :deal, :type => :deal_reference }
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
def name
|
49
|
+
if @name.nil? || @name.empty?
|
50
|
+
if !@path.nil?
|
51
|
+
return Pathname.new(path).basename.to_s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
return @name
|
56
|
+
end
|
57
|
+
|
58
|
+
def has_relative_path?()
|
59
|
+
return Pathname.new(@path).relative?
|
60
|
+
end
|
61
|
+
|
62
|
+
def organization=(org)
|
63
|
+
@organization = OrganizationReference.from_organization(org)
|
64
|
+
end
|
65
|
+
|
66
|
+
def deal=(deal)
|
67
|
+
@deal = DealReference.from_deal(deal)
|
68
|
+
end
|
69
|
+
|
70
|
+
def created_by=(coworker)
|
71
|
+
@created_by = CoworkerReference.from_coworker(coworker)
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate
|
75
|
+
error = String.new
|
76
|
+
|
77
|
+
if @path.nil? || @path.empty?
|
78
|
+
error = "Path is required for file.\n"
|
79
|
+
else
|
80
|
+
if has_relative_path?()
|
81
|
+
if defined?(FILES_FOLDER) && !FILES_FOLDER.empty?()
|
82
|
+
root_folder = FILES_FOLDER
|
83
|
+
else
|
84
|
+
root_folder = Dir.pwd
|
85
|
+
end
|
86
|
+
|
87
|
+
if !::File.exists?("#{root_folder}/#{@path}")
|
88
|
+
error = "#{error}Can't find file '#{root_folder}/#{@path}'.\n"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
if !::File.exists?(@path)
|
92
|
+
error = "#{error}Can't find file '#{@path}'.\n"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if @created_by.nil?
|
98
|
+
error = "#{error}Created_by is required for file.\n"
|
99
|
+
end
|
100
|
+
|
101
|
+
if @organization.nil? && @deal.nil?
|
102
|
+
error = "#{error}A file must have either an organization or a deal.\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
if !@organization.nil? && !@deal.nil?
|
106
|
+
error = "#{error}A file can't be attached to both an organization and a deal."
|
107
|
+
end
|
108
|
+
|
109
|
+
return error
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'zip'
|
4
|
+
require 'securerandom'
|
5
|
+
|
2
6
|
module GoImport
|
3
7
|
# The root model for Go import. This class is the container for everything else.
|
4
8
|
class RootModel
|
@@ -213,6 +217,11 @@ module GoImport
|
|
213
217
|
return @documents.add_link(link)
|
214
218
|
end
|
215
219
|
|
220
|
+
def add_file(file)
|
221
|
+
@documents = Documents.new if @documents == nil
|
222
|
+
|
223
|
+
return @documents.add_file(file)
|
224
|
+
end
|
216
225
|
|
217
226
|
def find_coworker_by_integration_id(integration_id)
|
218
227
|
return @coworkers.find do |coworker|
|
@@ -329,6 +338,13 @@ module GoImport
|
|
329
338
|
end
|
330
339
|
end
|
331
340
|
|
341
|
+
@documents.files.each do |file|
|
342
|
+
validation_message = file.validate
|
343
|
+
if !validation_message.empty?
|
344
|
+
error = "#{error}\n#{validation_message}"
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
332
348
|
return error.strip
|
333
349
|
end
|
334
350
|
|
@@ -339,6 +355,55 @@ module GoImport
|
|
339
355
|
SerializeHelper::serialize_variables_rexml(elem, self)
|
340
356
|
end
|
341
357
|
|
358
|
+
# @!visibility private
|
359
|
+
# zip-filename is the name of the zip file to create
|
360
|
+
def save_to_zip(zip_filename)
|
361
|
+
puts "Trying to save to '#{zip_filename}'..."
|
362
|
+
# saves the model to a zipfile that contains xml data and
|
363
|
+
# document files.
|
364
|
+
|
365
|
+
if ::File.exists?(zip_filename)
|
366
|
+
::File.delete zip_filename
|
367
|
+
end
|
368
|
+
|
369
|
+
Zip::File.open(zip_filename, Zip::File::CREATE) do |zip_file|
|
370
|
+
puts "Trying to add files to zip..."
|
371
|
+
# We must add files first to the zip file since we
|
372
|
+
# will set each file's location_in_zip_file when the
|
373
|
+
# zip file is created.
|
374
|
+
|
375
|
+
if defined?(FILES_FOLDER) && !FILES_FOLDER.empty?()
|
376
|
+
puts "Files with relative path are imported from '#{FILES_FOLDER}'."
|
377
|
+
root_folder = FILES_FOLDER
|
378
|
+
else
|
379
|
+
puts "Files with relative path are imported from the current folder (#{Dir.pwd})."
|
380
|
+
root_folder = Dir.pwd
|
381
|
+
end
|
382
|
+
|
383
|
+
# 1) files/ - a folder with all files referenced from
|
384
|
+
# the source.
|
385
|
+
documents.files.each do |file|
|
386
|
+
# we dont need to check that the file exists since
|
387
|
+
# we assume that rootmodel.validate has been
|
388
|
+
# called before save_to_zip.
|
389
|
+
if file.has_relative_path?
|
390
|
+
file.location_in_zip_file = "files/#{file.path}"
|
391
|
+
zip_file.add(file.location_in_zip_file, "#{root_folder}/#{file.path}")
|
392
|
+
else
|
393
|
+
file.location_in_zip_file = "files/__abs/#{SecureRandom.uuid}/#{::File.basename(file.path).to_s}"
|
394
|
+
zip_file.add(file.location_in_zip_file, file.path)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
# 2) go.xml - with all data from source
|
399
|
+
puts "Trying to add organizations, persons, etc to zip..."
|
400
|
+
go_data_file = Tempfile.new('go')
|
401
|
+
serialize_to_file(go_data_file)
|
402
|
+
zip_file.add('go.xml', go_data_file)
|
403
|
+
go_data_file.unlink
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
342
407
|
private
|
343
408
|
# returns all items from the object array with duplicate integration ids.
|
344
409
|
# To get all organizations with the same integration_id use
|
@@ -4,7 +4,7 @@ module GoImport
|
|
4
4
|
# The PhoneHelper helps you parse and format phone number strings
|
5
5
|
# into pretty looking numbers.
|
6
6
|
class PhoneHelper
|
7
|
-
GlobalPhone.db_path = File.join(File.dirname(__FILE__), 'global_phone.json')
|
7
|
+
GlobalPhone.db_path = ::File.join(::File.dirname(__FILE__), 'global_phone.json')
|
8
8
|
GlobalPhone.default_territory_name = :se
|
9
9
|
|
10
10
|
# Sets the country code used during parsning. The default is
|
@@ -25,8 +25,8 @@ module GoImport
|
|
25
25
|
if (raw_var.respond_to?(:serialize_variables))
|
26
26
|
SerializeHelper::serialize_variables_rexml(element, raw_var)
|
27
27
|
elsif (raw_var.is_a?(Array))
|
28
|
-
raw_var.each do |raw_var_elem|
|
29
|
-
SerializeHelper::serialize_rexml(element, raw_var_elem)
|
28
|
+
raw_var.each do |raw_var_elem|
|
29
|
+
SerializeHelper::serialize_rexml(element, raw_var_elem)
|
30
30
|
end
|
31
31
|
else
|
32
32
|
element.text = raw_var.to_s.encode('UTF-8')
|
@@ -71,7 +71,7 @@ module GoImport
|
|
71
71
|
|
72
72
|
# @!visibility private
|
73
73
|
def self.serialize_to_file(file, obj)
|
74
|
-
File.open(file, 'w') do |f|
|
74
|
+
::File.open(file, 'w') do |f|
|
75
75
|
f.write(SerializeHelper::serialize(obj))
|
76
76
|
end
|
77
77
|
end
|
data/lib/go_import/source.rb
CHANGED
@@ -54,13 +54,13 @@ module GoImport
|
|
54
54
|
private
|
55
55
|
def copy_source_to_folder(source_name, project_name)
|
56
56
|
puts "Trying to create project '#{project_name}' from source '#{source_name}'..."
|
57
|
-
FileUtils.cp_r File.expand_path(source_name, @path), project_name
|
57
|
+
FileUtils.cp_r ::File.expand_path(source_name, @path), project_name
|
58
58
|
end
|
59
59
|
|
60
60
|
private
|
61
61
|
def install_gems_for_project(project_name)
|
62
62
|
puts "Trying to verify that all required gems are installed..."
|
63
|
-
Dir.chdir(File.expand_path(project_name, Dir.pwd)) do
|
63
|
+
Dir.chdir(::File.expand_path(project_name, Dir.pwd)) do
|
64
64
|
exec_but_dont_show_unless_error('bundle install --verbose')
|
65
65
|
end
|
66
66
|
end
|
@@ -17,7 +17,7 @@ def convert_source
|
|
17
17
|
puts "Trying to convert LIME Easy source to LIME Go..."
|
18
18
|
|
19
19
|
if !make_sure_database_has_been_exported
|
20
|
-
puts "You must export KONTAKT.mdb to the #{EXPORT_FOLDER} folder."
|
20
|
+
puts "ERROR: You must export KONTAKT.mdb to the #{EXPORT_FOLDER} folder."
|
21
21
|
raise
|
22
22
|
end
|
23
23
|
|
@@ -34,7 +34,7 @@ def convert_source
|
|
34
34
|
# start with these since they are referenced
|
35
35
|
# from everywhere....
|
36
36
|
process_rows COWORKER_FILE do |row|
|
37
|
-
coworkers[row['
|
37
|
+
coworkers[row['idUser']] = row['PowerSellUserID']
|
38
38
|
rootmodel.add_coworker(converter.to_coworker(row))
|
39
39
|
end
|
40
40
|
|
@@ -77,6 +77,11 @@ def convert_source
|
|
77
77
|
rootmodel.add_note(converter.to_deal_note(row, coworkers, rootmodel))
|
78
78
|
end
|
79
79
|
|
80
|
+
# company documents
|
81
|
+
process_rows ORGANIZATION_DOCUMENT_FILE do |row|
|
82
|
+
rootmodel.add_file(converter.to_organization_document(row, coworkers, rootmodel))
|
83
|
+
end
|
84
|
+
|
80
85
|
return rootmodel
|
81
86
|
end
|
82
87
|
|
data/sources/easy/converter.rb
CHANGED
@@ -26,10 +26,14 @@ require 'go_import'
|
|
26
26
|
# 2) Modify this file (the to_* methods) according to your customer's
|
27
27
|
# KONTAKT.mdb and wishes.
|
28
28
|
#
|
29
|
-
# 3) Run
|
29
|
+
# 3) Run go-import run
|
30
30
|
#
|
31
|
-
# 4) Upload go.
|
31
|
+
# 4) Upload go.zip to LIME Go. First test your import on staging and
|
32
32
|
# when your customer has approved the import, run it on production.
|
33
|
+
#
|
34
|
+
# You will get a WARNING from 'go-import run' about FILES_FOLDER has
|
35
|
+
# not been set. You can ignore the warning since documents are
|
36
|
+
# exported with an absolute path from LIME Easy.
|
33
37
|
class Converter
|
34
38
|
# Turns a user from the User.txt Easy Export file into
|
35
39
|
# a go_import coworker.
|
@@ -262,6 +266,20 @@ class Converter
|
|
262
266
|
return nil
|
263
267
|
end
|
264
268
|
|
269
|
+
def to_organization_document(row, coworkers, rootmodel)
|
270
|
+
file = GoImport::File.new()
|
271
|
+
|
272
|
+
file.integration_id = row['PowerSellDocumentID']
|
273
|
+
file.path = row['Path']
|
274
|
+
file.name = row['Comment']
|
275
|
+
|
276
|
+
coworker_id = coworkers[row['idUser-Created']]
|
277
|
+
file.created_by = rootmodel.find_coworker_by_integration_id(coworker_id)
|
278
|
+
file.organization = rootmodel.find_organization_by_integration_id(row['PowerSellCompanyID'])
|
279
|
+
|
280
|
+
return file
|
281
|
+
end
|
282
|
+
|
265
283
|
# Turns a row from the Easy exported Project-History.txt file into
|
266
284
|
# a go_import model that is used to generate xml
|
267
285
|
# Uses coworkers hash to lookup coworkers to connect
|
@@ -9,20 +9,26 @@ def convert_source
|
|
9
9
|
|
10
10
|
converter = Converter.new
|
11
11
|
|
12
|
-
# *** TODO:
|
13
|
-
#
|
14
|
-
# Modify the name of the sheets. Or add/remove sheets based on
|
15
|
-
# your Excel file.
|
16
|
-
|
17
12
|
# First we read each sheet from the excel file into separate
|
18
13
|
# variables
|
14
|
+
|
15
|
+
if defined?(EXCEL_FILE) && !EXCEL_FILE.empty?()
|
16
|
+
if !::File.exists?(EXCEL_FILE)
|
17
|
+
puts "ERROR: Cant find excel file to import: '#{EXCEL_FILE}'."
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
else
|
21
|
+
puts "ERROR: You must set EXCEL_FILE in converter.rb to point to the excel file that should be imported."
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
|
19
25
|
excel_workbook = GoImport::ExcelHelper.Open(EXCEL_FILE)
|
20
26
|
|
21
27
|
if defined?(COWORKER_SHEET)
|
22
28
|
if excel_workbook.has_sheet?(COWORKER_SHEET)
|
23
29
|
coworker_rows = excel_workbook.rows_for_sheet COWORKER_SHEET
|
24
30
|
else
|
25
|
-
puts "
|
31
|
+
puts "WARNING: can't find sheet '#{COWORKER_SHEET}'"
|
26
32
|
end
|
27
33
|
end
|
28
34
|
|
@@ -30,7 +36,7 @@ def convert_source
|
|
30
36
|
if excel_workbook.has_sheet?(ORGANIZATION_SHEET)
|
31
37
|
organization_rows = excel_workbook.rows_for_sheet ORGANIZATION_SHEET
|
32
38
|
else
|
33
|
-
puts "
|
39
|
+
puts "WARNING: can't find sheet '#{ORGANIZATION_SHEET}'"
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
@@ -38,7 +44,7 @@ def convert_source
|
|
38
44
|
if excel_workbook.has_sheet?(PERSON_SHEET)
|
39
45
|
person_rows = excel_workbook.rows_for_sheet PERSON_SHEET
|
40
46
|
else
|
41
|
-
puts "
|
47
|
+
puts "WARNING: can't find sheet '#{PERSON_SHEET}'"
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
@@ -46,7 +52,7 @@ def convert_source
|
|
46
52
|
if excel_workbook.has_sheet?(DEAL_SHEET)
|
47
53
|
deal_rows = excel_workbook.rows_for_sheet DEAL_SHEET
|
48
54
|
else
|
49
|
-
puts "
|
55
|
+
puts "WARNING: can't find sheet '#{DEAL_SHEET}'"
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
@@ -54,7 +60,15 @@ def convert_source
|
|
54
60
|
if excel_workbook.has_sheet?(NOTE_SHEET)
|
55
61
|
note_rows = excel_workbook.rows_for_sheet NOTE_SHEET
|
56
62
|
else
|
57
|
-
puts "
|
63
|
+
puts "WARNING: can't find sheet '#{NOTE_SHEET}'"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if defined?(FILE_SHEET)
|
68
|
+
if excel_workbook.has_sheet?(FILE_SHEET)
|
69
|
+
file_rows = excel_workbook.rows_for_sheet FILE_SHEET
|
70
|
+
else
|
71
|
+
puts "WARNING: can't find sheet '#{FILE_SHEET}'"
|
58
72
|
end
|
59
73
|
end
|
60
74
|
|
@@ -111,6 +125,13 @@ def convert_source
|
|
111
125
|
end
|
112
126
|
end
|
113
127
|
|
128
|
+
if defined?(file_rows) && !file_rows.nil?
|
129
|
+
puts "Trying to convert files..."
|
130
|
+
file_rows.each do |row|
|
131
|
+
rootmodel.add_file(converter.to_file(row, rootmodel))
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
114
135
|
return rootmodel
|
115
136
|
end
|
116
137
|
|
data/sources/excel/converter.rb
CHANGED
@@ -16,6 +16,7 @@ ORGANIZATION_SHEET = "Företag"
|
|
16
16
|
PERSON_SHEET = "Kontaktperson"
|
17
17
|
DEAL_SHEET = "Affär"
|
18
18
|
NOTE_SHEET = "Anteckningar"
|
19
|
+
FILE_SHEET = "Dokument"
|
19
20
|
|
20
21
|
# Then you need to modify the script below according to the TODO
|
21
22
|
# comments.
|
@@ -24,6 +25,9 @@ NOTE_SHEET = "Anteckningar"
|
|
24
25
|
# command:
|
25
26
|
# go-import run
|
26
27
|
|
28
|
+
# If you want to include any file in the import.
|
29
|
+
FILES_FOLDER = "D:\\go-import\\file-test\\files"
|
30
|
+
|
27
31
|
class Converter
|
28
32
|
def configure(rootmodel)
|
29
33
|
# *** TODO: Add custom field to your rootmodel here. Custom fields
|
@@ -127,4 +131,16 @@ class Converter
|
|
127
131
|
|
128
132
|
return note
|
129
133
|
end
|
134
|
+
|
135
|
+
def to_file(row, rootmodel)
|
136
|
+
file = GoImport::File.new()
|
137
|
+
|
138
|
+
file.organization = rootmodel.find_organization_by_integration_id(row['Företag'])
|
139
|
+
file.created_by = rootmodel.find_coworker_by_integration_id(row['Skapad Av'])
|
140
|
+
file.name = row['Namn']
|
141
|
+
file.description = row['Kommentar']
|
142
|
+
file.path = row['Path']
|
143
|
+
|
144
|
+
return file
|
145
|
+
end
|
130
146
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/address_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
require 'go_import'
|
3
3
|
|
4
4
|
describe GoImport::Address do
|
@@ -29,7 +29,7 @@ describe GoImport::Address do
|
|
29
29
|
let (:parse_result){
|
30
30
|
address = GoImport::Address.new
|
31
31
|
line = "CZ-140 00 PRAHA 4"
|
32
|
-
address.parse_zip_and_address_se(line)
|
32
|
+
address.parse_zip_and_address_se(line)
|
33
33
|
}
|
34
34
|
it "should be nil" do
|
35
35
|
parse_result.should == nil
|
@@ -39,11 +39,11 @@ describe GoImport::Address do
|
|
39
39
|
let (:parse_result){
|
40
40
|
address = GoImport::Address.new
|
41
41
|
line = "0511 HELSINKI"
|
42
|
-
address.parse_zip_and_address_se(line)
|
42
|
+
address.parse_zip_and_address_se(line)
|
43
43
|
}
|
44
44
|
it "should be nil" do
|
45
45
|
parse_result.should == nil
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
|
-
end
|
49
|
+
end
|
data/spec/documents_spec.rb
CHANGED
@@ -33,5 +33,32 @@ describe "Documents" do
|
|
33
33
|
documents.find_link_by_integration_id("123").url.should eq "http://dropbox.com"
|
34
34
|
end
|
35
35
|
|
36
|
+
it "can add a new file" do
|
37
|
+
# given
|
38
|
+
file = GoImport::File.new
|
39
|
+
file.integration_id = "123key"
|
40
|
+
file.path = "k:\kontakt\databas\dokument"
|
41
|
+
|
42
|
+
# when
|
43
|
+
documents.add_file file
|
44
|
+
|
45
|
+
# then
|
46
|
+
documents.find_file_by_integration_id("123key").path.should eq "k:\kontakt\databas\dokument"
|
47
|
+
documents.files.length.should eq 1
|
48
|
+
end
|
49
|
+
|
50
|
+
it "will not add a new file with a file with the same integration_id already exists" do
|
51
|
+
# given
|
52
|
+
documents.add_file({ :integration_id => "123", :path => "c:\file-1.doc"})
|
53
|
+
documents.files.length.should eq 1
|
54
|
+
|
55
|
+
# when, then
|
56
|
+
expect {
|
57
|
+
documents.add_file({ :integration_id => "123", :path => "c:\file-2.doc"})
|
58
|
+
}.to raise_error(GoImport::AlreadyAddedError)
|
59
|
+
documents.files.length.should eq 1
|
60
|
+
documents.find_file_by_integration_id("123").path.should eq "c:\file-1.doc"
|
61
|
+
end
|
62
|
+
|
36
63
|
end
|
37
64
|
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'go_import'
|
3
|
+
|
4
|
+
describe "File" do
|
5
|
+
let ("file") {
|
6
|
+
GoImport::File.new
|
7
|
+
}
|
8
|
+
|
9
|
+
it "is valid when it has path, created_by and organization" do
|
10
|
+
# given
|
11
|
+
file.path = "spec\\sample_data\\offert.docx"
|
12
|
+
file.created_by = GoImport::CoworkerReference.new( { :integration_id => "123" } )
|
13
|
+
file.organization = GoImport::OrganizationReference.new( { :integration_id => "456" } )
|
14
|
+
|
15
|
+
# when, then
|
16
|
+
file.validate.should eq ""
|
17
|
+
end
|
18
|
+
|
19
|
+
it "is valid when it has name, path, created_by and deal" do
|
20
|
+
# given
|
21
|
+
file.name = "Offert"
|
22
|
+
file.path = "spec\\sample_data\\offert.docx"
|
23
|
+
file.created_by = GoImport::CoworkerReference.new( { :integration_id => "123" } )
|
24
|
+
file.deal = GoImport::DealReference.new( { :integration_id => "456" } )
|
25
|
+
|
26
|
+
# when, then
|
27
|
+
file.validate.should eq ""
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is not valid when it has path and deal" do
|
31
|
+
# must have a created_by
|
32
|
+
# given
|
33
|
+
file.path = "c:\mydocs\deal.xls"
|
34
|
+
file.deal = GoImport::DealReference.new({ :integration_id => "456", :heading => "The new deal" })
|
35
|
+
|
36
|
+
# when, then
|
37
|
+
file.validate.length.should be > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
it "is not valid when it has path and created_by" do
|
41
|
+
# must have an deal or organization
|
42
|
+
# given
|
43
|
+
file.path = "c:\mydocs\deal.xls"
|
44
|
+
file.created_by = GoImport::CoworkerReference.new( { :integration_id => "123", :heading => "billy bob" } )
|
45
|
+
|
46
|
+
# when, then
|
47
|
+
file.validate.length.should be > 0
|
48
|
+
end
|
49
|
+
|
50
|
+
it "is not valid when it has deal and created_by" do
|
51
|
+
# must have a path
|
52
|
+
# given
|
53
|
+
file.created_by = GoImport::CoworkerReference.new( { :integration_id => "123", :heading => "billy bob" } )
|
54
|
+
file.deal = GoImport::DealReference.new({ :integration_id => "456", :heading => "The new deal" })
|
55
|
+
|
56
|
+
# when, then
|
57
|
+
file.validate.length.should be > 0
|
58
|
+
end
|
59
|
+
|
60
|
+
it "knows when a path is not relative" do
|
61
|
+
# given
|
62
|
+
file.path = "c:\files\myfile.doc"
|
63
|
+
|
64
|
+
# when, then
|
65
|
+
file.has_relative_path?().should eq false
|
66
|
+
end
|
67
|
+
|
68
|
+
it "knows when a path is relative" do
|
69
|
+
# given
|
70
|
+
file.path = "files/myfile.doc"
|
71
|
+
|
72
|
+
# when, then
|
73
|
+
file.has_relative_path?().should eq true
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
it "will use filename from path as name if name set not explicit" do
|
78
|
+
# given
|
79
|
+
file.path = "some/files/myfile.docx"
|
80
|
+
file.name = ""
|
81
|
+
|
82
|
+
# when, then
|
83
|
+
file.name.should eq 'myfile.docx'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "will use name as name if name is set explicit" do
|
87
|
+
# given
|
88
|
+
file.path = "some/files/myfile.docx"
|
89
|
+
file.name = "This is a filename"
|
90
|
+
|
91
|
+
# when, then
|
92
|
+
file.name.should eq 'This is a filename'
|
93
|
+
end
|
94
|
+
|
95
|
+
it "will not have a name if name is not set or path is empty" do
|
96
|
+
# given
|
97
|
+
file.path = ""
|
98
|
+
file.name = ""
|
99
|
+
|
100
|
+
# when, then
|
101
|
+
file.name.should eq ''
|
102
|
+
end
|
103
|
+
|
104
|
+
it "will auto convert org to org.ref during assignment" do
|
105
|
+
# given
|
106
|
+
org = GoImport::Organization.new({:integration_id => "123", :name => "Beagle Boys!"})
|
107
|
+
|
108
|
+
# when
|
109
|
+
file.organization = org
|
110
|
+
|
111
|
+
# then
|
112
|
+
file.organization.is_a?(GoImport::OrganizationReference).should eq true
|
113
|
+
end
|
114
|
+
|
115
|
+
it "will auto convert deal to deal.ref during assignment" do
|
116
|
+
# given
|
117
|
+
deal = GoImport::Deal.new({:integration_id => "123" })
|
118
|
+
deal.name = "The new deal"
|
119
|
+
|
120
|
+
# when
|
121
|
+
file.deal = deal
|
122
|
+
|
123
|
+
# then
|
124
|
+
file.deal.is_a?(GoImport::DealReference).should eq true
|
125
|
+
end
|
126
|
+
|
127
|
+
it "will auto convert coworker to coworker.ref during assignment" do
|
128
|
+
# given
|
129
|
+
coworker = GoImport::Coworker.new({:integration_id => "123" })
|
130
|
+
coworker.parse_name_to_firstname_lastname_se "Billy Bob"
|
131
|
+
|
132
|
+
# when
|
133
|
+
file.created_by = coworker
|
134
|
+
|
135
|
+
# then
|
136
|
+
file.created_by.is_a?(GoImport::CoworkerReference).should eq true
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
end
|
data/spec/link_spec.rb
CHANGED
data/spec/rootmodel_spec.rb
CHANGED
@@ -238,6 +238,20 @@ describe "RootModel" do
|
|
238
238
|
rootmodel.documents.links.length.should eq 1
|
239
239
|
end
|
240
240
|
|
241
|
+
it "will add a new file" do
|
242
|
+
# given
|
243
|
+
file = GoImport::File.new
|
244
|
+
file.integration_id = "123key"
|
245
|
+
file.path = "k:\kontakt\databas\dokument"
|
246
|
+
|
247
|
+
# when
|
248
|
+
rootmodel.add_file file
|
249
|
+
|
250
|
+
# then
|
251
|
+
rootmodel.documents.find_file_by_integration_id("123key").path.should eq "k:\kontakt\databas\dokument"
|
252
|
+
rootmodel.documents.files.length.should eq 1
|
253
|
+
end
|
254
|
+
|
241
255
|
it "will not add a new organizations when the organizations is already added (same integration id)" do
|
242
256
|
# given
|
243
257
|
rootmodel.add_note({
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
6
6
|
# in spec/support/ and its subdirectories.
|
7
|
-
Dir[File.join(File.dirname(File.absolute_path(__FILE__)),"support/**/*.rb")].each { |f| require f }
|
7
|
+
Dir[File.join(File.dirname(File.absolute_path(__FILE__)), "support/**/*.rb")].each { |f| require f }
|
8
8
|
|
9
9
|
RSpec.configure do |config|
|
10
10
|
# ## Mock Framework
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: go_import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-09-
|
15
|
+
date: 2014-09-16 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: iso_country_codes
|
@@ -185,6 +185,7 @@ files:
|
|
185
185
|
- lib/go_import/model/deal_status_reference.rb
|
186
186
|
- lib/go_import/model/deal_status_setting.rb
|
187
187
|
- lib/go_import/model/documents.rb
|
188
|
+
- lib/go_import/model/file.rb
|
188
189
|
- lib/go_import/model/link.rb
|
189
190
|
- lib/go_import/model/note.rb
|
190
191
|
- lib/go_import/model/note_classification.rb
|
@@ -223,6 +224,11 @@ files:
|
|
223
224
|
- sources/excel/.gitignore
|
224
225
|
- sources/excel/.go_import/runner.rb
|
225
226
|
- sources/excel/converter.rb
|
227
|
+
- sources/excel/files/avtal.docx
|
228
|
+
- sources/excel/files/more/avtal.docx
|
229
|
+
- sources/excel/files/more/offert-2.pdf
|
230
|
+
- sources/excel/files/offert-2.docx
|
231
|
+
- sources/excel/files/offert.docx
|
226
232
|
- sources/excel/Gemfile
|
227
233
|
- sources/excel/sample-data.xlsx
|
228
234
|
- sources/VISMA/.gitignore
|
@@ -241,6 +247,7 @@ files:
|
|
241
247
|
- spec/deal_spec.rb
|
242
248
|
- spec/deal_status_reference_spec.rb
|
243
249
|
- spec/documents_spec.rb
|
250
|
+
- spec/file_spec.rb
|
244
251
|
- spec/helpers/csv_helper_spec.rb
|
245
252
|
- spec/helpers/email_helper_spec.rb
|
246
253
|
- spec/helpers/phone_helper_spec.rb
|
@@ -287,6 +294,7 @@ test_files:
|
|
287
294
|
- spec/deal_spec.rb
|
288
295
|
- spec/deal_status_reference_spec.rb
|
289
296
|
- spec/documents_spec.rb
|
297
|
+
- spec/file_spec.rb
|
290
298
|
- spec/helpers/csv_helper_spec.rb
|
291
299
|
- spec/helpers/email_helper_spec.rb
|
292
300
|
- spec/helpers/phone_helper_spec.rb
|