diff --git a/app/assets/javascripts/app/controllers/_channel/email.js.coffee b/app/assets/javascripts/app/controllers/_channel/email.js.coffee
index ccef65c00..d3f6e1a28 100644
--- a/app/assets/javascripts/app/controllers/_channel/email.js.coffee
+++ b/app/assets/javascripts/app/controllers/_channel/email.js.coffee
@@ -1,17 +1,24 @@
$ = jQuery.sub()
+$.fn.item = (genericObject) ->
+ elementID = $(@).data('id')
+ elementID or= $(@).parents('[data-id]').data('id')
+ genericObject.find(elementID)
+
class App.ChannelEmail extends App.ControllerTabs
constructor: ->
super
@tabs = [
{
- name: 'Inbound',
- target: 'c-inbound',
+ name: 'Inbound',
+ target: 'c-inbound',
+ controller: App.ChannelEmailInbound,
},
{
- name: 'Outbound',
- target: 'c-outbound',
+ name: 'Outbound',
+ target: 'c-outbound',
+ controller: App.ChannelEmailOutbound,
},
{
name: 'Adresses',
@@ -28,84 +35,197 @@ class App.ChannelEmail extends App.ControllerTabs
},
]
-# App.Channel.bind 'refresh change', @render
-# App.Channel.fetch()
@render()
- render2: =>
- settings = App.Setting.all()
+class App.ChannelEmailInboundEdit extends App.ControllerModal
+ constructor: ->
+ super
+ @render(@object)
+
+ render: (data = {}) ->
+
+ configure_attributes = [
+ { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { IMAP: 'IMAP', POP3: 'POP3' } , class: 'span4', default: data['adapter'] },
+ { name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (data['options']&&data['options']['host']) },
+ { name: 'user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (data['options']&&data['options']['user']) },
+ { name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (data['options']&&data['options']['password']) },
+ { name: 'ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: (data['options']&&data['options']['ssl']) },
+ { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: @edit_form, nulloption: false, relation: 'Group', class: 'span4', default: data['group_id'] },
+ { name: 'active', display: 'Active', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: data['active'] },
+ ]
+ form = @formGen( model: { configure_attributes: configure_attributes, className: '' } )
+
+ @html App.view('generic/admin/new')(
+ form: form,
+ head: 'New Channel'
+ )
+ @modalShow()
+
+ submit: (e) =>
+ e.preventDefault()
+
+ # get params
+ params = @formParam(e.target)
+
+ object = @object || new App.Channel
+ object.load(
+ area: 'Email::Inbound',
+ adapter: params['adapter'],
+ group_id: params['group_id'],
+ options: {
+ host: params['host'],
+ user: params['user'],
+ password: params['password'],
+ ssl: params['ssl'],
+ },
+ host: params['host'],
+ user: params['user'],
+ password: params['password'],
+ active: params['active'],
+ )
+
+ # validate form
+ errors = object.validate()
- html = $('
')
- for setting in settings
- if setting.area is @area
- item = new App.SettingsAreaItem( setting: setting )
- html.append( item.el )
+ # show errors in form
+ if errors
+ @log 'error new', errors
+ @validateForm( form: e.target, errors: errors )
+ return false
- @html html
+ # save object
+ object.save(
+ success: =>
+ @modalHide()
+ error: =>
+ @log 'errors'
+ @modalHide()
+ )
-
-class App.SettingsAreaItem2 extends App.Controller
+class App.ChannelEmailInbound extends App.Controller
events:
- 'submit form': 'update',
+ 'click [data-type=new]': 'new'
+ 'click [data-type=edit]': 'edit'
constructor: ->
super
- @render()
+
+ App.Channel.bind 'refresh change', @render
+ App.Channel.fetch()
render: =>
- # defaults
- for item in @setting.options['form']
- if typeof @setting.state.value is 'object'
- item['default'] = @setting.state.value[item.name]
- else
- item['default'] = @setting.state.value
+ channels = App.Channel.all()
+
+ html = $('')
+ data = []
+ for channel in channels
+ if channel.area is 'Email::Inbound'
+ channel.host = channel.options['host']
+ channel.user = channel.options['user']
+ data.push channel
- # form
- @configure_attributes = @setting.options['form']
- form = @formGen( model: { configure_attributes: @configure_attributes, className: '' }, autofocus: false )
+ table = @table(
+ overview: ['host', 'user', 'adapter', 'active'],
+ model: App.Channel,
+ objects: data,
+ )
- # item
- @html App.view('settings/item')(
- setting: @setting,
- form: form,
- )
+ html.append( table )
+ html.append( 'new account' )
+ @html html
+
+ new: (e) =>
+ e.preventDefault()
+ new App.ChannelEmailInboundEdit()
+
+ edit: (e) =>
+ e.preventDefault()
+ item = $(e.target).item( App.Channel )
+ new App.ChannelEmailInboundEdit( object: item )
+
+
+class App.ChannelEmailOutbound extends App.Controller
+ events:
+ 'change #_adapter': 'toggle'
+ 'submit #mail_adapter': 'update'
+
+ constructor: ->
+ super
+
+ App.Channel.bind 'refresh change', @render
+ App.Channel.fetch()
+
+ render: =>
+ channels = App.Channel.all()
+ data = []
+ adapters = {}
+ adapter_used = undefined
+ channel_used = undefined
+ for channel in channels
+ if channel.area is 'Email::Outbound'
+
+ data.push channel
+ adapters[channel.adapter] = channel.adapter
+ if @adapter_used
+ if @adapter_used is channel.adapter
+ adapter_used = channel.adapter
+ channel_used = channel
+ else if channel.active is true
+ adapter_used = channel.adapter
+ channel_used = channel
+
+ configure_attributes = [
+ { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , class: 'span4', default: adapter_used },
+ ]
+ form_adapter = @formGen( model: { configure_attributes: configure_attributes, className: '' } )
+
+ if adapter_used is 'SMTP'
+ configure_attributes = [
+ { name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (channel_used['options']&&channel_used['options']['host']) },
+ { name: 'user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, class: 'span4', autocapitalize: false, default: (channel_used['options']&&channel_used['options']['user']) },
+ { name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, class: 'span4', autocapitalize: false, default: (channel_used['options']&&channel_used['options']['password']) },
+ { name: 'ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: (channel_used['options']&&channel_used['options']['ssl']) },
+ ]
+ form_adapter_settings = @formGen( model: { configure_attributes: configure_attributes, className: '' } )
+
+ html = App.view('channel/email_outbound')(
+ form_adapter: form_adapter,
+ form_adapter_settings: form_adapter_settings,
+ )
+ html = $(html)
+ @html html
+
+ toggle: (e) =>
+
+ # get params
+ params = @formParam(e.target)
+
+ @adapter_used = params['adapter']
+
+ @render()
update: (e) =>
e.preventDefault()
- params = @formParam(e.target)
- @log 'submit', @setting, params, e.target
- if typeof @setting.state.value is 'object'
- state = {
- value: params
- }
- else
- state = {
- value: params[@setting.name]
- }
+ params = @formParam(e.target)
+ channels = App.Channel.all()
+ for channel in channels
+ if channel.area is 'Email::Outbound' && channel.adapter is params['adapter']
+ channel.updateAttributes(
+ options: {
+ host: params['host'],
+ user: params['user'],
+ password: params['password'],
+ ssl: params['ssl'],
+ },
+ active: true,
+ )
- @setting['state'] = state
- @setting.save(
- success: =>
+ # set all other to inactive
+ channels = App.Channel.all()
+ for channel in channels
+ if channel.area is 'Email::Outbound' && channel.adapter isnt params['adapter']
+ channel.updateAttributes( active: false )
- # login check
- auth = new App.Auth
- auth.loginCheck()
- )
-
-class App.ChannelEmail2 extends App.Controller
- events:
- 'click [data-toggle="tabnav"]': 'toggle',
-
- constructor: ->
- super
-
- # render page
+ # rerender
@render()
-
- render: ->
-
- @html App.view('channel/email')(
- head: 'some header'
- )
-
diff --git a/app/assets/javascripts/app/controllers/channel.js.coffee b/app/assets/javascripts/app/controllers/channel.js.coffee
index f3bc38d35..fc8bcd41f 100644
--- a/app/assets/javascripts/app/controllers/channel.js.coffee
+++ b/app/assets/javascripts/app/controllers/channel.js.coffee
@@ -1,14 +1,15 @@
$ = jQuery.sub()
class Index extends App.ControllerLevel2
- toggleable: true
+# toggleable: true
+ toggleable: false
menu: [
- { name: 'Web', 'target': 'web', controller: App.ChannelWeb },
- { name: 'Mail', 'target': 'email', controller: App.ChannelEmail },
- { name: 'Chat', 'target': 'chat', controller: App.ChannelChat },
- { name: 'Twitter', 'target': 'twitter', controller: App.ChannelTwitter },
- { name: 'Facebook', 'target': 'facebook', controller: App.ChannelFacebook },
+ { name: 'Web', target: 'web', controller: App.ChannelWeb },
+ { name: 'Mail', target: 'email', controller: App.ChannelEmail },
+ { name: 'Chat', target: 'chat', controller: App.ChannelChat },
+ { name: 'Twitter', target: 'twitter', controller: App.ChannelTwitter },
+ { name: 'Facebook', target: 'facebook', controller: App.ChannelFacebook },
]
page: {
title: 'Channels',
@@ -24,5 +25,6 @@ class Index extends App.ControllerLevel2
# render page
@render()
+Config.Routes['channels/:target'] = Index
Config.Routes['channels'] = Index
diff --git a/app/assets/javascripts/app/controllers/settings.js.coffee b/app/assets/javascripts/app/controllers/settings.js.coffee
index 29da305ff..a5c502855 100644
--- a/app/assets/javascripts/app/controllers/settings.js.coffee
+++ b/app/assets/javascripts/app/controllers/settings.js.coffee
@@ -2,7 +2,7 @@ $ = jQuery.sub()
class Index extends App.ControllerLevel2
toggleable: false
- toggleable: true
+# toggleable: true
constructor: ->
super
diff --git a/app/assets/javascripts/app/models/channel.js.coffee b/app/assets/javascripts/app/models/channel.js.coffee
new file mode 100644
index 000000000..f7622169e
--- /dev/null
+++ b/app/assets/javascripts/app/models/channel.js.coffee
@@ -0,0 +1,14 @@
+class App.Channel extends App.Model
+ @configure 'Channel', 'adapter', 'area', 'options', 'group_id', 'active'
+ @extend Spine.Model.Ajax
+
+ @configure_attributes = [
+ { name: 'adapter', display: 'Adapter', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
+ { name: 'area', display: 'Area', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
+# { name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
+# { name: 'user', display: 'User', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
+# { name: 'password', display: 'Password', tag: 'input', type: 'text', limit: 100, null: fa, 'class': 'xlarge' },
+ { name: 'options', display: 'Area', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
+ { name: 'group_id', display: 'Group', tag: 'option', type: 'text', limit: 100, null: true, 'class': 'xlarge' },
+ { name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, null: true, 'class': 'xlarge' },
+ ]
\ No newline at end of file
diff --git a/app/assets/javascripts/app/views/channel/email.jst.eco b/app/assets/javascripts/app/views/channel/email.jst.eco
deleted file mode 100644
index 93f76beac..000000000
--- a/app/assets/javascripts/app/views/channel/email.jst.eco
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
- Host |
- User |
- Type |
- Active |
- Delete |
-
-
- lalal.example.com |
- wpt234rwr |
- IMAP |
- true |
- x |
-
-
- l31alal.example.com |
- wpt23dd4rwr |
- POP3 |
- true |
- x |
-
-
-
-
-
-
-
-
- Host |
- User |
- Type |
- Active |
- Delete |
-
-
- lalal.example.com |
- wpt234rwr |
- SMTP |
- true |
- x |
-
-
- l31alal.example.com |
- wpt23dd4rwr |
- Sendmail |
- true |
- x |
-
-
-
-
-
-
- Name |
- Active |
- Delete |
-
-
- lalal.example.com |
- true |
- x |
-
-
- wpt23dd4rwr |
- true |
- x |
-
-
-
diff --git a/app/assets/javascripts/app/views/channel/email_outbound.jst.eco b/app/assets/javascripts/app/views/channel/email_outbound.jst.eco
new file mode 100644
index 000000000..d76457b9f
--- /dev/null
+++ b/app/assets/javascripts/app/views/channel/email_outbound.jst.eco
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/app/assets/javascripts/app/views/channel/facebook.jst.eco b/app/assets/javascripts/app/views/channel/facebook.jst.eco
index 1e3959159..a2cba7d4e 100644
--- a/app/assets/javascripts/app/views/channel/facebook.jst.eco
+++ b/app/assets/javascripts/app/views/channel/facebook.jst.eco
@@ -3,6 +3,7 @@
\ No newline at end of file
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 01fec8bdd..9d474ff1c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -130,8 +130,8 @@ class ApplicationController < ActionController::Base
# config
config = {}
- Setting.where( :frontend => true ).each { |setting|
- config[setting.name] = setting.state[:value]
+ Setting.select('name').where( :frontend => true ).each { |setting|
+ config[setting.name] = Setting.get(setting.name)
}
return config
end
diff --git a/app/controllers/channels_controller.rb b/app/controllers/channels_controller.rb
new file mode 100644
index 000000000..f72842ca6
--- /dev/null
+++ b/app/controllers/channels_controller.rb
@@ -0,0 +1,49 @@
+class ChannelsController < ApplicationController
+ before_filter :authentication_check
+
+ # GET /channels
+ def index
+ @channels = Channel.all
+
+ render :json => @channels
+ end
+
+ # GET /channels/1
+ def show
+ @channel = Channel.find(params[:id])
+
+ render :json => @channel
+ end
+
+ # POST /channels
+ def create
+
+ @channel = Channel.new(params[:channel])
+ @channel.created_by_id = current_user.id
+
+ if @channel.save
+ render :json => @channel, :status => :created
+ else
+ render :json => @channel.errors, :status => :unprocessable_entity
+ end
+ end
+
+ # PUT /channels/1
+ def update
+ @channel = Channel.find(params[:id])
+
+ if @channel.update_attributes(params[:channel])
+ render :json => @channel, :status => :ok
+ else
+ render :json => @channel.errors, :status => :unprocessable_entity
+ end
+ end
+
+ # DELETE /channels/1
+ def destroy
+ @channel = Channel.find(params[:id])
+ @channel.destroy
+
+ head :ok
+ end
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 56fa68956..5b251bb9c 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -37,15 +37,25 @@ class UsersController < ApplicationController
if @user.created_by_id == 1
# check if it's first user
- count = User.all.count()
- role_ids = []
+ count = User.all.count()
+ group_ids = []
+ role_ids = []
+
+ # add first user as admin/agent and to all groups
if count <= 2
- role_ids.push Role.where( :name => 'Admin' ).first.id
- role_ids.push Role.where( :name => 'Agent' ).first.id
+ Role.where( :name => [ 'Admin', 'Agent'] ).each { |role|
+ role_ids.push role.id
+ }
+ Group.all().each { |group|
+ group_ids.push group.id
+ }
+
+ # everybody else will go as customer per default
else
role_ids.push Role.where( :name => 'Customer' ).first.id
end
- @user.role_ids = role_ids
+ @user.role_ids = role_ids
+ @user.group_ids = group_ids
# else do assignment as defined
else
diff --git a/app/models/channel.rb b/app/models/channel.rb
index 33fda6295..10a491c32 100644
--- a/app/models/channel.rb
+++ b/app/models/channel.rb
@@ -1,11 +1,19 @@
class Channel < ActiveRecord::Base
+ store :options
+
+ def self.send2
+ # find outbound
+
+ end
+
def self.fetch
- Rails.application.config.channel.each { |channel|
+ channels = Channel.where( 'active = ? AND area LIKE ?', true, '%::Inbound' )
+ channels.each { |channel|
begin
- c = eval channel[:module] + '.new'
+ c = eval 'Channel::' + channel[:adapter] + '.new'
c.fetch(channel)
rescue Exception => e
- puts "can't use " + channel[:module]
+ puts "can't use " + 'Channel::' + channel[:adapter]
puts e.inspect
end
}
diff --git a/app/models/channel/imap.rb b/app/models/channel/imap.rb
index 2ffd92072..748af989d 100644
--- a/app/models/channel/imap.rb
+++ b/app/models/channel/imap.rb
@@ -4,12 +4,11 @@ require 'net/imap'
class Channel::IMAP
include UserInfo
-# def fetch(:oauth_token, :oauth_token_secret)
def fetch (account)
puts 'fetching imap'
- imap = Net::IMAP.new(account[:host], 993, true )
- imap.authenticate('LOGIN', account[:user], account[:pw])
+ imap = Net::IMAP.new(account[:options][:host], 993, true )
+ imap.authenticate('LOGIN', account[:options][:user], account[:options][:password])
imap.select('INBOX')
imap.search(['ALL']).each do |message_id|
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
@@ -50,7 +49,7 @@ class Channel::IMAP
end
# get ticket# from subject
- ticket = Ticket.number_check(mail[:subject].value)
+ ticket = Ticket.number_check( mail[:subject].value )
# set ticket state to open if not new
if ticket
@@ -65,7 +64,7 @@ class Channel::IMAP
# create new ticket
if !ticket then
ticket = Ticket.create(
- :group_id => Group.where( :name => account[:group] ).first.id,
+ :group_id => account[:group_id],
:customer_id => user.id,
:title => conv(mail['subject'].charset || 'LATIN1', mail['subject'].to_s),
:ticket_state_id => Ticket::State.where(:name => 'new').first.id,
@@ -143,59 +142,16 @@ class Channel::IMAP
end
imap.expunge()
imap.disconnect()
+ puts 'done'
end
- def send(attr, account, notification = false)
- mail = Mail.new
-
- # set organization
- organization = Setting.get('organization')
- if organization then;
- mail['organization'] = organization.to_s
+ def send(attr, notification = false)
+ channel = Channel.where( :area => 'Email::Outbound', :active => true ).first
+ begin
+ c = eval 'Channel::' + channel[:adapter] + '.new'
+ c.send(attr, channel, notification)
+ rescue Exception => e
+ puts "can't use " + 'Channel::' + channel[:adapter]
+ puts e.inspect
end
-
- # notification
- if notification
- attr['X-Loop'] = 'yes'
- attr['Precedence'] = 'bulk'
- attr['Auto-Submitted'] = 'auto-generated'
- end
-
- # set headers
- attr.each do |key, v|
- if key.to_s != 'attachments' && key.to_s != 'body'
- mail[key.to_s] = v.to_s
- end
- end
-
- # add body
- mail.text_part = Mail::Part.new do
- body attr[:body]
- end
-
- # add attachments
- if attr[:attachments]
- attr[:attachments].each do |attachment|
- mail.attachments[attachment.filename] = {
- :content_type => attachment.preferences['Content-Type'],
- :mime_type => attachment.preferences['Mime-Type'],
- :content => attachment.store_file.data
- }
- end
- end
-
- #mail.delivery_method :sendmail
- mail.delivery_method :smtp, {
- :openssl_verify_mode => 'none',
- :address => account[:host],
- # :port => 587,
- :port => 25,
- :domain => account[:host],
- :user_name => account[:user],
- :password => account[:pw],
- # :authentication => 'plain',
- :enable_starttls_auto => true
- }
- mail.deliver
-
end
end
\ No newline at end of file
diff --git a/app/models/channel/sendmail.rb b/app/models/channel/sendmail.rb
new file mode 100644
index 000000000..6b4a951cf
--- /dev/null
+++ b/app/models/channel/sendmail.rb
@@ -0,0 +1,48 @@
+require 'mail'
+
+class Channel::Sendmail
+ include UserInfo
+ def send(attr, channel, notification = false)
+ mail = Mail.new
+
+ # set organization
+ organization = Setting.get('organization')
+ if organization then;
+ mail['organization'] = organization.to_s
+ end
+
+ # notification
+ if notification
+ attr['X-Loop'] = 'yes'
+ attr['Precedence'] = 'bulk'
+ attr['Auto-Submitted'] = 'auto-generated'
+ end
+
+ # set headers
+ attr.each do |key, v|
+ if key.to_s != 'attachments' && key.to_s != 'body'
+ mail[key.to_s] = v.to_s
+ end
+ end
+
+ # add body
+ mail.text_part = Mail::Part.new do
+ body attr[:body]
+ end
+
+ # add attachments
+ if attr[:attachments]
+ attr[:attachments].each do |attachment|
+ mail.attachments[attachment.filename] = {
+ :content_type => attachment.preferences['Content-Type'],
+ :mime_type => attachment.preferences['Mime-Type'],
+ :content => attachment.store_file.data
+ }
+ end
+ end
+
+ mail.delivery_method :sendmail
+ mail.deliver
+
+ end
+end
\ No newline at end of file
diff --git a/app/models/channel/smtp.rb b/app/models/channel/smtp.rb
new file mode 100644
index 000000000..a38dd9c2b
--- /dev/null
+++ b/app/models/channel/smtp.rb
@@ -0,0 +1,58 @@
+require 'mail'
+
+class Channel::SMTP
+ include UserInfo
+ def send(attr, channel, notification = false)
+ mail = Mail.new
+
+ # set organization
+ organization = Setting.get('organization')
+ if organization then;
+ mail['organization'] = organization.to_s
+ end
+
+ # notification
+ if notification
+ attr['X-Loop'] = 'yes'
+ attr['Precedence'] = 'bulk'
+ attr['Auto-Submitted'] = 'auto-generated'
+ end
+
+ # set headers
+ attr.each do |key, v|
+ if key.to_s != 'attachments' && key.to_s != 'body'
+ mail[key.to_s] = v.to_s
+ end
+ end
+
+ # add body
+ mail.text_part = Mail::Part.new do
+ body attr[:body]
+ end
+
+ # add attachments
+ if attr[:attachments]
+ attr[:attachments].each do |attachment|
+ mail.attachments[attachment.filename] = {
+ :content_type => attachment.preferences['Content-Type'],
+ :mime_type => attachment.preferences['Mime-Type'],
+ :content => attachment.store_file.data
+ }
+ end
+ end
+
+ mail.delivery_method :smtp, {
+ :openssl_verify_mode => 'none',
+ :address => channel[:options][:host],
+ # :port => 587,
+ :port => 25,
+ :domain => channel[:options][:host],
+ :user_name => channel[:options][:user],
+ :password => channel[:options][:password],
+ # :authentication => 'plain',
+ :enable_starttls_auto => true
+ }
+ mail.deliver
+
+ end
+end
\ No newline at end of file
diff --git a/app/models/channel/twitter2.rb b/app/models/channel/twitter2.rb
index d1e565c36..90c93c710 100644
--- a/app/models/channel/twitter2.rb
+++ b/app/models/channel/twitter2.rb
@@ -1,4 +1,3 @@
-#require 'rubygems'
require 'twitter'
class Channel::Twitter2
@@ -37,6 +36,7 @@ class Channel::Twitter2
@article_type = 'twitter direct-message'
fetch_loop(tweets, account, account[:direct_messages][:group])
end
+ puts 'done'
end
def fetch_loop(tweets, account, group)
@@ -103,7 +103,6 @@ class Channel::Twitter2
# puts tweet.inspect
# user = User.where( :login => tweet.sender.screen_name ).first
auth = Authorization.where( :uid => sender.id, :provider => 'twitter' ).first
-# user = undef
user = nil
if auth
puts 'user_id', auth.user_id
diff --git a/app/models/setting.rb b/app/models/setting.rb
index 428a92a1b..f5eabb15b 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -1,17 +1,31 @@
class Setting < ActiveRecord::Base
- store :options
- store :state
- store :state_initial
+ store :options
+ store :state
+ store :state_initial
before_create :set_initial
@@config = nil
def self.load
+
+ # check if config is already generated
return @@config if @@config
+
+ # read all config settings
config = {}
Setting.select('name, state').order(:id).each { |setting|
config[setting.name] = setting.state[:value]
}
+
+ # config lookups
+ config.each { |key, value|
+ next if value.class.to_s != 'String'
+ config[key].gsub!( /\#\{config\.(.+?)\}/ ) { |s|
+ s = config[$1].to_s
+ }
+ }
+
+ # store for class requests
@@config = config
return config
end
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index f2e49b714..3e38ed8b0 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -158,7 +158,7 @@ class Ticket < ActiveRecord::Base
self.message_id = '<' + DateTime.current.to_s(:number) + '.' + self.ticket_id.to_s + '.' + rand(999999).to_s() + '@' + fqdn + '>'
# set sender
- self.from = Rails.application.config.email_sender
+ self.from = Setting.get('system_sender')
end
end
def attachment_check
@@ -235,8 +235,7 @@ class Ticket < ActiveRecord::Base
:subject => subject,
:body => self.body,
:attachments => self.attachments
- },
- Rails.application.config.channel_email
+ }
)
end
end
diff --git a/app/models/ticket/observer/notification.rb b/app/models/ticket/observer/notification.rb
index 2316a83a8..983a9f3f8 100644
--- a/app/models/ticket/observer/notification.rb
+++ b/app/models/ticket/observer/notification.rb
@@ -214,7 +214,6 @@ From: #{ticket.articles[-1].from}
:subject => subject,
:body => body,
},
- Rails.application.config.channel_email,
true
)
end
diff --git a/config/application.rb b/config/application.rb
index 4be60d160..0abdbc09b 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -24,6 +24,12 @@ module Zammad
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+ config.active_record.observers =
+ :history_observer,
+ 'ticket::_observer::_first_response',
+ 'ticket::_observer::_last_contact',
+ 'ticket::_observer::_close_time',
+ 'ticket::_observer::_notification'
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
diff --git a/config/routes.rb b/config/routes.rb
index f52c1dab2..be28d0af2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -21,10 +21,11 @@ Zammad::Application.routes.draw do
resources :notes
# tickets
- resources :ticket_articles, :only => [:create, :show, :index, :update]
- resources :ticket_priorities, :only => [:create, :show, :index, :update]
- resources :ticket_states, :only => [:create, :show, :index, :update]
- resources :tickets, :only => [:create, :show, :index, :update]
+ resources :channels, :only => [:create, :show, :index, :update, :destroy]
+ resources :ticket_articles, :only => [:create, :show, :index, :update]
+ resources :ticket_priorities, :only => [:create, :show, :index, :update]
+ resources :ticket_states, :only => [:create, :show, :index, :update]
+ resources :tickets, :only => [:create, :show, :index, :update]
match '/ticket_full/:id', :to => 'ticket_overviews#ticket_full'
match '/ticket_attachment/:id', :to => 'ticket_overviews#ticket_attachment'
match '/ticket_attachment_new', :to => 'ticket_overviews#ticket_attachment_new'
@@ -43,7 +44,7 @@ Zammad::Application.routes.draw do
match '/getting_started', :to => 'getting_started#index'
# sessions
- resources :sessions, :only => [:create, :destroy, :show]
+ resources :sessions, :only => [:create, :destroy, :show]
match '/signin', :to => 'sessions#create'
match '/signshow', :to => 'sessions#show'
match '/signout', :to => 'sessions#destroy'
diff --git a/db/migrate/20120101000070_create_channel.rb b/db/migrate/20120101000070_create_channel.rb
new file mode 100644
index 000000000..4d4c00477
--- /dev/null
+++ b/db/migrate/20120101000070_create_channel.rb
@@ -0,0 +1,21 @@
+class CreateChannel < ActiveRecord::Migration
+ def up
+
+ create_table :channels do |t|
+ t.references :group, :null => true
+ t.column :adapter, :string, :limit => 100, :null => false
+ t.column :area, :string, :limit => 100, :null => false
+ t.column :options, :string, :limit => 2000, :null => true
+ t.column :active, :boolean, :null => false, :default => true
+ t.column :created_by_id, :integer, :null => false
+ t.timestamps
+ end
+ add_index :channels, [:area]
+ add_index :channels, [:adapter]
+
+ end
+
+ def down
+ drop_table :channels
+ end
+end
diff --git a/db/seeds.rb b/db/seeds.rb
index dfc5244f2..c9294f032 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -627,7 +627,7 @@ Setting.create(
:value => {
:checksum => false,
:file => '/tmp/counter.log',
- :min_size => 4,
+ :min_size => 5,
},
},
:frontend => false
@@ -712,10 +712,130 @@ Setting.create(
:frontend => false
)
+Setting.create(
+ :title => 'Enable Ticket creation',
+ :name => 'customer_ticket_create',
+ :area => 'CustomerWeb::Base',
+ :description => 'Defines if a customer can create tickets via the web interface.',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => true,
+ :name => 'customer_ticket_create',
+ :tag => 'select',
+ :options => {
+ true => 'yes',
+ false => 'no',
+ },
+ },
+ ],
+ },
+ :state => {
+ :value => true,
+ },
+ :frontend => true
+)
+
+Setting.create(
+ :title => 'Enable Ticket View/Update',
+ :name => 'customer_ticket_view',
+ :area => 'CustomerWeb::Base',
+ :description => 'Defines if a customer view and update his own tickets.',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => true,
+ :name => 'customer_ticket_view',
+ :tag => 'select',
+ :options => {
+ true => 'yes',
+ false => 'no',
+ },
+ },
+ ],
+ },
+ :state => {
+ :value => true,
+ },
+ :frontend => true
+)
+
+Setting.create(
+ :title => 'Max. Email Size',
+ :name => 'postmaster_max_size',
+ :area => 'Email::Base',
+ :description => 'Maximal size in MB of emails.',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => true,
+ :name => 'postmaster_max_size',
+ :tag => 'select',
+ :options => {
+ 1 => 1,
+ 2 => 2,
+ 3 => 3,
+ 4 => 4,
+ 5 => 5,
+ 6 => 6,
+ 7 => 7,
+ 8 => 8,
+ 9 => 9,
+ 10 => 10,
+ 11 => 11,
+ 12 => 12,
+ 13 => 13,
+ 14 => 14,
+ 15 => 15,
+ 16 => 16,
+ 17 => 17,
+ 18 => 18,
+ 19 => 19,
+ 20 => 20,
+ },
+ },
+ ],
+ },
+ :state => {
+ :value => 10,
+ },
+ :frontend => false
+)
+
+Setting.create(
+ :title => 'Additional follow up detection',
+ :name => 'postmaster_follow_up_search_in',
+ :area => 'Email::Base',
+ :description => '"References" - Executes follow up checks on In-Reply-To or References headers for mails that don\'t have a ticket number in the subject. "Body" - Executes follow up mail body checks in mails that don\'t have a ticket number in the subject. "Attachment" - Executes follow up mail attachments checks in mails that don\'t have a ticket number in the subject. "Raw" - Executes follow up plain/raw mail checks in mails that don\'t have a ticket number in the subject.',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => true,
+ :name => 'postmaster_follow_up_search_in',
+ :tag => 'checkbox',
+ :options => {
+ 'references' => 'References',
+ 'body' => 'Body',
+ 'attachment' => 'Attachment',
+ 'raw' => 'Raw',
+ },
+ },
+ ],
+ },
+ :state => {
+ :value => ['subject'],
+ },
+ :frontend => false
+)
+
Setting.create(
:title => 'Notification Sender',
:name => 'notification_sender',
- :area => 'Ticket::Notification',
+ :area => 'Email::Base',
:description => 'Defines the sender of email notifications.',
:options => {
:form => [
@@ -728,11 +848,78 @@ Setting.create(
],
},
:state => {
- :value => 'Notify ',
+ :value => 'Notification Master ',
},
:frontend => false
)
+Setting.create(
+ :title => 'System Sender',
+ :name => 'system_sender',
+ :area => 'Email::Base',
+ :description => 'ONLY TEMP!',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => false,
+ :name => 'system_sender',
+ :tag => 'input',
+ },
+ ],
+ },
+ :state => {
+ :value => 'Zammad Team ',
+ },
+ :frontend => false
+)
+Setting.create(
+ :title => 'Block Notifications',
+ :name => 'send_no_auto_response_reg_exp',
+ :area => 'Email::Base',
+ :description => 'If this regex matches, no notification will be send by the sender.',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => false,
+ :name => 'send_no_auto_response_reg_exp',
+ :tag => 'input',
+ },
+ ],
+ },
+ :state => {
+ :value => '(MAILER-DAEMON|postmaster|abuse)@.+?\..+?',
+ },
+ :frontend => false
+)
+
+Setting.create(
+ :title => 'Enable Chat',
+ :name => 'chat',
+ :area => 'Chat::Base',
+ :description => 'Enable/Disable online chat.',
+ :options => {
+ :form => [
+ {
+ :display => '',
+ :null => true,
+ :name => 'chat',
+ :tag => 'select',
+ :options => {
+ true => 'yes',
+ false => 'no',
+ },
+ },
+ ],
+ },
+ :state => {
+ :value => false,
+ },
+ :frontend => true
+)
+
+
Role.create(
:id => 1,
:name => 'Admin',
@@ -818,56 +1005,35 @@ Ticket::Article::Sender.create( :name => 'Agent' )
Ticket::Article::Sender.create( :name => 'Customer' )
Ticket::Article::Sender.create( :name => 'System' )
-for i in (1..10)
- next
- ticket = Ticket.create(
-# :number => '1314' + i.to_s,
- :group_id => Group.where(:name => 'Users' ).first.id,
- :customer_id => User.where(:login => '-').first.id,
- :title => 'printer isn\'t working...',
- :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
- :ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
- :created_by_id => User.where(:login => '-').first.id
- )
- Ticket::Article.create(
- :created_by_id => User.where(:login => '-').first.id,
- :ticket_id => ticket.id,
- :ticket_article_type_id => Ticket::Article::Type.where(:name => 'email').first.id,
- :ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Agent').first.id,
- :body => 'Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
- :from => 'Some Agent ',
- :internal => false
- )
- Ticket::Article.create(
- :created_by_id => User.where(:login => '-').first.id,
- :ticket_id => ticket.id,
- :ticket_article_type_id => Ticket::Article::Type.where(:name => 'email').first.id,
- :ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Customer').first.id,
- :body => 'Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.',
- :from => 'Some Customer ',
- :internal => false
- )
-end
+ticket = Ticket.create(
+ :group_id => Group.where( :name => 'Users' ).first.id,
+ :customer_id => User.where( :login => '-' ).first.id,
+ :owner_id => User.where( :login => '-' ).first.id,
+ :title => 'Welcome to Zammad!',
+ :ticket_state_id => Ticket::State.where( :name => 'new' ).first.id,
+ :ticket_priority_id => Ticket::Priority.where( :name => '2 normal' ).first.id,
+ :created_by_id => User.where( :login => '-' ).first.id
+)
+Ticket::Article.create(
+ :created_by_id => User.where(:login => '-').first.id,
+ :ticket_id => ticket.id,
+ :ticket_article_type_id => Ticket::Article::Type.where(:name => 'email' ).first.id,
+ :ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Customer' ).first.id,
+ :from => 'Zammad Feedback ',
+ :body => 'Welcome!
-#Ticket.create(
-# :number => '1315',
-# :group_id => Group.where(:name => 'Users' ).first.id,
-# :customer_id => User.where(:login => '-').first.id,
-# :title => 'iphone isn\'t working...',
-# :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
-# :ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
-# :created_by_id => User.where(:login => '-').first.id
-#)
+Thank you for installing Zammad.
-#Ticket.create(
-# :number => '1316',
-# :group_id => Group.where(:name => 'Users' ).first.id,
-# :customer_id => User.where(:login => '-').first.id,
-# :title => 'android isn\'t working...',
-# :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
-# :ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
-# :created_by_id => User.where(:login => '-').first.id
-#)
+You will find updates and patches at http://zammad.org/. Online
+documentation is available at http://guides.zammad.org/. You can also
+use our forums at http://forums.zammad.org/
+
+Regards,
+
+The Zammad.org Project
+',
+ :internal => false
+)
Overview.create(
:name => 'my_assigned',
@@ -1058,6 +1224,74 @@ Overview.create(
}
)
+Channel.create(
+ :adapter => 'IMAP',
+ :area => 'Email::Inbound',
+ :options => {
+ :host => 'edenhofer.de',
+ :user => 'mebox',
+ :password => '123',
+ :ssl => true,
+ },
+ :active => true,
+ :created_by_id => User.where( :login => '-' ).first.id
+)
+
+
+Channel.create(
+ :adapter => 'SMTP',
+ :area => 'Email::Outbound',
+ :options => {
+ :host => 'edenhofer.de',
+ :user => 'me-box',
+ :password => 'BidZ&2#.z',
+ :ssl => true,
+ },
+ :group_id => 1,
+ :active => false,
+ :created_by_id => User.where( :login => '-' ).first.id
+)
+Channel.create(
+ :adapter => 'Sendmail',
+ :area => 'Email::Outbound',
+ :options => {},
+ :active => false,
+ :created_by_id => User.where( :login => '-' ).first.id
+)
+
+Channel.create(
+ :adapter => 'Twitter2',
+ :area => 'Twitter',
+ :options => {
+ :consumer_key => 'PJ4c3dYYRtSZZZdOKo8ow',
+ :consumer_secret => 'ggAdnJE2Al1Vv0cwwvX5bdvKOieFs0vjCIh5M8Dxk',
+ :oauth_token => '293437546-xxRa9g74CercnU5AvY1uQwLLGIYrV1ezYtpX8oKW',
+ :oauth_token_secret => 'ju0E4l9OdY2Lh1iTKMymAu6XVfOaU2oGxmcbIMRZQK4',
+ :search => [
+ {
+ :item => '#otrs',
+ :group => 'Twitter',
+ },
+ {
+ :item => '#zombie42',
+ :group => 'Twitter',
+ },
+ {
+ :item => '#otterhub',
+ :group => 'Twitter',
+ },
+ ],
+ :mentions => {
+ :group => 'Twitter',
+ },
+ :direct_messages => {
+ :group => 'Twitter',
+ }
+ },
+ :active => true,
+ :created_by_id => User.where( :login => '-' ).first.id
+)
+
network = Network.create(
:name => 'base'
)
@@ -1066,96 +1300,96 @@ Network::Category::Type.create(
:name => 'Announcement'
)
Network::Category::Type.create(
- :name => 'Idea'
+ :name => 'Idea'
)
Network::Category::Type.create(
- :name => 'Question'
+ :name => 'Question'
)
Network::Category::Type.create(
- :name => 'Bug Report'
+ :name => 'Bug Report'
)
Network::Privacy.create(
- :name => 'logged in',
- :key => 'loggedIn'
+ :name => 'logged in',
+ :key => 'loggedIn'
)
Network::Privacy.create(
- :name => 'logged in and moderator',
- :key => 'loggedInModerator'
+ :name => 'logged in and moderator',
+ :key => 'loggedInModerator'
)
Network::Category.create(
- :name => 'Announcements',
+ :name => 'Announcements',
:network_id => network.id,
- :allow_comments => true,
+ :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Announcement').first.id,
:network_privacy_id => Network::Privacy.where(:name => 'logged in and moderator').first.id,
- :allow_comments => true
+ :allow_comments => true
)
Network::Category.create(
- :name => 'Questions',
+ :name => 'Questions',
:network_id => network.id,
- :allow_comments => true,
- :network_category_type_id => Network::Category::Type.where(:name => 'Question').first.id,
- :network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id
+ :allow_comments => true,
+ :network_category_type_id => Network::Category::Type.where(:name => 'Question').first.id,
+ :network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id
# :network_categories_moderator_user_ids => User.where(:login => '-').first.id
)
Network::Category.create(
- :name => 'Ideas',
+ :name => 'Ideas',
:network_id => network.id,
- :allow_comments => true,
+ :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Idea').first.id,
:network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id,
- :allow_comments => true
+ :allow_comments => true
)
Network::Category.create(
- :name => 'Bug Reports',
+ :name => 'Bug Reports',
:network_id => network.id,
- :allow_comments => true,
+ :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Bug Report').first.id,
:network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id,
- :allow_comments => true
+ :allow_comments => true
)
item = Network::Item.create(
- :title => 'Example Announcement',
- :body => 'Some announcement....',
- :network_category_id => Network::Category.where(:name => 'Announcements').first.id,
- :created_by_id => User.where(:login => '-').first.id
+ :title => 'Example Announcement',
+ :body => 'Some announcement....',
+ :network_category_id => Network::Category.where(:name => 'Announcements').first.id,
+ :created_by_id => User.where(:login => '-').first.id
)
Network::Item::Comment.create(
:network_item_id => item.id,
- :body => 'Some comment....',
- :created_by_id => User.where(:login => '-').first.id
+ :body => 'Some comment....',
+ :created_by_id => User.where(:login => '-').first.id
)
item = Network::Item.create(
- :title => 'Example Question?',
- :body => 'Some questions....',
- :network_category_id => Network::Category.where(:name => 'Questions').first.id,
- :created_by_id => User.where(:login => '-').first.id
+ :title => 'Example Question?',
+ :body => 'Some questions....',
+ :network_category_id => Network::Category.where(:name => 'Questions').first.id,
+ :created_by_id => User.where(:login => '-').first.id
)
Network::Item::Comment.create(
:network_item_id => item.id,
- :body => 'Some comment....',
- :created_by_id => User.where(:login => '-').first.id
+ :body => 'Some comment....',
+ :created_by_id => User.where(:login => '-').first.id
)
item = Network::Item.create(
- :title => 'Example Idea',
- :body => 'Some idea....',
- :network_category_id => Network::Category.where(:name => 'Ideas').first.id,
- :created_by_id => User.where(:login => '-').first.id
+ :title => 'Example Idea',
+ :body => 'Some idea....',
+ :network_category_id => Network::Category.where(:name => 'Ideas').first.id,
+ :created_by_id => User.where(:login => '-').first.id
)
Network::Item::Comment.create(
:network_item_id => item.id,
- :body => 'Some comment....',
- :created_by_id => User.where(:login => '-').first.id
+ :body => 'Some comment....',
+ :created_by_id => User.where(:login => '-').first.id
)
item = Network::Item.create(
- :title => 'Example Bug Report',
- :body => 'Some bug....',
- :network_category_id => Network::Category.where(:name => 'Bug Reports').first.id,
- :created_by_id => User.where(:login => '-').first.id
+ :title => 'Example Bug Report',
+ :body => 'Some bug....',
+ :network_category_id => Network::Category.where(:name => 'Bug Reports').first.id,
+ :created_by_id => User.where(:login => '-').first.id
)
Network::Item::Comment.create(
:network_item_id => item.id,
- :body => 'Some comment....',
- :created_by_id => User.where(:login => '-').first.id
+ :body => 'Some comment....',
+ :created_by_id => User.where(:login => '-').first.id
)