Added first user also to all groups (master agent).

This commit is contained in:
Martin Edenhofer 2012-04-13 15:51:10 +02:00
parent f1c934caa4
commit 2c325454a1
22 changed files with 793 additions and 320 deletions

View file

@ -1,17 +1,24 @@
$ = jQuery.sub() $ = jQuery.sub()
$.fn.item = (genericObject) ->
elementID = $(@).data('id')
elementID or= $(@).parents('[data-id]').data('id')
genericObject.find(elementID)
class App.ChannelEmail extends App.ControllerTabs class App.ChannelEmail extends App.ControllerTabs
constructor: -> constructor: ->
super super
@tabs = [ @tabs = [
{ {
name: 'Inbound', name: 'Inbound',
target: 'c-inbound', target: 'c-inbound',
controller: App.ChannelEmailInbound,
}, },
{ {
name: 'Outbound', name: 'Outbound',
target: 'c-outbound', target: 'c-outbound',
controller: App.ChannelEmailOutbound,
}, },
{ {
name: 'Adresses', name: 'Adresses',
@ -28,84 +35,197 @@ class App.ChannelEmail extends App.ControllerTabs
}, },
] ]
# App.Channel.bind 'refresh change', @render
# App.Channel.fetch()
@render() @render()
render2: => class App.ChannelEmailInboundEdit extends App.ControllerModal
settings = App.Setting.all() 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 = $('<div></div>') # show errors in form
for setting in settings if errors
if setting.area is @area @log 'error new', errors
item = new App.SettingsAreaItem( setting: setting ) @validateForm( form: e.target, errors: errors )
html.append( item.el ) return false
@html html # save object
object.save(
success: =>
@modalHide()
error: =>
@log 'errors'
@modalHide()
)
class App.ChannelEmailInbound extends App.Controller
class App.SettingsAreaItem2 extends App.Controller
events: events:
'submit form': 'update', 'click [data-type=new]': 'new'
'click [data-type=edit]': 'edit'
constructor: -> constructor: ->
super super
@render()
App.Channel.bind 'refresh change', @render
App.Channel.fetch()
render: => render: =>
# defaults channels = App.Channel.all()
for item in @setting.options['form']
if typeof @setting.state.value is 'object' html = $('<div></div>')
item['default'] = @setting.state.value[item.name] data = []
else for channel in channels
item['default'] = @setting.state.value if channel.area is 'Email::Inbound'
channel.host = channel.options['host']
channel.user = channel.options['user']
data.push channel
# form table = @table(
@configure_attributes = @setting.options['form'] overview: ['host', 'user', 'adapter', 'active'],
form = @formGen( model: { configure_attributes: @configure_attributes, className: '' }, autofocus: false ) model: App.Channel,
objects: data,
)
# item html.append( table )
@html App.view('settings/item')( html.append( '<a data-type="new" class="btn">new account</a>' )
setting: @setting, @html html
form: form,
) 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) => update: (e) =>
e.preventDefault() e.preventDefault()
params = @formParam(e.target) params = @formParam(e.target)
@log 'submit', @setting, params, e.target channels = App.Channel.all()
if typeof @setting.state.value is 'object' for channel in channels
state = { if channel.area is 'Email::Outbound' && channel.adapter is params['adapter']
value: params channel.updateAttributes(
} options: {
else host: params['host'],
state = { user: params['user'],
value: params[@setting.name] password: params['password'],
} ssl: params['ssl'],
},
active: true,
)
@setting['state'] = state # set all other to inactive
@setting.save( channels = App.Channel.all()
success: => for channel in channels
if channel.area is 'Email::Outbound' && channel.adapter isnt params['adapter']
channel.updateAttributes( active: false )
# login check # rerender
auth = new App.Auth
auth.loginCheck()
)
class App.ChannelEmail2 extends App.Controller
events:
'click [data-toggle="tabnav"]': 'toggle',
constructor: ->
super
# render page
@render() @render()
render: ->
@html App.view('channel/email')(
head: 'some header'
)

View file

