chore: Merge contact copy over information (#2812)
fixes: #2767, #2773 Co-authored-by: Nithin David <1277421+nithindavid@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
class ContactMergeAction
|
||||
include Events::Types
|
||||
pattr_initialize [:account!, :base_contact!, :mergee_contact!]
|
||||
|
||||
def perform
|
||||
@@ -11,7 +12,7 @@ class ContactMergeAction
|
||||
merge_conversations
|
||||
merge_messages
|
||||
merge_contact_inboxes
|
||||
remove_mergee_contact
|
||||
merge_and_remove_mergee_contact
|
||||
end
|
||||
@base_contact
|
||||
end
|
||||
@@ -40,7 +41,18 @@ class ContactMergeAction
|
||||
ContactInbox.where(contact_id: @mergee_contact.id).update(contact_id: @base_contact.id)
|
||||
end
|
||||
|
||||
def remove_mergee_contact
|
||||
def merge_and_remove_mergee_contact
|
||||
mergable_attribute_keys = %w[identifier name email phone_number custom_attributes]
|
||||
base_contact_attributes = base_contact.attributes.slice(*mergable_attribute_keys).compact_blank
|
||||
mergee_contact_attributes = mergee_contact.attributes.slice(*mergable_attribute_keys).compact_blank
|
||||
|
||||
# attributes in base contact are given preference
|
||||
merged_attributes = mergee_contact_attributes.deep_merge(base_contact_attributes)
|
||||
# retaining old pubsub token to notify the contacts that are listening
|
||||
mergee_pubsub_token = mergee_contact.pubsub_token
|
||||
|
||||
@mergee_contact.destroy!
|
||||
Rails.configuration.dispatcher.dispatch(CONTACT_MERGED, Time.zone.now, contact: @base_contact, tokens: [mergee_pubsub_token])
|
||||
@base_contact.update!(merged_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,9 +10,22 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
'conversation.typing_off': this.onTypingOff,
|
||||
'conversation.status_changed': this.onStatusChange,
|
||||
'presence.update': this.onPresenceUpdate,
|
||||
'contact.merged': this.onContactMerge,
|
||||
};
|
||||
}
|
||||
|
||||
static refreshConnector = pubsubToken => {
|
||||
if (!pubsubToken || window.chatwootPubsubToken === pubsubToken) {
|
||||
return;
|
||||
}
|
||||
window.chatwootPubsubToken = pubsubToken;
|
||||
window.actionCable.disconnect();
|
||||
window.actionCable = new ActionCableConnector(
|
||||
window.WOOT_WIDGET,
|
||||
window.chatwootPubsubToken
|
||||
);
|
||||
};
|
||||
|
||||
onStatusChange = data => {
|
||||
this.app.$store.dispatch('conversationAttributes/update', data);
|
||||
};
|
||||
@@ -33,6 +46,11 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
this.app.$store.dispatch('agent/updatePresence', data.users);
|
||||
};
|
||||
|
||||
onContactMerge = data => {
|
||||
const { pubsub_token: pubsubToken } = data;
|
||||
ActionCableConnector.refreshConnector(pubsubToken);
|
||||
};
|
||||
|
||||
onTypingOn = () => {
|
||||
this.clearTimer();
|
||||
this.app.$store.dispatch('conversation/toggleAgentTyping', {
|
||||
@@ -63,16 +81,7 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
};
|
||||
}
|
||||
|
||||
export const refreshActionCableConnector = pubsubToken => {
|
||||
if (!pubsubToken || window.chatwootPubsubToken === pubsubToken) {
|
||||
return;
|
||||
}
|
||||
window.chatwootPubsubToken = pubsubToken;
|
||||
window.actionCable.disconnect();
|
||||
window.actionCable = new ActionCableConnector(
|
||||
window.WOOT_WIDGET,
|
||||
window.chatwootPubsubToken
|
||||
);
|
||||
};
|
||||
export const refreshActionCableConnector =
|
||||
ActionCableConnector.refreshConnector;
|
||||
|
||||
export default ActionCableConnector;
|
||||
|
||||
@@ -104,6 +104,13 @@ class ActionCableListener < BaseListener
|
||||
broadcast(account, tokens, CONTACT_UPDATED, contact.push_event_data)
|
||||
end
|
||||
|
||||
def contact_merged(event)
|
||||
contact, account = extract_contact_and_account(event)
|
||||
tokens = event.data[:tokens]
|
||||
|
||||
broadcast(account, tokens, CONTACT_MERGED, contact.push_event_data)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def typing_event_listener_tokens(account, conversation, user)
|
||||
|
||||
@@ -77,6 +77,8 @@ class Contact < ApplicationRecord
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ip_lookup
|
||||
return unless account.feature_enabled?('ip_lookup')
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ module Events::Types
|
||||
# contact events
|
||||
CONTACT_CREATED = 'contact.created'
|
||||
CONTACT_UPDATED = 'contact.updated'
|
||||
CONTACT_MERGED = 'contact.merged'
|
||||
|
||||
# agent events
|
||||
AGENT_ADDED = 'agent.added'
|
||||
|
||||
@@ -4,8 +4,14 @@ describe ::ContactMergeAction do
|
||||
subject(:contact_merge) { described_class.new(account: account, base_contact: base_contact, mergee_contact: mergee_contact).perform }
|
||||
|
||||
let!(:account) { create(:account) }
|
||||
let!(:base_contact) { create(:contact, account: account) }
|
||||
let!(:mergee_contact) { create(:contact, account: account) }
|
||||
let!(:base_contact) do
|
||||
create(:contact, identifier: 'base_contact', email: 'old@old.com', phone_number: '', custom_attributes: { val_test: 'old', val_empty_old: '' },
|
||||
account: account)
|
||||
end
|
||||
let!(:mergee_contact) do
|
||||
create(:contact, identifier: '', email: 'new@new.com', phone_number: '+12212345',
|
||||
custom_attributes: { val_test: 'new', val_new: 'new', val_empty_new: '' }, account: account)
|
||||
end
|
||||
|
||||
before do
|
||||
2.times.each do
|
||||
@@ -21,6 +27,18 @@ describe ::ContactMergeAction do
|
||||
expect { mergee_contact.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it 'copies information from mergee contact to base contact' do
|
||||
contact_merge
|
||||
base_contact.reload
|
||||
expect(base_contact.identifier).to eq('base_contact')
|
||||
expect(base_contact.email).to eq('old@old.com')
|
||||
expect(base_contact.phone_number).to eq('+12212345')
|
||||
expect(base_contact.custom_attributes['val_test']).to eq('old')
|
||||
expect(base_contact.custom_attributes['val_new']).to eq('new')
|
||||
expect(base_contact.custom_attributes['val_empty_old']).to eq('')
|
||||
expect(base_contact.custom_attributes['val_empty_new']).to eq('')
|
||||
end
|
||||
|
||||
context 'when base contact and merge contact are same' do
|
||||
it 'does not delete contact' do
|
||||
mergee_contact = base_contact
|
||||
|
||||
Reference in New Issue
Block a user