sf_migrate 1.0.4 → 1.2.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/lib/export.rb +22 -15
- data/lib/fields.rb +13 -9
- data/lib/import.rb +685 -269
- data/lib/sf_migrate.rb +14 -12
- metadata +48 -7
data/lib/export.rb
CHANGED
@@ -6,18 +6,18 @@ module SalesforceMigration
|
|
6
6
|
#
|
7
7
|
# @param [Hash] options hash representing passed command line options
|
8
8
|
def initialize(options)
|
9
|
-
credentials
|
10
|
-
consumer_key
|
11
|
-
consumer_secret
|
12
|
-
username
|
13
|
-
password
|
14
|
-
@csv_dir
|
15
|
-
@action
|
9
|
+
credentials = YAML.load_file(options[:config_file])
|
10
|
+
consumer_key = credentials['salesforce_consumer_key']
|
11
|
+
consumer_secret = credentials['salesforce_consumer_secret']
|
12
|
+
username = credentials['salesforce_username']
|
13
|
+
password = credentials['salesforce_password']
|
14
|
+
@csv_dir = options[:csv_dir]
|
15
|
+
@action = options[:action]
|
16
|
+
@last_modified_date = options[:last_modified_date]
|
16
17
|
@logger = SalesforceMigration::Runner::create_logger
|
17
18
|
@logger.info("Export action started")
|
18
19
|
@client = Databasedotcom::Client.new :client_id => consumer_key, :client_secret => consumer_secret
|
19
20
|
@client.authenticate :username => username, :password => password
|
20
|
-
|
21
21
|
@logger.info("Authentication to SalesForce successfull")
|
22
22
|
start
|
23
23
|
@logger.info("Export action ended successfully")
|
@@ -25,7 +25,7 @@ module SalesforceMigration
|
|
25
25
|
|
26
26
|
private
|
27
27
|
def start
|
28
|
-
%w(ISOs__c Agent__c Account Payment_Methods__c Banks__c MerchantToAPM__c ccrmbasic__Email__c Email_Association__c).each do |type|
|
28
|
+
%w(ISOs__c Agent__c Account Acquirer__c Contract Payment_Methods__c Banks__c MerchantToAPM__c ccrmbasic__Email__c Email_Association__c User).each do |type|
|
29
29
|
@logger.info "Writing CSV for #{type}"
|
30
30
|
write_to_csv type
|
31
31
|
end
|
@@ -45,7 +45,7 @@ module SalesforceMigration
|
|
45
45
|
records.each do |record|
|
46
46
|
arr = []
|
47
47
|
fields.each do |field|
|
48
|
-
arr << record.send(field)
|
48
|
+
arr << record.send(field).to_s
|
49
49
|
arr.map!(&method(:remove_quotes))
|
50
50
|
end
|
51
51
|
file << arr
|
@@ -75,14 +75,21 @@ module SalesforceMigration
|
|
75
75
|
# @return [Databasedotcom::Collection] the requested records
|
76
76
|
def get_records(type)
|
77
77
|
if @action == 'initial_run'
|
78
|
-
@logger.info "Getting all records from SalesForce for #{type}"
|
78
|
+
@logger.info "Getting all records from SalesForce for #{type} object"
|
79
79
|
records = get_all_sobjects(type)
|
80
80
|
else
|
81
|
-
@logger.info "Getting records for yesterday from SalesForce for #{type}"
|
81
|
+
@logger.info "Getting records for yesterday from SalesForce for #{type} object"
|
82
82
|
records = @client.materialize(type)
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
|
84
|
+
begin
|
85
|
+
datetime = DateTime.parse(@last_modified_date)
|
86
|
+
rescue
|
87
|
+
if defined? @last_modified_date == nil
|
88
|
+
datetime = DateTime.now
|
89
|
+
else
|
90
|
+
raise ArgumentError, "Invalid Date", caller
|
91
|
+
end
|
92
|
+
end
|
86
93
|
records.query("lastmodifieddate >= #{datetime}")
|
87
94
|
end
|
88
95
|
end
|
data/lib/fields.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
module SalesforceMigration
|
2
2
|
class Fields
|
3
3
|
# Salesforce objects and the fields for import
|
4
|
-
ISOS_FIELDS
|
5
|
-
AGENT_FIELDS
|
6
|
-
ACCOUNT_FIELDS
|
7
|
-
PAYMENT_METHODS_FIELDS
|
8
|
-
BANKS_FIELDS
|
9
|
-
MERCHANTTOAPM_FIELDS
|
10
|
-
CCRMBASIC__EMAIL_FIELDS
|
11
|
-
EMAIL_ASSOCIATION_FIELDS= %w{Merchant_Name__c Email__c}
|
12
|
-
|
4
|
+
ISOS_FIELDS = %w{Active__c Address__c Adult_Chargeback_Fee__c Adult_Commission__c Adult_Transaction_Fee__c Agreement_Received__c Background_Check_Complete__c Business_Phone_Number__c Cell_Phone_Number__c Comments__c CreatedBy CreatedById CreatedDate Curren__c CurrencyIsoCode Email_Address__c Fax_Number__c Gambling_Chargeback_Fee__c Gambling_Commission_Fee__c Gambling_Transaction_Fee__c General_Conventional_Chargeback_Fee__c General_Conventional_Commission_Fee__c General_Conventional_Transaction_Fee__c General_Non_Conventional_Chargeback_Fee__c General_Non_Conventional_Commission_Fee__c General_Non_Conventional_Transaction_Fee__c ISO_ID_Assigned__c ISO_ID_Number__c ISO_Owner_Name__c Id IsDeleted KYC_Gathered__c LastActivityDate LastModifiedBy LastModifiedById LastModifiedDate Name New_Hire_Package_Received__c Owner OwnerId Pharmacy_Chargeback_Fee__c Pharmacy_Commission_Fee__c Pharmacy_Transaction_Fee__c Projected_Deals_Count__c Recruiter__c Region__c System_Access_Granted__c Training_Completed__c Welcome_Call_Completed__c Welcome_Package_Sent__c eMerchantPay_ISO_ID__c}
|
5
|
+
AGENT_FIELDS = %w{Id IsDeleted Name LastActivityDate CreatedBy CreatedDate CreatedById LastModifiedDate LastModifiedById LastModifiedBy Owner OwnerId Agent_Billing_Address__c Agent_Cell_Phone__c Agent_Id__c Agent_Phone__c Agent_Skype__c Agreement_Received__c Agreement_Sent__c Background_Check_Complete__c Business_Phone_Number__c Comments__c Commission_Fee__c Email_Address__c eMerchantPay_Agent_ID__c Fee_Comments__c ISO_Company__c New_Hire_Package_Received__c One_Time_Commission_Currency__c Recruiter__c Region__c Split_percentage__c System_Access_Granted__c Title__c Transaction_Fee__c}
|
6
|
+
ACCOUNT_FIELDS = %w{Additional_Url__c Agents__c AnnualRevenue Approval_Citeria__c Approve_1__c Approve_2__c Approve_3__c BillingCity BillingCountry BillingPostalCode BillingState BillingStreet City__c Comment__c CreatedBy CreatedById CreatedDate Credit_Card__c CurrencyIsoCode Current_Volume__c Description Descriptor__c FD_Merchant_Number__c Fax ISO_Name__c Id IsDeleted Industry Info_Capture__c Integration__c Integrator__c Integrator_2__c Iovation__c IPSP__c IPSP_Name2__c IsPartner Jigsaw LastModifiedBy LastModifiedById LastModifiedDate Merchant_Email__c Merchant_Type__c Name NumberOfEmployees Overlying_Company__c Owner OwnerId Phone Projected_Monthly_Volume__c Recruiter__c Risk_Analyst__c Secondary_FD_Merchant_Number__c ShippingCity ShippingCountry ShippingPostalCode ShippingState ShippingStreet Status_Comments__c Status__c Threat_Metrix__c Type__c Url__c VBV_MC3D__c Vacation1__c Website} # OwnerName OwnerPhone OwnerEmail}
|
7
|
+
PAYMENT_METHODS_FIELDS = %w{Accounts__c Business_Contact__c Business_Type_Coments__c Business_type__c Buy_Rates__c Chargeback_Comments__c Chargeback__c Client_Integration__c Countries2__c Countries__c CreatedBy CreatedById CreatedDate CurrencyIsoCode Id IsDeleted Integration__c LastModifiedBy LastModifiedById LastModifiedDate Name Our_Buy_Rates__c Owner OwnerId Proccessing_Currency__c Processing_Currency__c Rebilling_Comments__c Rebilling__c Refund_Comments__c Refund__c Release_Date__c Settlement_Currency__c Settlement_Cycle__c Settlement__c Tech_Contact__c Type__c V_terminal_Comments__c V_terminal__c}
|
8
|
+
BANKS_FIELDS = %w{Account_Number__c BIC_Code__c Merchant_2__c Bank_Address__c Bank_Name__c Contract__c CreatedBy CreatedById CreatedDate CurrencyIsoCode Holder_Address__c IBAN__c Id IsDeleted LastActivityDate LastModifiedBy LastModifiedById LastModifiedDate Name Owner OwnerId Processing_Currency__c Routing_Number__c SWIFT__c Settlement_Currency__c}
|
9
|
+
MERCHANTTOAPM_FIELDS = %w{Merchant__c Payment_Methods__c}
|
10
|
+
CCRMBASIC__EMAIL_FIELDS = %w{Actual_Subject__c Agent__c ccrmbasic__Account__c ccrmbasic__Body__c ccrmbasic__Cc__c ccrmbasic__Direction__c ccrmbasic__From__c ccrmbasic__Internal_Contact__c ccrmbasic__To__c Id IsDeleted Name}
|
11
|
+
EMAIL_ASSOCIATION_FIELDS = %w{Merchant_Name__c Email__c}
|
12
|
+
CONTRACT_FIELDS = %w{Id IsDeleted AccountId CurrencyIsoCode StartDate EndDate BillingStreet BillingCity BillingState BillingPostalCode BillingCountry ContractTerm OwnerId Status StatusCode ContractNumber CreatedDate CreatedById LastModifiedDate LastModifiedById SystemModstamp LastActivityDate Commission_Fee__c Transaction_Fee_Approved__c Transaction_Fee_Declined__c Charge_Back_Fee__c Rolling_Reserve__c Rolling_Reserve_Period__c VBV_Fee__c Wiring_Fee__c PCI_Compliance_Test_Fee__c Billing_Period_Duration_Weekly__c Discover__c Delay_in_Payment_Weeks__c Amex__c Guaranty__c Amount_Number__c Currency__c Treasury_Executive__c Acquirer__c Proccessing_Start_Date__c Proccessing_End_Date__c Acquirer_Approval_Timeframe__c Url__c Date_of_Submission_to_the_Acquirer__c Date_of_Approval__c Refund_Fee__c Registration_Fee__c Integrator_1__c Integrator_2__c Descriptor__c City_Field__c Acquirer_Rejection_Timeframe__c Date_of_Rejection__c Date_of_Issuing_the_MID__c Date_of_Terminal_Setup__c Date_of_Activation__c Deactivation_Date__c Comments__c Threat_Matrix__c Iovation__c Info_Capture__c VBV_MC3D__c PCI_Compliance__c Website_Compliance__c Reason_of_Deactivation__c VISA__c MC__c JCB__c UATP__c Integration_Type__c Payment_Status__c Payment_Suspension_Reason__c IPSP_name__c Visa_MCC_Code__c MC_MCC_Code__c Rejection_Reason__c Type_Of_Agreement__c}
|
13
|
+
ACQUIRER_FIELDS = %w{Id IsDeleted OwnerId Owner Name CurrencyIsoCode CreatedDate CreatedById CreatedBy LastModifiedDate LastModifiedById LastModifiedBy SystemModstamp LastActivityDate Acquirer_Address__c Acquirer_Country__c SPLIT__c Chargeback_Fee__c One_time_Setup_Fee__c Swift_Wire_Transfer_Fee__c Card_Type__c Card_Scheme__c Currency__c Risk_Level__c Transaction__c Fees_Approved__c Fees_Declined__c Fees_other__c Flat_Commision_Fee__c EUR_Interchange__c Non_EUR_Interchange__c }
|
14
|
+
SYSTEM_FIELDS = %w{id acquirer ownerid createddate createdbyid integrator integrator_1 integrator_2 ipsp iso lastactivitydate lastmodifieddate lastmodifiedbyid systemmodstamp recruiter region risk_analyst}
|
15
|
+
SYSTEM_READABLE_FIELDS = %w{id acquirer_id owner_id created_date created_by_id integrator_id integrator_id integrator_2_id ipsp_id iso_id last_activity_date last_modified_date last_modified_by_id system_modstamp recruiter_id region_id risk_analyst_id}
|
16
|
+
USER_FIELDS = %w{Id FirstName LastName Phone Email}
|
13
17
|
end
|
14
18
|
end
|
data/lib/import.rb
CHANGED
@@ -7,7 +7,7 @@ module SalesforceMigration
|
|
7
7
|
# -> transform_agents
|
8
8
|
# -> populate_sugar -> get_sugarcrm_module_type
|
9
9
|
# -> convert_string_to_datetime
|
10
|
-
# ->
|
10
|
+
# -> create_associations -> find_sugarcrm_object
|
11
11
|
# -> create_user
|
12
12
|
class Import
|
13
13
|
|
@@ -23,11 +23,11 @@ module SalesforceMigration
|
|
23
23
|
SugarCRM.connect(url, username, password)
|
24
24
|
@action = options[:action]
|
25
25
|
@isos, @agents, @merchants, @bank_accounts, @agent_users, @iso_users, @emails = [], [], [], [], [], [], []
|
26
|
-
@payment_to_merchants, @emails_to_merchants = [], []
|
26
|
+
@payment_to_merchants, @emails_to_merchants, @acquirers, @contracts, @users = [], [], [], [], []
|
27
27
|
@logger = SalesforceMigration::Runner::create_logger
|
28
|
-
@logger.info("Import action started")
|
28
|
+
@logger.info("Import action started!")
|
29
29
|
start
|
30
|
-
@logger.info("Import action
|
30
|
+
@logger.info("Import action completed!")
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
@@ -35,11 +35,14 @@ module SalesforceMigration
|
|
35
35
|
def start
|
36
36
|
import_emails
|
37
37
|
import_payment_methods
|
38
|
+
import_settlement_bank_accounts
|
39
|
+
import_acquirers
|
40
|
+
import_contracts
|
41
|
+
import_users
|
38
42
|
import_isos
|
39
43
|
import_agents
|
40
44
|
import_merchants
|
41
|
-
|
42
|
-
|
45
|
+
|
43
46
|
associate_records_to_groups
|
44
47
|
end
|
45
48
|
|
@@ -47,66 +50,93 @@ module SalesforceMigration
|
|
47
50
|
# get rid of unnecessary information, transforms other fields, so
|
48
51
|
# they can match the one in SugarCRM and calls for the populate_sugar method
|
49
52
|
# which start the actual import. Keep in mind, that the order of the imports is important
|
53
|
+
|
54
|
+
def import_emails
|
55
|
+
records = load_file_for_import 'ccrmbasic__Email__c'
|
56
|
+
transform_emails! records
|
57
|
+
populate_sugar(records, "email")
|
58
|
+
load_email_to_merchant_associations
|
59
|
+
end
|
60
|
+
|
61
|
+
def load_email_to_merchant_associations
|
62
|
+
# Use the Email_Association CSV relation (Merchant.SalesForceId - Payment_Method.SalesForceId)
|
63
|
+
records = load_file_for_import 'Email_Association__c'
|
64
|
+
transform_email_to_merchants! records
|
65
|
+
@emails_to_merchants = records
|
66
|
+
end
|
67
|
+
|
68
|
+
def import_payment_methods
|
69
|
+
records = load_file_for_import 'Payment_Methods__c'
|
70
|
+
transform_payment_methods! records
|
71
|
+
populate_sugar(records, "payment_method")
|
72
|
+
load_payment_methods_to_merchant_associations
|
73
|
+
end
|
74
|
+
|
75
|
+
def load_payment_methods_to_merchant_associations
|
76
|
+
# Use the MerchantToAPM CSV relation (Merchant.SalesForceId - Payment_Method.SalesForceId)
|
77
|
+
records = load_file_for_import 'MerchantToAPM__c'
|
78
|
+
transform_apm_to_merchants! records
|
79
|
+
@payment_to_merchants = records
|
80
|
+
end
|
81
|
+
|
82
|
+
def import_settlement_bank_accounts
|
83
|
+
records = load_file_for_import 'Banks__c'
|
84
|
+
transform_settlement_bank_accounts! records
|
85
|
+
populate_sugar(records, "settlement_bank_account")
|
86
|
+
end
|
87
|
+
|
88
|
+
def import_acquirers
|
89
|
+
records = load_file_for_import 'Acquirer__c'
|
90
|
+
transform_acquirers! records
|
91
|
+
populate_sugar(records, "acquirer")
|
92
|
+
end
|
93
|
+
|
94
|
+
def import_contracts
|
95
|
+
records = load_file_for_import 'Contract'
|
96
|
+
transform_contracts! records
|
97
|
+
populate_sugar(records, "contract")
|
98
|
+
end
|
99
|
+
|
100
|
+
def import_users
|
101
|
+
records = load_file_for_import 'User'
|
102
|
+
transform_users! records
|
103
|
+
populate_sugar(records, "user")
|
104
|
+
end
|
105
|
+
|
50
106
|
def import_isos
|
51
107
|
records = load_file_for_import 'ISOs__c'
|
52
|
-
|
108
|
+
transform_isos! records
|
53
109
|
populate_sugar(records, "iso")
|
54
110
|
end
|
55
111
|
|
56
112
|
def import_agents
|
57
113
|
records = load_file_for_import 'Agent__c'
|
58
|
-
|
114
|
+
transform_agents! records
|
59
115
|
populate_sugar(records, "agent")
|
60
116
|
end
|
61
117
|
|
62
118
|
def import_merchants
|
63
119
|
records = load_file_for_import 'Account'
|
64
|
-
|
120
|
+
transform_merchants! records
|
65
121
|
populate_sugar(records, "merchant")
|
66
122
|
end
|
67
123
|
|
68
|
-
def import_settlement_bank_accounts
|
69
|
-
records = load_file_for_import 'Banks__c'
|
70
|
-
records = transform_settlement_bank_accounts(records)
|
71
|
-
populate_sugar(records, "settlement_bank_account")
|
72
|
-
end
|
73
|
-
|
74
|
-
def import_payment_methods
|
75
|
-
records = load_file_for_import 'Payment_Methods__c'
|
76
|
-
junction_records = load_file_for_import 'MerchantToAPM__c'
|
77
|
-
# We don`t need db table to save the many-to-many associations between Merchant and Payment Method,
|
78
|
-
# so we just store them in an array and use it later on
|
79
|
-
junction_records.each do |jrecord|
|
80
|
-
@payment_to_merchants << jrecord
|
81
|
-
end
|
82
|
-
populate_sugar(records, "payment_method")
|
83
|
-
end
|
84
|
-
|
85
|
-
def import_emails
|
86
|
-
records = load_file_for_import 'ccrmbasic__Email__c'
|
87
|
-
records = transform_emails(records)
|
88
|
-
junction_records = load_file_for_import 'Email_Association__c'
|
89
|
-
# We don`t need db table to save the many-to-many associations between Merchant and Payment Method,
|
90
|
-
# so we just store them in an array and use it later on
|
91
|
-
junction_records.each do |jrecord|
|
92
|
-
@emails_to_merchants << jrecord
|
93
|
-
end
|
94
|
-
populate_sugar(records, "email")
|
95
|
-
end
|
96
|
-
|
97
124
|
# Load CSV for import
|
98
125
|
#
|
99
126
|
# @param [String] module_name name of the module
|
100
127
|
#
|
101
128
|
# @return [Array] parsed CSV file
|
102
129
|
def load_file_for_import(module_name)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
130
|
+
|
131
|
+
case @action
|
132
|
+
when "initial_run"
|
133
|
+
filename = "#{@csv_dir}/initial/#{module_name}_export.csv"
|
134
|
+
when "update"
|
135
|
+
today = lambda { Date.today.to_s }
|
136
|
+
dir = "#{@csv_dir}/update/#{today.call}"
|
137
|
+
filename = "#{dir}/#{module_name}_export.csv"
|
109
138
|
end
|
139
|
+
|
110
140
|
@logger.error("Could not create or find a csv filename for module #{module_name}") unless defined? filename
|
111
141
|
@logger.info("Loading CSV file #{filename} for import")
|
112
142
|
csv_file = ::CSV.read(filename, :encoding => 'utf-8')
|
@@ -137,23 +167,165 @@ module SalesforceMigration
|
|
137
167
|
header.end_with?("__c") ? header.slice(0..-4).downcase : header.downcase
|
138
168
|
end
|
139
169
|
|
140
|
-
# Add sf_ prefix to all
|
170
|
+
# Add sf_ prefix to all SalesForce-related fields and rename them (if applicable)
|
141
171
|
#
|
142
|
-
# @param [Array<SugarCRM::Namespace::Object>] records records to be prefixed
|
172
|
+
# @param [Array<SugarCRM::Namespace::Object>] records - records to be prefixed
|
143
173
|
#
|
144
|
-
# @return [Array<SugarCRM::Namespace::Object>]
|
174
|
+
# @return [Array<SugarCRM::Namespace::Object>] records
|
145
175
|
def prefix_sf_attribute_names(records)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
176
|
+
field_names_default = SalesforceMigration::Fields::SYSTEM_FIELDS
|
177
|
+
field_names_readable = SalesforceMigration::Fields::SYSTEM_READABLE_FIELDS
|
178
|
+
|
179
|
+
records.each do |record|
|
180
|
+
field_names_default.each_with_index do |field, index|
|
181
|
+
if record.key?(field)
|
182
|
+
record["sf_#{field_names_readable[index].downcase}"] = record[field]
|
183
|
+
record.delete(field)
|
184
|
+
end
|
151
185
|
end
|
186
|
+
# Set the "deleted" flag according to SugarCRM's default fields
|
187
|
+
record['deleted'] = record['isdeleted'] unless record['isdeleted'].nil?
|
152
188
|
end
|
153
189
|
records
|
154
190
|
end
|
155
191
|
|
156
|
-
|
192
|
+
|
193
|
+
def transform_emails!(records)
|
194
|
+
@logger.info("Transforming Email fields")
|
195
|
+
records.each do |record|
|
196
|
+
record['sf_agent_id'] = record['agent']
|
197
|
+
record['sf_merchant_id'] = record['ccrmbasic__account']
|
198
|
+
record['direction'] = record['ccrmbasic__direction']
|
199
|
+
record['sender'] = record['ccrmbasic__from']
|
200
|
+
record['internal_contact'] = record['ccrmbasic__internal_contact']
|
201
|
+
record['receiver'] = record['ccrmbasic__to']
|
202
|
+
record['cc'] = record['ccrmbasic__cc']
|
203
|
+
record['name'] = record['actual_subject'] unless record['actual_subject'].blank?
|
204
|
+
record['body'] = convert_characters(record['ccrmbasic__body']) unless record['ccrmbasic__body'].nil?
|
205
|
+
|
206
|
+
record.delete 'agent'
|
207
|
+
record.delete 'ccrmbasic__to'
|
208
|
+
record.delete 'ccrmbasic__cc'
|
209
|
+
record.delete 'actual_subject'
|
210
|
+
record.delete 'ccrmbasic__body'
|
211
|
+
record.delete 'ccrmbasic__from'
|
212
|
+
record.delete 'ccrmbasic__account'
|
213
|
+
record.delete 'ccrmbasic__direction'
|
214
|
+
record.delete 'ccrmbasic__internal_contact'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def transform_payment_methods!(records)
|
219
|
+
@logger.info("Transforming Payment Method's fields")
|
220
|
+
records.each do |record|
|
221
|
+
record['business_type_comments'] = record['business_type_coments']
|
222
|
+
|
223
|
+
record.delete 'business_type_coments'
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
def transform_settlement_bank_accounts!(records)
|
229
|
+
@logger.info("Transforming Settlement Bank Account fields")
|
230
|
+
records.each do |record|
|
231
|
+
record['sf_contract_id'] = record['contract']
|
232
|
+
record['sf_merchant_id'] = record['merchant_2']
|
233
|
+
|
234
|
+
record.delete 'merchant_2'
|
235
|
+
record.delete 'contract'
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def transform_acquirers!(records)
|
240
|
+
@logger.info("Transforming Acquirer fields")
|
241
|
+
records.each do |record|
|
242
|
+
record['currency_iso_code'] = record['currencyisocode']
|
243
|
+
record['fees_transaction'] = record['transaction']
|
244
|
+
|
245
|
+
record.delete 'currencyisocode'
|
246
|
+
record.delete 'transaction'
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def transform_contracts!(records)
|
251
|
+
@logger.info("Transforming Contract fields")
|
252
|
+
records.each do |record|
|
253
|
+
record['name'] = record['contractnumber']
|
254
|
+
record['sf_account_id'] = record['accountid']
|
255
|
+
record['currency_iso_code'] = record['currencyisocode']
|
256
|
+
record['start_date'] = record['startdate']
|
257
|
+
record['end_date'] = record['enddate']
|
258
|
+
record['billing_street'] = record['billingstreet']
|
259
|
+
record['billing_city'] = record['billingcity']
|
260
|
+
record['billing_state'] = record['billingstate']
|
261
|
+
record['billing_postal_code'] = record['billingpostalcode']
|
262
|
+
record['billing_country'] = record['billingcountry']
|
263
|
+
record['contract_term'] = record['contractterm']
|
264
|
+
record['status_code'] = record['statuscode']
|
265
|
+
record['contract_number'] = record['contractnumber']
|
266
|
+
record['guarantee'] = record['guaranty']
|
267
|
+
record['guaranteed_amount'] = record['amount_number']
|
268
|
+
record['treasury_executive_sf_id'] = record['treasury_executive']
|
269
|
+
record['processing_start_date'] = record['proccessing_start_date']
|
270
|
+
record['processing_end_date'] = record['proccessing_end_date']
|
271
|
+
record['date_of_submission_to_acqirer'] = record['date_of_submission_to_the_acquirer']
|
272
|
+
record['chargeback_fee'] = record['charge_back_fee']
|
273
|
+
record['billing_period_duration'] = record['billing_period_duration_weekly']
|
274
|
+
record['payment_delay'] = record['delay_in_payment_weeks']
|
275
|
+
record['integrator1_sf_id'] = record['integrator_1']
|
276
|
+
record['integrator2_sf_id'] = record['integrator_2']
|
277
|
+
record['date_of_issuing_mid'] = record['date_of_issuing_the_mid']
|
278
|
+
record['date_of_deactivation'] = record['deactivation_date']
|
279
|
+
record['threatmetrix'] = record['threat_matrix']
|
280
|
+
record['deactivation_reason'] = record['reason_of_deactivation']
|
281
|
+
record['mastercard'] = record['mc']
|
282
|
+
record['ipsp_name_sf_id'] = record['ipsp_name']
|
283
|
+
record['mastercard_mcc_code'] = record['mc_mcc_code']
|
284
|
+
|
285
|
+
record.delete 'contractnumber'
|
286
|
+
record.delete 'accountid'
|
287
|
+
record.delete 'currencyisocode'
|
288
|
+
record.delete 'startdate'
|
289
|
+
record.delete 'enddate'
|
290
|
+
record.delete 'billingstreet'
|
291
|
+
record.delete 'billingcity'
|
292
|
+
record.delete 'billingstate'
|
293
|
+
record.delete 'billingpostalcode'
|
294
|
+
record.delete 'billingcountry'
|
295
|
+
record.delete 'contractterm'
|
296
|
+
record.delete 'statuscode'
|
297
|
+
record.delete 'guaranty'
|
298
|
+
record.delete 'amount_number'
|
299
|
+
record.delete 'treasury_executive'
|
300
|
+
record.delete 'proccessing_start_date'
|
301
|
+
record.delete 'proccessing_end_date'
|
302
|
+
record.delete 'date_of_submission_to_the_acquirer'
|
303
|
+
record.delete 'charge_back_fee'
|
304
|
+
record.delete 'billing_period_duration_weekly'
|
305
|
+
record.delete 'delay_in_payment_weeks'
|
306
|
+
record.delete 'integrator_1'
|
307
|
+
record.delete 'integrator_2'
|
308
|
+
record.delete 'date_of_issuing_the_mid'
|
309
|
+
record.delete 'deactivation_date'
|
310
|
+
record.delete 'threat_matrix'
|
311
|
+
record.delete 'reason_of_deactivation'
|
312
|
+
record.delete 'mc'
|
313
|
+
record.delete 'ipsp_name'
|
314
|
+
record.delete 'mc_mcc_code'
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def transform_users!(records)
|
319
|
+
@logger.info("Transforming User fields")
|
320
|
+
records.each do |record|
|
321
|
+
record['name'] = "#{record['firstname']} #{record['lastname']}"
|
322
|
+
|
323
|
+
record.delete 'firstname'
|
324
|
+
record.delete 'lastname'
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def transform_isos!(records)
|
157
329
|
@logger.info("Transforming ISO fields")
|
158
330
|
records.each do |record|
|
159
331
|
record['general_c_chargeback_fee'] = record['general_conventional_chargeback_fee']
|
@@ -162,6 +334,7 @@ module SalesforceMigration
|
|
162
334
|
record['general_nc_chargeback_fee'] = record['general_non_conventional_chargeback_fee']
|
163
335
|
record['general_nc_commission_fee'] = record['general_non_conventional_commission_fee']
|
164
336
|
record['general_nc_transaction_fee'] = record['general_non_conventional_transaction_fee']
|
337
|
+
|
165
338
|
record.delete 'general_conventional_chargeback_fee'
|
166
339
|
record.delete 'general_conventional_commission_fee'
|
167
340
|
record.delete 'general_conventional_transaction_fee'
|
@@ -169,80 +342,152 @@ module SalesforceMigration
|
|
169
342
|
record.delete 'general_non_conventional_commission_fee'
|
170
343
|
record.delete 'general_non_conventional_transaction_fee'
|
171
344
|
end
|
172
|
-
records
|
173
345
|
end
|
174
346
|
|
175
|
-
def transform_agents(records)
|
176
|
-
@logger.info("Transforming fields")
|
347
|
+
def transform_agents!(records)
|
348
|
+
@logger.info("Transforming Agent fields")
|
177
349
|
records.each do |record|
|
178
|
-
record['
|
350
|
+
record['sf_iso_id'] = record['iso_company']
|
351
|
+
|
179
352
|
record.delete 'iso_company'
|
180
353
|
end
|
181
|
-
records
|
182
354
|
end
|
183
355
|
|
184
|
-
def transform_merchants(records)
|
356
|
+
def transform_merchants!(records)
|
185
357
|
@logger.info("Transforming Merchant fields")
|
186
358
|
records.each do |record|
|
187
|
-
record['
|
188
|
-
record['
|
189
|
-
record['
|
359
|
+
record['sf_agent_id'] = record['agents']
|
360
|
+
record['ipsp_name'] = record['ipsp_name2']
|
361
|
+
record['url'] = record['url'].to_s.gsub(/<[^>]*>|^[\n\r]*/, '')
|
362
|
+
record['additional_url'] = record['additional_url'].to_s.gsub(/(<[^>]*>|^[\n\r]*)/, '')
|
363
|
+
|
190
364
|
record.delete 'agents'
|
191
|
-
record.delete 'sf_lastactivitydate'
|
192
|
-
record.delete 'sf_lastmodifieddate'
|
193
365
|
record.delete 'sf_region'
|
366
|
+
record.delete 'ipsp_name2'
|
194
367
|
end
|
195
|
-
records
|
196
368
|
end
|
197
369
|
|
198
|
-
def
|
199
|
-
@logger.info("Transforming
|
370
|
+
def transform_email_to_merchants!(records)
|
371
|
+
@logger.info("Transforming Emails to Merchant fields");
|
200
372
|
records.each do |record|
|
201
|
-
record['
|
202
|
-
record['
|
203
|
-
|
204
|
-
record.delete '
|
205
|
-
record.delete '
|
206
|
-
record.delete 'contract'
|
207
|
-
record.delete 'sf_recruiter'
|
208
|
-
record.delete 'sf_region'
|
373
|
+
record['sf_id'] = record['email']
|
374
|
+
record['sf_merchant_id'] = record['merchant_name']
|
375
|
+
|
376
|
+
record.delete 'email'
|
377
|
+
record.delete 'merchant_name'
|
209
378
|
end
|
210
|
-
records
|
211
379
|
end
|
212
|
-
|
213
|
-
def
|
214
|
-
@logger.info("Transforming
|
380
|
+
|
381
|
+
def transform_apm_to_merchants!(records)
|
382
|
+
@logger.info("Transforming APM to Merchant fields");
|
215
383
|
records.each do |record|
|
216
|
-
record['
|
217
|
-
record['
|
218
|
-
|
219
|
-
|
220
|
-
record.delete '
|
221
|
-
record.delete 'ccrmbasic__cc'
|
222
|
-
record.delete 'ccrmbasic__body'
|
384
|
+
record['sf_id'] = record['payment_methods']
|
385
|
+
record['sf_merchant_id'] = record['merchant']
|
386
|
+
|
387
|
+
record.delete 'payment_methods'
|
388
|
+
record.delete 'merchant'
|
223
389
|
end
|
224
|
-
records
|
225
390
|
end
|
226
391
|
|
227
|
-
#
|
392
|
+
# Correct/Sanitize field types in a record (Boolean, Date/DateTime, nil)
|
393
|
+
#
|
394
|
+
# @param [SugarCRM::Namespace::Object] record - the record we want to process
|
395
|
+
#
|
396
|
+
# @return [SugarCRM::Namespace::Object] record
|
397
|
+
def correct_field_types!(record)
|
398
|
+
strip_empty_arrays!(record)
|
399
|
+
|
400
|
+
replace_invalid_ids!(record)
|
401
|
+
|
402
|
+
convert_string_to_boolean!(record)
|
403
|
+
|
404
|
+
convert_string_to_datetime!(record)
|
405
|
+
|
406
|
+
strip_nil_to_empty_string!(record)
|
407
|
+
end
|
408
|
+
|
409
|
+
|
410
|
+
# Convert all fields with date/modstamp in their names to DateTime objects
|
228
411
|
#
|
229
|
-
# @param [SugarCRM::Namespace::Object] record the record
|
412
|
+
# @param [SugarCRM::Namespace::Object] record - the record, where we look for date/stamp values and make them DB-Compatible
|
230
413
|
#
|
231
|
-
# @return [SugarCRM::Namespace::Object]
|
232
|
-
def convert_string_to_datetime(record)
|
233
|
-
record
|
234
|
-
|
235
|
-
|
236
|
-
|
414
|
+
# @return [SugarCRM::Namespace::Object] record
|
415
|
+
def convert_string_to_datetime!(record)
|
416
|
+
record.each do |field_name, field_value|
|
417
|
+
if field_name =~ /(.*)date(.*)|modstamp/
|
418
|
+
record[field_name] = DateTime.parse(field_value).to_s(:db) rescue nil
|
419
|
+
end
|
420
|
+
end
|
237
421
|
end
|
238
|
-
|
422
|
+
|
423
|
+
# Convert all string fields to Boolean objects
|
424
|
+
#
|
425
|
+
# @param [SugarCRM::Namespace::Object] record - the record, where we look for boolean variables in string format
|
426
|
+
#
|
427
|
+
# @return [SugarCRM::Namespace::Object] record
|
428
|
+
def convert_string_to_boolean!(record)
|
429
|
+
record.each do |field_name, field_value|
|
430
|
+
case field_value
|
431
|
+
when /\Atrue\Z/i;
|
432
|
+
record[field_name] = true
|
433
|
+
when /\Afalse\Z/i;
|
434
|
+
record[field_name] = false
|
435
|
+
when /\Anil\Z/i, /\ANULL\Z/;
|
436
|
+
record[field_name] = nil
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
# Replace all empty arrays with empty strings
|
442
|
+
#
|
443
|
+
# @param [SugarCRM::Namespace::Object] record - the record, where we look for empty arrays
|
444
|
+
#
|
445
|
+
# @return [SugarCRM::Namespace::Object] record
|
446
|
+
def strip_empty_arrays!(record)
|
447
|
+
record.each do |field_name, field_value|
|
448
|
+
if field_value == "[]"
|
449
|
+
record[field_name] = ""
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
# nil (null) Values are not properly handled by SugarCRM, thus convert them to empty strings
|
455
|
+
#
|
456
|
+
# @param [SugarCRM::Namespace::Object] record - the record, where we look for empty arrays
|
457
|
+
#
|
458
|
+
# @return [SugarCRM::Namespace::Object] record
|
459
|
+
def strip_nil_to_empty_string!(record)
|
460
|
+
record.each do |field_name, field_value|
|
461
|
+
record[field_name] = "" if record[field_name].nil?
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
# Sometimes a record, may have an invalid id or a new owner, but the change might not be reflected in SalesForce thus we need to change it manually
|
466
|
+
#
|
467
|
+
# @param [SugarCRM::Namespace::Object] record - the record, where we look for empty arrays
|
468
|
+
#
|
469
|
+
# @return [SugarCRM::Namespace::Object] record
|
470
|
+
def replace_invalid_ids!(record)
|
471
|
+
valid_ids = %w{005300000057piVAAQ}
|
472
|
+
invalid_ids = %w{0053000000567TbAAI}
|
473
|
+
|
474
|
+
record.each do |field_name, field_value|
|
475
|
+
invalid_ids.each_with_index { |invalid_id, index| record[field_name] = valid_ids[index] if compare_salesforce_ids(record[field_value], invalid_id) }
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
# SQL escape string
|
480
|
+
#
|
481
|
+
# @param String string
|
482
|
+
#
|
483
|
+
# @return String string
|
239
484
|
def convert_characters(string)
|
240
485
|
string.gsub!(/\'/, ''')
|
241
486
|
string.gsub!(/'/, '')
|
242
487
|
string.gsub!(/"/, '')
|
243
488
|
string.gsub!(/\"/, '"')
|
244
489
|
string
|
245
|
-
|
490
|
+
end
|
246
491
|
|
247
492
|
# Populate SugarCRM with records
|
248
493
|
# If it's initial run, it will create all records from the CSV file
|
@@ -252,40 +497,46 @@ module SalesforceMigration
|
|
252
497
|
# @param [String] type type of the object
|
253
498
|
def populate_sugar(records, type)
|
254
499
|
module_type = get_sugarcrm_module_type(type)
|
500
|
+
|
255
501
|
case @action
|
256
|
-
|
257
|
-
|
502
|
+
when 'initial_run'
|
503
|
+
@logger.info("Creating new records for #{type} type")
|
504
|
+
records.each do |record|
|
505
|
+
create_sugar_record(module_type, record, type)
|
506
|
+
end
|
507
|
+
when 'update'
|
258
508
|
records.each do |record|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
record
|
509
|
+
correct_field_types! record
|
510
|
+
|
511
|
+
existing_record = find_sugarcrm_object(type, 'sf_id', record['sf_id'])
|
512
|
+
|
513
|
+
if existing_record
|
514
|
+
if existing_record.is_a?(Array)
|
515
|
+
@logger.error("More than one record for #{type} #{record['name']} - SalesForce Id (#{record['sf_id']}")
|
516
|
+
existing_record = existing_record.first
|
517
|
+
end
|
518
|
+
|
519
|
+
@logger.info("Updating record for #{type} #{record['name']}")
|
520
|
+
existing_record.update_attributes!(record)
|
521
|
+
else
|
522
|
+
@logger.info("Creating new record for #{type} #{record['name']}")
|
523
|
+
create_sugar_record(module_type, record, type)
|
271
524
|
end
|
272
|
-
@logger.info("Updating record for #{type} #{record['name']}")
|
273
|
-
existing_record.update_attributes!(record)
|
274
|
-
else
|
275
|
-
@logger.info("Creating new record for #{type} #{record['name']}")
|
276
|
-
create_sugar_record(module_type, record, type)
|
277
525
|
end
|
278
|
-
end
|
279
526
|
end
|
280
527
|
end
|
281
528
|
|
282
529
|
# Create the actual records and users in SugarCRM. Populates the var_pool
|
530
|
+
#
|
531
|
+
# @param module_type
|
532
|
+
# @param record [SugarCRM::Namespace::Object]
|
533
|
+
# @param type
|
283
534
|
def create_sugar_record(module_type, record, type)
|
284
|
-
|
535
|
+
correct_field_types!(record)
|
285
536
|
|
286
537
|
obj = module_type.new(record)
|
287
538
|
obj.save!
|
288
|
-
obj =
|
539
|
+
obj = create_associations(obj, type) unless %(email payment_method).include? type
|
289
540
|
create_security_group_iso obj if type == 'iso'
|
290
541
|
|
291
542
|
create_user(obj, type) if %(iso agent).include? type
|
@@ -295,21 +546,28 @@ module SalesforceMigration
|
|
295
546
|
# Populates variables with SugarCRM objects.
|
296
547
|
# We use them later on, when associating objects with Security Groups
|
297
548
|
# Actually we don`t use @bank_accounts & @emails for now, but it`s probably a good idea to store the objects
|
298
|
-
#
|
299
|
-
# @param [
|
549
|
+
#
|
550
|
+
# @param [SugarCRM::Namespace::Object] obj - object for which a user will be created
|
551
|
+
# @param [String] type - type of the object
|
300
552
|
def populate_var_pool(obj, type)
|
301
553
|
case type
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
554
|
+
when 'email'
|
555
|
+
@emails << obj
|
556
|
+
when 'settlement_bank_account'
|
557
|
+
@bank_accounts << obj
|
558
|
+
when 'acquirer'
|
559
|
+
@acquirers << obj
|
560
|
+
when 'contract'
|
561
|
+
@contracts << obj
|
562
|
+
when 'user'
|
563
|
+
@users << obj
|
564
|
+
when 'iso'
|
565
|
+
@isos << obj
|
566
|
+
when 'agent'
|
567
|
+
@agents << obj
|
568
|
+
when 'merchant'
|
569
|
+
@merchants << obj
|
570
|
+
end
|
313
571
|
end
|
314
572
|
|
315
573
|
# Create association for agent, merchant, settlement bank Account, Email, Payment Method
|
@@ -317,119 +575,243 @@ module SalesforceMigration
|
|
317
575
|
# If it is merchant, it will find the Agent, Payment Method, User and create the associations
|
318
576
|
# If it is Settlement Bank Account it will find the Merchant and create the associations
|
319
577
|
# @param [SugarCRM::Namespace::Object] obj the object for which an association will be created
|
320
|
-
# @param [String] type type of the object
|
578
|
+
# @param [String] type - type of the object
|
321
579
|
#
|
322
|
-
# @return [SugarCRM::Namespace::Object] the object
|
323
|
-
def
|
324
|
-
|
580
|
+
# @return [SugarCRM::Namespace::Object] - the object
|
581
|
+
def create_associations(obj, type)
|
582
|
+
# You need to save! the object before passing it, as it won't create associations
|
583
|
+
@logger.info("Creating associations for #{type} #{obj.name}")
|
584
|
+
|
325
585
|
case type
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
agent = find_sugarcrm_object('agent', 'sf_id', obj.sf_agent)
|
344
|
-
if agent
|
345
|
-
obj.associate! agent
|
346
|
-
obj.assigned_user_id = agent.assigned_user_id
|
347
|
-
end
|
348
|
-
|
349
|
-
when "settlement_bank_account"
|
350
|
-
merchant = find_sugarcrm_object('merchant', 'sf_id', obj.sf_merchant)
|
351
|
-
obj.associate! merchant if merchant
|
586
|
+
when "agent"
|
587
|
+
associate_with!('iso', @isos, 'sf_id', obj)
|
588
|
+
|
589
|
+
associate_with!('email', @emails, 'sf_agent_id', obj)
|
590
|
+
when "merchant"
|
591
|
+
associate_with!('agent', @agents, 'sf_id', obj)
|
592
|
+
|
593
|
+
associate_with!('contract', @contracts, 'sf_account_id', obj)
|
594
|
+
|
595
|
+
associate_with!('email', @emails_to_merchants, 'sf_merchant_id', obj)
|
596
|
+
|
597
|
+
associate_with!('payment_method', @payment_to_merchants, 'sf_merchant_id', obj)
|
598
|
+
|
599
|
+
associate_with!('settlement_bank_account', @bank_accounts, 'sf_merchant_id', obj)
|
600
|
+
|
601
|
+
assign_user_as_owner_to_record(obj, obj)
|
352
602
|
end
|
353
603
|
obj
|
354
604
|
end
|
355
605
|
|
356
|
-
#
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
#user.email1 = obj.email_address || "mail@example.com"
|
369
|
-
user.email1 = 'stefan@emerchantpay.com'
|
370
|
-
user.status = 'Inactive'
|
371
|
-
user.system_generated_password = false
|
372
|
-
user.save!
|
373
|
-
obj.assigned_user_id = user.id
|
374
|
-
obj.save!
|
375
|
-
|
376
|
-
populate_user_pool(user, type)
|
377
|
-
end
|
378
|
-
|
379
|
-
# Populates Users as SugarCRM objects.
|
380
|
-
# We use them later on, when associating objects with Security Groups
|
381
|
-
# @param [SugarCRM::Namespace::Object] Already created user object
|
382
|
-
# @param [String] type type of the object
|
383
|
-
def populate_user_pool(user, type)
|
384
|
-
case type
|
385
|
-
when 'iso'
|
386
|
-
@iso_users << user
|
387
|
-
when 'agent'
|
388
|
-
@agent_users << user
|
606
|
+
# Associate an object with selected ids
|
607
|
+
def associate_module_by_ids!(obj, type, list_of_ids, assign_to_user = false, reverse_association = false)
|
608
|
+
if list_of_ids.is_a?(Array)
|
609
|
+
list_of_ids.each do |record_id|
|
610
|
+
sugar_object = find_sugarcrm_object(type, 'sf_id', record_id)
|
611
|
+
if reverse_association
|
612
|
+
sugar_object.associate! obj if sugar_object
|
613
|
+
else
|
614
|
+
obj.associate! sugar_object if sugar_object
|
615
|
+
end
|
616
|
+
assign_user_as_owner_to_record(object, sugar_object) if assign_to_user
|
617
|
+
end
|
389
618
|
end
|
390
619
|
end
|
391
620
|
|
392
621
|
# Find records(payment methods, emails) in the junction object arrays, given the merchant_id
|
393
622
|
# Both payment methods and emails have a many-to-many relationship with the merchant in Salesforce
|
394
|
-
|
395
|
-
|
396
|
-
|
623
|
+
|
624
|
+
def associate_with!(type, relation_data, relation_field, object)
|
625
|
+
return unless type and relation_data and relation_field and object
|
626
|
+
|
627
|
+
case type
|
628
|
+
when "iso"
|
629
|
+
related_to_id = object.sf_iso_id
|
630
|
+
when "agent"
|
631
|
+
related_to_id = object.sf_agent_id
|
632
|
+
else
|
633
|
+
related_to_id = object.sf_id
|
634
|
+
end
|
635
|
+
|
636
|
+
relation_data = (@action == "update") ? type : relation_data
|
637
|
+
|
638
|
+
found_records = find_related_records(relation_data, relation_field, related_to_id)
|
639
|
+
|
640
|
+
return if found_records.blank?
|
641
|
+
|
642
|
+
if %(contract email settlement_bank_account).include? type
|
643
|
+
associate_module_by_ids!(obj, type, found_records, true, false)
|
644
|
+
else
|
645
|
+
associate_module_by_ids!(obj, type, found_records, false, false)
|
397
646
|
end
|
398
|
-
false
|
399
647
|
end
|
400
|
-
|
401
|
-
def
|
402
|
-
|
403
|
-
|
648
|
+
|
649
|
+
def find_related_records(relation_data, relation_field, related_to_id)
|
650
|
+
return unless relation_data and relation_field and related_to_id
|
651
|
+
|
652
|
+
search_results = []
|
653
|
+
|
654
|
+
case @action
|
655
|
+
when "initial_run"
|
656
|
+
relation_data.each do |record|
|
657
|
+
# Check if we are dealing with file-relations (stored as Array)
|
658
|
+
# OR if we're using SugarCRM records (store as Object)
|
659
|
+
|
660
|
+
record_id = (relation_data.first.is_a?(Hash)) ? record['sf_id'] : record.sf_id
|
661
|
+
relate_id = (relation_data.first.is_a?(Hash)) ? record[relation_field] : record.send(relation_field.to_sym)
|
662
|
+
|
663
|
+
search_results << record_id if compare_salesforce_ids(relate_id, related_to_id)
|
664
|
+
end
|
665
|
+
when "update"
|
666
|
+
# Check if we are dealing with file-relations (stored as Array)
|
667
|
+
if relation_data.first.is_a?(Hash)
|
668
|
+
relation_data.each { |record| search_results << record['sf_id'] if compare_salesforce_ids(record[relation_field], related_to_id) }
|
669
|
+
# OR extract the objects from SugarCRM
|
670
|
+
else
|
671
|
+
records = find_sugarcrm_object(relation_data, relation_field, related_to_id)
|
672
|
+
|
673
|
+
if records.is_a?(Array)
|
674
|
+
records.each { |record| search_results << record.sf_id }
|
675
|
+
else
|
676
|
+
search_results << records.sf_id
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
return search_results
|
682
|
+
end
|
683
|
+
|
684
|
+
# Assign user to an object, by providing a source and target objects
|
685
|
+
#
|
686
|
+
# @param [Object] id_object - An object holding the User Id
|
687
|
+
# @param [Object] target_object - The object we want to associate to this user
|
688
|
+
#
|
689
|
+
def assign_user_as_owner_to_record(id_object, object_to_assign)
|
690
|
+
return unless id_object and object_to_assign
|
691
|
+
|
692
|
+
salesforce_id = (id_object.sf_agent_id.blank?) ? id_object.sf_id : id_object.sf_agent_id
|
693
|
+
|
694
|
+
user = find_sugarcrm_object('users', 'salesforce_id', salesforce_id)
|
695
|
+
|
696
|
+
return if user.blank?
|
697
|
+
|
698
|
+
# Warn the user that we might've stumbbled upon some duplication or non-empty database (SalesForce Ids shoud be unique)
|
699
|
+
if user.is_a?(Array)
|
700
|
+
@logger.error("We found a SalesForce Id with two created SugarCRM users.")
|
701
|
+
user = user.first
|
404
702
|
end
|
703
|
+
|
704
|
+
@logger.info("Assigning #{user.last_name} as owner to #{object_to_assign.name}")
|
705
|
+
|
706
|
+
object_to_assign.assigned_user_id = user.id
|
707
|
+
object_to_assign.save!
|
708
|
+
end
|
709
|
+
|
710
|
+
# Compare SalesForce Ids - SalesForce have two type of ids - 15 digit case-sensitive and 18-digit case-insensitive
|
711
|
+
#
|
712
|
+
# @param [String] salesforce_id - salesforce id to compare to
|
713
|
+
# @param [String] target_id - id
|
714
|
+
#
|
715
|
+
# @return [Boolean] true on match, every other case - false
|
716
|
+
def compare_salesforce_ids(salesforce_id, target_id)
|
717
|
+
return false unless salesforce_id and target_id
|
718
|
+
|
719
|
+
case salesforce_id.length
|
720
|
+
when 15
|
721
|
+
if target_id.length == 18
|
722
|
+
target_id = target_id[0..-4]
|
723
|
+
end
|
724
|
+
if salesforce_id == target_id
|
725
|
+
return true
|
726
|
+
end
|
727
|
+
when 18
|
728
|
+
if target_id.length == 15
|
729
|
+
salesforce_id = salesforce_id[0..-4]
|
730
|
+
end
|
731
|
+
if salesforce_id.casecmp(target_id) == 0
|
732
|
+
return true
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
405
736
|
false
|
406
737
|
end
|
407
738
|
|
408
|
-
#Creates the Security Group object in SugarCRM
|
739
|
+
# Creates the Security Group object in SugarCRM
|
740
|
+
#
|
409
741
|
# @param [SugarCRM::Namespace::EmpIso] Iso object
|
410
742
|
def create_security_group_iso(iso)
|
411
743
|
@logger.info("Creating SecurityGroup #{iso.name}")
|
412
|
-
|
413
|
-
|
744
|
+
security_group = SugarCRM::SecurityGroup.new(:name => iso.name) unless find_sugarcrm_object('security_group','name', iso.name)
|
745
|
+
security_group.save!
|
414
746
|
end
|
415
747
|
|
416
|
-
# Assign all records,
|
748
|
+
# Assign all records, to their ISO's SecurityGroup
|
417
749
|
def associate_records_to_groups
|
418
750
|
put_isos_into_iso_group
|
419
751
|
put_agents_into_iso_group
|
420
752
|
put_merchants_into_iso_group
|
421
753
|
end
|
422
754
|
|
755
|
+
# Create user associated with SugarCRM object
|
756
|
+
# Default email: mail@example.com, default password: 123456
|
757
|
+
#
|
758
|
+
# @param [SugarCRM::Namespace::Object] obj object for which a user will be created
|
759
|
+
# @param [String] type type of the object
|
760
|
+
def create_user(obj, type)
|
761
|
+
@logger.info("Creating user for #{type} #{obj.name}")
|
762
|
+
if (defined?(obj.emerchantpay_iso_id) && (obj.emerchantpay_iso_id.blank? || obj.email_address.blank?)) ||
|
763
|
+
(defined?(obj.emerchantpay_agent_id) && (obj.emerchantpay_agent_id.blank? || obj.email_address.blank?))
|
764
|
+
@logger.error("Record |#{obj.name}| with type |#{type}| have empty fields (which are required), thus its skipped!")
|
765
|
+
else
|
766
|
+
user = SugarCRM::User.new
|
767
|
+
user.user_name = (type == 'agent') ? obj.emerchantpay_agent_id : obj.emerchantpay_iso_id
|
768
|
+
user.last_name = obj.name
|
769
|
+
user.emp_type = type
|
770
|
+
user.email1 = obj.email_address || ""
|
771
|
+
user.status = 'Inactive'
|
772
|
+
user.salesforce_id = obj.sf_id
|
773
|
+
user.system_generated_password = false
|
774
|
+
user.save!
|
775
|
+
obj.assigned_user_id = user.id
|
776
|
+
obj.save!
|
777
|
+
|
778
|
+
populate_user_pool(user, type)
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
# Populates Users as SugarCRM objects.
|
783
|
+
# We use them later on, when associating objects with Security Groups
|
784
|
+
# @param [SugarCRM::Namespace::Object] Already created user object
|
785
|
+
# @param [String] type type of the object
|
786
|
+
def populate_user_pool(user, type)
|
787
|
+
case type
|
788
|
+
when 'iso'
|
789
|
+
@iso_users << user
|
790
|
+
when 'agent'
|
791
|
+
@agent_users << user
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
423
795
|
def put_isos_into_iso_group
|
424
796
|
if @isos
|
425
797
|
@logger.info("Puting ISOs into ISO groups")
|
426
798
|
role = SugarCRM::ACLRole.find_by_name("isos")
|
427
799
|
@isos.each do |iso|
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
800
|
+
security_group = find_sugarcrm_object('security_group','name', iso.name)
|
801
|
+
|
802
|
+
if security_group
|
803
|
+
user = SugarCRM::User.find_by_last_name(iso.name)
|
804
|
+
iso.associate! security_group
|
805
|
+
role.associate! security_group
|
806
|
+
|
807
|
+
if user.nil?
|
808
|
+
@logger.error("ISO (#{iso.name}) doesn't have a user record")
|
809
|
+
else
|
810
|
+
user.associate! security_group
|
811
|
+
end
|
812
|
+
else
|
813
|
+
@logger.error("Couldn't find a SecurityGroup for ISO - #{iso.name}")
|
814
|
+
end
|
433
815
|
end
|
434
816
|
end
|
435
817
|
end
|
@@ -438,15 +820,24 @@ module SalesforceMigration
|
|
438
820
|
if @agents
|
439
821
|
@logger.info("Putting agent records, agent users and agent role into ISO groups")
|
440
822
|
@agents.each do |agent|
|
441
|
-
|
823
|
+
security_group = find_sugarcrm_object('security_group','name', agent.emp_iso.first.name) unless agent.emp_iso.empty?
|
442
824
|
role = SugarCRM::ACLRole.find_by_name('agents')
|
443
|
-
if
|
825
|
+
if security_group
|
444
826
|
user = SugarCRM::User.find_by_last_name(agent.name)
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
827
|
+
|
828
|
+
if user.nil?
|
829
|
+
@logger.error("Agent (#{agent.emp_iso.first.name}) doesn't have a user record")
|
830
|
+
else
|
831
|
+
user.associate! security_group
|
832
|
+
end
|
833
|
+
|
834
|
+
@logger.info("Puting Agent #{agent.name} in Security Group #{security_group.name}")
|
835
|
+
agent.associate! security_group
|
836
|
+
role.associate! security_group
|
837
|
+
put_email_objects_into_iso_group(security_group, 'agent', agent)
|
838
|
+
else
|
839
|
+
@logger.error("Couldn't find a ISO SecurityGroup for Agent - #{agent.emp_iso.first.name}")
|
840
|
+
end
|
450
841
|
end
|
451
842
|
end
|
452
843
|
end
|
@@ -459,81 +850,94 @@ module SalesforceMigration
|
|
459
850
|
if @merchants
|
460
851
|
@logger.info("Puting merchants into ISO groups")
|
461
852
|
@merchants.each do |merchant|
|
462
|
-
unless (merchant.emp_agent.
|
463
|
-
|
464
|
-
@logger.info("Puting merchant #{merchant.name} into ISO group")
|
465
|
-
|
466
|
-
if sg
|
467
|
-
merchant.associate! sg
|
468
|
-
put_email_objects_into_iso_group(sg, merchant.sf_id)
|
469
|
-
put_payment_methods_objects_into_iso_group(sg, merchant.sf_id)
|
470
|
-
end
|
853
|
+
unless (merchant.emp_agent.blank? || merchant.emp_agent.first.emp_iso.blank?)
|
854
|
+
security_group = find_sugarcrm_object('security_group','name', merchant.emp_agent.first.emp_iso.first.name)
|
471
855
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
856
|
+
if security_group
|
857
|
+
@logger.info("Puting merchant #{merchant.name} into ISO group")
|
858
|
+
merchant.associate! security_group
|
859
|
+
put_bank_accounts_into_iso_group(security_group, merchant)
|
860
|
+
put_email_objects_into_iso_group(security_group, 'merchant', merchant)
|
861
|
+
put_payment_methods_objects_into_iso_group(security_group, merchant)
|
862
|
+
else
|
863
|
+
@logger.error("Couldn't find a ISO SecurityGroup for Merchant - #{merchant.name}")
|
476
864
|
end
|
477
865
|
end
|
478
866
|
end
|
479
867
|
end
|
480
868
|
end
|
481
869
|
|
482
|
-
def put_bank_accounts_into_iso_group(
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
870
|
+
def put_bank_accounts_into_iso_group(security_group, merchant)
|
871
|
+
return unless security_group and merchant
|
872
|
+
|
873
|
+
@logger.info("Puting Bank Account for #{merchant.name} into ISO group")
|
874
|
+
|
875
|
+
case @action
|
876
|
+
when "initial_run"
|
877
|
+
bank_accounts_for_merchant_id = find_related_records(@bank_accounts, 'sf_merchant_id', merchant.sf_id)
|
878
|
+
when "update"
|
879
|
+
bank_accounts_for_merchant_id = find_related_records('settlement_bank_account', 'sf_merchant_id', merchant.sf_id)
|
489
880
|
end
|
881
|
+
|
882
|
+
return if bank_accounts_for_merchant_id.blank?
|
883
|
+
|
884
|
+
associate_module_by_ids!(security_group, 'settlement_bank_account', bank_accounts_for_merchant_id, false, true)
|
490
885
|
end
|
491
886
|
|
492
|
-
def put_email_objects_into_iso_group(
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
887
|
+
def put_email_objects_into_iso_group(security_group, type, obj)
|
888
|
+
return unless security_group and type and obj
|
889
|
+
|
890
|
+
@logger.info("Puting Emails for #{obj.name} into ISO group")
|
891
|
+
|
892
|
+
case type
|
893
|
+
when "agent"
|
894
|
+
case @action
|
895
|
+
when "initial_run"
|
896
|
+
email_ids_for_object = find_related_records(@emails, 'sf_agent_id', obj.sf_id)
|
897
|
+
when "update"
|
898
|
+
email_ids_for_object = find_related_records('email', 'sf_agent_id', obj.sf_id)
|
899
|
+
end
|
900
|
+
when "merchant"
|
901
|
+
case @action
|
902
|
+
when "initial_run"
|
903
|
+
email_ids_for_object = find_related_records(@emails_to_merchants, 'sf_merchant_id', obj.sf_id)
|
904
|
+
when "update"
|
905
|
+
email_ids_for_object = find_related_records('email', 'sf_merchant_id', obj.sf_id)
|
504
906
|
end
|
505
|
-
end
|
506
907
|
end
|
908
|
+
|
909
|
+
return if email_ids_for_object.blank?
|
910
|
+
|
911
|
+
associate_module_by_ids!(security_group, 'email', email_ids_for_object, false, true)
|
507
912
|
end
|
508
913
|
|
509
|
-
def put_payment_methods_objects_into_iso_group(
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
else
|
520
|
-
payment_method.associate! sg
|
521
|
-
end
|
522
|
-
end
|
523
|
-
end
|
914
|
+
def put_payment_methods_objects_into_iso_group(security_group, merchant)
|
915
|
+
return unless security_group and merchant
|
916
|
+
|
917
|
+
@logger.info("Puting Payment Methods for #{merchant.name} into ISO group")
|
918
|
+
|
919
|
+
payment_methods = find_related_records(@payment_to_merchants, 'sf_merchant_id', merchant.sf_id)
|
920
|
+
|
921
|
+
return if payment_methods.blank?
|
922
|
+
|
923
|
+
associate_module_by_ids!(security_group, 'payment_method', payment_methods, false, true)
|
524
924
|
end
|
525
925
|
|
526
926
|
# Returns the SugarCRM module namespace
|
527
927
|
# @param [String] type type of the module object
|
528
928
|
def get_sugarcrm_module_type(type)
|
529
929
|
modules = {
|
530
|
-
"
|
930
|
+
"acquirer" => SugarCRM::EmpAcquirer,
|
531
931
|
"agent" => SugarCRM::EmpAgent,
|
932
|
+
"contract" => SugarCRM::EmpContract,
|
933
|
+
"email" => SugarCRM::EmpEmail,
|
934
|
+
"iso" => SugarCRM::EmpIso,
|
532
935
|
"merchant" => SugarCRM::EmpMerchant,
|
533
936
|
"payment_method" => SugarCRM::EmpPaymentmethod,
|
534
937
|
"settlement_bank_account" => SugarCRM::EmpSettlementBankAccount,
|
938
|
+
"user" => SugarCRM::EmpUser,
|
535
939
|
"security_group" => SugarCRM::SecurityGroup,
|
536
|
-
"
|
940
|
+
"users" => SugarCRM::User,
|
537
941
|
}
|
538
942
|
modules[type]
|
539
943
|
end
|
@@ -549,5 +953,17 @@ module SalesforceMigration
|
|
549
953
|
SugarCRM.connection.get_entry_list(module_type, "#{module_type.downcase}.#{attribute} = '#{search_string}'")
|
550
954
|
end
|
551
955
|
|
956
|
+
# Populates the var_pool with Sugar Objects.
|
957
|
+
# Reason being, is that if you abort the current process (error or some other reason)
|
958
|
+
# You won't be able to continue from the same place and be able to correctly associate the objects
|
959
|
+
# To prevent this, we can just load back every object for every type and continue uninterrupted
|
960
|
+
#
|
961
|
+
# @param [String] id - SalesForce id of the object, that we want to retrieve
|
962
|
+
# @param [String] type - type of the object, that we want to retrieve (module type)
|
963
|
+
def populate_var_poll_from_sugar(id, type)
|
964
|
+
obj = find_sugarcrm_object(type, 'sf_id', id)
|
965
|
+
populate_var_pool(obj, type) if obj
|
966
|
+
end
|
967
|
+
|
552
968
|
end
|
553
969
|
end
|