agent_ticket_create.js.coffee 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. class App.TicketCreate extends App.Controller
  2. events:
  3. 'click .customer_new': 'userNew'
  4. 'submit form': 'submit'
  5. 'click .submit': 'submit'
  6. 'click .cancel': 'cancel'
  7. constructor: (params) ->
  8. super
  9. # check authentication
  10. return if !@authenticate()
  11. # set title
  12. @form_id = App.ControllerForm.formId()
  13. @edit_form = undefined
  14. # set article attributes
  15. default_type = 'call_inbound'
  16. if !@type
  17. @type = default_type
  18. article_sender_type_map =
  19. call_inbound:
  20. sender: 'Customer'
  21. article: 'phone'
  22. title: 'Call Inbound'
  23. call_outbound:
  24. sender: 'Agent'
  25. article: 'phone'
  26. title: 'Call Outbound'
  27. email:
  28. sender: 'Agent'
  29. article: 'email'
  30. title: 'Email'
  31. @article_attributes = article_sender_type_map[@type]
  32. # if no map entry exists, route to default
  33. if !@article_attributes
  34. @navigate '#ticket_create/' + default_type
  35. # update navbar highlighting
  36. @navupdate '#ticket_create/' + @type + '/id/' + @id
  37. @fetch(params)
  38. # lisen if view need to be rerendert
  39. App.Event.bind 'ticket_create_rerender', (defaults) =>
  40. @log 'notice', 'error', defaults
  41. @render(defaults)
  42. # start auto save
  43. @delay(
  44. => @autosave(),
  45. 5000
  46. )
  47. meta: =>
  48. text = App.i18n.translateInline( @article_attributes['title'] )
  49. subject = @el.find('[name=subject]').val()
  50. if subject
  51. text = "#{text}: #{subject}"
  52. meta =
  53. url: @url()
  54. head: text
  55. title: text
  56. id: @type
  57. url: =>
  58. '#ticket_create/' + @type + '/id/' + @id
  59. activate: =>
  60. @navupdate '#'
  61. @el.find('textarea').elastic()
  62. changed: =>
  63. formCurrent = @formParam( @el.find('.ticket-create') )
  64. diff = difference( @formDefault, formCurrent )
  65. return false if !diff || _.isEmpty( diff )
  66. return true
  67. release: =>
  68. # @clearInterval( @key, 'ticket_zoom' )
  69. @el.remove()
  70. @clearInterval( @id, @auto_save_key )
  71. autosave: =>
  72. @auto_save_key = 'create' + @type + @id
  73. update = =>
  74. data = @formParam( @el.find('.ticket-create') )
  75. diff = difference( @autosaveLast, data )
  76. if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
  77. @autosaveLast = data
  78. @log 'notice', 'form hash changed', diff, data
  79. App.TaskManager.update( @task_key, { 'state': data })
  80. @interval( update, 10000, @id, @auto_save_key )
  81. # get data / in case also ticket data for split
  82. fetch: (params) ->
  83. # use cache
  84. cache = App.Store.get( 'ticket_create_attributes' )
  85. if cache && !params.ticket_id && !params.article_id
  86. # get edit form attributes
  87. @edit_form = cache.edit_form
  88. # load user collection
  89. App.Collection.load( type: 'User', data: cache.users )
  90. @render()
  91. else
  92. App.Com.ajax(
  93. id: 'ticket_create'
  94. type: 'GET'
  95. url: 'api/ticket_create'
  96. data:
  97. ticket_id: params.ticket_id
  98. article_id: params.article_id
  99. processData: true
  100. success: (data, status, xhr) =>
  101. # cache request
  102. App.Store.write( 'ticket_create_attributes', data )
  103. # get edit form attributes
  104. @edit_form = data.edit_form
  105. # load user collection
  106. App.Collection.load( type: 'User', data: data.users )
  107. # load ticket collection
  108. if data.ticket && data.articles
  109. App.Collection.load( type: 'Ticket', data: [data.ticket] )
  110. # load article collections
  111. App.Collection.load( type: 'TicketArticle', data: data.articles || [] )
  112. # render page
  113. t = App.Collection.find( 'Ticket', params.ticket_id ).attributes()
  114. a = App.Collection.find( 'TicketArticle', params.article_id )
  115. # reset owner
  116. t.owner_id = 0
  117. t.customer_id_autocompletion = a.from
  118. t.subject = a.subject || t.title
  119. t.body = a.body
  120. @render( options: t )
  121. )
  122. render: (template = {}) ->
  123. # set defaults
  124. defaults =
  125. ticket_state_id: App.Collection.findByAttribute( 'TicketState', 'name', 'open' ).id
  126. ticket_priority_id: App.Collection.findByAttribute( 'TicketPriority', 'name', '2 normal' ).id
  127. # generate form
  128. configure_attributes = [
  129. { name: 'customer_id', display: 'Customer', tag: 'autocompletion', type: 'text', limit: 200, null: false, relation: 'User', class: 'span7', autocapitalize: false, help: 'Select the customer of the Ticket or create one.', link: '<a href="" class="customer_new">&raquo;</a>', callback: @localUserInfo, source: 'api/users/search', minLengt: 2 },
  130. { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: @edit_form, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', },
  131. { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
  132. { name: 'tags', display: 'Tags', tag: 'tag', type: 'text', null: true, default: defaults['tags'], class: 'span7', },
  133. { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 200, null: false, default: defaults['subject'], class: 'span7', },
  134. { name: 'body', display: 'Text', tag: 'textarea', rows: 8, null: false, default: defaults['body'], class: 'span7', upload: true },
  135. { name: 'ticket_state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['ticket_state_id'], translate: true, class: 'medium' },
  136. { name: 'ticket_priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['ticket_priority_id'], translate: true, class: 'medium' },
  137. ]
  138. @html App.view('agent_ticket_create')(
  139. head: 'New Ticket'
  140. title: @article_attributes['title']
  141. agent: @isRole('Agent')
  142. admin: @isRole('Admin')
  143. )
  144. params = undefined
  145. if template && !_.isEmpty( template.options )
  146. params = template.options
  147. else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state )
  148. params = App.TaskManager.get(@task_key).state
  149. new App.ControllerForm(
  150. el: @el.find('.ticket_create')
  151. form_id: @form_id
  152. model:
  153. configure_attributes: configure_attributes
  154. className: 'create_' + @type + '_' + @id
  155. autofocus: true
  156. form_data: @edit_form
  157. params: params
  158. )
  159. # update taskbar with new meta data
  160. App.Event.trigger 'task:render'
  161. # add elastic to textarea
  162. @el.find('textarea').elastic()
  163. # update textarea size
  164. @el.find('textarea').trigger('change')
  165. # show template UI
  166. new App.TemplateUI(
  167. el: @el.find('[data-id="ticket_template"]'),
  168. template_id: template['id'],
  169. )
  170. @formDefault = @formParam( @el.find('.ticket-create') )
  171. # show text module UI
  172. @textModule = new App.TextModuleUI(
  173. el: $('.ticket-create')
  174. )
  175. localUserInfo: (params) =>
  176. # update text module UI
  177. callback = (user) =>
  178. @textModule.reload(
  179. data:
  180. ticket:
  181. customer: user
  182. )
  183. @userInfo(
  184. user_id: params.customer_id
  185. el: @el.find('[data-id="customer_info"]')
  186. callback: callback
  187. )
  188. userNew: (e) =>
  189. e.preventDefault()
  190. new UserNew(
  191. create_screen: @
  192. )
  193. cancel: ->
  194. @navigate '#'
  195. submit: (e) ->
  196. e.preventDefault()
  197. # get params
  198. params = @formParam(e.target)
  199. # fillup params
  200. if !params.title
  201. params.title = params.subject
  202. # create ticket
  203. object = new App.Ticket
  204. # find sender_id
  205. sender = App.Collection.findByAttribute( 'TicketArticleSender', 'name', @article_attributes['sender'] )
  206. type = App.Collection.findByAttribute( 'TicketArticleType', 'name', @article_attributes['article'] )
  207. if params.group_id
  208. group = App.Collection.find( 'Group', params.group_id )
  209. # create article
  210. if sender.name is 'Customer'
  211. params['article'] = {
  212. to: (group && group.name) || ''
  213. from: params.customer_id_autocompletion
  214. subject: params.subject
  215. body: params.body
  216. ticket_article_type_id: type.id
  217. ticket_article_sender_id: sender.id
  218. form_id: @form_id
  219. }
  220. else
  221. params['article'] = {
  222. from: (group && group.name) || ''
  223. to: params.customer_id_autocompletion
  224. subject: params.subject
  225. body: params.body
  226. ticket_article_type_id: type.id
  227. ticket_article_sender_id: sender.id
  228. form_id: @form_id
  229. }
  230. object.load(params)
  231. # validate form
  232. errors = object.validate()
  233. # show errors in form
  234. if errors
  235. @log 'error', errors
  236. @formValidate( form: e.target, errors: errors )
  237. # save ticket, create article
  238. else
  239. # disable form
  240. @formDisable(e)
  241. ui = @
  242. object.save(
  243. success: ->
  244. # notify UI
  245. ui.notify
  246. type: 'success',
  247. msg: App.i18n.translateInline( 'Ticket %s created!', @number ),
  248. link: "#ticket/zoom/#{@id}"
  249. timeout: 12000,
  250. # close ticket create task
  251. App.TaskManager.remove( ui.task_key )
  252. # scroll to top
  253. ui.scrollTo()
  254. # access to group
  255. session = App.Session.all()
  256. if session && session['group_ids'] && _.contains(session['group_ids'], @group_id)
  257. ui.navigate "#ticket/zoom/#{@id}"
  258. return
  259. # if not, show start screen
  260. ui.navigate "#"
  261. error: ->
  262. ui.log 'save failed!'
  263. ui.formEnable(e)
  264. )
  265. class UserNew extends App.ControllerModal
  266. constructor: ->
  267. super
  268. @render()
  269. render: ->
  270. @html App.view('agent_user_create')( head: 'New User' )
  271. new App.ControllerForm(
  272. el: @el.find('#form-user'),
  273. model: App.User,
  274. required: 'quick',
  275. autofocus: true,
  276. )
  277. @modalShow()
  278. submit: (e) ->
  279. e.preventDefault()
  280. params = @formParam(e.target)
  281. # if no login is given, use emails as fallback
  282. if !params.login && params.email
  283. params.login = params.email
  284. user = new App.User
  285. # find role_id
  286. role = App.Collection.findByAttribute( 'Role', 'name', 'Customer' )
  287. params.role_ids = role.id
  288. @log 'notice', 'updateAttributes', params
  289. user.load(params)
  290. errors = user.validate()
  291. if errors
  292. @log 'error', errors
  293. @formValidate( form: e.target, errors: errors )
  294. return
  295. # save user
  296. ui = @
  297. user.save(
  298. success: ->
  299. # force to reload object
  300. callbackReload = (user) ->
  301. realname = user.displayName()
  302. ui.create_screen.el.find('[name=customer_id]').val( user.id )
  303. ui.create_screen.el.find('[name=customer_id_autocompletion]').val( realname )
  304. # start customer info controller
  305. ui.userInfo( user_id: user.id )
  306. ui.modalHide()
  307. App.Collection.find( 'User', @id, callbackReload , true )
  308. error: ->
  309. ui.modalHide()
  310. )
  311. class TicketCreateRouter extends App.ControllerPermanent
  312. constructor: (params) ->
  313. super
  314. # create new uniq form id
  315. if !params['id']
  316. id = Math.floor( Math.random() * 99999 )
  317. @navigate "#ticket_create/#{params['type']}/id/#{id}"
  318. return
  319. # cleanup params
  320. clean_params =
  321. ticket_id: params.ticket_id
  322. article_id: params.article_id
  323. type: params.type
  324. id: params.id
  325. App.TaskManager.add( 'TicketCreateScreen-' + params['type'] + '-' + params['id'], 'TicketCreate', clean_params )
  326. # split ticket
  327. App.Config.set( 'ticket_create/:ticket_id/:article_id', TicketCreateRouter, 'Routes' )
  328. # create new ticket routs/controller
  329. App.Config.set( 'ticket_create', TicketCreateRouter, 'Routes' )
  330. App.Config.set( 'ticket_create/:type', TicketCreateRouter, 'Routes' )
  331. App.Config.set( 'ticket_create/:type/id/:id', TicketCreateRouter, 'Routes' )
  332. # set new task actions
  333. App.Config.set( 'TicketNewCallOutbound', { prio: 8001, name: 'Call Outbound', target: '#ticket_create/call_outbound', role: ['Agent'] }, 'TaskActions' )
  334. App.Config.set( 'TicketNewCallInbound', { prio: 8002, name: 'Call Inbound', target: '#ticket_create/call_inbound', role: ['Agent'] }, 'TaskActions' )
  335. App.Config.set( 'TicketNewEmail', { prio: 8003, name: 'Email', target: '#ticket_create/email', role: ['Agent'] }, 'TaskActions' )