diff options
Diffstat (limited to 'app')
67 files changed, 1450 insertions, 368 deletions
diff --git a/app/controllers/api/v1/calls_controller.rb b/app/controllers/api/v1/calls_controller.rb new file mode 100644 index 0000000..329bd94 --- /dev/null +++ b/app/controllers/api/v1/calls_controller.rb @@ -0,0 +1,41 @@ +module Api + module V1 + class CallsController < ApplicationController + respond_to :json + + def index + @calls = Call.limit(10) + + respond_with @calls + end + + def show + @call = Call.find(params[:id]) + + if params[:transfer_blind] + @call.transfer_blind(params[:transfer_blind]) + else + if params[:transfer_attended] && @call.b_sip_account.phones.first.phone_model.manufacturer.name == 'SNOM Technology AG' + phone = @call.b_sip_account.phones.first + ip_address = phone.ip_address + http_user = phone.http_user + http_password = phone.http_password + + # Hold + open("http://#{ip_address}/command.htm?key=F_HOLD", :http_basic_authentication=>[http_user, http_password]) + + # Call the other party + (0..(params[:transfer_attended].length - 1)).each do |i| + digit = params[:transfer_attended][i] + open("http://#{ip_address}/command.htm?key=#{digit}", :http_basic_authentication=>[http_user, http_password]) + end + open("http://#{ip_address}/command.htm?key=ENTER", :http_basic_authentication=>[http_user, http_password]) + end + end + + respond_with @call + end + + end + end +end diff --git a/app/controllers/api/v1/phone_book_entries_controller.rb b/app/controllers/api/v1/phone_book_entries_controller.rb new file mode 100644 index 0000000..6a39623 --- /dev/null +++ b/app/controllers/api/v1/phone_book_entries_controller.rb @@ -0,0 +1,77 @@ +module Api + module V1 + class PhoneBookEntriesController < ApplicationController + respond_to :json + + def index + query = params[:query] + switchboard = Switchboard.find(params[:switchboard_id]) + + return nil if query.blank? + + current_ability = Ability.new(current_user) + phone_book_entries = PhoneBookEntry.accessible_by(current_ability) + + if query.match(/^\+?\d+$/) != nil && switchboard && switchboard.reverse_lookup_activated + # Find by phone number + phone_book_entries_ids = phone_book_entries.map{|entry| entry.id} + found_phone_numbers = PhoneNumber. + where(:phone_numberable_type => 'PhoneBookEntry', :phone_numberable_id => phone_book_entries_ids). + where('number LIKE ?', "#{query}%") + search_result = phone_book_entries.where(:id => found_phone_numbers.map{|entry| entry.phone_numberable_id}) + elsif query.match(/^[\"\'](.*)[\"\']$/) != nil + # The User searched for =>'example'<= so he wants an EXACT search for that. + # This is the fasted and most accurate way of searching. + # The order to search is: last_name, first_name and organization. + # It stops searching as soon as it finds results. + # + query = $1 + search_result = phone_book_entries.where(:last_name => query) + search_result = phone_book_entries.where(:first_name => query) if search_result.blank? + search_result = phone_book_entries.where(:organization => query) if search_result.blank? + + exact_search = true + else + # Search with SQL LIKE + # + search_result = phone_book_entries. + where( '( ( last_name LIKE ? ) OR ( first_name LIKE ? ) OR ( organization LIKE ? ) )', + "#{query}%", "#{query}%", "#{query}%" ) + + exact_search = false + end + + # Let's have a run with our phonetic search. + # + phonetic_query = PhoneBookEntry.koelner_phonetik(query) + phonetic_search_result = phone_book_entries.where(:last_name_phonetic => phonetic_query) + phonetic_search_result = phone_book_entries.where(:first_name_phonetic => phonetic_query) if phonetic_search_result.blank? + phonetic_search_result = phone_book_entries.where(:organization_phonetic => phonetic_query) if phonetic_search_result.blank? + + if phonetic_search_result.blank? + # Let's try the search with SQL LIKE. Just in case. + # + phonetic_search_result = phone_book_entries.where( 'last_name_phonetic LIKE ?', "#{phonetic_query}%" ) + phonetic_search_result = phone_book_entries.where( 'first_name_phonetic LIKE ?', "#{phonetic_query}%" ) if phonetic_search_result.blank? + phonetic_search_result = phone_book_entries.where( 'organization_phonetic LIKE ?', "#{phonetic_query}%" ) if phonetic_search_result.blank? + end + + phonetic_search = true if phonetic_search_result.any? + + phone_book_entries = search_result + + if phone_book_entries.count == 0 && exact_search == false && phonetic_search + phone_book_entries = phonetic_search_result + end + + # Let's sort the results and do pagination. + # + phone_book_entries = phone_book_entries. + order([ :last_name, :first_name, :organization ]).limit(20) + + respond_with phone_book_entries + end + + end + end +end diff --git a/app/controllers/api/v1/switchboards_controller.rb b/app/controllers/api/v1/switchboards_controller.rb index e6996ca..4d6607a 100644 --- a/app/controllers/api/v1/switchboards_controller.rb +++ b/app/controllers/api/v1/switchboards_controller.rb @@ -5,16 +5,20 @@ module Api def index @user = current_user - @switchboards = @user.switchboards + @switchboards = Switchboard.all - respond_with @switchboards + if can? :read, @switchboards + respond_with @switchboards + end end def show @user = current_user - @switchboard = @user.switchboards.find(params[:id]) + @switchboard = Switchboard.find(params[:id]) - respond_with @switchboard + if can? :read, @switchboard + respond_with @switchboard + end end end end diff --git a/app/controllers/call_forwards_controller.rb b/app/controllers/call_forwards_controller.rb index 1721aa3..0d0f946 100644 --- a/app/controllers/call_forwards_controller.rb +++ b/app/controllers/call_forwards_controller.rb @@ -29,8 +29,8 @@ class CallForwardsController < ApplicationController @call_forward.depth = GsParameter.get('DEFAULT_CALL_FORWARD_DEPTH') @call_forward.active = true @call_forwarding_destinations = call_forwarding_destination_types() + @call_forward.destinationable_type = 'PhoneNumber' @call_forward.destination = GsParameter.get('CALLFORWARD_DESTINATION_DEFAULT').to_s if defined?(GsParameter.get('CALLFORWARD_DESTINATION_DEFAULT')) - @destination_phone_number = @call_forward.destination @available_call_forward_cases = [] CallForwardCase.all.each do |available_call_forward_case| @@ -66,7 +66,6 @@ class CallForwardsController < ApplicationController @available_call_forward_cases = CallForwardCase.all @call_forwarding_destinations = call_forwarding_destination_types() @available_greetings = available_greetings() - @destination_phone_number = @call_forward.destination if @call_forward.call_forwarding_destination == ':PhoneNumber' end def update @@ -118,7 +117,7 @@ class CallForwardsController < ApplicationController add_breadcrumb @parent, sip_account_phone_number_path(@sip_account, @parent) elsif @parent.class == SipAccount add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant) - add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user) + add_breadcrumb @user, tenant_user_path(@user.current_tenant, @user) add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user) end end @@ -188,6 +187,18 @@ class CallForwardsController < ApplicationController end end + if @parent.class == HuntGroup && @parent.tenant + @parent.tenant.voicemail_accounts.each do |voicemail_account| + call_forwards_destination = CallForwardingDestination.new() + call_forwards_destination.id = "#{voicemail_account.id}:VoicemailAccount" + call_forwards_destination.label = "VoicemailAccount: #{voicemail_account.to_s}" + if !destinations_hash[call_forwards_destination.id] + destinations_hash[call_forwards_destination.id] = true + call_forwarding_destinations << call_forwards_destination + end + end + end + if @parent.class == PhoneNumber if @parent.phone_numberable.class == SipAccount sip_account = @parent.phone_numberable diff --git a/app/controllers/call_histories_controller.rb b/app/controllers/call_histories_controller.rb index a4d0c21..edd19cb 100644 --- a/app/controllers/call_histories_controller.rb +++ b/app/controllers/call_histories_controller.rb @@ -71,8 +71,17 @@ class CallHistoriesController < ApplicationController @call_history = CallHistory.where(:id => params[:id]).first if can?(:call, @call_history) && @sip_account.registration phone_number = @call_history.display_number - if ! phone_number.blank? - @sip_account.call(phone_number) + caller_id_number = phone_number + if ! phone_number.blank? + if @sip_account.clir != @call_history.clir + if @call_history.clir == true + phone_number = 'f-dcliron-' + phone_number + elsif call.clir == false + phone_number = 'f-dcliroff-' + phone_number + end + end + + @sip_account.call(phone_number, caller_id_number, @call_history.display_name) end end redirect_to(:back) diff --git a/app/controllers/cdrs_controller.rb b/app/controllers/cdrs_controller.rb new file mode 100644 index 0000000..3815f52 --- /dev/null +++ b/app/controllers/cdrs_controller.rb @@ -0,0 +1,43 @@ +class CdrsController < ApplicationController + load_and_authorize_resource :tenant + + before_filter :set_and_authorize_parent + before_filter :spread_breadcrumbs + + helper_method :sort_column, :sort_descending + + def index + @cdrs = Cdr.order(sort_column + ' ' + (sort_descending ? 'DESC' : 'ASC')).paginate( + :page => params[:page], + :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE') + ) + end + + def show + end + + def destroy + @cdr.destroy + m = method( :"#{@parent.class.name.underscore}_cdrs_url" ) + redirect_to m.(@parent), :notice => t('cdrs.controller.successfuly_destroyed') + end + + private + def set_and_authorize_parent + @parent = @user || @tenant + authorize! :read, @parent + end + + def spread_breadcrumbs + add_breadcrumb t("cdrs.index.page_title"), tenant_cdrs_path(@tenant) + end + + def sort_descending + params[:desc].to_s == 'true' + end + + def sort_column + Cdr.column_names.include?(params[:sort]) ? params[:sort] : 'start_stamp' + end + +end diff --git a/app/controllers/config_snom_controller.rb b/app/controllers/config_snom_controller.rb index 4b9489b..1cac4b2 100644 --- a/app/controllers/config_snom_controller.rb +++ b/app/controllers/config_snom_controller.rb @@ -1,6 +1,6 @@ class ConfigSnomController < ApplicationController - MAX_SIP_ACCOUNTS_COUNT = 11 - MAX_SOFTKEYS_COUNT = 12 + (42 * 3) - 1 + MAX_SIP_ACCOUNTS_COUNT = 11 + MAX_SOFTKEYS_COUNT = 12 + (42 * 3) - 1 MAX_DIRECTORY_ENTRIES = 20 KEY_REGEXP = { '0' => "[ -.,_0]+", @@ -15,12 +15,115 @@ class ConfigSnomController < ApplicationController '9' => "[wxyz9]", } - skip_authorization_check - - before_filter { |controller| + SNOM_PHONE_DEFAULTS = { + 'Snom 300' => { + :softkeys_physical => 6, + :softkeys_logical => 6, + }, + 'Snom 320' => { + :softkeys_physical => 12, + :softkeys_logical => 12, + }, + 'Snom 360' => { + :softkeys_physical => 12, + :softkeys_logical => 12, + }, + 'Snom 360' => { + :softkeys_physical => 12, + :softkeys_logical => 12, + }, + 'Snom 370' => { + :softkeys_physical => 12, + :softkeys_logical => 12, + }, + 'Snom 820' => { + :softkeys_physical => 4, + :softkeys_logical => 16, + }, + 'Snom 821' => { + :softkeys_physical => 4, + :softkeys_logical => 12, + }, + 'Snom 870' => { + :softkeys_physical => 0, + :softkeys_logical => 16, + }, + 'Snom vision' => { + :softkeys_physical => 16, + :softkeys_logical => 48, + :pages => 3, + }, + } + + skip_authorization_check + + before_filter { |controller| @mac_address = params[:mac_address].to_s.upcase.gsub(/[^0-9A-F]/,'') @provisioning_authenticated = false + if !params[:phone].blank? + @phone = Phone.where({ :id => params[:phone].to_i }).first + if !params[:sip_account].blank? + @sip_account = @phone.sip_accounts.where({ :id => params[:sip_account].to_i }).first + end + end + + @type = params[:type].blank? ? nil : params[:type].to_s.strip.downcase + @dialpad_keys = params[:keys].blank? ? nil : params[:keys].to_s.strip + } + + def show + if @mac_address.blank? + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Phone not found -->", + ) + return + end + + mac_address_to_model = { + '00041325' => 'Snom 300', + '00041328' => 'Snom 300', + '0004132D' => 'Snom 300', + '0004132F' => 'Snom 300', + '00041334' => 'Snom 300', + '00041350' => 'Snom 300', + '0004133B' => 'Snom 300', + '00041337' => 'Snom 300', + '00041324' => 'Snom 320', + '00041327' => 'Snom 320', + '0004132C' => 'Snom 320', + '00041331' => 'Snom 320', + '00041335' => 'Snom 320', + '00041338' => 'Snom 320', + '00041351' => 'Snom 320', + '00041323' => 'Snom 360', + '00041329' => 'Snom 360', + '0004132B' => 'Snom 360', + '00041339' => 'Snom 360', + '00041390' => 'Snom 360', + '00041326' => 'Snom 370', + '0004132E' => 'Snom 370', + '0004133A' => 'Snom 370', + '00041352' => 'Snom 370', + '00041340' => 'Snom 820', + '00041345' => 'Snom 821', + '00041348' => 'Snom 821', + '00041341' => 'Snom 870', + '00041332' => 'Snom meetingPoint', + '00041343' => 'Snom vision', + } + phone_model_str = mac_address_to_model[@mac_address[0, 8]] + if phone_model_str == 'Snom vision' + snom_vision + elsif !phone_model_str.blank? + snom_phone + end + end + + def snom_phone if !params[:provisioning_key].blank? @phone = Phone.where({ :provisioning_key => params[:provisioning_key] }).first if @phone @@ -154,6 +257,7 @@ class ConfigSnomController < ApplicationController :content_type => 'text/plain', :text => "<!-- Phone not found -->", ) + return end if ! params[:sip_account].blank? @@ -171,17 +275,16 @@ class ConfigSnomController < ApplicationController end end - if ! params[:type].blank? - @type = params[:type].to_s.strip.downcase + if ! @phone + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Phone not found -->", + ) + return end - if ! params[:keys].blank? - @dialpad_keys = params[:keys].to_s.strip - end - } - - - def show send_sensitve = @provisioning_authenticated || !@phone.provisioning_key_active @phone_settings = Hash.new() @@ -230,15 +333,15 @@ class ConfigSnomController < ApplicationController end end - if ! request.env['HTTP_USER_AGENT'].index('snom') - Rails.logger.info "---> User-Agent indicates not a Snom phone (#{request.env['HTTP_USER_AGENT'].inspect})" - else - Rails.logger.info "---> Phone #{@mac_address.inspect}, IP address #{request_remote_ip.inspect}" - @phone.update_attributes({ :ip_address => request_remote_ip }) - end + if ! request.env['HTTP_USER_AGENT'].index('snom') + Rails.logger.info "---> User-Agent indicates not a Snom phone (#{request.env['HTTP_USER_AGENT'].inspect})" + else + Rails.logger.info "---> Phone #{@mac_address.inspect}, IP address #{request_remote_ip.inspect}" + @phone.update_attributes({ :ip_address => request_remote_ip }) + end @softkeys = Array.new() - @sip_accounts = Array.new() + @sip_accounts = Array.new() phone_sip_accounts = Array.new() if send_sensitve @@ -252,16 +355,16 @@ class ConfigSnomController < ApplicationController phone_sip_accounts.each do |sip_account| if (sip_account.sip_accountable_type == @phone.phoneable_type) and (sip_account.sip_accountable_id == @phone.phoneable_id) - snom_sip_account = { + snom_sip_account = { :id => sip_account.id, :active => 'on', - :pname => sip_account.auth_name, - :pass => sip_account.password, - :host => sip_account.host, - :outbound => sip_account.host, - :name => sip_account.auth_name, - :realname => 'Call', - :user_idle_text => sip_account.caller_name, + :pname => sip_account.auth_name, + :pass => sip_account.password, + :host => sip_account.host, + :outbound => sip_account.host, + :name => sip_account.auth_name, + :realname => 'Call', + :user_idle_text => sip_account.caller_name, :expiry => expiry_seconds, } @@ -282,217 +385,11 @@ class ConfigSnomController < ApplicationController @sip_accounts.push(snom_sip_account) sip_account_index = @sip_accounts.length sip_account.softkeys.order(:position).each do |softkey| - if softkey.softkey_function - softkey_function = softkey.softkey_function.name - end - case softkey_function - when 'blf' - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "blf <sip:#{softkey.number}@#{sip_account.host}>|f-ia-"}) - when 'speed_dial' - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed #{softkey.number}"}) - when 'dtmf' - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "dtmf #{softkey.number}"}) - when 'log_out' - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed f-lo"}) - when 'log_in' - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "speed f-li-#{softkey.number}"}) - when 'conference' - conference = softkey.softkeyable - if conference.class == Conference - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "sip:conference#{conference.id}@#{sip_account.host}", - :for => "sip:conference#{conference.id}@#{sip_account.host}", - }, - :actions => [{ - :type => :dial, - :target => "f-ta-#{softkey.number}", - :when => 'on press', - :states => 'connected,holding', - },{ - :type => :dial, - :target => softkey.number, - :when => 'on press', - }], - }) - end - when 'parking_stall' - parking_stall = softkey.softkeyable - if parking_stall.class == ParkingStall - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "sip:park+#{parking_stall.name}@#{sip_account.host}", - :for => "sip:park+#{parking_stall.name}@#{sip_account.host}", - }, - :actions => [{ - :type => :dial, - :target => "f-cpa-#{parking_stall.name}", - :when => 'on press', - :states => 'connected,holding', - },{ - :type => :dial, - :target => "f-cpa-#{parking_stall.name}", - :when => 'on press', - }], - }) - end - when 'call_forwarding' - if softkey.softkeyable.class == CallForward then - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "sip:f-cftg-#{softkey.softkeyable_id}@#{sip_account.host}", - :for => "sip:f-cftg-#{softkey.softkeyable_id}@#{sip_account.host}" - }, - :actions => [{ - :type => :url, - :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?id=#{softkey.softkeyable_id}&function=toggle", - :when => 'on press', - }], - }) - end - when 'call_forwarding_always' - phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first - if phone_number - account_param = (phone_number.phone_numberable_id != snom_sip_account[:id] ? "&account=#{phone_number.phone_numberable_id}" : '') - else - phone_number = sip_account.phone_numbers.first - account_param = '' - end - - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "f-cfutg-#{phone_number.id}@#{sip_account.host}", - :for => "#{sip_account.auth_name}@#{sip_account.host}" - }, - :actions => [{ - :type => :url, - :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?type=always&function=toggle#{account_param}", - :when => 'on press', - }], - }) - when 'call_forwarding_assistant' - phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first - if phone_number - account_param = (phone_number.phone_numberable_id != snom_sip_account[:id] ? "&account=#{phone_number.phone_numberable_id}" : '') - else - phone_number = sip_account.phone_numbers.first - account_param = '' - end - - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "f-cfatg-#{phone_number.id}@#{sip_account.host}", - :for => "#{sip_account.auth_name}@#{sip_account.host}" - }, - :actions => [{ - :type => :url, - :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/call_forwarding.xml?type=assistant&function=toggle#{account_param}", - :when => 'on press', - }], - }) - when 'hunt_group_membership' - phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'HuntGroup').first - if phone_number - hunt_group = HuntGroup.where(:id => phone_number.phone_numberable_id).first - end - - sip_account_phone_numbers = Array.new() - SipAccount.where(:id => @sip_accounts.first[:id]).first.phone_numbers.each do |phone_number| - sip_account_phone_numbers.push(phone_number.number) - end - - hunt_group_member_numbers = PhoneNumber.where(:number => sip_account_phone_numbers, :phone_numberable_type => 'HuntGroupMember') - - hunt_group_member = nil - if hunt_group and hunt_group_member_numbers - hunt_group_member_numbers.each do |hunt_group_member_number| - hunt_group_member = hunt_group.hunt_group_members.where(:id => hunt_group_member_number.phone_numberable_id).first - if hunt_group_member - break - end - end - end - - if hunt_group_member - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "f-hgmtg-#{hunt_group_member.id}@#{sip_account.host}", - :for => "#{sip_account.auth_name}@#{sip_account.host}" - }, - :actions => [{ - :type => :url, - :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/hunt_group.xml?group=#{hunt_group.id}&account=#{hunt_group_member.id}&function=toggle", - :when => 'on press', - }], - }) - else - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => 'none'}) - end - when 'acd_membership' - acd_agent = nil - phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'AutomaticCallDistributor').first - if phone_number - acd = AutomaticCallDistributor.where(:id => phone_number.phone_numberable_id).first - if acd - acd_agent = acd.acd_agents.where(:destination_type => 'SipAccount', :destination_id => sip_account.id).first - end - end - - if acd_agent - @softkeys.push({ - :context => sip_account_index, - :function => softkey.softkey_function.name, - :label => softkey.label, - :softkey => softkey, - :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), - :subscription => { - :to => "f-acdmtg-#{acd_agent.id}@#{sip_account.host}", - :for => "#{sip_account.auth_name}@#{sip_account.host}" - }, - :actions => [{ - :type => :url, - :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{snom_sip_account[:id]}/acd.xml?acd=#{acd.id}&agent=#{acd_agent.id}&function=toggle", - :when => 'on press', - }], - }) - else - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => 'none'}) - end - when 'hold' - @softkeys.push({:context => sip_account_index, :label => softkey.label, :data => "keyevent F_R"}) - else - @softkeys.push({:label => softkey.label, :data => 'none'}) - end + @softkeys.push(format_key(softkey, sip_account_index)) + end + if @softkeys.any? && @phone.extension_modules.any? + phone_defaults = SNOM_PHONE_DEFAULTS[@phone.phone_model.name] + @softkeys = @softkeys.first(phone_defaults[:softkeys_physical]) end end end @@ -544,23 +441,22 @@ class ConfigSnomController < ApplicationController '41' => 'SWI', # Switzerland } + set_language + if @phone.phoneable if @phone.phoneable_type == 'Tenant' tenant = @phone.phoneable - language = tenant.language.code elsif @phone.phoneable_type == 'User' tenant = @phone.phoneable.current_tenant - language = @phone.phoneable.language.code end end if tenant && tenant.country tone_scheme = tenant.country.country_code + @phone_settings[:tone_scheme] = tone_schemes_map.include?(tone_scheme.to_s) ? tone_schemes_map[tone_scheme.to_s] : 'USA' end + @phone_settings[:language] = languages_map.include?(I18n.locale.to_s) ? languages_map[I18n.locale.to_s] : 'English' - @phone_settings[:tone_scheme] = tone_schemes_map.include?(tone_scheme.to_s) ? tone_schemes_map[tone_scheme.to_s] : 'USA' - @phone_settings[:language] = languages_map.include?(language.to_s) ? languages_map[language.to_s] : 'English' - xml_applications_url = "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{(@sip_accounts.blank? ? '0' : @sip_accounts.first[:id])}" @dkeys = { :menu => 'keyevent F_SETTINGS', @@ -603,18 +499,132 @@ class ConfigSnomController < ApplicationController end @softkeys.length().upto(MAX_SOFTKEYS_COUNT) do |index| - @softkeys.push({:label => "", :data => "none"}) + @softkeys.push({:label => "", :type => 'none', :value => ''}) end @state_settings_url = "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/state_settings.xml" - respond_to { |format| - format.any { - self.formats = [ :xml ] - render - } - } - end + extension_module = @phone.extension_modules.where(:active => true, :model => 'snom_vision').first + if extension_module + @phone_settings[:vision_mac_address] = extension_module.mac_address + @phone_settings[:vision_provisioning_url] = "#{provisioning_protocol}#{request.host_with_port}/settings-#{extension_module.mac_address}.xml" + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :snom_phone + } + } + end + + def snom_vision + if !params[:provisioning_key].blank? + @extension_module = ExtensionModule.where({ :provisioning_key => params[:provisioning_key] }).first + if @extension_module + @provisioning_authenticated = true + @mac_address = @extension_module.mac_address + end + elsif @mac_address + @extension_module = ExtensionModule.where({ :mac_address => @mac_address }).first + end + + + if !@extension_module + render( + :status => 404, + :layout => false, + :content_type => 'text/plain', + :text => "<!-- Extension module not found -->", + ) + return + end + + if ! request.env['HTTP_USER_AGENT'].index('snom') + Rails.logger.info "---> User-Agent indicates not a Snom Vision (#{request.env['HTTP_USER_AGENT'].inspect})" + else + Rails.logger.info "---> Extension module #{@mac_address.inspect}, IP address #{request_remote_ip.inspect}" + @extension_module.update_attributes({ :ip_address => request_remote_ip }) + end + + @phone = @extension_module.phone + + set_language + + provisioning_protocol = request.protocol + + @settings = { + :auth_type => 'basic', + :provisioning_server => "#{provisioning_protocol}#{request.host_with_port}/settings-#{@extension_module.mac_address}.xml", + :user => '', + :passwd => '', + :phone_ip => '', + } + + @buttons = Array.new() + softkeys = Array.new() + send_sensitve = @provisioning_authenticated || !@extension_module.provisioning_key_active + + if send_sensitve && @phone + if @provisioning_authenticated && !@extension_module.provisioning_key_active + @extension_module.update_attributes({ :provisioning_key_active => true }) + end + + @settings[:user] = @phone.http_user + @settings[:passwd] = @phone.http_password + @settings[:phone_ip] = @phone.ip_address + + if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0 && !@extension_module.provisioning_key.blank? + @settings[:provisioning_server] = "#{provisioning_protocol}#{request.host_with_port}/snom_vision-#{@extension_module.provisioning_key}.xml" + end + + @phone.sip_accounts.each do |sip_account| + softkeys.concat(sip_account.softkeys.order(:position)) + end + + phone_defaults = SNOM_PHONE_DEFAULTS[@phone.phone_model.name] + softkeys.shift(phone_defaults[:softkeys_physical] * @extension_module.position) + + else + @buttons << { + :imageurl => '', + :label => 'No provisioning key!', + :type => 'none', + :value => '', + } + end + + softkeys.each do |softkey| + image_url = nil + if softkey.softkeyable.class == SipAccount + if softkey.softkeyable.sip_accountable.class == User + user = softkey.softkeyable.sip_accountable + if user.image? + image_url = "#{provisioning_protocol}#{request.host_with_port}#{user.image_url(:small)}" + end + end + elsif softkey.softkeyable.class == PhoneBookEntry + entry = softkey.softkeyable + if entry.image? + image_url = "#{provisioning_protocol}#{request.host_with_port}#{entry.image_url(:small)}" + end + end + + button = format_key(softkey) + if button + button[:imageurl] = image_url + end + @buttons.push(button) + end + + respond_to { |format| + format.any { + self.formats = [ :xml ] + render :snom_vision + } + } + end + def idle_screen @@ -669,7 +679,7 @@ AAAA' end def log_in - + set_language base_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.split("?")[0]}" exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" @@ -758,6 +768,8 @@ AAAA' return end + set_language + exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" if @phone.user_logout() @@ -800,6 +812,8 @@ AAAA' return end + set_language + @phone_xml_object = { :name => 'snom_phone_directory', :title => "#{t('config_snom.phone_book.title')} #{@dialpad_keys}".strip, @@ -834,7 +848,7 @@ AAAA' phone_book_entries.each do |phone_book_entry| if phone_book_entry.phone_numbers.count > 1 - @phone_xml_object[:entries] << { :text => phone_book_entry.to_s, :number => phone_book_entry.phone_numbers.first } + @phone_xml_object[:entries] << { :text => phone_book_entry.to_s, :number => phone_book_entry.phone_numbers.first.number.to_s } end phone_book_entry.phone_numbers.each do |phone_number| if phone_book_entry.phone_numbers.count > 1 @@ -875,6 +889,8 @@ AAAA' return end + set_language + if ['dialed', 'missed', 'received', 'forwarded'].include? @type @phone_xml_object = { :name => "snom_phone_directory", @@ -893,11 +909,24 @@ AAAA' calls.each do |call| display_name = call.display_name phone_number = call.display_number + + if phone_number.blank? + next + end + phone_book_entry = call.phone_book_entry_by_number(phone_number) if display_name.blank? display_name = phone_book_entry.to_s end + if @sip_account.clir != call.clir + if call.clir == true + phone_number = 'f-dcliron-' + phone_number + elsif call.clir == false + phone_number = 'f-dcliroff-' + phone_number + end + end + @phone_xml_object[:entries].push({ :selected => false, :number => phone_number, @@ -947,6 +976,7 @@ AAAA' return end + set_language account = @sip_account.voicemail_account if ['read', 'unread'].include? @type @@ -1013,6 +1043,8 @@ AAAA' end end + set_language + respond_to { |format| format.any { self.formats = [ :xml ] @@ -1053,6 +1085,7 @@ AAAA' return end + set_language exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" if @function == 'toggle' @@ -1168,6 +1201,7 @@ AAAA' return end + set_language exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" if @function == 'toggle' @@ -1265,6 +1299,7 @@ AAAA' return end + set_language exit_url = "#{request.protocol}#{request.host_with_port}#{request.fullpath.rpartition("/")[0]}/exit.xml" if @function == 'toggle' @@ -1329,4 +1364,236 @@ AAAA' return date.strftime('%d.%m %H:%M') end + def format_key(softkey, sip_account_index = nil) + if !softkey.softkey_function + return nil + end + + sip_account = softkey.sip_account + + case softkey.softkey_function.name + when 'blf' + return {:context => sip_account_index, :label => softkey.label, :type => 'blf', :value => "<sip:#{softkey.number}@#{sip_account.host}>|f-ia-"} + when 'speed_dial' + return {:context => sip_account_index, :label => softkey.label, :type => 'speed', :value => softkey.number.to_s} + when 'dtmf' + return {:context => sip_account_index, :label => softkey.label, :type => 'dtmf', :value => softkey.number.to_s} + when 'log_out' + return {:context => sip_account_index, :label => softkey.label, :type => 'speed', :value => 'f-lo'} + when 'log_in' + return {:context => sip_account_index, :label => softkey.label, :type => 'speed', :value => "f-li-#{softkey.number}"} + when 'conference' + conference = softkey.softkeyable + if conference.class == Conference + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:conference#{conference.id}@#{sip_account.host}", + :for => "sip:conference#{conference.id}@#{sip_account.host}", + }, + :actions => [{ + :type => :dial, + :target => "f-ta-#{softkey.number}", + :when => 'on press', + :states => 'connected,holding', + },{ + :type => :dial, + :target => softkey.number, + :when => 'on press', + }], + } + end + when 'parking_stall' + parking_stall = softkey.softkeyable + if parking_stall.class == ParkingStall + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:park+#{parking_stall.name}@#{sip_account.host}", + :for => "sip:park+#{parking_stall.name}@#{sip_account.host}", + }, + :actions => [{ + :type => :dial, + :target => "f-cpa-#{parking_stall.name}", + :when => 'on press', + :states => 'connected,holding', + },{ + :type => :dial, + :target => "f-cpa-#{parking_stall.name}", + :when => 'on press', + }], + } + end + when 'call_forwarding' + if softkey.softkeyable.class == CallForward then + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:f-cftg-#{softkey.softkeyable_id}@#{sip_account.host}", + :for => "sip:f-cftg-#{softkey.softkeyable_id}@#{sip_account.host}" + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{sip_account.id}/call_forwarding.xml?id=#{softkey.softkeyable_id}&function=toggle", + :when => 'on press', + }], + } + end + when 'call_forwarding_always' + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first + if phone_number + account_param = (phone_number.phone_numberable_id != sip_account.id ? "&account=#{phone_number.phone_numberable_id}" : '') + else + phone_number = sip_account.phone_numbers.first + account_param = '' + end + + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:f-cfutg-#{phone_number.id}@#{sip_account.host}", + :for => "sip:f-cfutg-#{phone_number.id}@#{sip_account.host}", + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{sip_account.id}/call_forwarding.xml?type=always&function=toggle#{account_param}", + :when => 'on press', + }], + } + when 'call_forwarding_assistant' + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'SipAccount').first + if phone_number + account_param = (phone_number.phone_numberable_id != sip_account.id ? "&account=#{phone_number.phone_numberable_id}" : '') + else + phone_number = sip_account.phone_numbers.first + account_param = '' + end + + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:f-cfatg-#{phone_number.id}@#{sip_account.host}", + :for => "sip:f-cfatg-#{phone_number.id}@#{sip_account.host}", + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{sip_account.id}/call_forwarding.xml?type=assistant&function=toggle#{account_param}", + :when => 'on press', + }], + } + when 'hunt_group_membership' + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'HuntGroup').first + if phone_number + hunt_group = HuntGroup.where(:id => phone_number.phone_numberable_id).first + end + + sip_account_phone_numbers = Array.new() + SipAccount.where(:id => @sip_accounts.first[:id]).first.phone_numbers.each do |phone_number| + sip_account_phone_numbers.push(phone_number.number) + end + + hunt_group_member_numbers = PhoneNumber.where(:number => sip_account_phone_numbers, :phone_numberable_type => 'HuntGroupMember') + + hunt_group_member = nil + if hunt_group and hunt_group_member_numbers + hunt_group_member_numbers.each do |hunt_group_member_number| + hunt_group_member = hunt_group.hunt_group_members.where(:id => hunt_group_member_number.phone_numberable_id).first + if hunt_group_member + break + end + end + end + + if hunt_group_member + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:f-hgmtg-#{hunt_group_member.id}@#{sip_account.host}", + :for => "sip:f-hgmtg-#{hunt_group_member.id}@#{sip_account.host}", + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{sip_account.id}/hunt_group.xml?group=#{hunt_group.id}&account=#{hunt_group_member.id}&function=toggle", + :when => 'on press', + }], + } + else + return {:context => sip_account_index, :label => softkey.label, :type => 'none', :value => ''} + end + when 'acd_membership' + acd_agent = nil + phone_number = PhoneNumber.where(:number => softkey.number, :phone_numberable_type => 'AutomaticCallDistributor').first + if phone_number + acd = AutomaticCallDistributor.where(:id => phone_number.phone_numberable_id).first + if acd + acd_agent = acd.acd_agents.where(:destination_type => 'SipAccount', :destination_id => sip_account.id).first + end + end + + if acd_agent + return { + :context => sip_account_index, + :function => softkey.softkey_function.name, + :label => softkey.label, + :softkey => softkey, + :general_type => t("softkeys.functions.#{softkey.softkey_function.name}"), + :subscription => { + :to => "sip:f-acdmtg-#{acd_agent.id}@#{sip_account.host}", + :for => "sip:f-acdmtg-#{acd_agent.id}@#{sip_account.host}", + }, + :actions => [{ + :type => :url, + :target => "#{request.protocol}#{request.host_with_port}/config_snom/#{@phone.id}/#{sip_account.id}/acd.xml?acd=#{acd.id}&agent=#{acd_agent.id}&function=toggle", + :when => 'on press', + }], + } + else + return {:context => sip_account_index, :label => softkey.label, :type => 'none', :value => ''} + end + when 'hold' + return {:context => sip_account_index, :label => softkey.label, :type => 'keyevent', :value => 'F_R'} + else + return {:label => softkey.label, :type => 'none', :value => ''} + end + end + + private + def set_language + if @sip_account && !@sip_account.language_code.blank? + I18n.locale = @sip_account.language_code + elsif @phone + sip_account = @phone.sip_accounts.first + if sip_account && !sip_account.language_code.blank? + I18n.locale = sip_account.language_code + @locale = sip_account.language_code + elsif @phone.phoneable && @phone.phoneable.respond_to?('language') && @phone.phoneable.language + I18n.locale = @phone.phoneable.language.code + end + end + end + end diff --git a/app/controllers/extension_modules_controller.rb b/app/controllers/extension_modules_controller.rb new file mode 100644 index 0000000..3f8fe98 --- /dev/null +++ b/app/controllers/extension_modules_controller.rb @@ -0,0 +1,73 @@ +class ExtensionModulesController < ApplicationController + load_resource :phone + load_and_authorize_resource :extension_module, :through => [:phone] + + before_filter :spread_breadcrumbs + + def index + @extension_modules = @phone.extension_modules.all + end + + def show + @extension_module = @phone.extension_modules.find(params[:id]) + end + + def new + @extension_module = @phone.extension_modules.build() + end + + def create + @extension_module = @phone.extension_modules.build(params[:extension_module]) + if @extension_module.save + redirect_to phone_extension_module_path(@phone, @extension_module), :notice => t('extension_modules.controller.successfuly_created') + else + render :new + end + end + + def edit + @extension_module = @phone.extension_modules.find(params[:id]) + end + + def update + @extension_module = @phone.extension_modules.find(params[:id]) + if @extension_module.update_attributes(params[:extension_module]) + redirect_to phone_extension_module_path(@phone, @extension_module), :notice => t('extension_modules.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @extension_module = @phone.extension_modules.find(params[:id]) + @extension_module.destroy + redirect_to phone_extension_modules_url(@phone), :notice => t('extension_modules.controller.successfuly_destroyed') + end + + def restart + if @extension_module.resync + redirect_to phone_extension_module_path(@phone, @extension_module), :notice => t('extension_modules.controller.restart_invoked') + else + redirect_to phone_extension_module_path(@phone, @extension_module), :error => t('extension_modules.controller.restart_failed') + end + end + + private + def spread_breadcrumbs + if @phone.phoneable.class == User + add_breadcrumb t('users.index.page_title'), tenant_users_path(@phone.phoneable.current_tenant) + add_breadcrumb @phone.phoneable, tenant_user_path(@phone.phoneable.current_tenant, @phone.phoneable) + add_breadcrumb t('phones.index.page_title'), user_phones_path(@phone.phoneable) + elsif @phone.phoneable.class == Tenant + add_breadcrumb t('phones.index.page_title'), tenant_phones_path(@phone.phoneable) + end + + add_breadcrumb @phone, method( :"#{@phone.phoneable.class.name.underscore}_phone_path" ).(@phone.phoneable, @phone) + add_breadcrumb t("extension_modules.index.page_title"), phone_extension_modules_path(@phone) + + if @extension_module && !@extension_module.new_record? + add_breadcrumb @extension_module + end + + end +end diff --git a/app/controllers/gateway_headers_controller.rb b/app/controllers/gateway_headers_controller.rb new file mode 100644 index 0000000..60c16c4 --- /dev/null +++ b/app/controllers/gateway_headers_controller.rb @@ -0,0 +1,57 @@ +class GatewayHeadersController < ApplicationController + load_and_authorize_resource :gateway + load_and_authorize_resource :gateway_header, :through => [:gateway] + + before_filter :spread_breadcrumbs + + def index + @gateway_headers = @gateway.gateway_headers + end + + def show + @gateway_header = @gateway.gateway_headers.find(params[:id]) + end + + def new + @gateway_header = @gateway.gateway_headers.build + end + + def create + @gateway_header = @gateway.gateway_headers.build(params[:gateway_header]) + if @gateway_header.save + redirect_to @gateway, :notice => t('gateway_headers.controller.successfuly_created') + else + render :new + end + end + + def edit + @gateway_header = @gateway.gateway_headers.find(params[:id]) + end + + def update + @gateway_header = @gateway.gateway_headers.find(params[:id]) + if @gateway_header.update_attributes(params[:gateway_header]) + redirect_to @gateway, :notice => t('gateway_headers.controller.successfuly_updated') + else + render :edit + end + end + + def destroy + @gateway_header = @gateway.gateway_headers.find(params[:id]) + @gateway_header.destroy + redirect_to gateway_path(@gateway), :notice => t('gateway_headers.controller.successfuly_destroyed') + end + + private + def spread_breadcrumbs + add_breadcrumb t("gateways.index.page_title"), gateways_path + add_breadcrumb @gateway, @gateway + add_breadcrumb t("gateway_headers.index.page_title"), gateway_gateway_headers_url(@gateway) + + if @gateway_header && !@gateway_header.new_record? + add_breadcrumb @gateway_header + end + end +end diff --git a/app/controllers/sip_accounts_controller.rb b/app/controllers/sip_accounts_controller.rb index cd34953..3dc5a54 100644 --- a/app/controllers/sip_accounts_controller.rb +++ b/app/controllers/sip_accounts_controller.rb @@ -85,6 +85,7 @@ class SipAccountsController < ApplicationController m = method( :"#{@parent.class.name.underscore}_sip_account_path" ) redirect_to m.( @parent, @sip_account ), :notice => t('sip_accounts.controller.successfuly_updated') else + possible_voicemail_accounts render :edit end end diff --git a/app/controllers/switchboard_entries_controller.rb b/app/controllers/switchboard_entries_controller.rb index ef6c72e..5b41816 100644 --- a/app/controllers/switchboard_entries_controller.rb +++ b/app/controllers/switchboard_entries_controller.rb @@ -58,7 +58,7 @@ class SwitchboardEntriesController < ApplicationController private def switchboard_entry_params - params.require(:switchboard_entry).permit(:name, :sip_account_id) + params.require(:switchboard_entry).permit(:name, :sip_account_id, :switchable) end def spread_breadcrumbs diff --git a/app/controllers/switchboards_controller.rb b/app/controllers/switchboards_controller.rb index 3e2f8d6..03fd73e 100644 --- a/app/controllers/switchboards_controller.rb +++ b/app/controllers/switchboards_controller.rb @@ -19,6 +19,8 @@ class SwitchboardsController < ApplicationController @switchboard.entry_width = 2 @switchboard.reload_interval = 2000 @switchboard.amount_of_displayed_phone_numbers = 1 + @switchboard.blind_transfer_activated = true + @switchboard.attended_transfer_activated = false spread_breadcrumbs end @@ -56,7 +58,7 @@ class SwitchboardsController < ApplicationController private def switchboard_params - params.require(:switchboard).permit(:name, :reload_interval, :show_avatars, :entry_width, :amount_of_displayed_phone_numbers) + params.require(:switchboard).permit(:name, :reload_interval, :show_avatars, :entry_width, :amount_of_displayed_phone_numbers, :blind_transfer_activated, :attended_transfer_activated, :search_activated) end def spread_breadcrumbs diff --git a/app/controllers/trigger_controller.rb b/app/controllers/trigger_controller.rb index 290a1fc..ee4ddca 100644 --- a/app/controllers/trigger_controller.rb +++ b/app/controllers/trigger_controller.rb @@ -178,7 +178,7 @@ class TriggerController < ApplicationController if errors.count == 0 # Indicate a new fax in the navigation bar. # - if @last_fax_document.fax_account.fax_accountable.class == User + if @last_fax_document && @last_fax_document.fax_account.fax_accountable.class == User user = @last_fax_document.fax_account.fax_accountable PrivatePub.publish_to("/users/#{user.id}/messages/new", "$('#new_voicemail_or_fax_indicator').hide('fast').show('slow');") PrivatePub.publish_to("/users/#{user.id}/messages/new", "document.title = '* ' + document.title.replace( '* ' , '');") diff --git a/app/controllers/voicemail_settings_controller.rb b/app/controllers/voicemail_settings_controller.rb index f270c3d..ca3ae86 100644 --- a/app/controllers/voicemail_settings_controller.rb +++ b/app/controllers/voicemail_settings_controller.rb @@ -42,6 +42,9 @@ class VoicemailSettingsController < ApplicationController @voicemail_setting = @voicemail_account.voicemail_settings.find(params[:id]) @input_type = VoicemailSetting::VOICEMAIL_SETTINGS.fetch(@voicemail_setting.name,{}).fetch(:input, 'String') @input_html = VoicemailSetting::VOICEMAIL_SETTINGS.fetch(@voicemail_setting.name,{}).fetch(:html, {}) + if @input_type == :boolean && @voicemail_setting.value == 'true' + @input_html[:checked] = true + end end def update diff --git a/app/helpers/extension_modules_helper.rb b/app/helpers/extension_modules_helper.rb new file mode 100644 index 0000000..653769f --- /dev/null +++ b/app/helpers/extension_modules_helper.rb @@ -0,0 +1,2 @@ +module ExtensionModulesHelper +end diff --git a/app/mailers/notifications.rb b/app/mailers/notifications.rb index 44a6a7a..ec81d35 100644 --- a/app/mailers/notifications.rb +++ b/app/mailers/notifications.rb @@ -55,7 +55,8 @@ class Notifications < ActionMailer::Base if caller_number.blank? caller_number = 'anonymous' end - attachments["#{Time.at(freeswitch_voicemail_msg.created_epoch).getlocal.strftime('%Y%m%d-%H%M%S')}-#{caller_number}.wav"] = File.read(freeswitch_voicemail_msg.file_path) + @voicemail[:file_name] = "#{Time.at(freeswitch_voicemail_msg.created_epoch).getlocal.strftime('%Y%m%d-%H%M%S')}-#{caller_number}.wav" + attachments[@voicemail[:file_name]] = File.read(freeswitch_voicemail_msg.file_path) end mail(from: Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID')).from_field_voicemail_email, to: email, :subject => "New Voicemail from #{@voicemail[:from]}, received #{Time.at(freeswitch_voicemail_msg.created_epoch).getlocal.to_s}") diff --git a/app/models/ability.rb b/app/models/ability.rb index 8718dc4..66f3c60 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -95,6 +95,10 @@ class Ability # cannot :manage, RestoreJob + # Admin can manage all switchboards. + # + can :manage, Switchboard + else # Any user can do the following stuff. # diff --git a/app/models/call.rb b/app/models/call.rb index 2bbd08b..6755a96 100644 --- a/app/models/call.rb +++ b/app/models/call.rb @@ -44,11 +44,7 @@ class Call < ActiveRecord::Base return nil end - if call_leg == :bleg - channel_uuid = self.b_uuid - else - channel_uuid = self.uuid - end + channel_uuid = call_leg == :bleg ? self.b_uuid : channel_uuid = self.uuid if channel_uuid.blank? return nil @@ -63,24 +59,28 @@ class Call < ActiveRecord::Base return FreeswitchAPI.api_result(FreeswitchAPI.api('uuid_transfer', channel_uuid, destination)) end + def hold(call_leg=:aleg, action=:hold) + channel_uuid = call_leg == :bleg ? self.b_uuid : channel_uuid = self.uuid + hold_off = action == :retrieve ? 'off' : '' - def self.bridge(call_uuid1, call_uuid2, hangup_uuids=[]) - if call_uuid1.blank? || call_uuid2.blank? + if channel_uuid.blank? return nil end require 'freeswitch_event' - result = FreeswitchAPI.api_result(FreeswitchAPI.api('uuid_bridge', call_uuid1, call_uuid2)) - - if result - hangup_uuids.each do |kill_uuid| - FreeswitchAPI.execute('uuid_kill', kill_uuid, true) - end + result = FreeswitchAPI.api_result(FreeswitchAPI.api('uuid_hold', hold_off, channel_uuid)) + end + + def park(call_leg=:aleg) + channel_uuid = call_leg == :bleg ? self.b_uuid : channel_uuid = self.uuid + + if channel_uuid.blank? + return nil end - return result + require 'freeswitch_event' + result = FreeswitchAPI.api_result(FreeswitchAPI.api('uuid_park', channel_uuid)) end - def get_variable_from_uuid(channel_uuid, variable_name) if channel_uuid.blank? @@ -105,4 +105,20 @@ class Call < ActiveRecord::Base return get_variable_from_uuid(self.b_uuid, variable_name); end + def self.bridge(call_uuid1, call_uuid2, hangup_uuids=[]) + if call_uuid1.blank? || call_uuid2.blank? + return nil + end + + require 'freeswitch_event' + result = FreeswitchAPI.api_result(FreeswitchAPI.api('uuid_bridge', call_uuid1, call_uuid2)) + + if result + hangup_uuids.each do |kill_uuid| + FreeswitchAPI.execute('uuid_kill', kill_uuid, true) + end + end + + return result + end end diff --git a/app/models/call_forward.rb b/app/models/call_forward.rb index a4bfbb5..874a0de 100644 --- a/app/models/call_forward.rb +++ b/app/models/call_forward.rb @@ -7,7 +7,8 @@ class CallForward < ActiveRecord::Base :hunt_group_id, :call_forwardable_type, :call_forwardable_id, :call_forwarding_destination, :position, :uuid, - :destinationable_type, :destinationable_id + :destinationable_type, :destinationable_id, + :destination_phone_number, :destination_greeting belongs_to :call_forwardable, :polymorphic => true belongs_to :destinationable, :polymorphic => true @@ -23,12 +24,6 @@ class CallForward < ActiveRecord::Base :if => Proc.new { |cf| cf.to_voicemail == true } belongs_to :call_forward_case - - validates_numericality_of :depth, - :allow_nil => true, - :only_integer => true, - :greater_than_or_equal_to => 1, - :less_than_or_equal_to => (GsParameter.get('MAX_CALL_FORWARD_DEPTH').nil? ? 0 : GsParameter.get('MAX_CALL_FORWARD_DEPTH')) before_validation { self.timeout = nil if self.call_forward_case_id != 3 @@ -49,13 +44,6 @@ class CallForward < ActiveRecord::Base validates_presence_of :uuid validates_uniqueness_of :uuid - # Make sure the call forward's parent can't be changed: - before_validation { |cfwd| - if cfwd.id && (cfwd.call_forwardable_id != cfwd.call_forwardable_id_was || cfwd.call_forwardable_type != cfwd.call_forwardable_type_was) - errors.add( :call_forwardable_id, "cannot be changed." ) - end - } - before_validation :resolve_prerouting after_save :set_presence @@ -88,6 +76,30 @@ class CallForward < ActiveRecord::Base self.destinationable_id, delimeter, self.destinationable_type = destination_record.to_s.partition(':') end + def destination_phone_number + if self.destinationable_type.to_s.downcase == 'phonenumber' + return self.destination + end + end + + def destination_phone_number=(destination_number) + if self.destinationable_type.to_s.downcase == 'phonenumber' + self.destination = destination_number + end + end + + def destination_greeting + if self.destinationable_type.to_s.downcase == 'voicemailaccount' + return self.destination + end + end + + def destination_greeting=(destination_file) + if self.destinationable_type.to_s.downcase == 'voicemailaccount' + self.destination = destination_file + end + end + def toggle self.active = ! self.active return self.save diff --git a/app/models/cdr.rb b/app/models/cdr.rb new file mode 100644 index 0000000..ff9198f --- /dev/null +++ b/app/models/cdr.rb @@ -0,0 +1,17 @@ +class Cdr < ActiveRecord::Base + self.table_name = 'cdrs' + self.primary_key = 'uuid' + + belongs_to :account + belongs_to :bleg_account + belongs_to :forwarding_account + + + def self.seconds_to_minutes_seconds(call_seconds) + if call_seconds.to_i > 0 + minutes = (call_seconds / 1.minutes).to_i + seconds = call_seconds - minutes.minutes.seconds + return '%i:%02i' % [minutes, seconds] + end + end +end diff --git a/app/models/extension_module.rb b/app/models/extension_module.rb new file mode 100644 index 0000000..98ef700 --- /dev/null +++ b/app/models/extension_module.rb @@ -0,0 +1,58 @@ +class ExtensionModule < ActiveRecord::Base + attr_accessible :model, :mac_address, :phone_id, :ip_address, :position, :active, :provisioning_key, :provisioning_key_active + + MODELS = ['snom_vision'] + + belongs_to :phone + before_save :remove_ip_address_when_mac_address_was_changed + + before_save :generate_key + + def to_s + mac_address + end + + def resync() + if ! self.model == 'snom_vision' + return false + end + + http_user = nil + http_password = nil + + if self.phone + http_user = self.phone.http_user + http_password = self.phone.http_password + end + + require 'open-uri' + begin + if open("http://#{self.ip_address}/ConfigurationModule/restart", :http_basic_authentication=>[http_user, http_password], :proxy => nil) + return true + end + rescue + return false + end + end + + private + def sanitize_mac_address + if self.mac_address.split(/:/).count == 6 && self.mac_address.length < 17 + splitted_mac_address = self.mac_address.split(/:/) + self.mac_address = splitted_mac_address.map{|part| (part.size == 1 ? "0#{part}" : part)}.join('') + end + self.mac_address = self.mac_address.to_s.upcase.gsub( /[^A-F0-9]/, '' ) + end + + def remove_ip_address_when_mac_address_was_changed + if self.mac_address_changed? + self.ip_address = nil + end + end + + def generate_key + if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0 && self.provisioning_key.blank? + self.provisioning_key = SecureRandom.hex(GsParameter.get('PROVISIONING_KEY_LENGTH')) + end + end +end diff --git a/app/models/freeswitch_cdr.rb b/app/models/freeswitch_cdr.rb deleted file mode 100644 index fd0eb75..0000000 --- a/app/models/freeswitch_cdr.rb +++ /dev/null @@ -1,4 +0,0 @@ -class FreeswitchCdr < ActiveRecord::Base - self.table_name = 'cdrs' - self.primary_key = 'uuid' -end diff --git a/app/models/gateway.rb b/app/models/gateway.rb index 01b29b2..437d3af 100644 --- a/app/models/gateway.rb +++ b/app/models/gateway.rb @@ -6,6 +6,7 @@ class Gateway < ActiveRecord::Base has_many :gateway_settings, :dependent => :destroy has_many :gateway_parameters, :dependent => :destroy + has_many :gateway_headers, :dependent => :destroy has_many :call_routes, :as => :endpoint, :dependent => :nullify validates :name, @@ -72,6 +73,15 @@ class Gateway < ActiveRecord::Base GsParameter.where(:entity => 'sip_gateways', :section => 'settings').each do |default_setting| self.gateway_settings.create(:name => default_setting.name, :value => default_setting.value, :class_type => default_setting.class_type, :description => default_setting.description) end + GsParameter.where(:entity => 'sip_gateways', :section => 'headers_default').each do |default_header| + self.gateway_headers.create(:name => default_header.name, :value => default_header.value, :header_type => 'default', :description => default_header.description) + end + GsParameter.where(:entity => 'sip_gateways', :section => 'headers_default_clir_off').each do |default_header| + self.gateway_headers.create(:constraint_value => 'clir=false', :name => default_header.name, :value => default_header.value, :header_type => 'default', :description => default_header.description) + end + GsParameter.where(:entity => 'sip_gateways', :section => 'headers_default_clir_on').each do |default_header| + self.gateway_headers.create(:constraint_value => 'clir=true', :name => default_header.name, :value => default_header.value, :header_type => 'default', :description => default_header.description) + end end end diff --git a/app/models/gateway_header.rb b/app/models/gateway_header.rb new file mode 100644 index 0000000..474bfac --- /dev/null +++ b/app/models/gateway_header.rb @@ -0,0 +1,25 @@ +class GatewayHeader < ActiveRecord::Base + HEADER_TYPES = [ + 'default', + 'invite', + # 'provisional', + # 'request', + # 'bye', + ] + + attr_accessible :gateway_id, :header_type, :constraint_source, :constraint_value, :name, :value, :description + + belongs_to :gateway, :touch => true + + validates :name, + :presence => true, + :uniqueness => {:scope => [:gateway_id, :header_type, :constraint_source, :constraint_value]} + + validates :header_type, + :presence => true, + :inclusion => { :in => HEADER_TYPES } + + def to_s + name + end +end diff --git a/app/models/gateway_setting.rb b/app/models/gateway_setting.rb index e96bb52..a71b615 100644 --- a/app/models/gateway_setting.rb +++ b/app/models/gateway_setting.rb @@ -14,10 +14,7 @@ class GatewaySetting < ActiveRecord::Base 'contact' => 'String', 'dial_string' => 'String', 'profile' => 'String', - 'from' => 'String', - 'from_clir' => 'String', - 'asserted_identity' => 'String', - 'asserted_identity_clir' => 'String', + 'dtmf_type' => 'String', }, 'xmpp' => { 'server' => 'String', diff --git a/app/models/group_membership.rb b/app/models/group_membership.rb index 0f04ae1..d9d48e7 100644 --- a/app/models/group_membership.rb +++ b/app/models/group_membership.rb @@ -12,8 +12,6 @@ class GroupMembership < ActiveRecord::Base :presence => true, :uniqueness => { :scope => [:group_id, :item_id] } - validate :validate_item_type_consitency - validates :item, :presence => true @@ -27,11 +25,4 @@ class GroupMembership < ActiveRecord::Base return fist_item.class.name end end - - def validate_item_type_consitency - type_allowed = self.item_type_allowed - if type_allowed && type_allowed != self.item_type - errors.add(:item_type, "must be of type: #{type_allowed}") - end - end end diff --git a/app/models/hunt_group.rb b/app/models/hunt_group.rb index 93279ae..fac0cc5 100644 --- a/app/models/hunt_group.rb +++ b/app/models/hunt_group.rb @@ -2,7 +2,7 @@ class HuntGroup < ActiveRecord::Base attr_accessible :name, :strategy, :seconds_between_jumps, :phone_numbers_attributes belongs_to :tenant, :touch => true - has_many :destrination_call_forwards, :as => :destinationable, :dependent => :destroy + has_many :destrination_call_forwards, :class_name => 'CallForward', :as => :destinationable, :dependent => :destroy has_many :call_forwards, :as => :call_forwardable, :dependent => :destroy validates_uniqueness_of :name, :scope => :tenant_id, diff --git a/app/models/phone.rb b/app/models/phone.rb index 8b41b59..93553a2 100644 --- a/app/models/phone.rb +++ b/app/models/phone.rb @@ -13,6 +13,8 @@ class Phone < ActiveRecord::Base has_many :phone_sip_accounts, :dependent => :destroy, :uniq => true, :order => :position has_many :sip_accounts, :through => :phone_sip_accounts + + has_many :extension_modules belongs_to :tenant belongs_to :fallback_sip_account, :class_name => "SipAccount" @@ -195,8 +197,7 @@ class Phone < ActiveRecord::Base return true end - private - + private # Sanitize MAC address. # def sanitize_mac_address diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb index 668fbfe..a2644e9 100644 --- a/app/models/sip_account.rb +++ b/app/models/sip_account.rb @@ -154,14 +154,15 @@ class SipAccount < ActiveRecord::Base return SipRegistration.where(:sip_user => self.auth_name).first end - def call( phone_number, origin_cid_number = nil, origin_cid_name = 'Call' ) - origin_cid_number = origin_cid_number || phone_number + def call( phone_number, caller_id_number = nil, caller_id_name = 'Call', auto_answer = false ) require 'freeswitch_event' - return FreeswitchAPI.execute( + origination_uuid = UUID.new.generate + if FreeswitchAPI.execute( 'originate', - "{origination_uuid=#{UUID.new.generate},origination_caller_id_number='#{phone_number}',origination_caller_id_name='#{origin_cid_name}'}user/#{self.auth_name} #{phone_number}", - true - ); + "{origination_uuid=#{origination_uuid},origination_caller_id_number='#{caller_id_number||phone_number}',origination_caller_id_name='#{caller_id_name}',sip_auto_answer='#{auto_answer}'}user/#{self.auth_name} #{phone_number}", + true) + return origination_uuid + end end def target_group_ids_by_permission(permission) diff --git a/app/models/switchboard.rb b/app/models/switchboard.rb index 095f878..d62657f 100644 --- a/app/models/switchboard.rb +++ b/app/models/switchboard.rb @@ -25,8 +25,13 @@ class Switchboard < ActiveRecord::Base } belongs_to :user, :touch => true + has_many :switchboard_entries, :dependent => :destroy + has_many :switchable_switchboard_entries, :class_name => "SwitchboardEntry", :conditions => {:switchable => true} + has_many :sip_accounts, :through => :switchboard_entries + has_many :switchable_sip_accounts, :source => :sip_account, :through => :switchable_switchboard_entries, :uniq => true + has_many :phone_numbers, :through => :sip_accounts before_validation :convert_0_to_nil @@ -36,7 +41,11 @@ class Switchboard < ActiveRecord::Base end def active_calls - self.switchboard_entries.where(:switchable => true).map{|se| se.sip_account}.uniq.map{|sip_account| sip_account.calls}.flatten + Call.where("sip_account_id = ? or b_sip_account_id = ?", self.switchable_sip_account_ids, self.switchable_sip_account_ids).order(:start_stamp) + end + + def dispatchable_incoming_calls + Call.where("b_sip_account_id = ?", self.switchable_sip_account_ids).order(:start_stamp) end private diff --git a/app/models/user.rb b/app/models/user.rb index 5e97459..70c9042 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -107,6 +107,8 @@ class User < ActiveRecord::Base after_save :become_a_member_of_default_user_groups + after_save :change_language_of_child_objects + def destroy clean_whitelist_entries super @@ -246,4 +248,15 @@ class User < ActiveRecord::Base end end + def change_language_of_child_objects + if !self.language_id_changed? + return nil + end + + code = self.language.code + self.sip_accounts.each do |sip_account| + sip_account.update_attributes(:language_code => code) + end + end + end diff --git a/app/models/voicemail_account.rb b/app/models/voicemail_account.rb index 8ec181f..298516e 100644 --- a/app/models/voicemail_account.rb +++ b/app/models/voicemail_account.rb @@ -21,9 +21,9 @@ class VoicemailAccount < ActiveRecord::Base def notify_to send_notification = nil - if self.voicemail_settings.where(:name => 'notify', :value => true).first + if self.voicemail_settings.where(:name => 'notify', :value => 'true').first send_notification = true - elsif self.voicemail_settings.where(:name => 'notify', :value => false).first + elsif self.voicemail_settings.where(:name => 'notify', :value => 'false').first send_notification = false end @@ -49,9 +49,9 @@ class VoicemailAccount < ActiveRecord::Base def notification_setting(name) setting = nil - if self.voicemail_settings.where(:name => name, :value => true).first + if self.voicemail_settings.where(:name => name, :value => 'true').first setting = true - elsif self.voicemail_settings.where(:name => name, :value => false).first + elsif self.voicemail_settings.where(:name => name, :value => 'false').first setting = false end diff --git a/app/serializers/phone_book_entry_serializer.rb b/app/serializers/phone_book_entry_serializer.rb new file mode 100644 index 0000000..ac25832 --- /dev/null +++ b/app/serializers/phone_book_entry_serializer.rb @@ -0,0 +1,14 @@ +class PhoneBookEntrySerializer < ActiveModel::Serializer + embed :ids, :include => true + + attributes :id, :first_name, :last_name, :organization, :search_result_display + has_many :phone_numbers + + def search_result_display + result = "#{object.last_name}, #{object.first_name}".strip.gsub(/^, /,'').gsub(/,$/,'') + if result.blank? + result = "#{object.organization}" + end + return result + end +end diff --git a/app/serializers/sip_account_serializer.rb b/app/serializers/sip_account_serializer.rb index aa749b0..7465a17 100644 --- a/app/serializers/sip_account_serializer.rb +++ b/app/serializers/sip_account_serializer.rb @@ -1,7 +1,15 @@ class SipAccountSerializer < ActiveModel::Serializer embed :ids, :include => true - attributes :id, :auth_name, :caller_name, :sip_accountable_id + attributes :id, :auth_name, :caller_name, :sip_accountable_id, :is_registrated has_many :phone_numbers has_many :calls + + def is_registrated + if object.registration + true + else + false + end + end end diff --git a/app/serializers/switchboard_entry_serializer.rb b/app/serializers/switchboard_entry_serializer.rb index 1b6c761..5d76e16 100644 --- a/app/serializers/switchboard_entry_serializer.rb +++ b/app/serializers/switchboard_entry_serializer.rb @@ -1,5 +1,5 @@ class SwitchboardEntrySerializer < ActiveModel::Serializer - attributes :id, :name, :path_to_user, :avatar_src, :callstate + attributes :id, :name, :path_to_user, :avatar_src, :callstate, :switchable has_one :sip_account, embed: :ids has_one :switchboard, embed: :ids diff --git a/app/serializers/switchboard_serializer.rb b/app/serializers/switchboard_serializer.rb index 6d39667..8a8bd42 100644 --- a/app/serializers/switchboard_serializer.rb +++ b/app/serializers/switchboard_serializer.rb @@ -1,9 +1,10 @@ class SwitchboardSerializer < ActiveModel::Serializer embed :ids, :include => true - attributes :id, :name + attributes :id, :name, :show_avatars, :blind_transfer_activated, :attended_transfer_activated, :search_activated has_many :switchboard_entries has_many :sip_accounts, :through => :switchboard_entries has_many :phone_numbers has_many :active_calls + has_many :dispatchable_incoming_calls end diff --git a/app/views/call_forwards/_form_core.html.haml b/app/views/call_forwards/_form_core.html.haml index b730941..1c9ec30 100644 --- a/app/views/call_forwards/_form_core.html.haml +++ b/app/views/call_forwards/_form_core.html.haml @@ -7,11 +7,11 @@ = f.input :call_forwarding_destination , :as => :select, :collection => @call_forwarding_destinations, :label => t('call_forwards.form.call_forwarding_destination.label'), :hint => conditional_hint('call_forwards.form.call_forwarding_destination.hint'), :include_blank => false %div{:id => 'destination_phone_number_div'} - = f.input :destination, :label => t('call_forwards.form.destination_phone_number.label'), :hint => conditional_hint('call_forwards.form.destination_phone_number.hint'), :input_html => { :id => 'destination_phone_number', :value => @destination_phone_number } + = f.input :destination_phone_number, :label => t('call_forwards.form.destination_phone_number.label'), :hint => conditional_hint('call_forwards.form.destination_phone_number.hint'), :input_html => { :id => 'destination_phone_number' } - if @available_greetings.any? %div{:id => 'destination_greeting_div'} - = f.input :destination, :as => :select, :collection => @available_greetings, :label => t('call_forwards.form.destination_greeting.label'), :hint => conditional_hint('call_forwards.form.destination_greeting.hint'), :input_html => { :id => 'destination_greeting' } + = f.input :destination_greeting, :as => :select, :collection => @available_greetings, :label => t('call_forwards.form.destination_greeting.label'), :hint => conditional_hint('call_forwards.form.destination_greeting.hint'), :input_html => { :id => 'destination_greeting' } = f.input :active, :label => t('call_forwards.form.active.label'), :hint => conditional_hint('call_forwards.form.active.hint') diff --git a/app/views/call_histories/_index_core.html.haml b/app/views/call_histories/_index_core.html.haml index 9c2cf39..2915f35 100644 --- a/app/views/call_histories/_index_core.html.haml +++ b/app/views/call_histories/_index_core.html.haml @@ -65,7 +65,10 @@ - else = call_history.destination_number - elsif call_history.entry_type == 'dialed' - = call_history.caller_id_number + - if call_history.clir + %del= call_history.caller_id_number + - else + = call_history.caller_id_number - else = call_history.destination_number diff --git a/app/views/cdrs/_index_core.html.haml b/app/views/cdrs/_index_core.html.haml new file mode 100644 index 0000000..39e9e7f --- /dev/null +++ b/app/views/cdrs/_index_core.html.haml @@ -0,0 +1,33 @@ + +- if defined?(cdrs.total_pages) + = will_paginate cdrs, :renderer => BootstrapPagination::Rails, :previous_label => raw('<i class = "icon-chevron-left"></i>'), :next_label => raw('<i class = "icon-chevron-right"></i>') + +%table.table.table-striped + %thead + %tr + %th= sortable :start_stamp, t('cdrs.index.start_stamp') + %th= sortable :caller_id_number, t('cdrs.index.caller_id_number') + %th= sortable :caller_id_name, t('cdrs.index.caller_id_name') + %th= sortable :dialed_number, t('cdrs.index.dialed_number') + %th= sortable :destination_number, t('cdrs.index.destination_number') + %th= sortable :callee_id_number, t('cdrs.index.callee_id_number') + %th= sortable :callee_id_name, t('cdrs.index.callee_id_name') + %th= sortable :billsec, t('cdrs.index.billsec') + %th= sortable :hangup_cause, t('cdrs.index.hangup_cause') + %th= sortable :dialstatus, t('cdrs.index.dialstatus') + + %tbody + - for cdr in cdrs + %tr{:class => (cdr.dialstatus == 'SUCCESS' ? '' : 'warning')} + %td= l cdr.start_stamp, :format => :short + %td= cdr.caller_id_number + %td= cdr.caller_id_name + %td= cdr.dialed_number + %td= cdr.destination_number + %td= cdr.callee_id_number + %td= cdr.callee_id_name + %td= Cdr.seconds_to_minutes_seconds(cdr.billsec) + %td= cdr.hangup_cause + %td= cdr.dialstatus + + /=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => @tenant, :child => cdr} diff --git a/app/views/cdrs/index.html.haml b/app/views/cdrs/index.html.haml new file mode 100644 index 0000000..b260b38 --- /dev/null +++ b/app/views/cdrs/index.html.haml @@ -0,0 +1,4 @@ +- content_for :title, t("cdrs.index.page_title") + +- if @cdrs.count > 0 + = render "index_core", :cdrs => @cdrs diff --git a/app/views/config_snom/show.xml.haml b/app/views/config_snom/snom_phone.xml.haml index 22df8bc..39b5958 100644 --- a/app/views/config_snom/show.xml.haml +++ b/app/views/config_snom/snom_phone.xml.haml @@ -37,6 +37,7 @@ %display_method{:perm => 'RW'}= 'display_name_number' %callpickup_dialoginfo{:perm => 'RW'}= 'on' %pickup_indication{:perm => 'RW'}= 'off' + %auto_connect_indication{:perm => 'RW'}= 'off' %show_local_line{:perm => 'RW'}= 'off' %mwi_notification{:perm => 'RW'}= 'silent' %mwi_dialtone{:perm => 'RW'}= 'normal' @@ -55,6 +56,9 @@ %guess_start_length{:perm => 'RW'}= '3' %ieee8021x_eap_md5_username{:perm => 'RW'}= GsParameter.get('PROVISIONING_IEEE8021X_EAP_USERNAME') %ieee8021x_eap_md5_password{:perm => 'RW'}= GsParameter.get('PROVISIONING_IEEE8021X_EAP_PASSWORD') + %vision_connected_mac{:perm => 'RW'}= @phone_settings[:vision_mac_address] + %vision_provisioning_url{:perm => 'RW'}= @phone_settings[:vision_provisioning_url] + %vision_reconnect_timeout{:perm => 'RW'}= '15' - 0.upto(9) do |ringer_idx| %internal_ringer_text{:idx => ringer_idx, :perm => 'RW'}= "Ringer#{(ringer_idx+1)}" @@ -170,8 +174,8 @@ %functionKeys - @softkeys.each_with_index do |softkey, index| - - if softkey[:data] - %fkey{:idx => index, :context => (softkey[:context] ? softkey[:context].to_s : 'active'), :label => softkey[:label], :perm => 'RW'}= softkey[:data] + - if softkey[:type] + %fkey{:idx => index, :context => (softkey[:context] ? softkey[:context].to_s : 'active'), :label => softkey[:label], :perm => 'RW'}= "#{softkey[:type]} #{softkey[:value]}" - elsif softkey[:general_type] %fkey{:idx => index, :context => (softkey[:context] ? softkey[:context].to_s : 'active'), :label => softkey[:label], :perm => 'RW'} %general{:type => softkey[:general_type]} diff --git a/app/views/config_snom/snom_vision.xml.haml b/app/views/config_snom/snom_vision.xml.haml new file mode 100644 index 0000000..053feb9 --- /dev/null +++ b/app/views/config_snom/snom_vision.xml.haml @@ -0,0 +1,52 @@ +!!! XML +%settings + %webserver + %auth_type{:perm => '$'}= @settings[:auth_type] + %user{:perm => '!'}= @settings[:user] + %passwd{:perm => '!'}= @settings[:passwd] + + %global + %periodic_provisioning{:perm => '$'} + %periodic_provisioning_interval{:perm => '$'} + %provisioning_server{:perm => '!'}= @settings[:provisioning_server] + + %gui + %phone_ip{:perm => '!'}= @settings[:phone_ip] + %phone_scheme{:perm => '$'}https + %phone_user{:perm => '!'}= @settings[:user] + %phone_passwd{:perm => '!'}= @settings[:passwd] + + != "\<!-- active buttons: #{@buttons.count} --\>" + - index_left = 0 + - index_right = 0 + - for page in 1..3 do + != "\<!-- page: #{page} --\>" + - for key in 1..8 do + - index_left = index_left + 1 + - button = @buttons.shift + - if !button + - button = {} + + %left_button_imageurl{:idx=> index_left, :perm=>"!"}= button[:imageurl] + %left_button_name{:idx=> index_left, :perm=>"!"}= button[:label] + - if button[:general_type].blank? + %left_button_type{:idx=> index_left, :perm=>"!"}= button[:type] + %left_button_value{:idx=> index_left, :perm=>"!"}= button[:value] + - else + %left_button_type{:idx=> index_left, :perm=>"!"} xml + %left_button_value{:idx=> index_left, :perm=>"!"} + + - for key in 1..8 do + - index_right = index_right + 1 + - button = @buttons.shift + - if !button + - button = {} + + %right_button_imageurl{:idx=> index_right, :perm=>"!"}= button[:imageurl] + %right_button_name{:idx=> index_right, :perm=>"!"}= button[:label] + - if button[:general_type].blank? + %right_button_type{:idx=> index_right, :perm=>"!"}= button[:type] + %right_button_value{:idx=> index_right, :perm=>"!"}= button[:value] + - else + %right_button_type{:idx=> index_right, :perm=>"!"} xml + %right_button_value{:idx=> index_right, :perm=>"!"} diff --git a/app/views/extension_modules/_form.html.haml b/app/views/extension_modules/_form.html.haml new file mode 100644 index 0000000..496e695 --- /dev/null +++ b/app/views/extension_modules/_form.html.haml @@ -0,0 +1,7 @@ += simple_form_for([@phone, @extension_module]) do |f| + = f.error_notification + + = render "form_core", :f => f + + .form-actions + = f.button :submit, conditional_t('extension_modules.form.submit') diff --git a/app/views/extension_modules/_form_core.html.haml b/app/views/extension_modules/_form_core.html.haml new file mode 100644 index 0000000..bea4a77 --- /dev/null +++ b/app/views/extension_modules/_form_core.html.haml @@ -0,0 +1,6 @@ +.inputs + = f.input :model, :collection => ExtensionModule::MODELS, :label => t('extension_modules.form.model.label'), :hint => conditional_hint('extension_modules.form.model.hint'), :include_blank => false + = f.input :mac_address, :label => t('extension_modules.form.mac_address.label'), :hint => conditional_hint('extension_modules.form.mac_address.hint') + = f.input :position, :label => t('extension_modules.form.position.label'), :hint => conditional_hint('extension_modules.form.position.hint') + = f.input :active, :label => t('extension_modules.form.active.label'), :hint => conditional_hint('extension_modules.form.active.hint') + = f.input :provisioning_key_active, :label => t('extension_modules.form.provisioning_key_active.label'), :hint => conditional_hint('extension_modules.form.provisioning_key_active.hint') diff --git a/app/views/extension_modules/_index_core.html.haml b/app/views/extension_modules/_index_core.html.haml new file mode 100644 index 0000000..d5aef48 --- /dev/null +++ b/app/views/extension_modules/_index_core.html.haml @@ -0,0 +1,13 @@ +%table.table.table-striped + %tr + %th= t('extension_modules.index.model') + %th= t('extension_modules.index.mac_address') + %th= t('extension_modules.index.active') + + + - for extension_module in extension_modules + %tr + %td= extension_module.model + %td= extension_module.mac_address + %td= extension_module.active + =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => @phone, :child => extension_module}
\ No newline at end of file diff --git a/app/views/extension_modules/edit.html.haml b/app/views/extension_modules/edit.html.haml new file mode 100644 index 0000000..4fcb09b --- /dev/null +++ b/app/views/extension_modules/edit.html.haml @@ -0,0 +1,3 @@ +- content_for :title, t("extension_modules.edit.page_title") + += render "form"
\ No newline at end of file diff --git a/app/views/extension_modules/index.html.haml b/app/views/extension_modules/index.html.haml new file mode 100644 index 0000000..7a57eb5 --- /dev/null +++ b/app/views/extension_modules/index.html.haml @@ -0,0 +1,6 @@ +- content_for :title, t("extension_modules.index.page_title") + +- if @extension_modules && @extension_modules.count > 0 + = render "index_core", :extension_modules => @extension_modules + += render :partial => 'shared/create_link', :locals => {:parent => @phone, :child_class => ExtensionModule}
\ No newline at end of file diff --git a/app/views/extension_modules/new.html.haml b/app/views/extension_modules/new.html.haml new file mode 100644 index 0000000..2b4ae9a --- /dev/null +++ b/app/views/extension_modules/new.html.haml @@ -0,0 +1,3 @@ +- content_for :title, t("extension_modules.new.page_title") + += render "form"
\ No newline at end of file diff --git a/app/views/extension_modules/show.html.haml b/app/views/extension_modules/show.html.haml new file mode 100644 index 0000000..ac9d099 --- /dev/null +++ b/app/views/extension_modules/show.html.haml @@ -0,0 +1,22 @@ +- content_for :title, t("extension_modules.show.page_title") + +%p + %strong= t('extension_modules.show.model') + ":" + = @extension_module.model +%p + %strong= t('extension_modules.show.mac_address') + ":" + = @extension_module.mac_address +%p + %strong= t('extension_modules.show.position') + ":" + = @extension_module.position +%p + %strong= t('extension_modules.show.active') + ":" + = @extension_module.active +%p + %strong= t('extension_modules.show.provisioning_key_active') + ":" + = @extension_module.provisioning_key_active + +%p + = link_to raw("<i class = 'icon-repeat'></i> ") + t('extension_modules.show.actions.restart'), restart_phone_extension_module_path(@phone, @extension_module), :method => :put, :class => 'btn btn-mini' + += render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @phone, :child => @extension_module } diff --git a/app/views/gateway_headers/_form.html.haml b/app/views/gateway_headers/_form.html.haml new file mode 100644 index 0000000..0bd8f31 --- /dev/null +++ b/app/views/gateway_headers/_form.html.haml @@ -0,0 +1,7 @@ += simple_form_for([@gateway, @gateway_header]) do |f| + = f.error_notification + + = render "form_core", :f => f + + .form-actions + = f.button :submit, conditional_t('gateway_headers.form.submit') diff --git a/app/views/gateway_headers/_form_core.html.haml b/app/views/gateway_headers/_form_core.html.haml new file mode 100644 index 0000000..9a917d4 --- /dev/null +++ b/app/views/gateway_headers/_form_core.html.haml @@ -0,0 +1,7 @@ +.inputs + = f.input :header_type, :collection => GatewayHeader::HEADER_TYPES, :label => t('gateway_headers.form.header_type.label'), :hint => conditional_hint('gateway_headers.form.header_type.hint'), :include_blank => false + = f.input :constraint_value, :label => t('gateway_headers.form.constraint_value.label'), :hint => conditional_hint('gateway_headers.form.constraint_value.hint') + = f.input :name, :label => t('gateway_headers.form.name.label'), :hint => conditional_hint('gateway_headers.form.name.hint'), :autofocus => true + = f.input :value, :label => t('gateway_headers.form.value.label'), :hint => conditional_hint('gateway_headers.form.value.hint') + + = f.input :description, :label => t('gateway_headers.form.description.label'), :hint => conditional_hint('gateway_headers.form.description.hint') diff --git a/app/views/gateway_headers/_index_core.html.haml b/app/views/gateway_headers/_index_core.html.haml new file mode 100644 index 0000000..69b1cf2 --- /dev/null +++ b/app/views/gateway_headers/_index_core.html.haml @@ -0,0 +1,17 @@ +%table.table.table-striped + %thead + %tr + %th= t('gateway_headers.index.header_type') + %th= t('gateway_headers.index.constraint') + %th= t('gateway_headers.index.name') + %th= t('gateway_headers.index.value') + + %tbody + - for gateway_header in gateway_headers + %tr + %td= gateway_header.header_type + %td + = gateway_header.constraint_value + %td= gateway_header.name + %td= gateway_header.value + =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => gateway_header.gateway, :child => gateway_header} diff --git a/app/views/gateway_headers/edit.html.haml b/app/views/gateway_headers/edit.html.haml new file mode 100644 index 0000000..461ee17 --- /dev/null +++ b/app/views/gateway_headers/edit.html.haml @@ -0,0 +1,3 @@ +- content_for :title, t("gateway_headers.edit.page_title") + += render "form"
\ No newline at end of file diff --git a/app/views/gateway_headers/index.html.haml b/app/views/gateway_headers/index.html.haml new file mode 100644 index 0000000..8760b5e --- /dev/null +++ b/app/views/gateway_headers/index.html.haml @@ -0,0 +1,6 @@ +- content_for :title, t("gateway_headers.index.page_title") + +- if @gateway_headers && @gateway_headers.count > 0 + = render "index_core", :gateway_headers => @gateway_headers + += render :partial => 'shared/create_link', :locals => {:parent => @gateway, :child_class => GatewayHeader}
\ No newline at end of file diff --git a/app/views/gateway_headers/new.html.haml b/app/views/gateway_headers/new.html.haml new file mode 100644 index 0000000..3f6ea8e --- /dev/null +++ b/app/views/gateway_headers/new.html.haml @@ -0,0 +1,3 @@ +- content_for :title, t("gateway_headers.new.page_title") + += render "form"
\ No newline at end of file diff --git a/app/views/gateway_headers/show.html.haml b/app/views/gateway_headers/show.html.haml new file mode 100644 index 0000000..4f1af49 --- /dev/null +++ b/app/views/gateway_headers/show.html.haml @@ -0,0 +1,19 @@ +- content_for :title, t("gateway_headers.show.page_title") + +%p + %strong= t('gateway_headers.show.gateway') + ":" + = @gateway_header.gateway +%p + %strong= t('gateway_headers.show.name') + ":" + = @gateway_header.name +%p + %strong= t('gateway_headers.show.value') + ":" + = @gateway_header.value +%p + %strong= t('gateway_headers.show.class_type') + ":" + = @gateway_header.class_type +%p + %strong= t('gateway_headers.show.description') + ":" + = @gateway_header.description + += render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @gateway, :child => @gateway_header }
\ No newline at end of file diff --git a/app/views/gateways/show.html.haml b/app/views/gateways/show.html.haml index 19b1304..397b9cf 100644 --- a/app/views/gateways/show.html.haml +++ b/app/views/gateways/show.html.haml @@ -118,6 +118,12 @@ %br = render :partial => 'shared/create_link', :locals => { :parent => @gateway, :child_class => GatewaySetting } +%h3= t('gateway_headers.index.page_title') +- if @gateway.gateway_headers.any? + = render "gateway_headers/index_core", :gateway_headers => @gateway.gateway_headers + %br += render :partial => 'shared/create_link', :locals => { :parent => @gateway, :child_class => GatewayHeader } + %h3= t('gateway_parameters.index.page_title') - if @gateway.gateway_parameters.any? = render "gateway_parameters/index_core", :gateway_parameters => @gateway.gateway_parameters diff --git a/app/views/group_memberships/_form_core.html.haml b/app/views/group_memberships/_form_core.html.haml index 4a28a06..cadd33a 100644 --- a/app/views/group_memberships/_form_core.html.haml +++ b/app/views/group_memberships/_form_core.html.haml @@ -1,4 +1,3 @@ .inputs - - if @group.group_memberships.count < 1 - = f.input :item_type, :label => t('group_memberships.form.item_type.label'), :hint => conditional_hint('group_memberships.form.item_type.hint') + = f.input :item_type, :label => t('group_memberships.form.item_type.label'), :hint => conditional_hint('group_memberships.form.item_type.hint') = f.input :item_id, :label => t('group_memberships.form.item_id.label'), :hint => conditional_hint('group_memberships.form.item_id.hint') diff --git a/app/views/notifications/new_voicemail.text.erb b/app/views/notifications/new_voicemail.text.erb index 926610b..09edc0c 100644 --- a/app/views/notifications/new_voicemail.text.erb +++ b/app/views/notifications/new_voicemail.text.erb @@ -6,4 +6,6 @@ You've just received a voicemail on your Gemeinschaft account <%= @voicemail[:de To: <%= @voicemail[:to] %> Receiving Time: <%= @voicemail[:date] %> Message length: <%= @voicemail[:duration] %> +<% if !@voicemail[:file_name].blank? %> File: <%= @voicemail[:file_name] %> +<% end %> diff --git a/app/views/phones/show.html.haml b/app/views/phones/show.html.haml index 1996d48..1e9c7ed 100644 --- a/app/views/phones/show.html.haml +++ b/app/views/phones/show.html.haml @@ -96,3 +96,12 @@ = render "phone_sip_accounts/index_core", :phone_sip_accounts => @phone.phone_sip_accounts = render :partial => 'shared/create_link', :locals => {:parent => @phone, :child_class => PhoneSipAccount} + +.row + .span12 + %h2= t("extension_modules.index.page_title") + - if @phone.extension_modules.any? + = render "extension_modules/index_core", :extension_modules => @phone.extension_modules + + = render :partial => 'shared/create_link', :locals => {:parent => @phone, :child_class => ExtensionModule} + diff --git a/app/views/sip_accounts/_index_core.html.haml b/app/views/sip_accounts/_index_core.html.haml index be1f4cb..57641ce 100644 --- a/app/views/sip_accounts/_index_core.html.haml +++ b/app/views/sip_accounts/_index_core.html.haml @@ -1,6 +1,6 @@ -- if defined?(users.total_pages) - = will_paginate users, :renderer => BootstrapPagination::Rails, :previous_label => raw('<i class = "icon-chevron-left"></i>'), :next_label => raw('<i class = "icon-chevron-right"></i>') +- if defined?(sip_accounts.total_pages) + = will_paginate sip_accounts, :renderer => BootstrapPagination::Rails, :previous_label => raw('<i class = "icon-chevron-left"></i>'), :next_label => raw('<i class = "icon-chevron-right"></i>') %table.table.table-striped %thead @@ -26,7 +26,7 @@ %td = sip_account.sip_accountable %td - - if sip_account.registration + - if sip_account.registration && (sip_account.registration.expires - Time.now.to_i) > 0 %i.icon-ok - else %i.icon-ban-circle diff --git a/app/views/sip_accounts/show.html.haml b/app/views/sip_accounts/show.html.haml index a7cd3ce..0974ee5 100644 --- a/app/views/sip_accounts/show.html.haml +++ b/app/views/sip_accounts/show.html.haml @@ -42,6 +42,11 @@ %strong= t('sip_accounts.show.voicemail_account') + ":" %td = @sip_account.voicemail_account + %tr + %td + %strong= t('sip_accounts.show.language_code') + ":" + %td + = @sip_account.language_code - if @sip_account.registration.try(:network_ip) && @sip_account.registration.try(:network_port) %tr diff --git a/app/views/switchboard_entries/_form_core.html.haml b/app/views/switchboard_entries/_form_core.html.haml index 6f340c2..2caaba5 100644 --- a/app/views/switchboard_entries/_form_core.html.haml +++ b/app/views/switchboard_entries/_form_core.html.haml @@ -1,3 +1,4 @@ .inputs = f.association :sip_account, :collection => @sip_accounts, :label => t('switchboard_entries.form.sip_account_id.label'), :hint => conditional_hint('switchboard_entries.form.sip_account_id.hint'), :autofocus => true, :include_blank => false = f.input :name, :label => t('switchboard_entries.form.name.label'), :hint => conditional_hint('switchboard_entries.form.name.hint') + = f.input :switchable, :as => :boolean, :label => t('switchboard_entries.form.switchable.label'), :hint => conditional_hint('switchboard_entries.form.switchable.hint')
\ No newline at end of file diff --git a/app/views/switchboard_entries/show.html.haml b/app/views/switchboard_entries/show.html.haml index b519781..85b8166 100644 --- a/app/views/switchboard_entries/show.html.haml +++ b/app/views/switchboard_entries/show.html.haml @@ -18,5 +18,10 @@ %strong= t('switchboard_entries.show.position') + ":" %td = @switchboard_entry.position + %tr + %td + %strong= t('switchboard_entries.show.switchable') + ":" + %td + = @switchboard_entry.switchable = render :partial => 'shared/show_edit_destroy_part', :locals => {:parent => @switchboard, :child => @switchboard_entry }
\ No newline at end of file diff --git a/app/views/switchboards/_form_core.html.haml b/app/views/switchboards/_form_core.html.haml index 2258640..db843ad 100644 --- a/app/views/switchboards/_form_core.html.haml +++ b/app/views/switchboards/_form_core.html.haml @@ -3,4 +3,8 @@ = f.input :reload_interval, :label => t('switchboards.form.reload_interval.label'), :hint => conditional_hint('switchboards.form.reload_interval.hint') = f.input :show_avatars, :label => t('switchboards.form.show_avatars.label'), :hint => conditional_hint('switchboards.form.show_avatars.hint') = f.input :entry_width, :label => t('switchboards.form.entry_width.label'), :hint => conditional_hint('switchboards.form.entry_width.hint') - = f.input :amount_of_displayed_phone_numbers, :label => t('switchboards.form.amount_of_displayed_phone_numbers.label'), :hint => conditional_hint('switchboards.form.amount_of_displayed_phone_numbers.hint')
\ No newline at end of file + = f.input :amount_of_displayed_phone_numbers, :label => t('switchboards.form.amount_of_displayed_phone_numbers.label'), :hint => conditional_hint('switchboards.form.amount_of_displayed_phone_numbers.hint') + = f.input :blind_transfer_activated, :label => t('switchboards.form.blind_transfer_activated.label'), :hint => conditional_hint('switchboards.form.blind_transfer_activated.hint') + = f.input :attended_transfer_activated, :label => t('switchboards.form.attended_transfer_activated.label'), :hint => conditional_hint('switchboards.form.attended_transfer_activated.hint') + = f.input :search_activated, :label => t('switchboards.form.search_activated.label'), :hint => conditional_hint('switchboards.form.search_activated.hint') + = f.input :reverse_lookup_activated, :label => t('switchboards.form.reverse_lookup_activated.label'), :hint => conditional_hint('switchboards.form.reverse_lookup_activated.hint')
\ No newline at end of file diff --git a/app/views/switchboards/show.html.erb b/app/views/switchboards/show.html.erb index 2a2765f..b2cdbd4 100644 --- a/app/views/switchboards/show.html.erb +++ b/app/views/switchboards/show.html.erb @@ -16,53 +16,120 @@ </script> <script type="text/x-handlebars" data-template-name="switchboard"> - <h2>{{name}}</h2> + {{#if activeCalls.length}} + {{#each activeCall in activeCalls}} + <div {{bindAttr class=":alert activeCall.isActive:alert-success"}}> + {{#if activeCall.isRinging}}<i class="icon-bell"></i> Neuer {{/if}} + <button type="button" class="close" data-dismiss="alert">×</button> + Anruf von {{activeCall.b_caller_id_number}} an {{activeCall.destination}} ({{from_now activeCall.start_stamp}}). + </div> + {{/each}} + {{/if}} + + {{#if search_activated}} + <div class="well span3 pull-right"> + <p> + {{input type="text" value=searchText size="10" placeholder="Suchen..."}} + </p> + <ul> + {{#each phoneBookEntry in searchResults}} + <li> + {{phoneBookEntry.search_result_display}}<br /> + + {{#each phoneNumber in phoneBookEntry.phoneNumbers}} + <span class="label"> + {{phoneNumber.number}} + </span> + + {{#each dispatchableIncomingCall in dispatchableIncomingCalls}} + {{#if blind_transfer_activated}} + <button {{action transfer_blind dispatchableIncomingCall.id phoneNumber.number}} class="btn btn-small">Transfer</button> + {{/if}} + {{#if attended_transfer_activated}} + <button {{action transfer_attended dispatchableIncomingCall.id phoneNumber.number}} class="btn btn-small">Attended Transfer</button> + {{/if}} + {{/each}} + {{/each}} + </li> + {{/each}} + </ul> + </div> + {{/if}} {{#if switchboardEntrys.length}} <ul class="thumbnails"> {{#each switchboardEntry in switchboardEntrys}} <li class="span2"> <div class="thumbnail"> - {{avatar_img switchboardEntry.avatar_src}} - <small> - <p> + {{#if switchboardEntry.switchboard.show_avatars}} + {{avatar_img switchboardEntry.avatar_src}} + {{/if}} + <small> + <p></p> + {{#if switchboardEntry.name}} + <p class="text-center"> <span class="label">{{switchboardEntry.name}}</span> + </p> + {{/if}} + {{#if switchboardEntry.sipAccount.is_registrated}} + {{#if switchboardEntry.switchable}} + <p> {{#each phoneNumber in switchboardEntry.sipAccount.phoneNumberShortList}} <span class="label"> {{phoneNumber.number}} </span> {{/each}} - </p> - - {{show_callstate switchboardEntry.callstate}} - {{#if switchboardEntry.sipAccount.calls.length}} + </p> + {{else}} <p> - Anrufe: - <br> - {{#each call in switchboardEntry.sipAccount.calls}} - <span {{bindAttr class=":label call.isActive:label-success"}}> - {{call.b_caller_id_number}} -> {{call.destination}} - {{#if call.isActive}} - * - {{/if}} + {{#each phoneNumber in switchboardEntry.sipAccount.phoneNumberShortList}} + <span class="label"> + {{phoneNumber.number}} </span> + + {{#if dispatchableIncomingCalls.length}} + <p> + {{#each dispatchableIncomingCall in dispatchableIncomingCalls}} + {{#if switchboardEntry.switchboard.blind_transfer_activated}} + <button {{action transfer_blind dispatchableIncomingCall.id phoneNumber.number}} class="btn btn-small">Transfer</button> + {{/if}} + {{#if switchboardEntry.switchboard.attended_transfer_activated}} + <button {{action transfer_attended dispatchableIncomingCall.id phoneNumber.number}} class="btn btn-small">Attended Transfer</button> + {{/if}} + {{/each}} + </p> + {{/if}} {{/each}} </p> {{/if}} - {{#if activeCalls.length}} + {{#if switchboardEntry.sipAccount.calls.length}} <p> - Verbinden mit: - <br> - {{#each activeCall in activeCalls}} - <button {{action blind_transfer}}> - {{activeCall.b_caller_id_number}} - </button> - {{/each}} + {{#each call in switchboardEntry.sipAccount.calls}} + <span {{bindAttr class=":label call.isRinging:label-warning:label-success"}}> + {{#if call.isRinging}}<i class="icon-bell icon-white"></i>{{/if}} + von {{call.b_caller_id_number}} an {{call.destination}} + </span> + {{/each}} </p> {{/if}} - </small> + {{else}} + <p> + {{#each phoneNumber in switchboardEntry.sipAccount.phoneNumberShortList}} + <span class="label"> + {{phoneNumber.number}} + </span> + {{/each}} + </p> + + <p> + <span class="label label-warning"> + offline + </span> + </p> + {{/if}} + </small> </div> </li> {{/each}} @@ -73,6 +140,8 @@ </div> </div> +<script src="/js/libs/moment/moment.min.js"></script> +<script src="/js/libs/moment/lang/de.js"></script> <script src="/js/libs/handlebars.js"></script> <script src="/js/libs/ember.js"></script> <script src="/js/libs/ember-data.js"></script> diff --git a/app/views/voicemail_settings/_edit_form_core.html.haml b/app/views/voicemail_settings/_edit_form_core.html.haml index 4352f24..81ab2f8 100644 --- a/app/views/voicemail_settings/_edit_form_core.html.haml +++ b/app/views/voicemail_settings/_edit_form_core.html.haml @@ -1,2 +1,2 @@ .inputs - = f.input :value, :label => t("voicemail_settings.settings.#{@voicemail_setting.name.to_s}"), :hint => @voicemail_setting.description, :as => @input_type, input_html: @input_html + = f.input :value, :label => t("voicemail_settings.settings.#{@voicemail_setting.name.to_s}"), :hint => @voicemail_setting.description, :as => @input_type, input_html: @input_html |