Browse Source

Fixes #5117 - Caller is not identified if the caller has only entered a telephone number (no firstname, lastname, email).

Martin Edenhofer 10 months ago
parent
commit
da3e688ae9

+ 5 - 0
app/assets/javascripts/app/controllers/agent_ticket_create.coffee

@@ -616,6 +616,11 @@ class App.TicketCreate extends App.Controller
     # to replace in text modules properly
     params.customer = App.User.find(params.customer_id) || {}
 
+    # show selected user display name in customer attribute in UI
+    if _.isEmpty(@el.find('input[name=customer_id_completion]').val())
+      if params.customer && params.customer.displayName
+        @el.find('input[name=customer_id_completion]').val(params.customer.displayName())
+
     @sidebarWidget.render(params)
     @textModule.reload(
       config: App.Config.all()

+ 18 - 5
app/assets/javascripts/app/models/user.coffee

@@ -40,18 +40,27 @@ class App.User extends App.Model
   initials: ->
     if @firstname && @lastname && @firstname[0] && @lastname[0]
       return @firstname[0] + @lastname[0]
-    else if @firstname && @firstname[0] && !@lastname
+
+    if @firstname && @firstname[0] && !@lastname
       if @firstname[1]
         return @firstname[0] + @firstname[1]
       return @firstname[0]
-    else if !@firstname && @lastname && @lastname[0]
+
+    if !@firstname && @lastname && @lastname[0]
       if @lastname[1]
         return @lastname[0] + @lastname[1]
       return @lastname[0]
-    else if @email
+
+    if @email
       return @email[0] + @email[1]
-    else
-      return '??'
+
+    if @phone
+      return @phone.slice(-2)
+
+    if @mobile
+      return @mobile.slice(-2)
+
+    return '??'
 
   avatar: (size = 40, placement = '', cssClass = '', unique = false, avatar, type = undefined) ->
     baseSize = 40
@@ -448,6 +457,8 @@ class App.User extends App.Model
       return @email
     if @phone
       return @phone
+    if @mobile
+      return @mobile
     if @login
       return @login
     return '-'
@@ -474,6 +485,8 @@ class App.User extends App.Model
       return @email
     if @phone
       return @phone
+    if @mobile
+      return @mobile
     if @login
       return @login
     return '-'

+ 1 - 0
app/frontend/apps/mobile/pages/ticket/graphql/fragments/ticketAttributes.api.ts

@@ -25,6 +25,7 @@ export const TicketAttributesFragmentDoc = gql`
     lastname
     fullname
     phone
+    mobile
     image
     vip
     active

+ 1 - 0
app/frontend/apps/mobile/pages/ticket/graphql/fragments/ticketAttributes.graphql

@@ -20,6 +20,7 @@ fragment ticketAttributes on Ticket {
     lastname
     fullname
     phone
+    mobile
     image
     vip
     active

+ 6 - 4
app/frontend/shared/components/CommonUserAvatar/CommonUserAvatar.vue

@@ -29,15 +29,17 @@ export interface Props {
 const props = defineProps<Props>()
 
 const initials = computed(() => {
-  const { lastname, firstname, email } = props.entity
+  const { lastname, firstname, email, phone, mobile } = props.entity
 
-  return getInitials(firstname, lastname, email)
+  return getInitials(firstname, lastname, email, phone, mobile)
 })
 
 const { backgroundColors } = getUserAvatarClasses()
 
 const fullName = computed(() => {
-  const { lastname, firstname } = props.entity
+  const { lastname, firstname, fullname } = props.entity
+
+  if (fullname) return fullname
 
   return [firstname, lastname].filter(Boolean).join(' ')
 })
@@ -49,7 +51,7 @@ const colorClass = computed(() => {
 
   if (internalId === SYSTEM_USER_INTERNAL_ID) return 'bg-white'
 
-  // get color based on mod of the fullname length
+  // get color based on mod of the integer ID
   // so it stays consistent between different interfaces and logins
   return backgroundColors[internalId % (backgroundColors.length - 1)]
 })

+ 2 - 0
app/frontend/shared/components/CommonUserAvatar/types.ts

@@ -5,6 +5,8 @@ export interface AvatarUser {
   firstname?: Maybe<string>
   fullname?: Maybe<string>
   email?: Maybe<string>
+  phone?: Maybe<string>
+  mobile?: Maybe<string>
   vip?: Maybe<boolean>
   outOfOffice?: Maybe<boolean>
   active?: Maybe<boolean>

File diff suppressed because it is too large
+ 0 - 0
app/frontend/shared/graphql/types.ts


+ 5 - 0
app/frontend/shared/utils/__tests__/formatters.spec.ts

@@ -28,6 +28,11 @@ describe('getInitials', () => {
     expect(getInitials('John', 'Doe', '')).toBe('JD')
     expect(getInitials('John', 'Doe', 'email@mail.com')).toBe('JD')
   })
+
+  it('returns last two numbers from phone and mobile', () => {
+    expect(getInitials('', '', '', '490123456789')).toBe('89')
+    expect(getInitials('', '', '', '', '491234567890')).toBe('90')
+  })
 })
 
 describe('toClassName', () => {

+ 13 - 10
app/frontend/shared/utils/formatter.ts

@@ -55,31 +55,34 @@ export const phoneify = (phone: string) => {
   return phone.replace(/[^0-9,+,#,*]+/g, '').replace(/(.)\+/, '$1')
 }
 
-export const getFullName = (
-  firstname?: Maybe<string>,
-  lastname?: Maybe<string>,
-): string => {
-  const fullname = [firstname, lastname].filter(Boolean).join(' ')
-  if (fullname === '-') return ''
-  return fullname
-}
-
 /**
  * Returns user's initials based on their first name, last name and email, if any present.
  * @param firstname - user's first name
  * @param lastname - user's last name
  * @param email - user's email address
+ * @param phone - user's phone number
+ * @param mobile - user's mobile number
  */
 export const getInitials = (
   firstname?: Maybe<string>,
   lastname?: Maybe<string>,
   email?: Maybe<string>,
+  phone?: Maybe<string>,
+  mobile?: Maybe<string>,
 ) => {
   if (firstname && lastname) {
     return firstname[0] + lastname[0]
   }
 
-  return (firstname || lastname || email)?.substring(0, 2).toUpperCase() || '??'
+  if (firstname || lastname || email) {
+    return (firstname || lastname || email)?.substring(0, 2).toUpperCase()
+  }
+
+  if (phone || mobile) {
+    return (phone || mobile)?.slice(-2).toUpperCase()
+  }
+
+  return '??'
 }
 
 /**

+ 12 - 4
app/models/user.rb

@@ -145,6 +145,14 @@ returns
       return email
     end
 
+    return name if name.present?
+
+    %w[phone mobile].each do |item|
+      next if self[item].blank?
+
+      return self[item]
+    end
+
     name
   end
 
@@ -908,9 +916,9 @@ try to find correct name
 
   def ensure_identifier
     return if login.present? && !login.start_with?('auto-')
-    return if [email, firstname, lastname, phone].any?(&:present?)
+    return if [email, firstname, lastname, phone, mobile].any?(&:present?)
 
-    errors.add :base, __('At least one identifier (firstname, lastname, phone or email) for user is required.')
+    errors.add :base, __('At least one identifier (firstname, lastname, phone, mobile or email) for user is required.')
   end
 
   def ensure_uniq_email
@@ -1176,14 +1184,14 @@ raise 'At least one user need to have admin permissions'
     true
   end
 
-  # When adding/removing a phone number from the User table,
+  # When adding/removing a phone/mobile number from the User table,
   # update caller ID table
   # to adopt/orphan matching Cti::Logs accordingly
   # (see https://github.com/zammad/zammad/issues/2057)
   def update_caller_id
     # skip if "phone/mobile" does not change, or changes like [nil, ""]
     return if persisted? && previous_changes.slice(:phone, :mobile).values.flatten.none?(&:present?)
-    return if destroyed? && phone.blank?
+    return if destroyed? && phone.blank? && mobile.blank?
 
     Cti::CallerId.build(self)
   end

Some files were not shown because too many files changed in this diff