@ -1,14 +1,15 @@
$ = jQuery.sub() $ = jQuery.sub()
class Index extends App.ControllerLevel2 class Index extends App.ControllerLevel2
toggleable: true # toggleable: true
toggleable: false
menu: [ menu: [
{ name: 'Web', 'target': 'web', controller: App.ChannelWeb }, { name: 'Web', target: 'web', controller: App.ChannelWeb },
{ name: 'Mail', 'target': 'email', controller: App.ChannelEmail }, { name: 'Mail', target: 'email', controller: App.ChannelEmail },
{ name: 'Chat', 'target': 'chat', controller: App.ChannelChat }, { name: 'Chat', target: 'chat', controller: App.ChannelChat },
{ name: 'Twitter', 'target': 'twitter', controller: App.ChannelTwitter }, { name: 'Twitter', target: 'twitter', controller: App.ChannelTwitter },
{ name: 'Facebook', 'target': 'facebook', controller: App.ChannelFacebook }, { name: 'Facebook', target: 'facebook', controller: App.ChannelFacebook },
] ]
page: { page: {
title: 'Channels', title: 'Channels',
@ -24,5 +25,6 @@ class Index extends App.ControllerLevel2
# render page # render page
@render() @render()
Config.Routes['channels/:target'] = Index
Config.Routes['channels'] = Index Config.Routes['channels'] = Index

View file

@ -2,7 +2,7 @@ $ = jQuery.sub()
class Index extends App.ControllerLevel2 class Index extends App.ControllerLevel2
toggleable: false toggleable: false
toggleable: true # toggleable: true
constructor: -> constructor: ->
super super

View file

@ -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' },
]

View file

@ -1,72 +0,0 @@
<div class="tab-pane active" id="channel-inbound">
<table class="table table-striped">
<tr>
<th>Host</th>
<th>User</th>
<th>Type</th>
<th>Active</th>
<th>Delete</th>
</tr>
<tr>
<td>lalal.example.com</td>
<td>wpt234rwr</td>
<td>IMAP</td>
<td>true</td>
<td>x</td>
</tr>
<tr>
<td>l31alal.example.com</td>
<td>wpt23dd4rwr</td>
<td>POP3</td>
<td>true</td>
<td>x</td>
</tr>
</table>
</div>
<div class="tab-pane" id="channel-outbound">
<table class="table table-striped">
<tr>
<th>Host</th>
<th>User</th>
<th>Type</th>
<th>Active</th>
<th>Delete</th>
</tr>
<tr>
<td>lalal.example.com</td>
<td>wpt234rwr</td>
<td>SMTP</td>
<td>true</td>
<td>x</td>
</tr>
<tr>
<td>l31alal.example.com</td>
<td>wpt23dd4rwr</td>
<td>Sendmail</td>
<td>true</td>
<td>x</td>
</tr>
</table>
</div>
<div class="tab-pane" id="channel-filter">
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Active</th>
<th>Delete</th>
</tr>
<tr>
<td>lalal.example.com</td>
<td>true</td>
<td>x</td>
</tr>
<tr>
<td>wpt23dd4rwr</td>
<td>true</td>
<td>x</td>
</tr>
</table>
</div>

View file

@ -0,0 +1,5 @@
<form id="mail_adapter">
<%- @form_adapter %>
<%- @form_adapter_settings %>
<button data-type="" type="submit" class="btn">submit</botton>
</form>

View file

@ -3,6 +3,7 @@
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id=""> <div class="tab-pane active" id="">
<table class="table table-striped"> <table class="table table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
@ -20,5 +21,6 @@
<td>x</td> <td>x</td>
</tr> </tr>
</table> </table>
</div> </div>
</div> </div>

View file

@ -130,8 +130,8 @@ class ApplicationController < ActionController::Base
# config # config
config = {} config = {}
Setting.where( :frontend => true ).each { |setting| Setting.select('name').where( :frontend => true ).each { |setting|
config[setting.name] = setting.state[:value] config[setting.name] = Setting.get(setting.name)
} }
return config return config
end end

View file

@ -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

View file

@ -37,15 +37,25 @@ class UsersController < ApplicationController
if @user.created_by_id == 1 if @user.created_by_id == 1
# check if it's first user # check if it's first user
count = User.all.count() count = User.all.count()
role_ids = [] group_ids = []
role_ids = []
# add first user as admin/agent and to all groups
if count <= 2 if count <= 2
role_ids.push Role.where( :name => 'Admin' ).first.id Role.where( :name => [ 'Admin', 'Agent'] ).each { |role|
role_ids.push Role.where( :name => 'Agent' ).first.id role_ids.push role.id
}
Group.all().each { |group|
group_ids.push group.id
}
# everybody else will go as customer per default
else else
role_ids.push Role.where( :name => 'Customer' ).first.id role_ids.push Role.where( :name => 'Customer' ).first.id
end end
@user.role_ids = role_ids @user.role_ids = role_ids
@user.group_ids = group_ids
# else do assignment as defined # else do assignment as defined
else else

View file

@ -1,11 +1,19 @@
class Channel < ActiveRecord::Base class Channel < ActiveRecord::Base
store :options
def self.send2
# find outbound
end
def self.fetch def self.fetch
Rails.application.config.channel.each { |channel| channels = Channel.where( 'active = ? AND area LIKE ?', true, '%::Inbound' )
channels.each { |channel|
begin begin
c = eval channel[:module] + '.new' c = eval 'Channel::' + channel[:adapter] + '.new'
c.fetch(channel) c.fetch(channel)
rescue Exception => e rescue Exception => e
puts "can't use " + channel[:module] puts "can't use " + 'Channel::' + channel[:adapter]
puts e.inspect puts e.inspect
end end
} }

View file

@ -4,12 +4,11 @@ require 'net/imap'
class Channel::IMAP class Channel::IMAP
include UserInfo include UserInfo
# def fetch(:oauth_token, :oauth_token_secret)
def fetch (account) def fetch (account)
puts 'fetching imap' puts 'fetching imap'
imap = Net::IMAP.new(account[:host], 993, true ) imap = Net::IMAP.new(account[:options][:host], 993, true )
imap.authenticate('LOGIN', account[:user], account[:pw]) imap.authenticate('LOGIN', account[:options][:user], account[:options][:password])
imap.select('INBOX') imap.select('INBOX')
imap.search(['ALL']).each do |message_id| imap.search(['ALL']).each do |message_id|
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822'] msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
@ -50,7 +49,7 @@ class Channel::IMAP
end end
# get ticket# from subject # 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 # set ticket state to open if not new
if ticket if ticket
@ -65,7 +64,7 @@ class Channel::IMAP
# create new ticket # create new ticket
if !ticket then if !ticket then
ticket = Ticket.create( ticket = Ticket.create(
:group_id => Group.where( :name => account[:group] ).first.id, :group_id => account[:group_id],
:customer_id => user.id, :customer_id => user.id,
:title => conv(mail['subject'].charset || 'LATIN1', mail['subject'].to_s), :title => conv(mail['subject'].charset || 'LATIN1', mail['subject'].to_s),
:ticket_state_id => Ticket::State.where(:name => 'new').first.id, :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
@ -143,59 +142,16 @@ class Channel::IMAP
end end
imap.expunge() imap.expunge()
imap.disconnect() imap.disconnect()
puts 'done'
end end
def send(attr, account, notification = false) def send(attr, notification = false)
mail = Mail.new channel = Channel.where( :area => 'Email::Outbound', :active => true ).first
begin
# set organization c = eval 'Channel::' + channel[:adapter] + '.new'
organization = Setting.get('organization') c.send(attr, channel, notification)
if organization then; rescue Exception => e
mail['organization'] = organization.to_s puts "can't use " + 'Channel::' + channel[:adapter]
puts e.inspect
end 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
end end

View file

@ -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

View file

@ -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

View file

@ -1,4 +1,3 @@
#require 'rubygems'
require 'twitter' require 'twitter'
class Channel::Twitter2 class Channel::Twitter2
@ -37,6 +36,7 @@ class Channel::Twitter2
@article_type = 'twitter direct-message' @article_type = 'twitter direct-message'
fetch_loop(tweets, account, account[:direct_messages][:group]) fetch_loop(tweets, account, account[:direct_messages][:group])
end end
puts 'done'
end end
def fetch_loop(tweets, account, group) def fetch_loop(tweets, account, group)
@ -103,7 +103,6 @@ class Channel::Twitter2
# puts tweet.inspect # puts tweet.inspect
# user = User.where( :login => tweet.sender.screen_name ).first # user = User.where( :login => tweet.sender.screen_name ).first
auth = Authorization.where( :uid => sender.id, :provider => 'twitter' ).first auth = Authorization.where( :uid => sender.id, :provider => 'twitter' ).first
# user = undef
user = nil user = nil
if auth if auth
puts 'user_id', auth.user_id puts 'user_id', auth.user_id

View file

@ -1,17 +1,31 @@
class Setting < ActiveRecord::Base class Setting < ActiveRecord::Base
store :options store :options
store :state store :state
store :state_initial store :state_initial
before_create :set_initial before_create :set_initial
@@config = nil @@config = nil
def self.load def self.load
# check if config is already generated
return @@config if @@config return @@config if @@config
# read all config settings
config = {} config = {}
Setting.select('name, state').order(:id).each { |setting| Setting.select('name, state').order(:id).each { |setting|
config[setting.name] = setting.state[:value] 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 @@config = config
return config return config
end end

View file

@ -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 + '>' self.message_id = '<' + DateTime.current.to_s(:number) + '.' + self.ticket_id.to_s + '.' + rand(999999).to_s() + '@' + fqdn + '>'
# set sender # set sender
self.from = Rails.application.config.email_sender self.from = Setting.get('system_sender')
end end
end end
def attachment_check def attachment_check
@ -235,8 +235,7 @@ class Ticket < ActiveRecord::Base
:subject => subject, :subject => subject,
:body => self.body, :body => self.body,
:attachments => self.attachments :attachments => self.attachments
}, }
Rails.application.config.channel_email
) )
end end
end end

View file

@ -214,7 +214,6 @@ From: #{ticket.articles[-1].from}
:subject => subject, :subject => subject,
:body => body, :body => body,
}, },
Rails.application.config.channel_email,
true true
) )
end end

