ticket.coffee 5.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. class App.Ticket extends App.Model
  2. @configure 'Ticket', 'number', 'title', 'group_id', 'owner_id', 'customer_id', 'state_id', 'priority_id', 'article', 'tags', 'links', 'updated_at'
  3. @extend Spine.Model.Ajax
  4. @url: @apiPath + '/tickets'
  5. @configure_attributes = [
  6. { name: 'number', display: '#', tag: 'input', type: 'text', limit: 100, null: true, readonly: 1, width: '68px' },
  7. { name: 'title', display: 'Title', tag: 'input', type: 'text', limit: 100, null: false },
  8. { name: 'customer_id', display: 'Customer', tag: 'input', type: 'text', limit: 100, null: false, autocapitalize: false, relation: 'User' },
  9. { name: 'organization_id', display: 'Organization', tag: 'select', relation: 'Organization', readonly: 1 },
  10. { name: 'group_id', display: 'Group', tag: 'select', multiple: false, limit: 100, null: false, relation: 'Group', width: '10%', edit: true },
  11. { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, limit: 100, null: true, relation: 'User', width: '12%', edit: true },
  12. { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, relation: 'TicketState', default: 'new', width: '12%', edit: true, customer: true },
  13. { name: 'pending_time', display: 'Pending Time', tag: 'datetime', null: true, width: '130px' },
  14. { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, relation: 'TicketPriority', default: '2 normal', width: '12%', edit: true, customer: true },
  15. { name: 'article_count', display: 'Article#', readonly: 1, width: '12%' },
  16. { name: 'escalation_time', display: 'Escalation', tag: 'datetime', null: true, readonly: 1, width: '110px', class: 'escalation' },
  17. { name: 'last_contact', display: 'Last contact', tag: 'datetime', null: true, readonly: 1, width: '110px' },
  18. { name: 'last_contact_agent', display: 'Last contact (Agent)', tag: 'datetime', null: true, readonly: 1, width: '110px' },
  19. { name: 'last_contact_customer', display: 'Last contact (Customer)', tag: 'datetime', null: true, readonly: 1, width: '110px' },
  20. { name: 'first_response', display: 'First response', tag: 'datetime', null: true, readonly: 1, width: '110px' },
  21. { name: 'close_time', display: 'Close time', tag: 'datetime', null: true, readonly: 1, width: '110px' },
  22. { name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
  23. { name: 'created_at', display: 'Created at', tag: 'datetime', width: '110px', align: 'right', readonly: 1 },
  24. { name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
  25. { name: 'updated_at', display: 'Updated at', tag: 'datetime', width: '110px', align: 'right', readonly: 1 },
  26. ]
  27. uiUrl: ->
  28. '#ticket/zoom/' + @id
  29. getState: ->
  30. type = App.TicketState.find( @state_id )
  31. stateType = App.TicketStateType.find( type.state_type_id )
  32. state = 'closed'
  33. if stateType.name is 'new' || stateType.name is 'open'
  34. state = 'open'
  35. # if ticket is escalated, overwrite state
  36. if @escalation_time && new Date( Date.parse( @escalation_time ) ) < new Date
  37. state = 'escalating'
  38. else if stateType.name is 'pending reminder'
  39. state = 'pending'
  40. # if ticket pending_time is reached, overwrite state
  41. if @pending_time && new Date( Date.parse( @pending_time ) ) < new Date
  42. state = 'open'
  43. else if stateType.name is 'pending action'
  44. state = 'pending'
  45. state
  46. icon: ->
  47. 'task-state'
  48. iconClass: ->
  49. @getState()
  50. iconTitle: ->
  51. type = App.TicketState.find( @state_id )
  52. stateType = App.TicketStateType.find( type.state_type_id )
  53. if stateType.name is 'pending reminder' && @pending_time && new Date( Date.parse( @pending_time ) ) < new Date
  54. return "#{App.i18n.translateInline(type.displayName())} - #{App.i18n.translateInline('reached')}"
  55. if @escalation_time && new Date( Date.parse( @escalation_time ) ) < new Date
  56. return "#{App.i18n.translateInline(type.displayName())} - #{App.i18n.translateInline('escalated')}"
  57. App.i18n.translateInline(type.displayName())
  58. iconTextClass: ->
  59. "task-state-#{ @getState() }-color"
  60. iconActivity: (user) ->
  61. return if !user
  62. if @owner_id == user.id
  63. return 'important'
  64. ''
  65. searchResultAttributes: ->
  66. display: "##{@number} - #{@title}"
  67. id: @id
  68. class: "task-state-#{ @getState() } ticket-popover"
  69. url: @uiUrl()
  70. icon: 'task-state'
  71. iconClass: @getState()
  72. activityMessage: (item) ->
  73. return if !item
  74. if item.type is 'create'
  75. return App.i18n.translateContent('%s created Ticket |%s|', item.created_by.displayName(), item.title)
  76. else if item.type is 'update'
  77. return App.i18n.translateContent('%s updated Ticket |%s|', item.created_by.displayName(), item.title)
  78. else if item.type is 'reminder_reached'
  79. return App.i18n.translateContent('Pending reminder reached for Ticket |%s|', item.title)
  80. else if item.type is 'escalation'
  81. return App.i18n.translateContent('Ticket |%s| is escalated!', item.title)
  82. return "Unknow action for (#{@objectDisplayName()}/#{item.type}), extend activityMessage() of model."