Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d4296fd1f | ||
|
|
81a3ba6ed5 | ||
|
|
2b1e809a25 | ||
|
|
2117a941af | ||
|
|
f55467c919 | ||
|
|
4f26e2dd25 | ||
|
|
edab2b65bf |
@@ -0,0 +1,53 @@
|
|||||||
|
class Migration::PopulateAccountContactStatusAndSocialsJob < ApplicationJob
|
||||||
|
queue_as :async_database_migration
|
||||||
|
|
||||||
|
def perform(account_id)
|
||||||
|
account = Account.find_by(id: account_id)
|
||||||
|
return unless account
|
||||||
|
|
||||||
|
Rails.logger.info "Processing contact migration for account #{account_id} (#{account.name})"
|
||||||
|
|
||||||
|
# Find the first lead contact to determine cutoff
|
||||||
|
first_lead = account.contacts.lead.order(:created_at).first
|
||||||
|
|
||||||
|
# Build the contacts scope in a more readable way
|
||||||
|
contacts_scope = if first_lead.present?
|
||||||
|
account.contacts.visitor.where('created_at < ?', first_lead.created_at)
|
||||||
|
else
|
||||||
|
account.contacts.visitor
|
||||||
|
end
|
||||||
|
|
||||||
|
total_count = contacts_scope.count
|
||||||
|
processed_count = 0
|
||||||
|
|
||||||
|
contacts_scope.find_each(batch_size: 500) do |contact|
|
||||||
|
processed_count += 1 if sync_contact_attributes(contact)
|
||||||
|
end
|
||||||
|
|
||||||
|
Rails.logger.info "Processed #{processed_count}/#{total_count} contacts for account #{account_id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def sync_contact_attributes(contact)
|
||||||
|
# Track only the fields we care about
|
||||||
|
original_contact_type = contact.contact_type
|
||||||
|
original_additional = contact.additional_attributes.dup
|
||||||
|
|
||||||
|
# Run the sync service with migration
|
||||||
|
::Contacts::SyncAttributes.new(contact).perform_with_migration
|
||||||
|
|
||||||
|
# Build update hash with only changed fields we care about
|
||||||
|
update_hash = {}
|
||||||
|
update_hash[:contact_type] = contact.contact_type if contact.contact_type != original_contact_type
|
||||||
|
update_hash[:additional_attributes] = contact.additional_attributes if contact.additional_attributes != original_additional
|
||||||
|
|
||||||
|
return false if update_hash.empty?
|
||||||
|
|
||||||
|
# Use update_columns to bypass callbacks and avoid triggering events
|
||||||
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
|
contact.update_columns(update_hash)
|
||||||
|
# rubocop:enable Rails/SkipsModelValidations
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -10,6 +10,12 @@ class Contacts::SyncAttributes
|
|||||||
set_contact_type
|
set_contact_type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def perform_with_migration
|
||||||
|
update_contact_location_and_country_code
|
||||||
|
migrate_social_attributes
|
||||||
|
set_contact_type
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def update_contact_location_and_country_code
|
def update_contact_location_and_country_code
|
||||||
@@ -24,7 +30,7 @@ class Contacts::SyncAttributes
|
|||||||
return unless @contact.contact_type == 'visitor'
|
return unless @contact.contact_type == 'visitor'
|
||||||
# If the contact has an email or phone number or social details( facebook_user_id, instagram_user_id, etc) then it is a lead
|
# If the contact has an email or phone number or social details( facebook_user_id, instagram_user_id, etc) then it is a lead
|
||||||
# If contact is from external channel like facebook, instagram, whatsapp, etc then it is a lead
|
# If contact is from external channel like facebook, instagram, whatsapp, etc then it is a lead
|
||||||
return unless @contact.email.present? || @contact.phone_number.present? || social_details_present?
|
return unless @contact.email.present? || @contact.phone_number.present? || @contact.identifier.present? || social_details_present?
|
||||||
|
|
||||||
@contact.contact_type = 'lead'
|
@contact.contact_type = 'lead'
|
||||||
end
|
end
|
||||||
@@ -34,4 +40,71 @@ class Contacts::SyncAttributes
|
|||||||
key.start_with?('social_') && @contact.additional_attributes[key].present?
|
key.start_with?('social_') && @contact.additional_attributes[key].present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def migrate_social_attributes
|
||||||
|
return if @contact.additional_attributes.blank?
|
||||||
|
|
||||||
|
attrs = @contact.additional_attributes
|
||||||
|
social_profiles = attrs['social_profiles'] || {}
|
||||||
|
|
||||||
|
return if social_profiles.blank?
|
||||||
|
|
||||||
|
# Migrate Telegram - check both social_profiles and legacy username field
|
||||||
|
migrate_telegram_attributes(attrs, social_profiles)
|
||||||
|
|
||||||
|
# Migrate Facebook
|
||||||
|
migrate_facebook_attributes(attrs, social_profiles)
|
||||||
|
|
||||||
|
# Migrate LINE
|
||||||
|
migrate_line_attributes(attrs, social_profiles)
|
||||||
|
end
|
||||||
|
|
||||||
|
def migrate_telegram_attributes(attrs, profiles)
|
||||||
|
# Previous format
|
||||||
|
# {
|
||||||
|
# "social_profiles": {
|
||||||
|
# "telegram": "gilpadraocruz"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# New format
|
||||||
|
# {
|
||||||
|
# "social_telegram_user_name": "gilpadraocruz"
|
||||||
|
# }
|
||||||
|
telegram_username = profiles['telegram'].presence || attrs['username'].presence
|
||||||
|
return if telegram_username.blank?
|
||||||
|
|
||||||
|
attrs['social_telegram_user_name'] ||= telegram_username
|
||||||
|
end
|
||||||
|
|
||||||
|
def migrate_facebook_attributes(attrs, profiles)
|
||||||
|
# Previous format
|
||||||
|
# {
|
||||||
|
# "social_profiles": {
|
||||||
|
# "facebook": "gilpadraocruz"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# New format
|
||||||
|
# {
|
||||||
|
# "social_facebook_user_name": "gilpadraocruz"
|
||||||
|
# }
|
||||||
|
return if profiles['facebook'].blank?
|
||||||
|
|
||||||
|
attrs['social_facebook_user_name'] ||= profiles['facebook']
|
||||||
|
end
|
||||||
|
|
||||||
|
def migrate_line_attributes(attrs, profiles)
|
||||||
|
# Previous format
|
||||||
|
# {
|
||||||
|
# "social_profiles": {
|
||||||
|
# "line": "gilpadraocruz"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# New format
|
||||||
|
# {
|
||||||
|
# "social_line_user_id": "gilpadraocruz"
|
||||||
|
# }
|
||||||
|
return if profiles['line'].blank?
|
||||||
|
|
||||||
|
attrs['social_line_user_id'] ||= profiles['line']
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user