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,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 LIME Pro "Core" database to LIME Go.
@@ -0,0 +1,524 @@
1
+ # encoding: iso-8859-1
2
+
3
+ require 'move-to-go'
4
+ require 'tiny_tds'
5
+ require_relative("../converter")
6
+
7
+
8
+ def convert_source
9
+ puts "Trying to convert LIME Pro source to LIME Go..."
10
+
11
+ if !defined?(SQL_SERVER) || SQL_SERVER.empty?
12
+ raise "SQL_SERVER must be set in converter.rb"
13
+ end
14
+
15
+ if !defined?(SQL_SERVER_DATABASE) || SQL_SERVER_DATABASE.empty?
16
+ raise "SQL_SERVER_DATABASE must be set in converter.rb"
17
+ end
18
+
19
+ if !defined?(LIME_SERVER) || LIME_SERVER.empty?
20
+ raise "LIME_SERVER must be set in converter.rb"
21
+ end
22
+
23
+ if !defined?(LIME_DATABASE) || LIME_DATABASE.empty?
24
+ raise "LIME_DATABASE must be set in converter.rb"
25
+ end
26
+
27
+ if !defined?(LIME_LANGUAGE) || LIME_LANGUAGE.empty?
28
+ raise "LIME_LANGUAGE must be set in converter.rb"
29
+ end
30
+
31
+ windows_authentication = false
32
+ if defined?(SQL_SERVER_USER) && !SQL_SERVER_USER.empty?
33
+ begin
34
+ print "Password for #{SQL_SERVER_USER}: "
35
+ # We hide the entered characters before to ask for the password
36
+ system 'stty -echo'
37
+ sql_server_password = $stdin.gets.chomp
38
+ system 'stty echo'
39
+ puts ""
40
+ rescue NoMethodError, Interrupt
41
+ # When the process is exited, we display the characters
42
+ # again And we exit
43
+ system 'stty echo'
44
+ exit
45
+ end
46
+ else
47
+ puts "No user defined, using Windows authentication to connect to SQL Server. We will connect as the user that is running move-to-go. Set a value for SQL_SERVER_USER in converter.rb to change."
48
+ windows_authentication = true
49
+ end
50
+
51
+ begin
52
+ if windows_authentication
53
+ db_con = TinyTds::Client.new(dataserver: SQL_SERVER,
54
+ database: SQL_SERVER_DATABASE)
55
+ else
56
+ db_con = TinyTds::Client.new(username: SQL_SERVER_USER,
57
+ password: sql_server_password,
58
+ dataserver: SQL_SERVER,
59
+ database: SQL_SERVER_DATABASE)
60
+ end
61
+
62
+ puts "Connected to SQL Server."
63
+ rescue Exception => e
64
+ puts "ERROR: Failed to connect to SQL-server"
65
+ puts e.message
66
+ exit
67
+ end
68
+
69
+ con = LIMEProConnection.new db_con
70
+ converter = Converter.new
71
+ rootmodel = MoveToGo::RootModel.new
72
+
73
+
74
+ # coworker_class = con.get_class_by_name("coworker")
75
+ # puts "Coworker class: #{coworker_class}"
76
+ # name_field = coworker_class.get_field_by_label(FieldLabel::Name)
77
+
78
+ # puts "name field #{name_field}"
79
+
80
+
81
+ # exit
82
+
83
+
84
+ converter.configure rootmodel
85
+
86
+ #Add custom fields for LIME-links
87
+ rootmodel.settings.with_person do |person|
88
+ person.set_custom_field( { :integration_id => 'limelink', :title => 'Länk till LIME Pro', :type => :Link} )
89
+ end
90
+
91
+ rootmodel.settings.with_organization do |org|
92
+ org.set_custom_field( { :integration_id => 'limelink', :title => 'Länk till LIME Pro', :type => :Link} )
93
+ end
94
+
95
+ rootmodel.settings.with_deal do |deal|
96
+ deal.set_custom_field( { :integration_id => 'limelink', :title => 'Länk till LIME Pro', :type => :Link} )
97
+ end
98
+
99
+ # coworkers
100
+ # start with these since they are referenced
101
+ # from everywhere....
102
+ con.fetch_data "coworker" do |row|
103
+ coworker = init_coworker(row, con.get_class_by_name('coworker'))
104
+ rootmodel.add_coworker(converter.to_coworker(coworker, row))
105
+ end
106
+
107
+ # organizations
108
+ con.fetch_data "company" do |row|
109
+ organization = init_organization(row, con.get_class_by_name('company'), rootmodel)
110
+ rootmodel.add_organization(converter.to_organization(organization, row))
111
+ converter.organization_hook(row, organization, rootmodel) if defined? converter.organization_hook
112
+ end
113
+
114
+ # persons
115
+ # depends on organizations
116
+ con.fetch_data "person" do |row|
117
+ # init method also adds the person to the employer
118
+ person = init_person(row, con.get_class_by_name('person'), rootmodel)
119
+ converter.to_person(person, row)
120
+ end
121
+
122
+ # deals
123
+ # deals can reference coworkers (responsible), organizations
124
+ # and persons (contact)
125
+ if defined?(IMPORT_DEALS) && IMPORT_DEALS == true
126
+ puts "Trying to import deals..."
127
+ con.fetch_data 'business' do |row|
128
+ deal = init_deal(row, con.get_class_by_name('business'), rootmodel)
129
+ rootmodel.add_deal(converter.to_deal(deal, row))
130
+ end
131
+ else
132
+ puts "Deals are not imported. To enable set IMPORT_DEALS = true in converter.rb."
133
+ end
134
+
135
+ if defined?(IMPORT_HISTORY) && IMPORT_HISTORY == true
136
+ con.fetch_data 'history' do |row|
137
+ history = converter.to_history(init_history(row, con.get_class_by_name('history'), rootmodel), row)
138
+ #if !history.organization.nil? || !history.person.nil?
139
+ rootmodel.add_history(history)
140
+ #end
141
+ end
142
+ else
143
+ puts "History is not imported. To enable set IMPORT_HISTORY = true in converter.rb."
144
+ end
145
+
146
+ """
147
+ # documents
148
+ if defined?(IMPORT_DOCUMENTS) && !IMPORT_DOCUMENTS.nil? && IMPORT_DOCUMENTS
149
+ process_rows ORGANIZATION_DOCUMENT_FILE do |row|
150
+ rootmodel.add_file(to_organization_document(row, rootmodel))
151
+ end
152
+
153
+ process_rows PROJECT_DOCUMENT_FILE do |row|
154
+ rootmodel.add_file(to_deal_document(row, rootmodel))
155
+ end
156
+ end
157
+ """
158
+
159
+ return rootmodel
160
+ end
161
+
162
+
163
+ def init_coworker(row, table)
164
+ coworker = MoveToGo::Coworker.new
165
+ # integration_id is typically the idcoworker in Pro
166
+ # Must be set to be able to import the same file more
167
+ # than once without creating duplicates
168
+ coworker.integration_id = row['idcoworker'].to_s
169
+
170
+ coworker.parse_name_to_firstname_lastname_se table.get_value_for_field_with_label(row, FieldLabel::Name)
171
+ coworker.email = table.get_value_for_field_with_label(row, FieldLabel::PrimaryEmailAddress)
172
+ coworker.direct_phone_number = table.get_value_for_field_with_label(row, FieldLabel::BusinessTelephoneNumber)
173
+ coworker.mobile_phone_number = table.get_value_for_field_with_label(row, FieldLabel::MobileTelephoneNumber)
174
+
175
+ return coworker
176
+ end
177
+
178
+ def init_organization(row, table, rootmodel)
179
+ organization = MoveToGo::Organization.new
180
+ # integration_id is typically the company Id in Easy
181
+ # Must be set to be able to import the same file more
182
+ # than once without creating duplicates
183
+ organization.integration_id = row['idcompany'].to_s
184
+ organization.set_custom_value("limelink", build_lime_link("company", row['idcompany']))
185
+
186
+ organization.name = table.get_value_for_field_with_label(row, FieldLabel::Name)
187
+
188
+ organization.organization_number = table.get_value_for_field_with_label(row, FieldLabel::CompanyNumber)
189
+ organization.email = table.get_value_for_field_with_label(row, FieldLabel::PrimaryEmailAddress)
190
+ organization.web_site = table.get_value_for_field_with_label(row, FieldLabel::BusinessHomepage)
191
+ organization.central_phone_number = table.get_value_for_field_with_label(row, FieldLabel::BusinessTelephoneNumber)
192
+
193
+ organization.with_postal_address do |address|
194
+ address.street = table.get_value_for_field_with_label(row, FieldLabel::StreetAddress) + " " +
195
+ table.get_value_for_field_with_label(row, FieldLabel::StreetAddress2)
196
+ address.zip_code = table.get_value_for_field_with_label(row, FieldLabel::ZipCode)
197
+ address.city = table.get_value_for_field_with_label(row, FieldLabel::City)
198
+ address.country_name = table.get_value_for_field_with_label(row, FieldLabel::Country)
199
+ end
200
+
201
+ organization.with_visit_address do |address|
202
+ address.street = table.get_value_for_field_with_label(row, FieldLabel::VisitingAddress_StreetAddress) + " " +
203
+ table.get_value_for_field_with_label(row, FieldLabel::VisitingAddress_StreetAddress2)
204
+ address.zip_code = table.get_value_for_field_with_label(row, FieldLabel::VisitingAddress_ZipCode)
205
+ address.city = table.get_value_for_field_with_label(row, FieldLabel::VisitingAddress_City)
206
+ address.country_name = table.get_value_for_field_with_label(row, FieldLabel::VisitingAddress_Country)
207
+ end
208
+
209
+ if defined?(ORGANIZATION_RESPONSIBLE_FIELD) && !ORGANIZATION_RESPONSIBLE_FIELD.nil? && !ORGANIZATION_RESPONSIBLE_FIELD.empty?
210
+ # Responsible coworker for the organization.
211
+ # For instance responsible sales rep.
212
+ coworker_id = row[ORGANIZATION_RESPONSIBLE_FIELD].to_s
213
+ organization.responsible_coworker = rootmodel.find_coworker_by_integration_id(coworker_id)
214
+ end
215
+
216
+ return organization
217
+ end
218
+
219
+ def init_person(row, table, rootmodel)
220
+ person = MoveToGo::Person.new
221
+
222
+ person.integration_id = row['idperson'].to_s
223
+ person.set_custom_value("limelink", build_lime_link("person", row['idperson']))
224
+
225
+ # set employer connection
226
+ employer = rootmodel.find_organization_by_integration_id(row['company'].to_s)
227
+ employer.add_employee(person) if employer
228
+
229
+ person.parse_name_to_firstname_lastname_se table.get_value_for_field_with_label(row, FieldLabel::Name)
230
+ person.direct_phone_number = table.get_value_for_field_with_label(row, FieldLabel::BusinessTelephoneNumber)
231
+ person.mobile_phone_number = table.get_value_for_field_with_label(row, FieldLabel::MobileTelephoneNumber)
232
+ person.position = table.get_value_for_field_with_label(row, FieldLabel::JobTitle)
233
+ person.email = table.get_value_for_field_with_label(row, FieldLabel::PrimaryEmailAddress)
234
+
235
+ return person
236
+ end
237
+
238
+ def init_deal(row, table, rootmodel)
239
+ deal = MoveToGo::Deal.new
240
+
241
+ deal.integration_id = row['idbusiness'].to_s
242
+ deal.set_custom_value("limelink", build_lime_link("person", row['idbusiness']))
243
+
244
+ coworker = rootmodel.find_coworker_by_integration_id(row[DEAL_RESPONSIBLE_FIELD].to_s)
245
+ deal.responsible_coworker = coworker if coworker
246
+
247
+ organization = rootmodel.find_organization_by_integration_id(row[DEAL_COMPANY_FIELD].to_s)
248
+ deal.customer = organization if organization
249
+
250
+ deal.name = table.get_value_for_field_with_name(row, "name")
251
+ deal.description = table.get_value_for_field_with_name(row, "wonlostreason")
252
+ deal.value = table.get_value_for_field_with_name(row, "businessvalue")
253
+
254
+ if (deal.name.nil? || deal.name.empty?) && !organization.nil?
255
+ deal.name = organization.name
256
+ end
257
+
258
+ return deal
259
+ end
260
+
261
+ def init_history(row, table, rootmodel)
262
+ history = MoveToGo::History.new
263
+
264
+ history.integration_id = row['idhistory'].to_s
265
+
266
+ coworker = rootmodel.find_coworker_by_integration_id(row[HISTORY_COWORKER_FIELD].to_s)
267
+ history.created_by = coworker if coworker
268
+
269
+ organization = rootmodel.find_organization_by_integration_id(row[HISTORY_COMPANY_FIELD].to_s)
270
+ history.organization = organization if organization
271
+
272
+ person = rootmodel.find_person_by_integration_id(row[HISTORY_PERSON_FIELD].to_s)
273
+ history.person = person if person
274
+
275
+ deal = rootmodel.find_deal_by_integration_id(row[HISTORY_DEAL_FIELD].to_s)
276
+ history.deal = deal if deal
277
+
278
+ history.text = table.get_value_for_field_with_label(row, FieldLabel::historys)
279
+ history.date = table.get_value_for_field_with_label(row, FieldLabel::StartDate)
280
+
281
+ return history
282
+ end
283
+
284
+
285
+ ############################################################################
286
+ ## Helper functions and classes
287
+ ############################################################################
288
+
289
+ module FieldLabel
290
+ None = 0
291
+ Name = 1
292
+ Key = 2
293
+ Description = 3
294
+ StartDate = 4
295
+ DueDate = 5
296
+ Category = 6
297
+ Completed = 7
298
+ Notes = 8
299
+ Priority = 9
300
+ ResponsibleCoworker = 10
301
+ HomeTelephoneNumber = 13
302
+ BusinessTelephoneNumber = 14
303
+ MobileTelephoneNumber = 15
304
+ HomeFaxNumber = 16
305
+ BusinessFaxNumber = 17
306
+ Birthday = 18
307
+ HomeAddress = 19
308
+ BusinessAddress = 20
309
+ BusinessHomepage = 21
310
+ PersonalHomepage = 22
311
+ PrimaryEmailAddress = 23
312
+ SecondaryEmailAddress = 24
313
+ JobTitle = 25
314
+ Nickname = 26
315
+ ReceivedTime = 27
316
+ SentTime = 28
317
+ Location = 29
318
+ FirstName = 30
319
+ LastName = 31
320
+ Table = 11
321
+ IdDecord = 12
322
+ Inactive = 32
323
+ CompanyNumber = 33
324
+ VisitingAddress = 34
325
+ RecordImage = 35
326
+ Signature = 36
327
+ Screenshot = 37
328
+ StreetAddress = 38
329
+ ZipCode = 39
330
+ City = 40
331
+ Country = 41
332
+ CustomerNumber = 42
333
+ Geography = 43
334
+ StreetAddress2 = 44
335
+ VisitingAddress_StreetAddress = 45
336
+ VisitingAddress_StreetAddress2 = 46
337
+ VisitingAddress_ZipCode = 47
338
+ VisitingAddress_City = 48
339
+ VisitingAddress_Country = 49
340
+
341
+ end
342
+
343
+ class LIMEProConnection
344
+ def initialize(db_con)
345
+ @db_con = db_con
346
+ @tablestructure = get_table_structure().map{|proClass| proClass}
347
+ end
348
+
349
+ def fetch_data(table_name)
350
+ table = @tablestructure.find{|tbl| tbl.name == table_name}
351
+ sql = build_sql_query(table)
352
+ # puts sql
353
+ dataQuery = @db_con.execute sql
354
+
355
+ dataQuery.each do |row|
356
+ yield row
357
+ end
358
+ end
359
+
360
+ def get_class_by_name(name)
361
+ table = @tablestructure.find{|tbl| tbl.name == name}
362
+
363
+ return table
364
+ end
365
+
366
+ private
367
+ def db_con
368
+ @db_con
369
+ end
370
+
371
+ private
372
+ def tablestructure
373
+ @tablestructure
374
+ end
375
+
376
+ private
377
+ def get_table_structure()
378
+ tablesQuery = @db_con.execute("SELECT * FROM [table]")
379
+ avaiblableProClasses = tablesQuery.map{|table| table}
380
+
381
+ return avaiblableProClasses.map {|proClass| LIMEProClass.new(proClass["name"], proClass["idtable"], @db_con)}
382
+ end
383
+
384
+ private
385
+ def build_sql_query(table)
386
+ sqlForFields = table.fields.map{|field|
387
+ case field.fieldtype
388
+ when "relation"
389
+ desc = @tablestructure.find{|tbl| tbl.name == field.relatedTable}.descriptive
390
+ next "[#{table.name}].[#{field.name}],(SELECT #{desc} from [#{field.relatedTable}] WHERE [#{table.name}].[#{field.name}] = [#{field.relatedTable}].[id#{field.relatedTable}]) as #{field.name}_descriptive"
391
+ when "set"
392
+ next "dbo.lfn_getfieldsettext2([#{field.name}],';','#{LIME_LANGUAGE}') as #{field.name}"
393
+ when "option"
394
+ next "(SELECT #{LIME_LANGUAGE} FROM string WHERE idstring = #{field.name}) as #{field.name}"
395
+ else
396
+ next "[#{table.name}].[#{field.name}]"
397
+ end
398
+ }.join(",")
399
+
400
+ sql = "SELECT #{sqlForFields} FROM [#{table.name}] WHERE [#{table.name}].[status] = 0"
401
+ return sql
402
+ end
403
+
404
+ private
405
+ class LIMEProClass
406
+ attr_reader :name, :id, :descriptive, :fields
407
+ def initialize(name, id, db_con)
408
+ @name = name
409
+ @id = id
410
+ @db_con = db_con
411
+ @fields = get_fields()
412
+ @descriptive = get_desc().first
413
+ end
414
+
415
+ def get_field_by_label(label)
416
+ @fields.find{|field| field.label == label}
417
+ end
418
+
419
+ def get_field_by_name(name)
420
+ @fields.find{|field| field.name == name}
421
+ end
422
+
423
+ def get_value_for_field_with_label(row, label)
424
+ field = get_field_by_label(label)
425
+
426
+ if field.nil?
427
+ return nil
428
+ end
429
+
430
+ return row[field.name]
431
+ end
432
+
433
+ def get_value_for_field_with_name(row, name)
434
+ field = get_field_by_name(name)
435
+
436
+ if field.nil?
437
+ return nil
438
+ end
439
+
440
+ return row[field.name]
441
+ end
442
+
443
+ private
444
+ def get_desc()
445
+ descriptive = @db_con.execute("SELECT dbo.lfn_getdescriptive(#{@id})")
446
+ descriptive.each(:as => :array) {|desc| return desc}
447
+ end
448
+
449
+ private
450
+ def get_fields()
451
+ metadataForRelationFieldsQuery = @db_con.execute(
452
+ """
453
+ SELECT * from relationfieldview
454
+ WHERE relationsingle = 1 AND relationintable = 1 AND idtable = #{@id}
455
+ """
456
+ )
457
+ metadataForRelationFields = metadataForRelationFieldsQuery.map {|relationField| relationField }
458
+
459
+ avaialableFieldsQuery = @db_con.execute(
460
+ """
461
+ SELECT field.idtable, field.name, field.idfield, fieldtype.name as 'fieldtypename',
462
+ cast(isnull(ad.value, 0) as int) as 'fieldlabel'
463
+ FROM field
464
+ INNER JOIN fieldtype ON field.fieldtype = fieldtype.idfieldtype
465
+ LEFT OUTER JOIN attributedata ad on ad.idrecord = field.idfield and ad.owner = 'field' and ad.name = 'label'
466
+ WHERE field.idtable = #{@id}
467
+ """
468
+ )
469
+
470
+ fields = avaialableFieldsQuery.map{ |field|
471
+ if field["fieldtypename"] != "relation"
472
+ LIMEProField.new(field["name"], field["fieldtypename"], field['fieldlabel'])
473
+ else
474
+ relationFieldMetadata = metadataForRelationFields.find {|relField| relField["idfield"] == field["idfield"]}
475
+ if relationFieldMetadata
476
+ LIMEProRelationField.new(field["name"], field["fieldtypename"], relationFieldMetadata)
477
+ end
478
+ end
479
+ }.compact
480
+
481
+ # Add hardcoded fields
482
+ fields.push LIMEProField.new "id#{@name}", "int", FieldLabel::None
483
+ fields.push LIMEProField.new "status", "int", FieldLabel::None
484
+ fields.push LIMEProField.new "createdtime", "datetime", FieldLabel::None
485
+ fields.push LIMEProField.new "createduser", "int", FieldLabel::None
486
+ fields.push LIMEProField.new "updateduser", "int", FieldLabel::None
487
+ fields.push LIMEProField.new "timestamp", "datetime", FieldLabel::None
488
+
489
+ # puts "Field for table: #{name}"
490
+ # fields.each{|f| puts "Field: #{f.name}, type: #{f.fieldtype}, label: #{f.label} "}
491
+
492
+ return fields
493
+ end
494
+ end
495
+
496
+ private
497
+ class LIMEProField
498
+ attr_reader :name, :fieldtype, :label
499
+
500
+ def initialize(name, fieldtype, label)
501
+ @name = name
502
+ @fieldtype = fieldtype
503
+ @label = label
504
+ end
505
+ end
506
+
507
+ class LIMEProRelationField < LIMEProField
508
+ def initialize(name, fieldtype, relationFieldMetadata)
509
+ super(name, fieldtype, FieldLabel::None)
510
+ @relatedTable = relationFieldMetadata["relatedtable"]
511
+ end
512
+
513
+ def relatedTable
514
+ @relatedTable
515
+ end
516
+ end
517
+ end
518
+
519
+ def build_lime_link(limeClassName, id)
520
+ return "limecrm:#{limeClassName}.#{LIME_DATABASE}.#{LIME_SERVER}?idrecord=#{id}"
521
+ end
522
+
523
+
524
+
@@ -0,0 +1,6 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'thor'
4
+ gem 'move-to-go'
5
+ gem 'rspec'
6
+ gem 'tiny_tds'