View file

@ -24,6 +24,12 @@ module Zammad
# Activate observers that should always be running. # Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer # 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. # 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. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.

View file

@ -21,10 +21,11 @@ Zammad::Application.routes.draw do
resources :notes resources :notes
# tickets # tickets
resources :ticket_articles, :only => [:create, :show, :index, :update] resources :channels, :only => [:create, :show, :index, :update, :destroy]
resources :ticket_priorities, :only => [:create, :show, :index, :update] resources :ticket_articles, :only => [:create, :show, :index, :update]
resources :ticket_states, :only => [:create, :show, :index, :update] resources :ticket_priorities, :only => [:create, :show, :index, :update]
resources :tickets, :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_full/:id', :to => 'ticket_overviews#ticket_full'
match '/ticket_attachment/:id', :to => 'ticket_overviews#ticket_attachment' match '/ticket_attachment/:id', :to => 'ticket_overviews#ticket_attachment'
match '/ticket_attachment_new', :to => 'ticket_overviews#ticket_attachment_new' 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' match '/getting_started', :to => 'getting_started#index'
# sessions # sessions
resources :sessions, :only => [:create, :destroy, :show] resources :sessions, :only => [:create, :destroy, :show]
match '/signin', :to => 'sessions#create' match '/signin', :to => 'sessions#create'
match '/signshow', :to => 'sessions#show' match '/signshow', :to => 'sessions#show'
match '/signout', :to => 'sessions#destroy' match '/signout', :to => 'sessions#destroy'

