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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 30c626193cc7bca95c36653b34caaf2bf9e7b593
|
4
|
+
data.tar.gz: 0ffa9010615f179ed02e9c0a51b7f9723eee3cfd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6338cf52b8472ffd1d4ccc2a494d2191549b27aa290e8feed5971e9716f7d9eac84662dc87a472c40b7830cbda310b1390209763fdaa03817116c22e11c42119
|
7
|
+
data.tar.gz: d961df52d8fa809abd86d355420da3eaf626b60a04a8bcac207829d911943cae79fe9b5c8eaa2ad01bba18232a60308bb00e03bc46c95a9182e7f2c3bc25ee43
|
data/bin/move-to-go
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
require_relative '../lib/move-to-go'
|
5
|
+
require 'progress'
|
6
|
+
|
7
|
+
|
8
|
+
RUNNER_DIR = ".move-to-go"
|
9
|
+
|
10
|
+
class MoveToGoCommandLine < Thor
|
11
|
+
|
12
|
+
desc "about", "About move-to-go"
|
13
|
+
def about()
|
14
|
+
puts "move-to-go is an migration tool for LIME Go. It can take virtually any input source and create import data files that LIME Go likes."
|
15
|
+
puts "move-to-go has some predefined sources that will make it easy for you to migrate your data."
|
16
|
+
puts ""
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "list-sources", "Lists the available sources"
|
20
|
+
def list_sources()
|
21
|
+
puts "The following sources are available:"
|
22
|
+
puts
|
23
|
+
|
24
|
+
sources = MoveToGo::Sources.new(source_path)
|
25
|
+
sources.list().each do |s|
|
26
|
+
puts "\t#{s}"
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "\nCreate a new project with 'move-to-go new <PROJECT> <SOURCE>' with one of these sources."
|
30
|
+
puts "Use 'move-to-go about <SOURCE>' for more information about a specific source."
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "about <SOURCE>", "Prints information about the specifed source"
|
34
|
+
def about(source)
|
35
|
+
sources = MoveToGo::Sources.new(source_path)
|
36
|
+
|
37
|
+
sources.about_source(source)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "new <PROJECT> <SOURCE>", "Creates a new migration project with a specifed name and source"
|
41
|
+
def new(project, source)
|
42
|
+
sources = MoveToGo::Sources.new(source_path)
|
43
|
+
|
44
|
+
if sources.create_project_from_source(project, source)
|
45
|
+
puts "\nProject '#{project}' created from source '#{source}'."
|
46
|
+
puts "Modify the #{project}/converter.rb script to suit your source."
|
47
|
+
puts "Use 'move-to-go run' from the project directory to create the zip file for LIME Go."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
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."
|
52
|
+
option(:output,
|
53
|
+
: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.",
|
54
|
+
:type => :string,
|
55
|
+
:required => false)
|
56
|
+
option(:ignore_invalid_files,
|
57
|
+
:desc => "Output will be created even if the import contains missing or invalid files",
|
58
|
+
:type => :boolean,
|
59
|
+
:required => false)
|
60
|
+
option(:log_to_file,
|
61
|
+
:desc => "Console output will be redirected to file",
|
62
|
+
:type => :string,
|
63
|
+
:required => false)
|
64
|
+
option(:max_file_size,
|
65
|
+
:desc => "Maximum size in bytes of documents included in zip",
|
66
|
+
:type => :numeric,
|
67
|
+
:required => false)
|
68
|
+
option(:output_documents,
|
69
|
+
:desc => "Name of the file to put imported documents in (default in same as --output)",
|
70
|
+
:type => :string,
|
71
|
+
:required => false)
|
72
|
+
option(:shard_size,
|
73
|
+
:desc => "Large imports are sharded into several zip-files. This property sets how many objects each zip-file should contain. Default is 25 000",
|
74
|
+
:type => :numeric,
|
75
|
+
:required => false)
|
76
|
+
def run_import()
|
77
|
+
if !options.log_to_file.nil?
|
78
|
+
$stdout = File.new(options.log_to_file == "log_to_file" ? "move-to-go.log" : options.log_to_file, 'w')
|
79
|
+
$stdout.sync = true
|
80
|
+
end
|
81
|
+
max_file_size = options.max_file_size.nil? ? MoveToGo::File::DEFAULT_MAX_FILE_SIZE : options.max_file_size
|
82
|
+
|
83
|
+
if !is_valid_project?
|
84
|
+
return
|
85
|
+
end
|
86
|
+
|
87
|
+
runner_file = ::File.expand_path("./#{RUNNER_DIR}/runner.rb", Dir.pwd)
|
88
|
+
require(runner_file)
|
89
|
+
model = convert_source()
|
90
|
+
|
91
|
+
if model.documents.files.length > 0 && (!defined?(FILES_FOLDER) || FILES_FOLDER.empty?())
|
92
|
+
puts "WARNING: It looks like you are importing files but FILES_FOLDER has not been set in your converter.rb."
|
93
|
+
puts "WARNING: FILES_FOLDER should be set unless you are only importing files with absolute paths."
|
94
|
+
end
|
95
|
+
|
96
|
+
if model.documents.files.length > 0 && (!defined?(FILES_FOLDER_AT_CUSTOMER) || FILES_FOLDER_AT_CUSTOMER.empty?())
|
97
|
+
puts "WARNING: It looks like you are importing files but FILES_FOLDER_AT_CUSTOMER has not been set in your converter.rb"
|
98
|
+
puts "WARNING: This means that files with an absolute path will be imported with their original path. Set this constant if you want to get files from the FILES_FOLDER directory."
|
99
|
+
end
|
100
|
+
|
101
|
+
is_ok, error_msg, warnings_msg = can_be_serialized?(model, options.ignore_invalid_files, max_file_size)
|
102
|
+
if is_ok
|
103
|
+
|
104
|
+
if options.ignore_invalid_files && model.documents.files.length > 0
|
105
|
+
log_and_remove_invalid_files model, max_file_size
|
106
|
+
end
|
107
|
+
model.report_rootmodel_status()
|
108
|
+
|
109
|
+
puts "Starting sharding of model..."
|
110
|
+
sharder = MoveToGo::ShardHelper.new(options.shard_size)
|
111
|
+
models_to_serialize = sharder.shard_model(model)
|
112
|
+
|
113
|
+
if models_to_serialize.length > 1
|
114
|
+
puts "Import is large and will be broken into #{models_to_serialize.length} files"
|
115
|
+
end
|
116
|
+
|
117
|
+
models_to_serialize.each_with_index do |model, i|
|
118
|
+
go_data_zip = options.output.nil? == true ? "go" : options.output
|
119
|
+
go_data_zip += "_#{i}.zip"
|
120
|
+
go_files = options.output_documents.nil? == true ? nil : ::File.basename(options.output_documents,File.extname(options.output_documents))
|
121
|
+
model.save_to_zip(go_data_zip, go_files)
|
122
|
+
puts "Source has been been converted into '#{go_data_zip}'."
|
123
|
+
puts " - and files into '#{go_files}.zip'." if !go_files.nil?
|
124
|
+
if !warnings_msg.empty?
|
125
|
+
puts "WARNINGS: "
|
126
|
+
puts warnings_msg
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
puts "ERROR: Source could not be converted due to:"
|
131
|
+
puts error_msg
|
132
|
+
|
133
|
+
if !options.ignore_invalid_files &&
|
134
|
+
model.documents.files.any? {|file| file.validate.empty?}
|
135
|
+
puts "move-to-go detected invalid files (see above), you can ignore these with the option --ignore-invalid-files."
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
def log_and_remove_invalid_files(model, max_file_size)
|
142
|
+
if model.documents.files.length > 0
|
143
|
+
file_log_header = "name;integration_id;path;organization.integrationid;organization.name;deal.integrationid;deal.name;file.size"
|
144
|
+
file_log = ""
|
145
|
+
files_to_remove = []
|
146
|
+
model.documents.files.with_progress(" - Trying to log files that can't be found...").each do |file|
|
147
|
+
if !::File.exists?(file.path_for_project)
|
148
|
+
file_log = "#{file_log}#{file.name};#{file.integration_id};#{file.path};#{file.organization.nil? ? '' : file.organization.integration_id};#{file.organization.nil? ? '' : file.organization.name};#{file.deal.nil? ? '' : file.deal.integration_id};#{file.deal.nil? ? '' : file.deal.name};0\n"
|
149
|
+
files_to_remove.push file
|
150
|
+
elsif ::File.size(file.path_for_project) > max_file_size
|
151
|
+
file_log = "#{file_log}#{file.name};#{file.integration_id};#{file.path};#{file.organization.nil? ? '' : file.organization.integration_id};#{file.organization.nil? ? '' : file.organization.name};#{file.deal.nil? ? '' : file.deal.integration_id};#{file.deal.nil? ? '' : file.deal.name};#{::File.size(file.path_for_project)}\n"
|
152
|
+
files_to_remove.push file
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
files_to_remove.each do |file|
|
157
|
+
model.documents.files.delete file
|
158
|
+
end
|
159
|
+
|
160
|
+
if file_log.length > 0
|
161
|
+
log_filename = 'move-to-go-invalid-files.csv'
|
162
|
+
::File.open(log_filename, 'w') { |f|
|
163
|
+
f.puts file_log_header
|
164
|
+
f.puts file_log
|
165
|
+
}
|
166
|
+
puts "WARNING: move-to-go has invalid files (#{files_to_remove.length} of #{model.documents.files.length}). Filenames of all ignored files has been written to '#{log_filename}'."
|
167
|
+
else
|
168
|
+
puts "All files are OK."
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
def can_be_serialized?(rootmodel, ignore_invalid_files, max_file_size)
|
175
|
+
is_ok = false
|
176
|
+
error = rootmodel.sanity_check
|
177
|
+
if error.empty?
|
178
|
+
error, warnings = rootmodel.validate(ignore_invalid_files, max_file_size)
|
179
|
+
|
180
|
+
if error.empty?
|
181
|
+
is_ok = true
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
return [is_ok, error, warnings]
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
def is_valid_project?()
|
190
|
+
if Dir.exists?(RUNNER_DIR) == false
|
191
|
+
puts "This doesnt look like a move-to-go project. Are you in the right directory or did you mess with the '#{RUNNER_DIR}' folder?"
|
192
|
+
return false
|
193
|
+
end
|
194
|
+
|
195
|
+
runner_file = File.expand_path("./#{RUNNER_DIR}/runner.rb", Dir.pwd)
|
196
|
+
if File.exists?(runner_file) == false
|
197
|
+
puts "I can't run this project. Did you mess with the '#{RUNNER_DIR}' folder?"
|
198
|
+
return false
|
199
|
+
end
|
200
|
+
|
201
|
+
return true
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
def source_path()
|
206
|
+
File.expand_path("../sources", File.dirname(__FILE__))
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
MoveToGoCommandLine.start(ARGV)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module MoveToGo
|
3
|
+
class CanBecomeImmutable
|
4
|
+
def self.immutable_accessor(name)
|
5
|
+
define_method(name) do
|
6
|
+
return instance_variable_get("@#{name}")
|
7
|
+
end
|
8
|
+
|
9
|
+
define_method("#{name}=") do |value|
|
10
|
+
raise_if_immutable
|
11
|
+
instance_variable_set("@#{name}", value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def raise_if_immutable
|
16
|
+
if @is_immutable
|
17
|
+
raise ObjectIsImmutableError
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_is_immutable()
|
22
|
+
@is_immutable = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_immutable()
|
26
|
+
@is_immutable
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "csv"
|
2
|
+
module MoveToGo
|
3
|
+
module CsvHelper
|
4
|
+
|
5
|
+
# @example Detect column separator and transform to hashes
|
6
|
+
# hashes = MoveToGo::CsvHelper.text_to_hashes(text)
|
7
|
+
#
|
8
|
+
# @example Use specific column separator and transform to hashes
|
9
|
+
# column_separator = ','
|
10
|
+
# hashes = MoveToGo::CsvHelper.text_to_hashes(text, column_separator)
|
11
|
+
def self.text_to_hashes(text, column_separator = nil, row_separator = :auto, quote_char = '"')
|
12
|
+
if !text
|
13
|
+
raise "Missing text"
|
14
|
+
end
|
15
|
+
|
16
|
+
if !column_separator
|
17
|
+
column_separator = self.detect_col_sep text
|
18
|
+
end
|
19
|
+
|
20
|
+
rows = CSV.parse(text.strip,{:col_sep => column_separator,
|
21
|
+
:row_sep => row_separator, :quote_char => quote_char})
|
22
|
+
map = {}
|
23
|
+
first = rows.first
|
24
|
+
(0 .. first.length-1).each do |i|
|
25
|
+
map[i] = first[i]
|
26
|
+
end
|
27
|
+
rs = []
|
28
|
+
(1 .. rows.length-1).each do |i|
|
29
|
+
r={}
|
30
|
+
(0 .. map.length-1).each do |j|
|
31
|
+
r[map[j]] = rows[i][j]
|
32
|
+
end
|
33
|
+
rs.push(r)
|
34
|
+
end
|
35
|
+
return rs
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def self.detect_col_sep(text)
|
40
|
+
firstline = text.split('\n').first
|
41
|
+
col_seps = [';','\t',',']
|
42
|
+
return col_seps.find do |c|
|
43
|
+
firstline.include? c
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "sixarm_ruby_email_address_validation"
|
2
|
+
|
3
|
+
module MoveToGo
|
4
|
+
# The EmailHelper helps you validate email addresses.
|
5
|
+
class EmailHelper
|
6
|
+
def self.is_valid?(email)
|
7
|
+
begin
|
8
|
+
return (email =~ EmailAddressValidation::Pattern) ? true : false
|
9
|
+
rescue
|
10
|
+
return false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MoveToGo
|
2
|
+
class AlreadyAddedError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class IntegrationIdIsRequiredError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class InvalidCustomFieldError < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
class InvalidRelationError < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
class InvalidValueError < StandardError
|
15
|
+
def initalize(value)
|
16
|
+
super("#{value} is not a valid value.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class InvalidDealStatusError < StandardError
|
21
|
+
end
|
22
|
+
|
23
|
+
class InvalidHistoryClassificationError < StandardError
|
24
|
+
def initalize(classification)
|
25
|
+
super("#{classification} is not a valid history classification")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ObjectIsImmutableError < StandardError
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module MoveToGo
|
2
|
+
# The ExcelHelper just makes it a little bit easier to open an
|
3
|
+
# excel file in the imports. With ExcelHelper you don't need to
|
4
|
+
# know anything about Roo and RooHelper.
|
5
|
+
class ExcelHelper
|
6
|
+
def self.Open(excel_filename)
|
7
|
+
return RooHelper.new(Roo::Excelx.new(excel_filename))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|