View file

@ -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

View file

@ -627,7 +627,7 @@ Setting.create(
:value => { :value => {
:checksum => false, :checksum => false,
:file => '/tmp/counter.log', :file => '/tmp/counter.log',
:min_size => 4, :min_size => 5,
}, },
}, },
:frontend => false :frontend => false
@ -712,10 +712,130 @@ Setting.create(
:frontend => false :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( Setting.create(
:title => 'Notification Sender', :title => 'Notification Sender',
:name => 'notification_sender', :name => 'notification_sender',
:area => 'Ticket::Notification', :area => 'Email::Base',
:description => 'Defines the sender of email notifications.', :description => 'Defines the sender of email notifications.',
:options => { :options => {
:form => [ :form => [
@ -728,11 +848,78 @@ Setting.create(
], ],
}, },
:state => { :state => {
:value => 'Notify <noreply@znuny.com>', :value => 'Notification Master <noreply@#{config.fqdn}>',
}, },
:frontend => false :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 <zammad@#{config.fqdn}>',
},
: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( Role.create(
:id => 1, :id => 1,
:name => 'Admin', :name => 'Admin',
@ -818,56 +1005,35 @@ Ticket::Article::Sender.create( :name => 'Agent' )
Ticket::Article::Sender.create( :name => 'Customer' ) Ticket::Article::Sender.create( :name => 'Customer' )
Ticket::Article::Sender.create( :name => 'System' ) Ticket::Article::Sender.create( :name => 'System' )
for i in (1..10) ticket = Ticket.create(
next :group_id => Group.where( :name => 'Users' ).first.id,
ticket = Ticket.create( :customer_id => User.where( :login => '-' ).first.id,
# :number => '1314' + i.to_s, :owner_id => User.where( :login => '-' ).first.id,
:group_id => Group.where(:name => 'Users' ).first.id, :title => 'Welcome to Zammad!',
:customer_id => User.where(:login => '-').first.id, :ticket_state_id => Ticket::State.where( :name => 'new' ).first.id,
:title => 'printer isn\'t working...', :ticket_priority_id => Ticket::Priority.where( :name => '2 normal' ).first.id,
:ticket_state_id => Ticket::State.where(:name => 'new').first.id, :created_by_id => User.where( :login => '-' ).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::Article.create( :ticket_id => ticket.id,
:created_by_id => User.where(:login => '-').first.id, :ticket_article_type_id => Ticket::Article::Type.where(:name => 'email' ).first.id,
:ticket_id => ticket.id, :ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Customer' ).first.id,
:ticket_article_type_id => Ticket::Article::Type.where(:name => 'email').first.id, :from => 'Zammad Feedback <feedback@zammad.org>',
:ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Agent').first.id, :body => 'Welcome!
: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 <agent@localhost>',
: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 <customer@localhost>',
:internal => false
)
end
#Ticket.create( Thank you for installing Zammad.
# :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
#)
#Ticket.create( You will find updates and patches at http://zammad.org/. Online
# :number => '1316', documentation is available at http://guides.zammad.org/. You can also
# :group_id => Group.where(:name => 'Users' ).first.id, use our forums at http://forums.zammad.org/
# :customer_id => User.where(:login => '-').first.id,
# :title => 'android isn\'t working...', Regards,
# :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
# :ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id, The Zammad.org Project
# :created_by_id => User.where(:login => '-').first.id ',
#) :internal => false
)
Overview.create( Overview.create(
:name => 'my_assigned', :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( network = Network.create(
:name => 'base' :name => 'base'
) )
@ -1066,96 +1300,96 @@ Network::Category::Type.create(
:name => 'Announcement' :name => 'Announcement'
) )
Network::Category::Type.create( Network::Category::Type.create(
:name => 'Idea' :name => 'Idea'
) )
Network::Category::Type.create( Network::Category::Type.create(
:name => 'Question' :name => 'Question'
) )
Network::Category::Type.create( Network::Category::Type.create(
:name => 'Bug Report' :name => 'Bug Report'
) )
Network::Privacy.create( Network::Privacy.create(
:name => 'logged in', :name => 'logged in',
:key => 'loggedIn' :key => 'loggedIn'
) )
Network::Privacy.create( Network::Privacy.create(
:name => 'logged in and moderator', :name => 'logged in and moderator',
:key => 'loggedInModerator' :key => 'loggedInModerator'
) )
Network::Category.create( Network::Category.create(
:name => 'Announcements', :name => 'Announcements',
:network_id => network.id, :network_id => network.id,
:allow_comments => true, :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Announcement').first.id, :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, :network_privacy_id => Network::Privacy.where(:name => 'logged in and moderator').first.id,
:allow_comments => true :allow_comments => true
) )
Network::Category.create( Network::Category.create(
:name => 'Questions', :name => 'Questions',
:network_id => network.id, :network_id => network.id,
:allow_comments => true, :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Question').first.id, :network_category_type_id => Network::Category::Type.where(:name => 'Question').first.id,
:network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id :network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id
# :network_categories_moderator_user_ids => User.where(:login => '-').first.id # :network_categories_moderator_user_ids => User.where(:login => '-').first.id
) )
Network::Category.create( Network::Category.create(
:name => 'Ideas', :name => 'Ideas',
:network_id => network.id, :network_id => network.id,
:allow_comments => true, :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Idea').first.id, :network_category_type_id => Network::Category::Type.where(:name => 'Idea').first.id,
:network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id, :network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id,
:allow_comments => true :allow_comments => true
) )
Network::Category.create( Network::Category.create(
:name => 'Bug Reports', :name => 'Bug Reports',
:network_id => network.id, :network_id => network.id,
:allow_comments => true, :allow_comments => true,
:network_category_type_id => Network::Category::Type.where(:name => 'Bug Report').first.id, :network_category_type_id => Network::Category::Type.where(:name => 'Bug Report').first.id,
:network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id, :network_privacy_id => Network::Privacy.where(:name => 'logged in').first.id,
:allow_comments => true :allow_comments => true
) )
item = Network::Item.create( item = Network::Item.create(
:title => 'Example Announcement', :title => 'Example Announcement',
:body => 'Some announcement....', :body => 'Some announcement....',
:network_category_id => Network::Category.where(:name => 'Announcements').first.id, :network_category_id => Network::Category.where(:name => 'Announcements').first.id,
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
Network::Item::Comment.create( Network::Item::Comment.create(
:network_item_id => item.id, :network_item_id => item.id,
:body => 'Some comment....', :body => 'Some comment....',
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
item = Network::Item.create( item = Network::Item.create(
:title => 'Example Question?', :title => 'Example Question?',
:body => 'Some questions....', :body => 'Some questions....',
:network_category_id => Network::Category.where(:name => 'Questions').first.id, :network_category_id => Network::Category.where(:name => 'Questions').first.id,
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
Network::Item::Comment.create( Network::Item::Comment.create(
:network_item_id => item.id, :network_item_id => item.id,
:body => 'Some comment....', :body => 'Some comment....',
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
item = Network::Item.create( item = Network::Item.create(
:title => 'Example Idea', :title => 'Example Idea',
:body => 'Some idea....', :body => 'Some idea....',
:network_category_id => Network::Category.where(:name => 'Ideas').first.id, :network_category_id => Network::Category.where(:name => 'Ideas').first.id,
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
Network::Item::Comment.create( Network::Item::Comment.create(
:network_item_id => item.id, :network_item_id => item.id,
:body => 'Some comment....', :body => 'Some comment....',
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
item = Network::Item.create( item = Network::Item.create(
:title => 'Example Bug Report', :title => 'Example Bug Report',
:body => 'Some bug....', :body => 'Some bug....',
:network_category_id => Network::Category.where(:name => 'Bug Reports').first.id, :network_category_id => Network::Category.where(:name => 'Bug Reports').first.id,
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )
Network::Item::Comment.create( Network::Item::Comment.create(
:network_item_id => item.id, :network_item_id => item.id,
:body => 'Some comment....', :body => 'Some comment....',
:created_by_id => User.where(:login => '-').first.id :created_by_id => User.where(:login => '-').first.id
) )