class ApiController < ApplicationController
session :off, :except => [:login, :login_form]
include SqlExport
require 'builder/xmlbase'
before_filter :check_allow_api
before_filter :check_send_method, :except => [:simple_balance, :balance]
before_filter :log_access
before_filter :find_current_user_for_api, :only => [:user_subscriptions, :user_invoices, :personal_payments, :user_rates, :callflow_edit, :devices_callflow, :user_devices, :main_page, :logout, :cc_by_cli, :create_payment, :payments_list, :show_calling_card_group, :buy_card_from_callingroup, :financial_statements]
before_filter :check_mor_11_extend, :only => [:credit_notes, :credit_note_update, :credit_note_delete, :credit_note_create, :financial_statements, :create_payment, :cc_by_cli, :show_calling_card_group, :buy_card_from_callingroup, :send_sms]
before_filter :check_api_parrams_with_hash, :only => [:show_calling_card_group, :buy_card_from_callingroup, :cc_by_cli, :financial_statements]
before_filter :check_calling_card_addon, :only => [:show_calling_card_group, :cc_by_cli, :buy_card_from_callingroup]
before_filter :check_sms_addon, :only => [:send_sms]
def method_missing(method_name, *args, &block)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.error {
doc.type("Undefined method")
doc.name(method_name.to_s)
}
#logger.info out_string
send_xml_data(out_string, params[:test].to_i)
end
#logins user to the system
def login
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8", :standalone => "yes"
check_user(params[:u], params[:p])
login_ok = false
if @user
add_action(@user.id, "login", request.env["REMOTE_ADDR"].to_s)
@user.logged = 1
@user.save
if Confline.get_value("API_Login_Redirect_to_Main").to_i == 0
doc.action {
doc.name("login")
doc.status("ok")
doc.user_id("#{@user.id.to_s}")
doc.status_message("Succesfully logged in")
}
else
login_ok = true
renew_session(@user)
session[:login] = login_ok
check_devices()
end
else
add_action2(0, "bad_login", params[:u].to_s + "/" + params[:p].to_s, request.env["REMOTE_ADDR"].to_s)
doc.action {
doc.name("login")
doc.status("failed")
if Action.disable_login_check(request.env["REMOTE_ADDR"].to_s).to_i == 0
doc.status_message("Please wait 10 seconds before trying to login again")
else
doc.status_message("Login failed")
end
}
end
if Confline.get_value("API_Login_Redirect_to_Main").to_i == 1 and login_ok
bad_psw = (params[:p].to_s == 'admin' and @user.id == 0) ? _('ATTENTION!_Please_change_admin_password_from_default_one_Press')+ " #{_('Here')} " + _('to_do_this') : ''
flash[:notice] = bad_psw if !bad_psw.blank?
flash[:status] = _('login_succesfull')
redirect_to :controller => :callc, :action => :main and return false
else
send_xml_data(out_string, params[:test].to_i)
end
end
#logout user from the system
def logout
username = params[:u]
password = params[:p]
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
if username.length > 0 and password.length > 0
add_action(@current_user.id, "logout", "")
user.logged = 0
user.save
doc.action {
doc.name("logout")
doc.status("ok")
}
else
doc.action {
doc.name("logout")
doc.status("failed")
}
end
send_xml_data(out_string, params[:test].to_i)
end
#Initiates callback
def callback
if callback_active?
username = params[:u].to_s
password = params[:p].to_s
user = User.find(:first, :conditions => ["username = ? and password = ?", username, Digest::SHA1.hexdigest(password)])
if username.length > 0 and password.length > 0 and user
device = Device.find(:first, :conditions => ["id =?", params[:device]])
if params[:device] and device and device.user_id == user.id
if params[:src] and params[:src].length > 0
src = params[:src]
dst = ""
dst = params[:dst] if params[:dst]
channel = "Local/#{src}@mor_cb_src/n"
if dst.length > 0
originate_call(device.id, src, channel, "mor_cb_dst", dst, device.callerid_number)
else
originate_call(device.id, src, channel, "mor_cb_dst_ask", "123", device.callerid_number)
end
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Status("Ok")
else
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Status("No source")
end
else
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Status("Bad device")
end
else
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Status("Not authenticated")
end
else
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Status("Dont be so smart")
end
send_xml_data(out_string, params[:test].to_i)
end
#Retrieves list of invoices in selected time period.
=begin rdoc
Returns invoices for selected user in selected period
*Params*
* +file+ - return file or plain response. Values - [true, false] Default : true
=end
def invoices
MorLog.my_debug("INVOICES")
opts = {}
["true", "false"].include?(params[:file].to_s) ? opts[:file] = params[:file] : opts[:file] = "true"
username = params[:u]
password = params[:p]
from = params[:from]
till = params[:till]
username = "" if not username
password = "" if not password
from = 0 if not password
till = 0 if not password
from_t = Time.at(from.to_i)
till_t = Time.at(till.to_i)
from_nice = nice_date(from_t, 0)
till_nice = nice_date(till_t, 0)
user = User.find(:first, :conditions => ["username = ? and password = ?", username, Digest::SHA1.hexdigest(password)])
if user
User.current = user
cond = ""
case user.usertype.to_s
when "admin"
cond = " AND users.owner_id = #{user.id}"
when "accountant"
cond = " AND users.owner_id = #{user.owner_id}"
when "reseller"
cond = " AND (users.owner_id = #{user.id} OR users.id = #{user.id})"
when "user"
cond = " AND invoices.user_id = #{user.id}"
end
invoices = Invoice.find(:all, :select => "invoices.*", :joins => "JOIN users on (users.id = invoices.user_id)", :conditions => ["period_start >= ? AND period_end <= ? AND users.generate_invoice != 0 #{cond}", from_nice, till_nice])
if invoices or invoices.size == 0
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Invoices("from" => from_nice, "till" => till_nice) {
for inv in invoices
iuser = inv.user
doc.Invoice("user_id" => inv.user_id, "agreementnumber" => iuser.agreement_number, "clientid" => iuser.clientid, "number" => inv.number) {
for invdet in inv.invoicedetails
doc.Product {
doc.Name(invdet.name)
doc.Quantity(invdet.quantity)
doc.Price(nice_number(invdet.price))
doc.Date_added((inv.payment ? nice_date(inv.payment.date_added, 0) : ''))
doc.Issue_date(nice_date(inv.issue_date, 0))
}
end
}
end
}
else
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Error("no invoices found")
end
else
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.Error("user not found")
end
#return out_string
if opts[:file] == "true"
if confline("XML_API_Extension").to_i == 0
send_data(out_string, :type => "text/xml", :filename => "mor_api_response.xml")
else
send_data(out_string, :type => "text/html", :filename => "mor_api_response.html")
end
else
render :text => out_string
end
end
def login_form
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8", :standalone => "yes"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
doc.page {
doc.pagename("Login page")
doc.language("#{Localization.lang}")
doc.error_msg("")
doc.aval_languages {
}
}
else
doc.page {
doc.pagename("Login page")
doc.language("#{Localization.lang}")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def payments_list
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8", :standalone => "yes"
if @current_user.is_accountant?
unless @current_user.accountant_allow_read('payments_manage')
doc.status { doc.error(_('Dont_be_so_smart')) }
send_xml_data(out_string, params[:test].to_i)
return false
end
end
if allow == true
#show uncompleted payments?
hide_uncompleted_payment = Confline.get_value("Hide_non_completed_payments_for_user", 0).to_i
@options = {}
[:s_transaction, :s_completed, :s_username, :s_first_name, :s_last_name, :s_paymenttype, :s_amount_min, :s_amount_max, :s_currency, :s_user_id, :s_from, :s_till, :s_number, :s_pin].each { |key|
params[key] ? @options[key] = params[key].to_s : (@options[key] = "" if !@options[key])
}
#set correct owner id;
if @current_user.usertype == 'accountant' or @current_user.usertype == 'admin'
@owner_id = 0
elsif @current_user.usertype == 'reseller'
if @options[:s_user_id].to_i == @user.id.to_i
@owner_id = 0
else
@owner_id = @current_user.id
end
else
#user can see only his, so overwrite s_user_id
@owner_id = @current_user.owner_id
@options[:s_user_id] = @current_user.id
end
if @options[:s_user_id] and !@options[:s_user_id].blank?
if !@current_user.is_user?
if @options[:s_user_id] =~ /[0-9]/
user = User.find(:first, :conditions => {:id => @options[:s_user_id], :owner_id => @owner_id})
end
unless user
doc.status { doc.error(_('Dont_be_so_smart')) }
send_xml_data(out_string, params[:test].to_i)
return false
end
end
end
cond = ["date_added BETWEEN ? AND ?"]
cond << "payments.owner_id = ?"
#default today
if !@options[:s_from].blank? and !@options[:s_till].blank?
cond_param = ["#{q(Time.at(@options[:s_from].to_i).to_s(:db))}", "#{q(Time.at(@options[:s_till].to_i).to_s(:db))}", @owner_id]
else
cond_param = ["#{Time.mktime(Time.now.year, Time.now.month, Time.now.day, 0, 0, 0).to_s(:db)}", "#{Time.mktime(Time.now.year, Time.now.month, Time.now.day, 23, 59, 59).to_s(:db)}", @owner_id]
end
if hide_uncompleted_payment == 1
cond << " (payments.pending_reason != 'Unnotified payment' or payments.pending_reason is null)"
end
["username", "first_name", "last_name"].each { |col|
add_contition_and_param(@options["s_#{col}".to_sym], @options["s_#{col}".intern].to_s+"%", "users.#{col} LIKE ?", cond, cond_param) }
["number", "pin"].each { |col|
add_contition_and_param(@options["s_#{col}".to_sym], @options["s_#{col}".intern].to_s+"%", "cards.#{col} LIKE ?", cond, cond_param) }
["paymenttype", "currency", "completed", "user_id"].each { |col|
add_contition_and_param(@options["s_#{col}".to_sym], @options["s_#{col}".intern].to_s, "payments.#{col} = ?", cond, cond_param) }
["transaction"].each { |col|
add_contition_and_param(@options["s_#{col}".to_sym], @options["s_#{col}".intern].to_s+"%", "payments.transaction_id LIKE ?", cond, cond_param) }
cond << "amount >= '#{q(@options[:s_amount_min])}' " if !@options[:s_amount_min].blank?
cond << "amount <= '#{q(@options[:s_amount_max])}' " if !@options[:s_amount_max].blank?
@payments = Payment.find(:all,
:select => "payments.*, payments.user_id as 'user_id', payments.first_name as 'payer_first_name', payments.last_name as 'payer_last_name', users.username, users.first_name, users.last_name, cards.number, cards.pin, cards.id as card_id",
:joins => "left join users on (payments.user_id = users.id and payments.card = '0') left join cards on (payments.user_id = cards.id and payments.card != '0') left join cardgroups on (cards.cardgroup_id = cardgroups.id)",
:conditions => [cond.join(" AND ")] + cond_param)
doc.page {
doc.pagename("#{_('Payments_list')}")
doc.payments {
@payments.each { |payment|
doc.payment {
if payment.card == 0
user = User.find(:first, :conditions => ["id = ?", payment.user_id]) if !payment.user_id.blank?
if user
doc.user("#{nice_user(user)}")
end
else
if Card.find_by_id(payment.user_id)
doc.user("#{payment.number}+" "+(#{payment.pin})")
else
doc.user(" #{_('Batch_card_sale')}")
end
end
digits = (payment.paymenttype == "invoice" and payment.invoice) ? nice_invoice_number_digits(payment.invoice.invoice_type) : 0
payment.paymenttype == "gateways_authorize_net" ? doc.payer("#{payment.payer_first_name.to_s}"+" "+"#{payment.payer_last_name.to_s}") : doc.payer("#{payment.payer_email}")
doc.transaction_id("#{payment.transaction_id}")
doc.date("#{nice_date_time payment.date_added}")
doc.confirm_date("#{ nice_date_time payment.shipped_at}")
doc.type("#{payment.paymenttype.capitalize}") if payment.paymenttype
doc.amount("#{nice_number(payment.payment_amount)}")
doc.fee("#{nice_number(payment.fee)}")
doc.amount_with_tax("#{nice_number(payment.payment_amount_with_vat(digits))}")
doc.currency("#{payment.currency}")
if payment.completed.to_i == 0
doc.completed("No (#{payment.pending_reason})")
else
doc.completed("Completed")
end
if !payment.completed? and payment.pending_reason == "Waiting for confirmation"
doc.confirmed_by_admin("No")
else
doc.confirmed_by_admin("Yes")
end
}
}
}
}
else
doc.error("Incorrect hash")
end
send_xml_data(out_string, params[:test].to_i)
end
def main_page
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
if @user
@user.logged = 1
@user.save
today = Time.now.strftime("%Y-%m-%d")
@missed_calls = @user.calls("missed_inc", today, today)
@missed_calls_today = @missed_calls.size
@not_processed_calls_today = @user.calls("missed_not_processed_inc", today, today).size
@not_processed_calls_total = @user.calls("missed_not_processed_inc", "2000-01-01", today).size
#front_page_stats
month_t = Time.now.year.to_s + "-" + good_date(Time.now.month.to_s)
last_day = last_day_of_month(Time.now.year.to_s, good_date(Time.now.month.to_s))
day_t = Time.now.year.to_s + "-" + good_date(Time.now.month.to_s) + "-" + good_date(Time.now.day.to_s)
if @current_user.usertype == "admin"
@callsm = Call.find_by_sql("SELECT calls.* FROM calls WHERE calls.reseller_id = '#{@current_user.id}' AND calls.calldate BETWEEN '#{month_t}-01 00:00:00' AND '#{month_t}-#{last_day} 23:59:59' AND disposition = 'ANSWERED'")
@callsd = Call.find_by_sql("SELECT calls.* FROM calls WHERE calls.reseller_id = '#{@current_user.id}' AND calls.calldate BETWEEN '#{day_t} 00:00:00' AND '#{day_t} 23:59:59' AND disposition = 'ANSWERED'")
else
@callsm = Call.find_by_sql("SELECT calls.* FROM calls WHERE calls.user_id = '#{@current_user.id}' AND calls.calldate BETWEEN '#{month_t}-01 00:00:00' AND '#{month_t}-#{last_day} 23:59:59' AND disposition = 'ANSWERED'")
@callsd = Call.find_by_sql("SELECT calls.* FROM calls WHERE calls.user_id = '#{@current_user.id}' AND calls.calldate BETWEEN '#{day_t} 00:00:00' AND '#{day_t} 23:59:59' AND disposition = 'ANSWERED'")
if @current_user.usertype == "reseller"
@callsm = Call.find_by_sql("SELECT calls.* FROM calls WHERE calls.reseller_id = '#{@current_user.id}' AND calls.calldate BETWEEN '#{month_t}-01 00:00:00' AND '#{month_t}-#{last_day} 23:59:59' AND disposition = 'ANSWERED'")
@callsd = Call.find_by_sql("SELECT calls.* FROM calls WHERE calls.reseller_id = '#{@current_user.id}' AND calls.calldate BETWEEN '#{day_t} 00:00:00' AND '#{day_t} 23:59:59' AND disposition = 'ANSWERED'")
end
end
@total_durationm = 0
@total_call_pricem = 0
@total_call_selfpricem = 0
@total_callsm = 0
@total_durationd = 0
@total_call_priced = 0
@total_call_selfpriced = 0
@total_callsd = 0
if @current_user.usertype == "reseller"
for call in @callsm
@total_callsm = @total_callsm + 1
@total_durationm += (call.billsec).to_i
@total_call_pricem += (call.user_price).to_f
@total_call_selfpricem += (call.reseller_price).to_f
end
else
for call in @callsm
@total_callsm= @total_callsm + 1
@total_durationm += (call.billsec).to_i
if call.reseller_id == 0
@total_call_pricem = @total_call_pricem + (call.user_price).to_f
else
@total_call_pricem = @total_call_pricem + (call.reseller_price).to_f
end
@total_call_selfpricem = @total_call_selfpricem + (call.provider_price).to_f
end
end
if @current_user.usertype == "reseller"
for call in @callsd
@total_callsd=@total_callsd+1
@total_durationd += (call.billsec).to_i
@total_call_priced += (call.user_price).to_f
@total_call_selfpriced += (call.reseller_price).to_f
end
else
for call in @callsd
@total_callsd=@total_callsd+1
@total_durationd += (call.billsec).to_i
if call.reseller_id == 0
@total_call_priced = @total_call_priced + (call.user_price).to_f
else
@total_call_priced = @total_call_priced + (call.reseller_price).to_f
end
@total_call_selfpriced = @total_call_selfpriced + (call.provider_price).to_f
end
end
@total_profitm = @total_call_pricem - @total_call_selfpricem
@total_profitd = @total_call_priced - @total_call_selfpriced
doc.page {
doc.pagename("#{_('Main_page')}")
doc.username("#{params[:u]}")
doc.userid("#{@current_user.id}")
doc.language("#{Localization.lang}")
doc.stats {
doc.missed_calls {
doc.missed_today("#{@missed_calls_today}")
doc.missed_total("#{@not_processed_calls_total}")
}
doc.call_history {
doc.calls {
doc.call_counts("#{@total_callsm}")
doc.period("#{_('Month')}")
doc.call_duration("#{ nice_time @total_durationm}")
if @current_user.usertype == "reseller" or @current_user.usertype == "admin"
doc.call_profit("#{@total_profitm}")
end
}
doc.calls {
doc.call_counts("#{@total_callsd}")
doc.period("#{_('Day')}")
doc.call_duration("#{nice_time @total_durationd}")
if @current_user.usertype == "reseller" or @current_user.usertype == "admin"
doc.call_profit("#{@total_profitd}")
end
}
}
doc.finances {
if @user.postpaid == 1
doc.account("#{_('Postpaid')}")
else
doc.account("#{_('Prepaid')}")
end
doc.balance("#{nice_number @user.balance } #{Currency.get_default.name}")
if @user.credit.to_i == -1
doc.credit("#{_('Unlimited')}")
else
doc.credit("#{nice_number @user.credit}")
end
}
}
}
else
doc.page {
doc.pagename("#{_('Main_page')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
=begin rdoc
Returns user personal information.
*Post*/*Get* *params*:
* user_id - User ID
* hash - SHA1 hash
=end
def user_details
allow, values =API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
if allow == true
username = params[:u].to_s
password = params[:p].to_s
@user_logged = User.find(:first, :conditions => ["username = ? and password = ?", username, Digest::SHA1.hexdigest(password)])
if @user_logged
if @user_logged.usertype == 'admin'
@user = User.find(:first, :conditions => "id = #{values[:user_id].to_i}") if values [:user_id]
elsif @user_logged.usertype == 'reseller'
if values [:user_id]
if @user_logged.id.to_i == values[:user_id].to_i
owner = 0
else
owner = @user_logged.id
end
@user = User.find(:first, :conditions => "id = #{values[:user_id].to_i} AND owner_id = #{owner.to_i}")
end
else
@user = User.find(:first, :conditions => ["username = ? and password = ?", username, Digest::SHA1.hexdigest(password)])
end
if @user
@address = @user.address
@country = Direction.find(:first, :conditions => ["id =?", @user.taxation_country])
doc.page {
doc.pagename("#{_('Personal_details')}")
doc.language("en")
doc.userid("#{@user_logged.id}")
doc.details {
doc.main_detail {
@user.postpaid == 1 ? doc.account("#{_('Postpaid')}") : doc.account("#{_('Prepaid')}")
doc.balance("#{nice_number @user.balance } #{Currency.get_default.name}")
#ticket #4913, there's a rumor that api wil be rewriten, thats the only viable
#reason to add these elements, cause this mess wil be thrown away soon
doc.balance_number(@user.balance.to_s)
doc.balance_currency(Currency.get_default.name)
@user.credit != -1 ? doc.credit("#{ nice_number(@user.credit.to_s) }") : doc.credit("#{ _('Unlimited')}")
}
doc.other_details {
doc.username("#{@user.username}")
doc.first_name("#{@user.first_name}")
doc.surname("#{@user.last_name}")
doc.personalid("#{@user.clientid}")
doc.agreement_number("#{@user.agreement_number}")
ad = @user.agreement_date
ad= Time.now if !ad
doc.agreement_date("#{nice_date(ad, 0)}")
doc.taxation_country("#{@country.name[0, 22]}") if @country
doc.vat_reg_number("#{@user.vat_number}")
doc.vat_percent("#{@user.vat_percent}")
}
if @address
doc.registration {
doc.reg_address("#{@address.address}")
doc.reg_postcode("#{@address.postcode}")
doc.reg_city("#{@address.city}")
doc.reg_country("#{@address.county}")
doc.reg_state("#{@address.state}")
doc.reg_direction("#{@address.email}")
doc.reg_phone("#{@address.phone}")
doc.reg_mobile("#{@address.mob_phone}")
doc.reg_fax("#{@address.fax}")
doc.reg_email("#{@address.email}")
}
end
}
}
else
doc.error("User was not found")
end
else
doc.error("User was not found")
API::create_error_action(params, request, 'API : User not found by login and password')
end
else
doc.error("Incorrect hash")
end
send_xml_data(out_string, params[:test].to_i)
end
def user_devices
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@devices = @user.devices
doc.page {
doc.pagename("#{_('Devices')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.devices {
for dev in @devices
doc.device {
doc.acc("#{dev.id}")
doc.description("#{dev.description}")
doc.type("#{dev.device_type}")
doc.extension("#{dev.extension}")
doc.username("#{dev.name}")
doc.password("#{dev.secret}")
doc.cid("#{dev.callerid}")
doc.last_time_registered("#{nice_date_time(Time.at(dev.regseconds))}")
}
end
}
}
else
doc.page {
doc.pagename("#{_('Devices')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def devices_callflow
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
if @current_user.usertype != "admin"
if @current_user.usertype == "user" and @current_user.manager_in_groups.size == 0
#simple user
@device = Device.find(params[:device_id])
else
#group manager
@device = Device.find(params[:id])
@user = @device.user
can_check = false
for group in @current_user.manager_in_groups
for user in group.users
can_check = true if user.id == @user.id
end
end
end
else
#admin
@device = Device.find(params[:device_id])
@user = @device.user
end
#need security increase because rigth now everybody can see everybodies call flows
@before_call_cfs = Callflow.find(:all, :conditions => "cf_type = 'before_call' AND device_id = #{@device.id}", :order => "priority ASC")
@no_answer_cfs = Callflow.find(:all, :conditions => "cf_type = 'no_answer' AND device_id = #{@device.id}", :order => "priority ASC")
@busy_cfs = Callflow.find(:all, :conditions => "cf_type = 'busy' AND device_id = #{@device.id}", :order => "priority ASC")
@failed_cfs = Callflow.find(:all, :conditions => "cf_type = 'failed' AND device_id = #{@device.id}", :order => "priority ASC")
if @before_call_cfs.empty?
cf = create_empty_callflow(@device.id, "before_call")
@before_call_cfs << cf
end
if @no_answer_cfs.empty?
cf = create_empty_callflow(@device.id, "no_answer")
@no_answer_cfs << cf
end
if @busy_cfs.empty?
cf = create_empty_callflow(@device.id, "busy")
@busy_cfs << cf
end
if @failed_cfs.empty?
cf = create_empty_callflow(@device.id, "failed")
@failed_cfs << cf
end
doc.page {
doc.pagename("#{_('Call_Flow')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.device {
doc.device_id("#{@device.id}")
doc.device_description("#{@device.description}")
doc.device_icon("#{}")
doc.callflows {
doc.callflow {
doc.call_state("#{_('Before_Call')}")
doc.callflow_action("#{draw_callflows(@before_call_cfs)}")
}
doc.callflow {
doc.call_state("#{_('Call')}")
doc.callflow_action("#{"Dial(#{@device.device_type}/#{@device.name}|#{@device.timeout})"}")
}
doc.callflow {
doc.call_state("#{_('Answered')}")
doc.callflow_action("#{_('Hangup')}")
}
doc.callflow {
doc.call_state("#{_('No_Answer')}")
doc.callflow_action("#{draw_callflows(@no_answer_cfs)}")
}
doc.callflow {
doc.call_state("#{_('Busy')}")
doc.callflow_action("#{draw_callflows(@busy_cfs)}")
}
doc.callflow {
doc.call_state("#{_('Failed')}")
doc.callflow_action("#{draw_callflows(@failed_cfs)}")
}
}
}
}
else
doc.page {
doc.pagename("#{_('Call_Flow')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def draw_callflows(cfs)
output = ""
for cf in cfs
case cf.action
when "empty"
output += "-"
when "forward"
dev = Device.find(cf.data) if cf.data2 == "local"
output += _('Forward') + " " + dev.device_type + "/" + dev.name if cf.data2 == "local"
output += _('Forward') + " " + cf.data if cf.data2 == "external"
output += _('Forward_not_functional_please_enter_dst') if cf.data2 == ""
when "voicemail"
output += _('VoiceMail')
when "fax_detect"
dev = Device.find(cf.data) if cf.data2 == "fax"
output += _('Fax_detect') + ": " + dev.device_type + "/" + dev.extension if cf.data2 == "fax"
output += _('Fax_detect_not_functional_please_select_fax_device') if cf.data2 == ""
end
end
output
end
def callflow_edit
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@device = Device.find(params[:device_id])
@user = @device.user
@cf = Callflow.find(params[:cf])
@devices = @user.devices
doc.page {
doc.pagename("#{_('Call_State')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.callflow {
doc.device_id("#{@device.id}")
doc.device_description("#{@device.description}")
doc.device_icon("#{}")
doc.call_state("#{params[:cft]}")
doc.actions {
doc.action {
doc.priority("#{@cf.priority}")
doc.action_id("#{"1"}")
doc.aval_devices {
for dev in @devices
doc.device {
doc.device_id("#{dev.id}")
doc.device_name("#{dev.name}")
}
end
}
}
doc.action {
doc.priority("#{@cf.priority}")
doc.action_id("#{"3"}")
}
doc.action {
doc.priority("#{@cf.priority}")
doc.action_id("#{"4"}")
doc.aval_devices {
for dev in @devices
doc.device {
doc.device_id("#{dev.id}")
doc.device_name("#{dev.name}")
}
end
}
}
}
}
}
else
doc.page {
doc.pagename("#{_('Call_State')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def user_rates
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@tariff = @current_user.tariff
@dgroups = Destinationgroup.find(:all, :order => "name ASC, desttype ASC")
@vat = 0.to_f
@rates_cur2 = []
sql = "SELECT rates.* FROM rates, destinations, directions WHERE rates.tariff_id = #{@tariff.id} AND rates.destination_id = destinations.id AND destinations.direction_code = directions.code ORDER by directions.name ASC;"
rates = Rate.find_by_sql(sql)
exrate = Currency.count_exchange_rate(@tariff.currency, @current_user.currency.name)
for rate in rates
get_provider_rate_details(rate, exrate)
@rates_cur2[rate.id]=@rate_cur
end
@currency = Currency.get_active
doc.page {
doc.pagename("#{_('Payments')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.currency("#{@current_user.currency.name}")
doc.vat_percent("#{@vat}")
doc.aval_currencies {
for curr in @currency
doc.currency("#{curr.name}")
end
}
doc.rates {
for rat in rates
doc.rate {
doc.ratename("#{rat.destination.direction.name}")
doc.rateicon("#{rat.destination.prefix}")
doc.ratetype("#{rat.destination.subcode}")
doc.ratecost("#{nice_number @rates_cur2[rat.id]}")
doc.rate_vat_cost("#{nice_number(@rates_cur2[rat.id] * (100 + @vat) / 100)}")
}
end
}
}
else
doc.page {
doc.pagename("#{_('Call_State')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def get_tariff
allow, values = API::check_params_with_all_keys(params, request)
#doc = Builder::XmlMarkup.new( :target => out_string = "", :indent => 2 )
#doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
outstring = ''
if allow
if @user
#admin? reseller? user?
if values[:tariff_id] and @user.usertype != 'user' and @user.usertype != 'accountant'
if @user.usertype == 'admin'
@tariff = Tariff.find(values[:tariff_id].to_i)
else
@tariff = Tariff.find(:first, :conditions => ["id = ? and owner_id = ?", values[:tariff_id].to_i, @user.id.to_i])
end
else
@tariff = @user.tariff
end
if @tariff
if @tariff.purpose.to_s == 'user'
result = @tariff.tariffs_api_retail
rates={}
result.each { |rate|
rates[rate['name'].to_s] ||= {}
rates[rate['name'].to_s][rate['desttype'].to_s] ||= []
rates[rate['name'].to_s][rate['desttype'].to_s] << rate
}
outstring << "
#{_('Tariff')}
#{CGI::escapeHTML(@tariff.name.to_s)}
#{@tariff.purpose}
#{@tariff.currency}
"
rates.each { |name, type|
type.each { |type_name, rate_data|
outstring << " "
outstring << "#{CGI::escapeHTML(name)}
#{CGI::escapeHTML(type_name)}"
rate_data.each { |rate|
outstring << ""
if rate["duration"].to_i == -1
outstring << "Infinity"
else
outstring << "#{rate['duration']}"
end
outstring << "#{rate['artype'].to_s}
#{rate['round'].to_s}
#{rate['price'].to_s}
#{rate['start_time'].to_s}
#{rate['end_time'].to_s}
#{rate['daytype'].to_s}
#{rate['from'].to_s}
"
}
outstring << " "
}
}
outstring << "
"
else
result = @tariff.tariffs_api_wholesale
outstring << "
#{_('Tariff')}
#{CGI::escapeHTML(@tariff.name.to_s)}
#{@tariff.purpose}
#{@tariff.currency}
"
result.each { |rate|
outstring << "
#{CGI::escapeHTML(rate['direction'].to_s)}
#{CGI::escapeHTML(rate['destination'].to_s)}
#{rate['prefix'].to_s}
#{rate['subcode'].to_s}
#{rate['code'].to_s}
#{nice_number(rate['rate']).to_s}
#{nice_number(rate['connection_fee']).to_s}
#{rate['increment_s'].to_s}
#{rate['min_time'].to_s}
#{rate['start_time'].to_s}
#{rate['end_time'].to_s}
#{rate['daytype'].to_s}
"
}
outstring << "
"
end
else
outstring << "No tariff found"
end
else
outstring << "Bad login"
end
else
outstring << "Incorrect hash"
end
send_xml_data(outstring, params[:test].to_i, "get_tariff_#{Time.now.to_i}.xml", true)
end
def get_provider_rate_details(rate, exrate)
@rate_details = Ratedetail.find(:all, :conditions => "rate_id = #{rate.id.to_s}", :order => "rate DESC")
if @rate_details.size > 0
@rate_increment_s=@rate_details[0]['increment_s']
@rate_cur, @rate_free = Currency.count_exchange_prices({:exrate => exrate, :prices => [@rate_details[0]['rate'].to_f, @rate_details[0]['connection_fee'].to_f]})
end
@rate_details
end
def dg_list_user_destinations
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@destgroup = Destinationgroup.find(params[:dest_gr_id])
@destinations = @destgroup.destinations
doc.page {
doc.pagename("#{_('Destinations')}")
doc.language("#{Localization.lang}")
doc.groupname("#{@destgroup.name} #{@destgroup.desttype}")
doc.groupicon("#{@destgroup.flag}")
doc.directions {
for destination in @destinations
doc.direction {
doc.details("#{destination.direction.name} #{destination.name}")
doc.prefix("#{destination.prefix}")
doc.dir_code("#{destination.subcode}")
}
end
}
}
else
doc.page {
doc.pagename("#{_('Call_State')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def personal_payments
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@payments = @user.payments
doc.page {
doc.pagename("#{_('Payments')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.payments {
for payment in @payments
completed = _('Yes')
if payment.completed.to_i == 0
completed = _('No')
completed += " (" + payment.pending_reason + ")" if payment.pending_reason
end
doc.payment {
doc.payment_date("#{nice_date_time payment.date_added}")
doc.confirmed_date("#{nice_date_time payment.shipped_at}")
doc.payment_type("#{payment.paymenttype.capitalize}")
pa = payment.amount
pa = (payment.amount / (100 + @user.vat_percent)) * 100 if payment.paymenttype == "paypal"
pa = (payment.amount / (100 + payment.vat_percent)) * 100 if payment.paymenttype == "voucher"
doc.amount("#{nice_number pa}")
if payment.paymenttype != "voucher"
doc.vat("#{@user.vat_percent}")
else
doc.vat("#{payment.vat_percent}")
end
awv = payment.amount
awv = payment.amount if payment.paymenttype == "paypal"
awv = payment.invoice.price_with_vat if payment.paymenttype == "invoice"
awv = payment.amount if payment.paymenttype == "voucher"
doc.amount_vat("#{nice_number awv}")
doc.currency("#{payment.currency}")
doc.completed("#{completed}")
}
end
}
}
else
doc.page {
doc.pagename("#{_('Call_State')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def user_invoices
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@user.postpaid.to_i == 1 ? type = "postpaid" : type = "prepaid"
@invoices = @user.invoices(:include => [:tax, :user])
doc.page {
doc.pagename("#{_('Invoices')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.invoices {
for inv in @invoices
doc.invoice {
user = inv.user
doc.user("#{user.first_name + " " + user.last_name}")
doc.inv_number("#{inv.number}")
doc.period_start("#{inv.period_start}")
doc.period_end("#{inv.period_end}")
doc.issue_date("#{inv.issue_date}")
doc.paid("#{inv.paid}")
doc.paid_date("#{nice_date_time inv.paid_date if inv.paid == 1 }")
doc.price("#{nice_invoice_number(inv.price, type)}")
doc.price_vat("#{nice_invoice_number(inv.price_with_tax(:precision => nice_invoice_number_digits(type)), type)}")
}
end
}
}
else
doc.page {
doc.pagename("#{_('Call_State')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def user_subscriptions
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
@subscriptions = @user.subscriptions
doc.page {
doc.pagename("#{_('User_subscriptions')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.subscriptions {
for sub in @subscriptions
doc.subscription {
doc.service("#{sub.service.name}")
doc.date_added("#{sub.added}")
doc.activation_start("#{sub.activation_start}")
doc.activation_end("#{sub.activation_end}")
doc.price("#{sub.service.price}")
}
end
}
}
else
doc.page {
doc.pagename("#{_('User_subscriptions')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
=begin rdoc
*Post*/*Get* *params*:
*s_direction - "outgoing"
* period_start - calls period starting date.
Default - Today 00:00
* period_end - calls period ending date.
Default - Today 23:59
*s_call_type -"all",
*s_device=>"all",
*s_provider=>"all",
*s_hgc=>0,
*s_user => "all",
*user => nil,
*s_did => "all",
*s_destination => "",
*order_by => "time",
*order_desc => 0,
*s_country=>''
* Hash - SHA1 hash
=end
def user_calls
allow, values =API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
if allow == true
username = params[:u].to_s
password = params[:p].to_s
@user_logged = check_user(username, password)
if @user_logged
@options = last_calls_stats_parse_params
if @user_logged.usertype.to_s == "user"
user = @user_logged
device = Device.find_by_id(@options[:s_device]) if @options[:s_device] != "all" and !@options[:s_device].blank?
end
if @user_logged.usertype.to_s == "reseller"
user = User.find(:first, :conditions => ["id=? and owner_id =?", @options[:s_user], @user_logged.id]) if @options[:s_user] =~ /^[0-9]+$/
user = @user_logged if @options[:s_user].to_i == @user_logged.id.to_i
device = Device.find_by_id(@options[:s_device]) if @options[:s_device] != "all" and !@options[:s_device].blank?
if Confline.get_value('Show_HGC_for_Resellers').to_i == 1
hgc = Hangupcausecode.find_by_id(@options[:s_hgc]) if @options[:s_hgc].to_i > 0
end
if @user_logged.reseller_allow_providers_tariff?
if @options[:s_provider].to_i > 0
provider = Provider.find(:first, :conditions => ["providers.id = ?", @options[:s_provider]])
unless provider
provider = nil
end
end
else
provider = nil
end
end
if ["admin", "accountant"].include?(@user_logged.usertype.to_s)
user = User.find_by_id(@options[:s_user]) if @options[:s_user] =~ /^[0-9]+$/
device = Device.find_by_id(@options[:s_device]) if @options[:s_device] != "all" and !@options[:s_device].blank?
did = Did.find_by_id(@options[:s_did]) if @options[:s_did] != "all" and !@options[:s_did].blank?
hgc = Hangupcausecode.find_by_id(@options[:s_hgc]) if @options[:s_hgc].to_i > 0
provider = Provider.find_by_id(@options[:s_provider]) if @options[:s_provider].to_i > 0
end
if user or @options[:s_user] == "all"
@options[:from] = values[:period_start] ? Time.at(values[:period_start]).to_s(:db) : Time.mktime(Time.now.year, Time.now.month, Time.now.day, 0, 0, 0).to_s(:db)
@options[:till] = values[:period_end] ? Time.at(values[:period_end]).to_s(:db) : Time.mktime(Time.now.year, Time.now.month, Time.now.day, 23, 59, 59).to_s(:db)
@options[:exchange_rate] = 1 #exchange_rate
options = last_calls_stats_set_variables(@options, {:user => user, :device => device, :hgc => hgc, :did => did, :current_user => @user_logged, :provider => provider, :can_see_finances => can_see_finances?})
options[:current_user] = @user_logged
calls = Call.last_calls_csv(options.merge({:pdf => 1}))
doc.page {
doc.pagename("Calls")
doc.language("en")
doc.error_msg("#{}")
doc.userid(@user_logged.id)
doc.username(@user_logged.username)
doc.total_calls("#{calls.size}")
doc.currency(Currency.find(1).name)
doc.calls_stat {
doc.period {
doc.period_start(@options[:from])
doc.period_end(@options[:till])
}
doc.show_user(@options[:s_user])
doc.show_device(@options[:s_device])
doc.show_status(@options[:s_call_type])
doc.show_provider(@options[:s_provider]) if !@options[:s_provider].blank?
doc.show_hgc(((@options[:s_hgc].to_i > 0) ? @options[:s_hgc].to_i : 'all')) if !@options[:s_hgc].blank?
doc.show_did(@options[:s_did]) if !@options[:s_did].blank?
doc.show_destination(@options[:s_destination]) if !@options[:s_destination].blank?
if calls and calls.size.to_i > 0
doc.calls {
for call in calls
doc.call {
call.attributes.sort.each { |key, value|
case key.to_s
when 'calldate'
doc.tag!(key, nice_date_time(value))
when 'dst'
doc.tag!(key, hide_dst_for_user(@user_logged, "gui", value))
else
doc.tag!(key, call[key])
end
}
}
end
}
end
}
}
else
doc.error("User was not found")
end
else
doc.error('Dont be so smart')
API::create_error_action(params, request, 'API : User not found by login and password')
end
else
doc.error("Incorrect hash")
end
send_xml_data(out_string, params[:test].to_i)
end
=begin rdoc
*Post*/*Get* *params*:
* monitoring_id - monitoring id
* users - user id list separated by commas
* email - true/false send or do not send emails
* block - true/false block ar do not block users
=end
def ma_activate
allow, values =API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
users = []
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
if allow == true
if defined?(MA_Active) and MA_Active == 1
if values.has_keys?(:monitoring_id, :users, :block, :email, :mtype)
monitoring = Monitoring.find(:first, :conditions => {:id => values[:monitoring_id], :block => (values[:block] == "true") ? true : false, :email => (values[:email] == "true") ? true : false, :mtype => values[:mtype]})
if monitoring
doc.status {
doc.monitoring_found("success")
doc.users {
values[:users].split(",").each { |id|
user = User.find_by_id(id)
doc.user {
doc.id(id)
if user
users << user
status = ""
if monitoring.block_user?
unless user.blocked?
user.update_attribute(:blocked, 1) unless user.blocked?
status << " blocked"
else
status << " already blocked"
end
end
if monitoring.send_email?
if Confline.get('Email_Sending_Enabled').value.to_i == 1
admin = User.find_by_id(monitoring.owner_id)
if admin.address and !admin.address.email.empty?
status << " email sent"
else
status << " monitoring owner has no email set"
end
else
status << " email sending not enabled, check configuration"
end
unless users.empty?
email = Email.find(:first, :conditions => {:name => 'monitoring_activation', :owner_id => monitoring.owner_id})
user = User.find_by_id(monitoring.owner_id)
call_list = ''
if monitoring.monitoring_type == 'simultaneous'
for calls in monitoring.simultaneous_calls
call_list = calls.dst + '|' + calls.calldateA + '|' + calls.srcA + '|' + calls.calldateB + '|' + calls.srcB + "|\n"
end
end
logger.fatal call_list
logger.fatal call_list
variables = Email.email_variables(user, nil, {:monitoring => monitoring, :monitoring_type => _(monitoring.monitoring_types), :monitoring_users_list => users, :call_list => call_list})
EmailsController::send_email(email, Confline.get_value("Email_from", user.id), [user], variables)
end
end
Action.add_action_hash(admin.id, # for admin
{:action => "monitoring_activate",
:data => "Monitoring activated",
:data2 => status,
:data3 => "user: #{user.id} #{user.username} #{user.balance} #{Currency.get_default.name}",
:target_id => monitoring.id,
:target_type => "monitoring"
})
doc.status(status)
# else
# doc.status("error: this monitoring does not apply for this user")
# end
else
doc.status("error: not found")
end
}
}
}
}
else
doc.status {
doc.error("Such monitoring was not found. Verify master-slave database integrity.")
}
end
else
doc.status {
doc.error("You must supply these params: monitoring_id, users, block, email, mtype")
}
end
else
doc.status {
doc.error("Monitorings addon is disabled")
}
end
else
doc.status {
doc.error("Incorrect hash")
}
end
send_xml_data(out_string, params[:test].to_i)
end
def new_calls_list
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
check_user(params[:u], params[:p])
if @user
@user.logged = 1
@user.save
calls_hash = @user.new_calls(@current_user.system_time(Date.today.to_s, 1))
@calls = []
for call_h in calls_hash
@calls << Call.find(call_h["id"])
end
@select_date = false
doc.page {
doc.pagename("#{_('New_calls')}")
doc.language("#{Localization.lang}")
doc.userid("#{@current_user.id}")
doc.calls_stat {
doc.total_calls("#{@calls.size}")
doc.calls {
for call in @calls
doc.call {
doc.date("#{call.date.strftime("%Y-%m-%d %H:%M:%S")}")
doc.called_from("#{call.src}")
doc.called_to("#{hide_dst_for_user(@user, "gui", call.dst)}")
if @call_type != "missed"
doc.duration("#{nice_time call.billsec}")
else
doc.duration("#{nice_time call.duration}")
end
doc.hangup_cause("#{call.disposition}")
}
end
}
}
}
else
doc.page {
doc.pagename("#{_('User_subscriptions')}")
doc.language("en")
doc.error_msg("")
doc.aval_languages {
}
}
end
send_xml_data(out_string, params[:test].to_i)
end
def simple_balance
if Confline.get_value("Devices_Check_Ballance").to_i == 1
@user = User.find(:first, :conditions => "uniquehash = '#{params[:id]}'")
if @user
if params[:currency].to_s.blank? # in case currency was not supplied or is blank return balance in system's currency
user_balance = @user.balance
elsif params[:currency].to_s.downcase == 'user'
user_balance = @user.balance * Currency.count_exchange_rate(Currency.get_default.name, @user.currency.name)
elsif Currency.find(:first, :conditions => {:name => params[:currency]}) # in case valid currency was supplied return balance in that currency
user_balance = @user.balance * Currency.count_exchange_rate(Currency.get_default.name, params[:currency])
else # in case invalid currency value was supplied, return currency in system's currency
user_balance = @user.balance
end
render :text => nice_number(user_balance).to_s
else
render :text => _("User_Not_Found")
end
else
render :text => _("Feature_Disabled")
end
end
def balance
if Confline.get_value("Devices_Check_Ballance").to_i == 1
user = User.find(:first, :conditions => ["username = ?", params[:username]])
if user
if params[:currency].to_s.blank? # in case currency was not supplied or is blank return balance in system's currency
user_balance = user.balance
elsif params[:currency].to_s.downcase == 'user'
user_balance = user.balance * Currency.count_exchange_rate(Currency.get_default.name, user.currency.name)
elsif Currency.find(:first, :conditions => {:name => params[:currency]}) # in case valid currency was supplied return balance in that currency
user_balance = user.balance * Currency.count_exchange_rate(Currency.get_default.name, params[:currency])
else # in case invalid currency value was supplied, return currency in system's currency
user_balance = user.balance
end
render :text => nice_number(user_balance).to_s
else
render :text => _("User_Not_Found")
end
else
render :text => _("Feature_Disabled")
end
end
def rate
if Confline.get_value("Devices_Check_Rate").to_i == 1
prefix = split_number(params[:prefix])
if prefix.size > 0
user = User.find(:first, :conditions => ["username = ?", params[:username]])
if user
destination = Destination.find(:first, :include => [:destinationgroup],
:conditions => ["prefix IN (?)", prefix],
:order => "LENGTH(prefix) DESC")
if destination
dg = destination.destinationgroup
rate = Rate.find(:first, :include => [:ratedetails, :aratedetails], :conditions => ["(rates.destination_id = ? or rates.destinationgroup_id = ?) AND rates.tariff_id = ?", destination.id, dg.id, user.tariff_id])
if rate and (rate.ratedetails.size > 0 or rate.aratedetails.size > 0)
text = "#{rate.aratedetails[0].price}\##{destination.name}\##{destination.prefix}" if rate.aratedetails.size > 0
text = "#{rate.ratedetails[0].rate}\##{destination.name}\##{destination.prefix}" if rate.ratedetails.size > 0
render :text => text.to_s
else
tariff = user.tariff
err = ["API::Rate error: rate not found"]
err << " >> Destination: ID:'#{destination.id}' Name: #{destination.name}, Prefix:#{destination.prefix}"
err << " >> Tariff: ID:#{tariff.id} Name:'#{tariff.name}' Purpose:'#{tariff.purpose}'" if tariff
err << " >> Rate: ID:#{rate.id}" if rate
err << " >> RateDetails: #{rate.ratedetails.size}" if rate and rate.ratedetails
err << " >> aRateDetails: #{rate.aratedetails.size}" if rate and rate.aratedetails
MorLog.my_debug(err.join("\n"))
render :text => _("Rate_was_not_found") # Rate not found
end
else
MorLog.my_debug("API::Rate error: destination/prefix was not found")
render :text => _("Prefix_not_found") # Destination/prefix not found
end
else
MorLog.my_debug("API::Rate error: user was not found")
render :text => _("User_not_found") # User not found
end
else
MorLog.my_debug("API::Rate error: prefix is blank")
render :text => _("Empty_prefix") # empty prefix
end
else
MorLog.my_debug("API::Rate error: Feature is disabled")
render :text => _("Feature_Disabled")
end
end
def user_register
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8", :standalone => "yes"
doc.page {
if Confline.get_value("API_Allow_registration_ower_API").to_i == 1
if !params[:id] or !User.find(:first, :conditions => ["uniquehash = ?", params[:id]])
doc.status { doc.error(_('Dont_be_so_smart')) }
else
owner = User.find(:first, :conditions => ['uniquehash=?', params[:id]])
if owner
notice = User.validate_from_registration(params)
capt = true
if Confline.get_value("reCAPTCHA_enabled").to_i == 1
usern = User.new
capt = verify_recaptcha(usern) ? true : (false; notice = _('Please_enter_captcha'))
end
if capt and notice.blank?
reg_ip = request.remote_ip
user, send_email_to_user, device, notice2 = User.create_from_registration(params, owner, reg_ip, free_extension(), new_device_pin(), random_password(12), next_agreement_number, 1)
if notice2.blank?
doc.status { doc.success(_('Registration_succesful')) }
a = Thread.new { configure_extensions(device.id, {:api => 1, :current_user => owner}) }
doc.user_device_settings {
MorLog.my_debug user.to_yaml
us = User.find(user.id)
MorLog.my_debug "************************************************88"
MorLog.my_debug us.to_yaml if us
if send_email_to_user == 1
doc.email(user.address.email)
end
#if !a
if device
doc.device_type(device.device_type)
doc.username(device.username)
doc.password(device.secret)
doc.pin(device.pin)
doc.server_ip(Confline.get_value("Asterisk_Server_IP", 0))
end
doc.registration_notice("*#{_('Registration_notice')}")
#end
}
else
doc.status { doc.error(notice2) }
end
else
doc.status { doc.error(notice) }
end
else
doc.status { doc.error(_('Dont_be_so_smart')) }
end
end
else
doc.status { doc.error("Registration over API is disabled") }
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin rdoc
*Post*/*Get* *params*:
* user_id - User id
* balance - balance.
* Hash - SHA1 hash
=end
def user_balance_change
allow, values =API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
user_b = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", values[:user_id], @user.id]) if values[:user_id]
if user_b
old_balance = user_b.balance.to_f
if values[:balance]
user_b.balance = user_b.balance + values[:balance].to_f
if user_b.save
Action.add_action_hash(@user, {:target_id => user_b.id, :target_type => 'User', :action => 'User balance changed from API', :data => old_balance, :data2 => user_b.balance, :data3 => request.env["REMOTE_ADDR"].to_s})
doc.page {
doc.status("User balance updated")
doc.user {
doc.username(user_b.username)
doc.id(user_b.id)
doc.balance(user_b.balance)
}
}
else
Action.add_action_hash(@user, {:target_id => user_b.id, :target_type => 'User', :action => 'User balance not changet from API', :data => request["REQUEST_URI"].to_s[0..255], :data2 => request["REMOTE_ADDR"].to_s, :data3 => params.inspect.to_s[0..255], :data4 => user_b.errors.to_yaml})
doc.error("User balance not updeted")
#doc.notice("User balance not updeted")
end
else
Action.add_action_hash(@user, {:target_id => user_b.id, :target_type => 'User', :action => 'User balance not changet from API', :data => request["REQUEST_URI"].to_s[0..255], :data2 => request["REMOTE_ADDR"].to_s, :data3 => params.inspect.to_s[0..255], :data4 => user_b.errors.to_yaml})
doc.error("User balance not updeted")
end
else
doc.error("User was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
# http://trac.kolmisoft.com/trac/ticket/4236
# ALTER TABLE devices ADD allow_grandstreams INT default 0 COMMENT 'Allow grandstreams realtime data sending';
#
# def grandstreams_realtime_data_for_callshop
#
# doc = Builder::XmlMarkup.new( :target => out_string = "", :indent => 2 )
# doc.instruct! :xml, :version => "1.0"
# doc.Screen{
# doc.IdleScreen{
# doc.ShowStatusLine("true")
# if call_shop_active?
# user = User.find(:first, :include=>[:tariff, :currency],:conditions=>{:id => params[:id]})
# if user
# device = Device.find(:first, :conditions=>{:user_id => user.id})
# if device and device.try(:allow_grandstreams).to_i == 1
# call = Activecall.find(:first, :select=>"activecalls.prefix, activecalls.answer_time, activecalls.user_rate, activecalls.start_time",:conditions=>{:user_id => user.id})
#
# if call
# time = nice_time2(call.start_time)
# duration = nice_time(call.duration)
# dest = Destination.find(:first, :conditions => ["prefix = ?", call.prefix])
# if dest
# n_dest = dest.direction.name if dest.direction
# end
#
# if user.tariff.purpose == 'user'
# connection_fee = 0
# else
# ratedetails = Rate.find(:first, :select=>"*", :joins=>" JOIN ratedetails ON (rate_id = rates.id)", :conditions=>["tariff_id = ? and destination_id = ? AND ? BETWEEN ratedetails.start_time AND ratedetails.end_time", user.tariff_id, dest.id, time ])
# connection_fee = ratedetails.connection_fee
# end
#
# price = nice_number((call.user_rate.to_f * (call.duration.to_f / 60.to_f).to_f) + connection_fee.to_f)
#
# rate = call.user_rate
#
# doc.DisplayString(:font=>"f8"){
# doc.DisplayStr(n_dest.to_s + ' ' + _('Rate') + ': ' + rate.to_s + ' ' + user.currency.name.to_s + '/min')
# doc.x(0)
# doc.y(0)
# }
# doc.DisplayString(:font=>"f8"){
# doc.DisplayStr(_('Time') + ': ' +duration.to_s + ' ' + _('Price') + ': '+ price.to_s + ' ' + user.currency.name.to_s)
# doc.x(65)
# doc.y(12)
# }
# else
# doc.DisplayString(:font=>"f8"){
# doc.DisplayStr(_('Call_not_found'))
# doc.x(65)
# doc.y(12)
# }
# end
# else
# doc.DisplayString(:font=>"f8"){
# doc.DisplayStr(_('Setting_is_off'))
# doc.x(65)
# doc.y(12)
# }
# end
# else
# doc.DisplayString(:font=>"f8"){
# doc.DisplayStr(_('User_not_found'))
# doc.x(65)
# doc.y(12)
# }
# end
# else
# doc.DisplayString(:font=>"f8"){
# doc.DisplayStr(_('No_callshop_addon_active'))
# doc.x(65)
# doc.y(12)
# }
# end
#
# }
# }
# send_xml_data(out_string, params[:test].to_i, "gs_screen.xml")
# end
def user_update_api
allow, values =API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
if @user.usertype == 'user' or (@user.usertype == 'accountant' and (values[:user_id].to_i == 0 or values[:user_id].to_i == @user.id))
doc.error("Don't be so smart")
else
if @user.usertype == 'accountant'
owner_id = 0
else
owner_id = @user.id
end
if @user.usertype == 'reseller'
user_u = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", values[:user_id], owner_id]) if values[:user_id]
user_u = @user if values[:user_id] == owner_id
else
user_u = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", values[:user_id], owner_id]) if values[:user_id]
end
if user_u
params[:address] = {}
['address', 'city', 'postcode', 'county', 'mob_phone', 'fax', 'direction_id', 'phone', 'email', 'state'].each_with_index { |s, i|
params[:address][s.to_sym] = params["a#{i}"] if params["a#{i}"]
}
params[:user] = {}
['vat_number', 'lcr_id', 'warning_email_hour', 'hide_destination_end', 'currency_id', 'tariff_id', 'warning_email_balance',
'spy_device_id', 'language', 'username', 'warning_balance_call', 'acc_group_id', 'generate_invoice', 'usertype', 'taxation_country', 'blocked', 'quickforwards_rule_id', 'last_name', 'call_limit',
'clientid', 'recording_hdd_quota', 'cyberplat_active', 'recordings_email', 'first_name', 'warning_balance_sound_file_id', 'postpaid', 'accounting_number', 'agreement_number', 'hidden'].each_with_index { |s, i|
params[:user][s.to_sym] = params["u#{i}"] if params["u#{i}"]
}
params[:agr_date] = {}
params[:agr_date][:year] = params[:ay]
params[:agr_date][:day] = params[:ad]
params[:agr_date][:month] = params[:am]
params[:block_at_date] = {}
params[:block_at_date][:year] = params[:by]
params[:block_at_date][:day] = params[:bd]
params[:block_at_date][:month] = params[:bm]
params[:password] = {}
params[:password][:password]=params[:pswd] if params[:pswd]
params[:date] = {}
params[:date][:user_warning_email_hour] = params[:user_warning_email_hour]
params[:privacy] = {}
params[:privacy][:gui] = params[:pgui]
params[:privacy][:csv] = params[:pcsv]
params[:privacy][:pdf] = params[:ppdf]
#paramas += pp
MorLog.my_debug @user.usertype
if @user.usertype == 'accountant'
sql = "SELECT value FROM acc_group_rights JOIN acc_groups ON (acc_groups.id = acc_group_id) JOIN acc_rights ON (acc_rights.id = acc_right_id) WHERE acc_rights.name ='user_manage' and right_type = 'accountant' AND acc_group_id = #{@user.acc_group_id}"
v = ActiveRecord::Base.connection.select_value(sql)
MorLog.my_debug v
MorLog.my_debug sql
allow_edit = v.to_i == 2 ? true : false
else
allow_edit = true
end
notice, par = user_u.validate_from_update(@user, params, allow_edit, 1)
if notice.blank?
tax = {"tax1_enabled" => 1}
tax.merge!({:tax2_enabled => params[:tax2_enabled].to_i}) if params[:tax2_enabled]
tax.merge!({:tax3_enabled => params[:tax3_enabled].to_i}) if params[:tax3_enabled]
tax.merge!({:tax4_enabled => params[:tax4_enabled].to_i}) if params[:tax4_enabled]
tax.merge!({:tax1_name => params[:tax1_name].to_s}) if params[:tax1_name]
tax.merge!({:tax2_name => params[:tax2_name].to_s}) if params[:tax2_name]
tax.merge!({:tax3_name => params[:tax3_name].to_s}) if params[:tax3_name]
tax.merge!({:tax4_name => params[:tax4_name].to_s}) if params[:tax4_name]
tax.merge!({:total_tax_name => params[:total_tax_name].to_s}) if params[:total_tax_name]
tax.merge!({:tax1_value => params[:tax1_value].to_f}) if params[:tax1_value]
tax.merge!({:tax2_value => params[:tax2_value].to_f}) if params[:tax2_value]
tax.merge!({:tax3_value => params[:tax3_value].to_f}) if params[:tax3_value]
tax.merge!({:tax4_value => params[:tax4_value].to_f}) if params[:tax4_value]
tax.merge!({:compound_tax => params[:compound_tax].to_i}) if params[:compound_tax]
user_u.update_from_edit(par, @user, tax, monitoring_enabled_for(@user), rec_active?, 1)
if user_u.save
if user_u.usertype == "reseller"
user_u.check_default_user_conflines
end
user_u.address.save
doc.status("User was updated")
else
doc.error("User was not updated")
user_u.errors.each { |key, value|
doc.message(_(value))
} if user_u.respond_to?(:errors)
end
else
doc.error(notice)
end
else
doc.error("User was not found")
end
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
def device_destroy
allow, values =API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
device = Device.find(:first, :conditions => {:id => params[:device]})
if device
if check_owner_for_device(device.user_id, 0, @user)
if @user.usertype == 'accountant'
sql = "SELECT value FROM acc_group_rights JOIN acc_groups ON (acc_groups.id = acc_group_id) JOIN acc_rights ON (acc_rights.id = acc_right_id) WHERE acc_rights.name ='device_manage' and right_type = 'accountant' AND acc_group_id = #{@user.acc_group_id}"
v = ActiveRecord::Base.connection.select_value(sql)
allow_edit = v.to_i == 1 ? true : false
else
allow_edit = true
end
notice = device.validate_before_destroy(@user, allow_edit)
if !notice.blank?
doc.error(notice)
else
device.destroy_all
doc.status("Device was deleted")
end
else
dont_be_so_smart
doc.error("Dont be so smart")
end
else
doc.error("Device was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
# HACK: laikinas metodas pritaikantis xmlsimple parse formata prie parasyto funcionalumo
# TO DO: reikia patvarkyti kad veiktu be sito!!!
def transition_hash(h)
def clean_keys(h)
nh = {}
h.each_pair do |k, v|
if v.is_a?(Array) and v.first.is_a?(String)
nh[k.to_sym] = v.first.strip
elsif v.is_a?(Array)
nh[k.to_sym] = []
v.each { |i| nh[k.to_sym] << clean_keys(i) }
end
end
nh
end
# get one level down
h.each_pair do |key, value|
if value.is_a?(Array) and value.first.is_a?(Hash) and value.first.keys.size == 1
value = value.first[value.first.keys.first]
h[key] = value
end
end
clean_keys(h)
end
#----
def import_tariff_retail
doc = Builder::XmlMarkup.new(:target => out_string4 = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
#check if user exists
@user = check_user(params[:u], params[:p])
collision_rates = []
collision_rates_with_db = []
bad_destination_array = []
bad_rates_array = []
bad_rates_time_array = []
day_type_collision = []
if @user
# get xml and parse
if params[:xml]
xml = params[:xml]
tariffs = []
begin
tariffs = XmlSimple.xml_in(xml)
value = transition_hash(tariffs)
#---- TO CHECK PARAMS HERE!-------------------
logger.fatal "CHECK HERE"
logger.fatal value.inspect
value, error = check_params_name_id(value, @user)
if error.empty? #then proceed
logger.fatal "TARIFF NAME "+ value[:name].to_s
#now we have tariff with name and id
tariff_id = value[:id]
#check if there are destinations
if value[:destinations]
#go trough destinations
logger.fatal "DESTINATIONS FOUND: " +value[:destinations].size.to_s
value[:destinations].each do |destination|
logger.fatal "----------DATA -------------------------------------"
logger.fatal "Direction name: '" + destination[:direction].to_s + "'"
logger.fatal "Destination name: '" + destination[:destination_group_name].to_s + "'"
logger.fatal "Destination type: '"+ destination[:destination_group_type].to_s + "'"
logger.fatal "Rates for this destination: "+destination[:rates].size.to_s
#check for collision in xml rates
##### bad_rates_time TO DO ISVESTI KUR BLOGI LAIKAI, RATES ISTRINAMI
collision_rates, bad_rates_time_array = check_params_rates(destination[:rates], destination) if destination[:rates].size > 1
logger.fatal "Rates for this destination after collision check in xlm: "+destination[:rates].size.to_s
logger.fatal "----------WORK WITH DB ----------------------------"
#find destinationgroups_id by name and type
sql = "SELECT destinationgroup_id FROM destinations WHERE destinationgroup_id = (SELECT id FROM destinationgroups WHERE name = \"#{destination[:destination_group_name].to_s}\" AND desttype = '#{destination[:destination_group_type].to_s}') GROUP BY subcode"
rate_destinationgroups_id = ActiveRecord::Base.connection.select_value(sql)
if rate_destinationgroups_id
logger.fatal "DB DESTINATION ID: " + rate_destinationgroups_id.to_s
#find rate by tariff id and destination group
rate_id = Rate.find(:first, :conditions => ["tariff_id = ? and destinationgroup_id = ?", tariff_id, rate_destinationgroups_id])
if rate_id
#find existing rates
db_rates = Aratedetail.find(:all, :conditions => ['rate_id= ?', rate_id.id])
collision_rates_with_db = []
#start1 <= end2 and start2 <= end1
db_rates.each do |rate1|
# tikrinimas del koliziju su egzistuojanciu tarifu
destination[:rates].each do |rate2|
if (["WD", "FD"].include?(rate2[:day_type].to_s) and ["WD", "FD"].include?(rate1[:daytype].to_s)) or ([""].include?(rate2[:day_type].to_s) and [""].include?(rate1[:daytype].to_s))
if (rate1[:start_time].strftime("%X") != rate2[:rate_start_time] or rate1[:end_time].strftime("%X") != rate2[:rate_end_time]) and (rate1[:start_time].strftime("%X") <= rate2[:rate_end_time] and rate2[:rate_start_time] <= rate1[:end_time].strftime("%X")) and rate2[:day_type].to_s == rate1[:daytype].to_s
logger.fatal 'COLLISION!!!!!!!!!!!!!!!!!'
collision_rates_with_db << "#{destination[:destination_group_name]} #{destination[:destination_group_type]} COLLISION WITH EXISTING RATES IN " +[rate1[:start_time].strftime("%X"), rate2[:rate_start_time]].min.to_s + " AND " + [rate1[:end_time].strftime("%X"), rate2[:rate_end_time]].max.to_s + " TIME RANGE"
#delete all xml rates in collision time range
destination[:rates].delete_if { |el| (([rate1[:end_time].strftime("%X"), rate2[:rate_end_time]].max >= el[:rate_start_time] and el[:rate_start_time] >= [rate1[:start_time].strftime("%X"), rate2[:rate_start_time]].min) or ([rate1[:start_time].strftime("%X"), rate2[:rate_start_time]].min <= el[:rate_end_time] and el[:rate_end_time]<= [rate1[:end_time].strftime("%X"), rate2[:rate_end_time]].max)) and el[:day_type].to_s == rate1[:daytype].to_s }
end
else
day_type_collision << destination
destination[:rates].delete_if { |el| el == rate2 }
end
end
end
logger.fatal "Rates for this destination after collision check xml with db: "+destination[:rates].size.to_s
logger.fatal "DB RATE ID " + rate_id.id.to_s
#create rates and log bad rates
bad_rates_array = create_rates_merge(destination, rate_id.id, db_rates)
else
logger.fatal "DB RATE ID NOT FOUND"
logger.fatal "LETS CREATE"
rate_new = Rate.new()
rate_new.tariff_id = tariff_id.to_i
rate_new.destination_id = 0
rate_new.destinationgroup_id = rate_destinationgroups_id.to_i
if rate_new.save
#set now existing tariff id
logger.fatal "RATE CREATED " + rate_new.id.to_s
else
logger.fatal "RATE exists??!!! "
doc.response {
doc.error("RATE exists??!!")
}
end
#create rates and log bad rates
bad_rates_array = create_rates(destination, rate_new.id)
end
logger.fatal "---------------END----------------------------"
else
logger.fatal "THIS DESTINATION NAME OR TYPE IS WRONG!"
bad_destination_array << destination
end
end
bad_rates_array = bad_rates_array + bad_rates_time_array
doc.response {
doc.tariff_id("#{tariff_id}")
doc.tariff_name("#{value[:name]}")
doc.bad_destinations { |bd|
bad_destination_array.each { |d|
doc.destination { |i|
doc.destination_group_name("#{d[:destination_group_name]}")
doc.destination_group_type("#{d[:destination_group_type]}")
}
}
}
doc.destination_with_day_type_collision { |bd|
day_type_collision.each { |d|
doc.destination { |i|
doc.destination_group_name("#{d[:destination_group_name]}")
doc.destination_group_type("#{d[:destination_group_type]}")
}
}
}
doc.destination_with_bad_rates { |br|
bad_rates_array.each { |r|
doc.destination { |i|
doc.destination_group_name("#{r[:destination_group_name]}")
doc.destination_group_type("#{r[:destination_group_type]}")
doc.rate_price("#{r[:rate_price]}")
doc.rate_round_by("#{r[:rate_round_by]}")
doc.rate_duration("#{r[:rate_duration]}")
doc.rate_type("#{r[:rate_type]}")
doc.rate_start_time("#{r[:rate_start_time]}")
doc.rate_end_time("#{r[:rate_end_time]}")
doc.day_type("#{r[:day_type]}")
}
}
}
doc.destination_with_time_collisions_in_xml { |tc|
collision_rates.each { |d|
doc.destination { |i|
doc.collision_in_time_range("#{d}")
}
}
}
doc.destination_with_time_collisions_in_db { |tc|
collision_rates_with_db.each { |d|
doc.destination { |i|
doc.collision_in_time_range("#{d}")
}
}
}
}
else
doc.response {
doc.error("No destinations!")
doc.tariff_id("#{tariff_id}")
doc.tariff_name("#{value[:name]}")
}
end
else
doc.response {
doc.error(error)
}
end
rescue REXML::ParseException
logger.fatal 'No data!'
doc.response {
doc.error("Bad XML data")
}
rescue ArgumentError
logger.fatal 'File does not exist!'
doc.response {
doc.error("File does not exist")
}
end
else
doc.response {
doc.error("No XML")
}
end
else
doc.response {
doc.error("Bad login")
}
end
send_xml_data(out_string4, params[:test].to_i)
#----------------------------------------------------------END--------------
end
def wholesale_tariff
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user and mor_11_extend? and (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_edit('Tariff_manage')))
tariff_id = params[:id].to_i
if tariff_id == 0
tariff = Tariff.new
tariff.name = params[:name].to_s if params[:name]
tariff.currency = params[:currency].to_s if params[:currency]
tariff.purpose = 'user_wholesale'
tariff.owner_id = @current_user.id
if tariff.save
doc.status('ok')
doc.tariff_id(tariff.id)
else
doc.error {
tariff.errors.each { |key, value|
doc.message(_(value))
} if tariff.respond_to?(:errors)
}
end
else
tariff = Tariff.find(:first, :conditions => {:id => tariff_id, :owner_id => @user.id, :purpose => 'user_wholesale'})
if tariff
tariff.name = params[:name].to_s if params[:name]
tariff.currency = params[:currency].to_s if params[:currency]
if tariff.save
doc.status('ok')
else
doc.error {
tariff.errors.each { |key, value|
doc.message(_(value))
} if tariff.respond_to?(:errors)
}
end
else
doc.error('Tariff not found')
end
end
else
doc.error('Bad login')
end
else
doc.error('Incorrect hash')
end
}
send_xml_data(out_string, params[:test].to_i)
end
def check_params_name_id(tariff, user)
error = ""
# id - found - do not create tariff, but proceed
# id - not found:
# name - found - error:check id! change name or id -> exit
# name - not found - will create tariff -> proceed
if tariff[:id] and !tariff[:id].to_s.empty?
if tariff[:name] and !tariff[:name].empty?
#try find tariff by id
#if not found - create one with given name
try_find_tariff = Tariff.find_by_id(tariff[:id].to_i)
if !try_find_tariff
logger.fatal "TARIFF NOT FOUND. CREATING ONE"
tariff_new = Tariff.new()
tariff_new.name = tariff[:name].to_s
tariff_new.purpose = "user"
tariff_new.owner_id = @user.id
tariff_new.currency = @user.currency.name
if tariff_new.save
#set now existing tariff id
tariff[:id] = tariff_new.id
logger.fatal "TARIFF CREATED " + tariff[:id].to_s
else
find_tariff_id = Tariff.find(:first, :conditions => ['name =? and purpose = "user"', tariff[:name].to_s])
if find_tariff_id and (find_tariff_id.owner_id.to_i == user.id or user.usertype.to_s == 'admin')
logger.fatal "TARIFF with same name exists, ID:#{find_tariff_id.id}!!! CHANGE NAME OR ID"
error += "TARIFF with same name exists, ID:#{find_tariff_id.id}!!! CHANGE NAME OR ID"
else
logger.fatal "TARIFF with same name exists, it belongs to other user! CHANGE NAME OR ID"
error += "TARIFF with same name exists, it belongs to other user! CHANGE NAME OR ID"
end
end
else
if try_find_tariff.owner_id.to_i == user.id
if try_find_tariff.name.to_s == tariff[:name].to_s
logger.fatal "TARIFF FOUND ID: " + tariff[:id].to_s
else
logger.fatal "NAME AND ID DO NOT MATCH !!! TARIFF FOUND ID: " + tariff[:id].to_s
error += "TARIFF NAME WITH THIS ID DO NOT MATCH !!!"
error += "FOUND " + try_find_tariff.name.to_s
end
else
error += "Tariff belongs to other user!"
end
end
else
logger.fatal("No tariff name")
error += "No tariff name"
end
else
logger.fatal("No tariff id")
error += "No tariff id"
end
return tariff, error
end
def check_params_rates(rates, destination)
collision_rates = []
bad_destination_time_rates = []
#start1 <= end2 and start2 <= end1
rates.each do |rate1|
# tikrinimas del koliziju
if rate1[:rate_start_time].length == 8 and rate1[:rate_start_time].to_s !~ /[^0-9.\:]/ and rate1[:rate_end_time].length == 8 and rate1[:rate_end_time].to_s !~ /[^0-9.\:]/
rates.each do |rate2|
if rate2[:rate_start_time].length == 8 and rate2[:rate_start_time].to_s !~ /[^0-9.\:]/ and rate2[:rate_end_time].length == 8 and rate2[:rate_end_time].to_s !~ /[^0-9.\:]/
if (rate1[:rate_start_time] != rate2[:rate_start_time] or rate1[:rate_end_time] != rate2[:rate_end_time]) and (rate1[:rate_start_time] <= rate2[:rate_end_time] and rate2[:rate_start_time] <= rate1[:rate_end_time]) and rate2[:day_type].to_s == rate1[:daytype].to_s
logger.fatal 'COLLISION!!!!!!!!!!!!!!!!!'
logger.fatal "#{destination[:destination_group_name]} #{destination[:destination_group_type]} COLLISION IN " +[rate1[:rate_start_time], rate2[:rate_start_time]].min.to_s + " AND " + [rate1[:rate_end_time], rate2[:rate_end_time]].max.to_s + " TIME RANGE "
collision_rates << "#{destination[:destination_group_name]} #{destination[:destination_group_type]} COLLISION IN " +[rate1[:rate_start_time], rate2[:rate_start_time]].min.to_s + " AND " + [rate1[:rate_end_time], rate2[:rate_end_time]].max.to_s + " TIME RANGE "
#delete all rates in collision time range
rates.delete_if { |el| (([rate1[:rate_end_time], rate2[:rate_end_time]].max >= el[:rate_start_time] and el[:rate_start_time] >= [rate1[:rate_start_time], rate2[:rate_start_time]].min) or ([rate1[:rate_start_time], rate2[:rate_start_time]].min <= el[:rate_end_time] and el[:rate_end_time]<= [rate1[:rate_end_time], rate2[:rate_end_time]].max))and el[:day_type].to_s == rate2[:day_type].to_s }
end
else
bad_destination_time_rates << rate2.merge!(:destination_group_name => destination[:destination_group_name], :destination_group_type => destination[:destination_group_type])
rates.delete_if { |el| el==rate2 }
logger.fatal 'BAD TIME!!!!!!!!!!!!!!!!!'
end
end
else
bad_destination_time_rates << rate1.merge!(:destination_group_name => destination[:destination_group_name], :destination_group_type => destination[:destination_group_type])
rates.delete_if { |el| el==rate1 }
logger.fatal 'BAD TIME!!!!!!!!!!!!!!!!!'
end
end
return collision_rates, bad_destination_time_rates
end
def create_rates(destination, rate_id)
#check params, duration, round by, increase from
array_of_values = []
array_to_create = []
@from = 1
@end = []
@start = []
@daytype = []
@is_duration_infinity = false
@is_round_by_bigger_than_from_plus_duration = false
bad_rates = ""
bad_rates_array = []
destination[:rates].each do |rate|
bad = check_rates_params(rate)
if bad
rate.merge!(:destination_group_name => destination[:destination_group_name], :destination_group_type => destination[:destination_group_type])
bad_rates_array << rate
else
from_to_create = array_to_create.find_all { |r| r[:start_time] == rate[:rate_start_time] and r[:end_time] == rate[:rate_end_time] and r[:daytype] == rate[:day_type] }.sort_by { |a| a[:from].to_i }.last
if !from_to_create
@from = 1
else
#if minute goes after event, 'from' matches
@from = from_to_create[:from].to_i + from_to_create[:duration].to_i if from_to_create[:artype] != 'event'
@from = from_to_create[:from].to_i if from_to_create[:artype] == 'event'
end
#check if rate was infinity or round_by is too big in that time period and daytype, if not - proceed, if was - skip
if (!@is_duration_infinity or !@is_round_by_bigger_than_from_plus_duration) and (!@start.include?(rate[:rate_start_time]) or !@end.include?(rate[:rate_end_time]) or !@daytype.include?(rate[:daytype].to_s))
arate_new = {}
arate_new[:rate_id] = rate_id
arate_new[:price] = rate[:rate_price].to_f
arate_new[:round] = rate[:rate_round_by].to_i
arate_new[:artype] = rate[:rate_type] ? rate[:rate_type].to_s : "minute"
arate_new[:start_time] = rate[:rate_start_time] if rate[:rate_start_time]
arate_new[:end_time] = rate[:rate_end_time] if rate[:rate_end_time]
arate_new[:daytype] = rate[:day_type] ? rate[:day_type] : ''
#if duration -1 , no new rate added to this rate time interval!
arate_new[:duration] = rate[:rate_duration] ? rate[:rate_duration] : -1
if arate_new[:duration].to_i == -1 and arate_new[:artype] != 'event'
@is_duration_infinity = true
@start << rate[:rate_start_time]
@end << rate[:rate_end_time]
@daytype << rate[:day_type].to_s
end
#count this by duration
arate_new[:from] = @from
if arate_new[:duration].to_i != -1 and arate_new[:artype] != 'event' and (arate_new[:from].to_i + arate_new[:duration].to_i) < arate_new[:round].to_i
#round by check
@is_round_by_bigger_than_from_plus_duration = true
@start << rate[:rate_start_time]
@end << rate[:rate_end_time]
@daytype << rate[:day_type].to_s
bad_rates += "// Price: " +rate[:rate_price].to_s + " Round: " + rate[:rate_round_by].to_s + " Duration: " + rate[:rate_duration].to_s + " From: " + arate_new[:from].to_s + " Artype: "+ rate[:rate_type].to_s + " Start time: "+ rate[:rate_start_time].to_s + " End time: "+ rate[:rate_end_time].to_s + " Daytype: "+ rate[:day_type].to_s + "//"
rate.merge!(:destination_group_name => destination[:destination_group_name], :destination_group_type => destination[:destination_group_type])
bad_rates_array << rate
else
array_to_create << arate_new
array_of_values << "('#{arate_new[:duration]}' , '#{arate_new[:price]}' , '#{arate_new[:end_time]}','#{arate_new[:daytype]}' ,'#{arate_new[:from]}' , '#{arate_new[:artype]}' , '#{arate_new[:rate_id]}','#{arate_new[:round]}','#{arate_new[:start_time]}')"
end
end
end
end
if !array_of_values.empty?
sql_insert = "INSERT INTO aratedetails (`duration`, `price`, `end_time`, `daytype`, `from`, `artype`, `rate_id`, `round`, `start_time`)
VALUES #{array_of_values.join(',')};"
logger.fatal "#{sql_insert}"
ActiveRecord::Base.connection.execute(sql_insert)
end
bad_rates_array
end
def create_rates_merge(destination, rate_id, db_rates)
#check params, duration, round by, increase from
database_rates = db_rates
array_of_values = []
array_to_create = []
bad_rates_array = []
@from = 1
@type = ""
@end = []
@start = []
@daytype = []
@is_duration_infinity = false
@is_round_by_bigger_than_from_plus_duration = false
bad_rates = ""
destination[:rates].each do |rate|
bad = check_rates_params(rate)
if bad
rate.merge!(:destination_group_name => destination[:destination_group_name], :destination_group_type => destination[:destination_group_type])
bad_rates_array << rate
else
#find last 'from' in that time period
db_from = database_rates.find_all { |r| r.start_time.strftime("%X") == rate[:rate_start_time] and r.end_time.strftime("%X") == rate[:rate_end_time] and r.daytype.to_s == rate[:day_type].to_s }.sort_by { |a| a.from.to_i }.last
from_to_create = array_to_create.find_all { |r| r[:start_time] == rate[:rate_start_time] and r[:end_time] == rate[:rate_end_time] and r[:daytype] == rate[:day_type] }.sort_by { |a| a[:from].to_i }.last
#check first rates to create
if !from_to_create
@from = 1
else
#if minute goes after event, 'from' matches
@from = from_to_create[:from].to_i + from_to_create[:duration].to_i if from_to_create[:artype] != 'event'
@from = from_to_create[:from].to_i if from_to_create[:artype] == 'event'
end
#then check with db rates
if db_from
if db_from[:duration].to_i == -1
#last rate is infinity, do not add!
@is_duration_infinity = true
@start << db_from[:start_time].strftime("%X")
@end << db_from[:end_time].strftime("%X")
@daytype << db_from[:daytype]
else
#set next from
sum = db_from[:from].to_i + db_from[:duration].to_i
if sum < @from
@from = @from
else
@from = sum if db_from[:artype] != 'event'
@from = db_from[:from].to_i if db_from[:artype] == 'event'
end
end
end
#check if rate was infinity or round_by is too big in that time period and daytype, if not - proceed, if was - skip
if (!@is_duration_infinity or !@is_round_by_bigger_than_from_plus_duration) and (!@start.include?(rate[:rate_start_time]) or !@end.include?(rate[:rate_end_time]) or !@daytype.include?(rate[:daytype].to_s))
arate_new = {}
arate_new[:rate_id] = rate_id
arate_new[:price] = rate[:rate_price].to_f
arate_new[:round] = rate[:rate_round_by].to_i
arate_new[:artype] = rate[:rate_type] ? rate[:rate_type].to_s : "minute"
@type = arate_new[:artype]
arate_new[:start_time] = rate[:rate_start_time] if rate[:rate_start_time]
arate_new[:end_time] = rate[:rate_end_time] if rate[:rate_end_time]
arate_new[:daytype] = rate[:day_type] ? rate[:day_type] : ''
#if duration -1 , no new rate added to this rate time interval!
arate_new[:duration] = rate[:rate_duration] ? rate[:rate_duration] : -1
if arate_new[:duration].to_i == -1 and arate_new[:artype] != 'event'
@is_duration_infinity = true
@start << rate[:rate_start_time]
@end << rate[:rate_end_time]
@daytype << rate[:day_type].to_s
end
#count this by duration
arate_new[:from] = @from
if arate_new[:duration].to_i != -1 and arate_new[:artype] != 'event' and (arate_new[:from].to_i + arate_new[:duration].to_i) < arate_new[:round].to_i
#round by check
@is_round_by_bigger_than_from_plus_duration = true
@start << rate[:rate_start_time]
@end << rate[:rate_end_time]
@daytype << rate[:day_type].to_s
bad_rates += "// Price: " +rate[:rate_price].to_s + " Round: " + rate[:rate_round_by].to_s + " Duration: " + rate[:rate_duration].to_s + " From: " + arate_new[:from].to_s + " Artype: "+ rate[:rate_type].to_s + " Start time: "+ rate[:rate_start_time].to_s + " End time: "+ rate[:rate_end_time].to_s + " Daytype: "+ rate[:day_type].to_s + "//"
rate.merge!(:destination_group_name => destination[:destination_group_name], :destination_group_type => destination[:destination_group_type])
bad_rates_array << rate
logger.fatal rate.inspect
else
array_to_create << arate_new
array_of_values << "('#{arate_new[:duration]}' , '#{arate_new[:price]}' , '#{arate_new[:end_time]}','#{arate_new[:daytype]}' ,'#{arate_new[:from]}' , '#{arate_new[:artype]}' , '#{arate_new[:rate_id]}','#{arate_new[:round]}','#{arate_new[:start_time]}')"
end
end
end
end
if !array_of_values.empty?
sql_insert = "INSERT INTO aratedetails (`duration`, `price`, `end_time`, `daytype`, `from`, `artype`, `rate_id`, `round`, `start_time`)
VALUES #{array_of_values.join(',')};"
logger.fatal "#{sql_insert}"
ActiveRecord::Base.connection.execute(sql_insert)
end
bad_rates_array
end
def check_rates_params(rate)
ret = 0
ret += 1 if rate[:rate_price] and rate[:rate_price].to_s.length > 0 and rate[:rate_price].to_s !~ /[^0-9.\-\+]/
ret += 1 if rate[:rate_round_by] and rate[:rate_round_by].to_s !~ /[^0-9]/ and rate[:rate_round_by].to_s.length > 0
ret += 1 if rate[:rate_type] and ["minute", "event"].include?(rate[:rate_type].to_s)
ret += 1 if rate[:rate_start_time] and rate[:rate_start_time].to_s !~ /[^0-9.\:]/ and rate[:rate_start_time].to_s.length > 0
ret += 1 if rate[:rate_end_time] and rate[:rate_end_time].to_s !~ /[^0-9.\:]/ and rate[:rate_end_time].to_s.length > 0
ret += 1 if rate[:day_type] and ['', "WD", "FD"].include?(rate[:day_type].to_s)
ret += 1 if rate[:rate_duration] and rate[:rate_duration].to_s !~ /[^0-9.\-]/ and rate[:rate_duration].to_s.length > 0
if ret < 7
return true
else
return false
end
end
def device_create
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
if check_owner_for_device(params[:user_id], 0, @user)
coi = @user.usertype == 'accountant' ? 0 : @user.id
user_u = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", values[:user_id], coi]) if values[:user_id]
if user_u
params[:device] = {}
params[:device][:description] = params[:description]
params[:device][:devicegroup_id] = params[:devicegroup_id]
params[:device][:device_type] = params[:type]
params[:device][:pin] = params[:pin] if params[:pin]
az, av = @user.alow_device_types_dahdi_virt
notice, params2 = Device.validate_before_create(@user, user_u, params, az, av)
if !notice.blank?
doc.error(_(notice).gsub('_', ' '))
else
if !params2[:device][:device_type] or params2[:device][:device_type].blank?
params2[:device][:device_type] = Confline.get_value("Default_device_type", @user.id).to_s
end
if params2[:device][:device_type].blank?
params2[:device][:device_type] = "SIP"
end
params2[:device][:pin] = new_device_pin if !params2[:device][:pin]
fextension = free_extension()
device = user_u.create_default_device({:device_ip_authentication_record => params2[:ip_authentication].to_i, :description => params2[:device][:description], :device_type => params2[:device][:device_type], :dev_group => params2[:device][:devicegroup_id], :free_ext => fextension, :secret => random_password(12), :username => fextension, :pin => params2[:device][:pin]})
if device.save
a = Thread.new { configure_extensions(device.id, {:api => 1, :current_user => @user}) }
doc.status(device.check_callshop_user(_('device_created')))
doc.id(device.id)
else
doc.error("Device was not created")
device.errors.each { |key, value|
doc.message(_(value))
} if device.respond_to?(:errors)
end
end
else
doc.error("User was not found")
end
else
dont_be_so_smart
doc.error("Dont be so smart")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
#====================================== Phonebooks =======================================
def phonebooks
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
if @user.usertype == 'user'
user_u = @user
else
if values[:user_id] and values[:user_id].to_i != @user.id
user_u = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", values[:user_id], @user.get_correct_owner_id])
MorLog.my_debug @user.get_correct_owner_id
else
user_u = @user
end
end
if user_u
ph = Phonebook.user_phonebooks(user_u)
if ph and ph.size.to_i > 0
doc.phonebooks {
for p in ph
doc.phonebook {
doc.name(p.name)
doc.number(p.number)
doc.speeddial(p.speeddial)
}
end
}
else
doc.error("No Phonebooks")
end
else
doc.error("User was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
def phonebook_edit
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
ph = Phonebook.find_by_id(params[:phonebook_id])
if ph
if ph.user_id != @user.id and @user.usertype != "admin"
dont_be_so_smart
doc.error("Dont be so smart")
else
ph.number = params[:number] if params[:number]
ph.name = params[:name] if params[:name]
ph.speeddial = params[:speeddial] if params[:speeddial]
if ph.valid?
ph.save
doc.status('Phonebook saved')
else
doc.error("Phonebook was not saved")
ph.errors.each { |key, value|
doc.message(_(value))
} if ph.respond_to?(:errors)
end
end
else
doc.error("Phonebook was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
Lists all credit notes available to to wiev for the user. He can select one
specific credit note by supplying it's id(credit_note_id=XXX) or filter only
specific user's credit notes(user_id=YYY). In case user can not see financial
data it will no be displayed for him.
If accountant is allow to read invoices, he may list credit notes. but ha can see
financial data only if he is also allowed to see financial data.
for instance these would be valid queries, given there is such user and id's
are valid:
/api/credit_notes?u=user&p=user1
/api/credit_notes?u=user&p=user1&credit_note_id=XXX
/api/credit_notes?u=user&p=user1&user_id=YYY
=end
def credit_notes
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user and (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_read('invoices_manage')))
if @user.is_reseller?
condition = ["users.owner_id = #{@user.id}"]
elsif @user.is_admin? or @user.is_accountant?
condition = ['users.owner_id = 0']
end
if params[:credit_note_id]
condition << "credit_notes.id = #{params[:credit_note_id].to_i}"
elsif values[:user_id]
condition << "credit_notes.user_id = #{values[:user_id].to_i}"
end
notes = CreditNote.find(:all, :include => :user, :conditions => condition.join(' AND '))
if notes and notes.size.to_i > 0
can_see_finances = (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_read('see_financial_data')))
doc.credit_notes {
for note in notes
doc.credit_note {
doc.user_id(note.user_id)
doc.issue_date(note.issue_date)
doc.number(note.number)
doc.comment(note.comment)
if can_see_finances
doc.price(note.price)
doc.price_with_vat(note.price_with_vat)
doc.pay_date(note.pay_date)
end
}
end
}
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
User can update only his user's credit notes. there is an exception for accountant -
he can update admin's users credit notes.
Expecting to get at least one necesary parameter - credit_note_id. if it is not
provider, id defaults to 0 and nothing wil be found, error message will be send.
two optional parameters are comment and status. status can be only 'paid' or 'unpaid'
if none of these parameters are supplied or status is not valid credit note will not
be updated, but still because everything vent without errors status will be send informing
that note was updated. if user cannot see financial data he cannot set status.
for instance these would be valid queries, given there is such user and id's
are valid, though the last one would not change anything:
/api/credit_note_update?u=user&p=user1&credit_note_id=XXX&status=paid
/api/credit_note_update?u=user&p=user1&credit_note_id=XXX&status=unpaid
/api/credit_note_update?u=user&p=user1&credit_note_id=XXX&comment=AAA
/api/credit_note_update?u=user&p=user1&credit_note_id=XXX&comment=AAA&status=paid
/api/credit_note_update?u=user&p=user1&credit_note_id=XXX
=end
def credit_note_update
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user and (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_read('invoices_manage')))
if @user.is_reseller?
condition = ['users.owner_id = ? AND credit_notes.id = ?', @user.id, params[:credit_note_id].to_i]
elsif @user.is_admin? or @user.is_accountant?
condition = ['users.owner_id = 0 AND credit_notes.id = ?', params[:credit_note_id].to_i]
end
note = CreditNote.find(:first, :include => :user, :conditions => condition)
if note
if params[:status] and (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_edit('see_financial_data')))
if params[:status] == 'paid'
note.pay
elsif params[:status] == 'unpaid'
note.unpay
end
end
if params[:comment]
note.comment = params[:comment]
end
if note.save
doc.status("Credit note was updated")
else
doc.error("Credit note was not updated")
end
else
doc.error("Credit note was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
User can delete only his user's credit notes. there is an exception for accountant -
he can delete admin's users credit notes. normal user cannot use this function, it is
available only for admin, accountant and reseller.
for instance this would be the only valid query, given there is such user and id's
are valid:
/api/credit_note_delete?u=user&p=user1&credit_note_id=XXX
=end
def credit_note_delete
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user and (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_edit('invoices_manage') and @user.accountant_allow_edit('see_financial_data')))
if @user.is_reseller?
condition = ['users.owner_id = ? AND credit_notes.id = ?', @user.id, params[:credit_note_id].to_i]
elsif @user.is_admin? or @user.is_accountant?
condition = ['users.owner_id = 0 AND credit_notes.id = ?', params[:credit_note_id].to_i]
end
note = CreditNote.find(:first, :include => :user, :conditions => condition)
if note
note.destroy
doc.status("Credit note was deleted")
else
doc.error("Credit note was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
Credit note may be created only for valid user, that is owned by user who tries
to create credit note(in accountant's case user has to be owned by admin). normal
user cannot use this function, it is available only for admin, accountant and reseller,
though reseller has to be able to see financial data.
Accountant is allow to create credit notes only if he may edit financial data and manage
invoices.
for instance these would be valid queries, given there is such user and id's
are valid:
/api/credit_note_create?u=user&p=user1&user_id=XXX&price=YYY&issue_date=YYYY-MM-DD
/api/credit_note_create?u=user&p=user1&user_id=XXX&price=YYY&issue_date=YYYY-MM-DD&comment=CCCCC
/api/credit_note_create?u=user&p=user1&user_id=XXX&price=YYY&issue_date=YYYY-MM-DD&number=NNN
/api/credit_note_create?u=user&p=user1&user_id=XXX&price=YYY&issue_date=YYYY-MM-DD&comment=CCCCC&number=NNN
note that credit note cannot be created for admin, hance ..and user.id > 0
note that is issue_date must be specified, if not we dont event try to save note(cause it would crash)
=end
def credit_note_create
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user and (@user.is_admin? or @user.is_reseller? or (@user.is_accountant? and @user.accountant_allow_read('invoices_manage') and @user.accountant_allow_edit('see_financial_data')))
if @user.is_reseller?
condition = ['users.owner_id = ? AND users.id = ?', @user.id, params[:user_id].to_i]
elsif @user.is_admin? or @user.is_accountant?
condition = ['users.owner_id = 0 AND users.id = ?', params[:user_id].to_i]
end
user = User.find(:first, :include => :tax, :conditions => condition)
if user and user.id > 0
note = CreditNote.new
note.user = user
note.comment = params[:comment] if params[:comment]
note.issue_date = Time.at(params[:issue_date].to_i) if params[:issue_date].to_i > 0
note.number = params[:number].to_i if params[:number].to_i > 0
note.price = params[:price] if params[:price]
if params[:issue_date].to_i > 0 and note.save
doc.status("Credit note was created")
else
doc.error("Credit note was not created")
end
else
doc.error("User was not found")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
If accountant cannot see financial data, manage invoices/payments in read mode,
he cannot see financial statements. if accountant has suficient permissions or
user is so other type, he may view his(user) or his users(admin, reseller)
financial statements.
Accountant and reseller may filter theyr users by sending valid id.
Valid date range is mandatory parameter. Dates has to be supplied as unix timestamps.
Every user may flter by status. Valid statuses are - paid, unpaid, 'all'. if not
supplied defaults to 'all'.
For instance some posible api commands are:
/api/financial_statements?u=admin&p=admin&date_from=1231453&date_till=23452&hash=234234
/api/financial_statements?u=admin&p=admin&status=all&date_from=1231453&date_till=23452&hash=234234
/api/financial_statements?u=admin&p=admin&status=paid&date_from=1231453&date_till=23452$hash=234234
/api/financial_statements?u=admin&p=admin&user_id=3&date_from=1231453&date_till=23452$hash=23453
/api/financial_statements?u=admin&p=admin&status=all&user_id=5&date_from=1231453&date_till=23452&hash=354234
=end
def financial_statements
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if @current_user and not (@current_user.is_accountant? and (not @current_user.accountant_allow_read('can_see_finances') or not @current_user.allow_read('payments_manage') or not @current_user.accountant_allow_read('invoices_manage')))
if @values[:date_from] and @values[:date_till]
date_from = Time.at(@values[:date_from].to_i).to_date.to_s(:db)
date_till = Time.at(@values[:date_till].to_i).to_date.to_s(:db)
end
date_from = Date.today.to_s(:db) if !date_from
date_till = Time.now.tomorrow.to_s(:db) if !date_till
if ['paid', 'unpaid', 'all'].include? @values[:status]
status = @values[:status]
else
status = 'all'
end
if @current_user.usertype == 'user'
user_id = @current_user.id
ordinary_user = @current_user.is_user?
elsif @values[:user_id] and @values[:user_id].to_i > 0
user_id = @values[:user_id].to_i
end
if @current_user.is_admin? or @current_user.is_accountant?
owner_id = 0
else
owner_id = @current_user.id
end
if !@current_user.is_user?
coi = @current_user.usertype == 'accountant' ? 0 : @current_user.id
user = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", @values[:user_id], coi]) if @values[:user_id]
else
user = @current_user
end
if user or !@values[:user_id]
financial_statements = {}
financial_statements["invoices"] = Invoice.financial_statements(owner_id, user_id, status, date_from, date_till, ordinary_user)
financial_statements["credit_notes"] = CreditNote.financial_statements(owner_id, user_id, status, date_from, date_till, ordinary_user)
default_currency_name = Currency.get_default.name
financial_statements["payments"] = Payment.financial_statements(owner_id, user_id, status, date_from, date_till, ordinary_user, default_currency_name)
doc.financial_statement("currency" => default_currency_name) {
financial_statements.each { |type, statements|
statements.each { |data|
doc.statement("type" => type) {
doc.status(data.status)
doc.count(data.count)
if type == 'invoices'
doc.price(nice_number(data.price * count_exchange_rate(@current_user.currency.name, default_currency_name)))
doc.price_with_vat(nice_number(data.price_with_vat * count_exchange_rate(@current_user.currency.name, default_currency_name)))
else
doc.price(nice_number(data.price))
doc.price_with_vat(nice_number(data.price_with_vat))
end
}
}
}
}
else
doc.error("Dont be so smart")
end
else
doc.error("Bad login")
end
}
send_xml_data(out_string, params[:test].to_i)
end
def create_payment
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
if Confline.get_value("API_Allow_payments_ower_API").to_i == 1
if !@current_user.is_user?
coi = @current_user.usertype == 'accountant' ? 0 : @current_user.id
user = User.find(:first, :conditions => ["id = ? AND owner_id = ? ", values[:user_id], coi]) if values[:user_id]
end
if user
currency = Currency.get_by_name(values[:p_currency])
if currency
pttype = "from_api : #{values[:paymenttype]}"
if values[:tax_in_amount].to_i == 1
gross = values[:amount].to_f
amount = user.get_tax.count_amount_without_tax(gross).to_f
else
amount = values[:amount].to_f
gross = user.get_tax.apply_tax(amount).to_f
end
tax = gross - amount
comfirm = Confline.get_value("API_payment_confirmation").to_i
paym = Payment.create_for_user(user, {:pending_reason => comfirm == 1 ? 'Waiting for confirmation' : "completed", :paymenttype => pttype, :currency => currency.name, :gross => gross.to_f, :tax => tax, :amount => amount.to_f, :transaction_id => values[:transaction], :payer_email => values[:payer_email], :shipped_at => values[:shipped_at], :fee => values[:fee]})
paym.completed = comfirm == 1 ? 0 : 1
paym.description = values[:description].to_s
if paym.save
if comfirm.to_i == 0
exchange_rate = Currency.count_exchange_rate(Currency.get_default.name, currency.name)
curr_amount = amount / exchange_rate.to_f
userrr = @current_user
User.current = nil
user.balance += curr_amount
user.save
User.current = userrr
Action.add_action_hash(paym.user_id,
{:action => "payment: #{pttype}",
:data => "User successfully payed using #{pttype}",
:data3 => "#{paym.amount} #{paym.currency} | tax: #{paym.gross - paym.amount} #{paym.currency} | fee: #{paym.fee} #{paym.currency} | sent: #{paym.gross} #{paym.currency}",
:data2 => "payment id: #{paym.id}",
:data4 => "authorization: #{paym.transaction_id}"
})
else
Action.add_action_hash(paym.user_id,
{:action => "payment: #{pttype}",
:data => "User successfully created #{pttype}",
:data3 => "#{paym.amount} #{paym.currency} | tax: #{paym.gross - paym.amount} #{paym.currency} | fee: #{paym.fee} #{paym.currency} | sent: #{paym.gross} #{paym.currency}",
:data2 => "payment id: #{paym.id}",
:data4 => "authorization: #{paym.transaction_id}"
})
end
doc.response {
doc.status('ok')
doc.payment("currency" => currency.name) {
doc.payment_id(paym.id)
doc.tax(nice_number(paym.tax))
doc.amount(nice_number(paym.amount))
doc.gross(nice_number(paym.gross))
}
}
else
doc.error("Payment was not saved") {
paym.errors.each { |key, value|
doc.message(_(value))
} if paym.respond_to?(:errors)
}
end
else
doc.error("No currency")
end
else
doc.error("Dont be so smart")
end
else
doc.error("Payments not allow from api")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
def cc_by_cli_geras_disablinu_iki_mk_grizimo #2012-05-21
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
values = @values
if values[:callerid].blank?
doc.error("Callerid must be specified")
else
if values[:pin] and !values[:pin].blank?
# II
device = Device.find(:first, :include => [:user, :callerids], :conditions => ['callerids.cli = ? OR callerids.cli LIKE ?', params[:callerid], '%' + params[:callerid] + '%'])
if !device or (device and device.user and device.user.owner_id == @current_user.get_correct_owner_id)
if device
#4 * We find device by callerid and card by PIN, device.user.balance+=card.balance, card.disable
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
card_by_pin = Card.find(:first, :include => :cardgroup, :conditions => {:pin => values[:pin], :owner_id => @current_user.get_correct_owner_id})
if card_by_pin
if card_by_pin.balance == 0
doc.error("PIN number balance is zero")
else
card_by_pin.disable
if card_by_pin.save
if device.user.add_to_balance(card_by_pin.balance, 'card_refill')
card_by_pin.add_to_balance(card_by_pin.balance * -1, false)
doc.response {
doc.status("ok")
doc.device_id(device.id)
doc.user_id(device.user_id)
doc.new_balance(nice_number(device.user.balance))
doc.new_balance_with_vat(nice_number(device.user.balance_with_vat))
}
else
doc.error("Failed to make transaction")
end
else
doc.error {
card_by_pin.errors.each { |key, value|
doc.error(_(value))
} if card_by_pin.respond_to?(:errors)
}
end
end
else
doc.error("PIN number not found")
end
else
card = Card.find(:first, :conditions => {:callerid => values[:callerid]})
if !card or (card and card.cardgroup.owner_id == @current_user.get_correct_owner_id)
if card
card_by_pin = Card.find(:first, :include => :cardgroup, :conditions => ['cards.pin = ? AND cardgroups.owner_id =? AND cards.id <> ?', values[:pin], @current_user.get_correct_owner_id, card.id])
if card_by_pin
if card.cardgroup_id == card_by_pin.cardgroup_id
#2 * We find card2 by callerid and card1 by PIN, then card2.balance += card1.balance, card1.disable.
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
amount = card_by_pin.balance
if amount == 0
doc.error("PIN number balance is zero")
else
logger.fatal card.to_yaml
logger.fatal card_by_pin.to_yaml
card_by_pin.disable
card_by_pin.add_to_balance(card.balance * -1, false)
if card_by_pin.save
card.sell
if card.add_to_balance(amount, false)
respond_to_successful_card_operation(doc, card)
else
doc.error("Failed to make transaction")
end
else
doc.error {
card_by_pin.errors.each { |key, value|
doc.error(_(value))
} if card_by_pin.respond_to?(:errors)
}
end
end
else
#3 * We find card2 by callerid and card1 by PIN. card1.callerid=card2.callerid, card2.callerid=nil, card1.balance +=card2.balance, card1.sold, card2.disable
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
amount = card.balance
if amount == 0
doc.error("PIN number balance is zero")
else
card.sell
card_by_pin.sell
card.add_to_balance(card.balance * -1, false)
card_by_pin.callerid = card.callerid
card.callerid = nil
if card.save
if card_by_pin.add_to_balance(amount, false)
card.disable
card.save
respond_to_successful_card_operation(doc, card_by_pin)
else
doc.error("Failed to make transaction")
end
else
doc.error {
card.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
end
end
else
doc.error("PIN number not found")
end
else
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
#1 * We check if callerid_id is free. If it is free then we search cardgroup by card using PIN, then we create card2 in same cardgroup.
# ** There is no need to create a new card2; just mark the card with the entered PIN number as sold, active, and associate the callerID to it.
card_by_pin = Card.find(:first, :include => :cardgroup, :conditions => {:pin => values[:pin], :owner_id => @current_user.get_correct_owner_id})
if card_by_pin
card_by_pin.callerid = values[:callerid]
if card_by_pin.sell
respond_to_successful_card_operation(doc, card_by_pin)
else
doc.error {
card_by_pin.errors.each { |key, value|
doc.error(_(value))
} if card_by_pin.respond_to?(:errors)
}
end
else
doc.error("PIN number not found")
end
end
else
doc.error("You do not have permission to access card")
end
end
else
doc.error("You do not have permission to add to user's balance")
end
else
# I
device = Device.find(:first, :include => [:user, :callerids], :conditions => ['callerids.cli = ? OR callerids.cli LIKE ?', values[:callerid], '%' + values[:callerid] + '%'])
if !device or (device and device.user.owner_id == @current_user.get_correct_owner_id)
if device
#4 * We find device by callerid, device.user.balance+=amount
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
if device.user.add_to_balance(device.user.get_tax.count_amount_without_tax(values[:amount].to_f), 'card_refill')
doc.response {
doc.status("ok")
doc.device_id(device.id)
doc.user_id(device.user_id)
doc.new_balance(nice_number(device.user.balance))
doc.new_balance_with_vat(nice_number(device.user.balance_with_vat))
}
else
doc.error("Failed to make transaction")
end
else
card = Card.find(:first, :conditions => {:callerid => values[:callerid]})
if !card or (card and (card.cardgroup.owner_id == @current_user.get_correct_owner_id) or card.cardgroup.hidden == 1)
if card
if values[:cardgroup_id]
cardgroup = Cardgroup.find(:first, :conditions => {:hidden => 0, :id => values[:cardgroup_id], :owner_id => @current_user.get_correct_owner_id})
else
cardgroup = card.cardgroup
end
if cardgroup
if cardgroup.id != card.cardgroup_id
#3 * We find card1 by callerid and cardgroup2 by cardgroup_id, then we check If card1.cardgroup != cardgroup2, then we create card_n in cardgroup2 , card_n.callerid = Caller_id, card_n.balance = amount + card1.balance, card_n.sold , card1.disable
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
original_balance = card.balance
card.add_to_balance(card.balance * -1, false)
card.disable
card.callerid = nil
amount = values[:amount].to_f * Currency.count_exchange_rate(cardgroup.tell_balance_in_currency, Currency.get_default).to_f
amount = cardgroup.get_tax.count_amount_without_tax(original_balance + amount)
if card.save
card_n = cardgroup.create_card({:balance => amount, :callerid => values[:callerid]})
if card_n.sell and card_n.save
respond_to_successful_card_operation(doc, card_n)
else
doc.error {
card_n.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
else
doc.error {
card.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
else
#2 * We find card1 by callerid and cardgroup by card1, we check if cardgroup is allowed for user then then card1.balance += amount
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
card.sell
amount = values[:amount].to_f * Currency.count_exchange_rate(card.cardgroup.tell_balance_in_currency, Currency.get_default).to_f
amount = cardgroup.get_tax.count_amount_without_tax(amount)
if card.add_to_balance(amount)
respond_to_successful_card_operation(doc, card)
else
doc.error("Failed to make transaction")
end
end
else
doc.error("You do not have permission to access cardgroup")
end
else
#1 * We check if callerid_id is free. If it is free then we search cardgroup by cardgroup_id, then we create card_n in cardgroup, card_n.callerid = Caller_id, card_n.balance = amount, card_n.sold
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
cardgroup = Cardgroup.find(:first, :conditions => {:hidden => 0, :id => values[:cardgroup_id], :owner_id => @current_user.get_correct_owner_id})
if cardgroup
logger.fatal cardgroup.tell_balance_in_currency
amount = values[:amount].to_f * Currency.count_exchange_rate(cardgroup.tell_balance_in_currency, Currency.get_default).to_f
amount = cardgroup.get_tax.count_amount_without_tax(amount)
card_n = cardgroup.create_card({:balance => amount, :callerid => values[:callerid]})
if card_n.sell and card_n.save
respond_to_successful_card_operation(doc, card_n)
else
doc.error {
card_n.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
else
doc.error("Supplied Cardgroup_id is invalid")
end
end
else
doc.error("You do not have permission to access card")
end
end
else
doc.error("You do not have permission to add to user's balance")
end
end
end
}
send_xml_data(out_string, params[:test].to_i)
end
def cc_by_cli
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
values = @values
if values[:callerid].blank?
doc.error("Callerid must be specified")
else
if values[:pin] and !values[:pin].blank?
# II
device = Device.find(:first, :include => [:user, :callerids], :conditions => ['callerids.cli = ? OR callerids.cli LIKE ?', params[:callerid], '%' + params[:callerid] + '%'])
if !device or (device and device.user and device.user.owner_id == @current_user.get_correct_owner_id)
if device
#4 * We find device by callerid and card by PIN, device.user.balance+=card.balance, card.disable
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
card_by_pin = Card.find(:first, :include => :cardgroup, :conditions => {:pin => values[:pin], :owner_id => @current_user.get_correct_owner_id})
if card_by_pin
card_by_pin.disable
if card_by_pin.save
if device.user.add_to_balance(card_by_pin.balance)
card_by_pin.add_to_balance(card_by_pin.balance * -1)
doc.response {
doc.status("ok")
doc.device_id(device.id)
doc.user_id(device.user_id)
doc.new_balance(device.user.balance)
}
else
doc.error("Failed to make transaction")
end
else
doc.error {
card_by_pin.errors.each { |key, value|
doc.error(_(value))
} if card_by_pin.respond_to?(:errors)
}
end
else
doc.error("PIN number not found")
end
else
card = Card.find(:first, :conditions => {:callerid => values[:callerid]})
if !card or (card and card.cardgroup.owner_id == @current_user.get_correct_owner_id)
if card
card_by_pin = Card.find(:first, :include => :cardgroup, :conditions => ['cards.pin = ? AND cardgroups.owner_id =? AND cards.id <> ?', values[:pin], @current_user.get_correct_owner_id, card.id])
if card_by_pin
if card.cardgroup_id == card_by_pin.cardgroup_id
#2 * We find card2 by callerid and card1 by PIN, then card2.balance += card1.balance, card1.disable.
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
amount = card_by_pin.balance
logger.fatal card.to_yaml
logger.fatal card_by_pin.to_yaml
card_by_pin.disable
card_by_pin.add_to_balance(card.balance * -1)
if card_by_pin.save
if card.add_to_balance(amount)
respond_to_successful_card_operation(doc, card)
else
doc.error("Failed to make transaction")
end
else
doc.error {
card_by_pin.errors.each { |key, value|
doc.error(_(value))
} if card_by_pin.respond_to?(:errors)
}
end
else
#3 * We find card2 by callerid and card1 by PIN. card1.callerid=card2.callerid, card2.callerid=nil, card1.balance +=card2.balance, card1.sold, card2.disable
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
amount = card.balance
card.disable
card.add_to_balance(card.balance * -1)
card_by_pin.callerid = card.callerid
card.callerid = nil
if card.save
if card_by_pin.add_to_balance(amount)
respond_to_successful_card_operation(doc, card_by_pin)
else
doc.error("Failed to make transaction")
end
else
doc.error {
card.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
end
else
doc.error("PIN number not found")
end
else
logger.fatal "II%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
#1 * We check if callerid_id is free. If it is free then we search cardgroup by card using PIN, then we create card2 in same cardgroup.
# ** There is no need to create a new card2; just mark the card with the entered PIN number as sold, active, and associate the callerID to it.
card_by_pin = Card.find(:first, :include => :cardgroup, :conditions => {:pin => values[:pin], :owner_id => @current_user.get_correct_owner_id})
if card_by_pin
card_by_pin.callerid = values[:callerid]
if ((!card_by_pin.sold? and card_by_pin.sell) or card_by_pin.sold?) and card_by_pin.save
respond_to_successful_card_operation(doc, card_by_pin)
else
doc.error {
card_by_pin.errors.each { |key, value|
doc.error(_(value))
} if card_by_pin.respond_to?(:errors)
}
end
else
doc.error("PIN number not found")
end
end
else
doc.error("You do not have permission to access card")
end
end
else
doc.error("You do not have permission to add to user's balance")
end
else
# I
device = Device.find(:first, :include => [:user, :callerids], :conditions => ['callerids.cli = ? OR callerids.cli LIKE ?', values[:callerid], '%' + values[:callerid] + '%'])
if !device or (device and device.user.owner_id == @current_user.get_correct_owner_id)
if device
#4 * We find device by callerid, device.user.balance+=amount
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
if device.user.add_to_balance(values[:amount].to_f)
doc.response {
doc.status("ok")
doc.device_id(device.id)
doc.user_id(device.user_id)
doc.new_balance(device.user.balance)
}
else
doc.error("Failed to make transaction")
end
else
card = Card.find(:first, :conditions => {:callerid => values[:callerid]})
if !card or (card and card.cardgroup.owner_id == @current_user.get_correct_owner_id)
if card
if values[:cardgroup_id]
cardgroup = Cardgroup.find(:first, :conditions => {:id => values[:cardgroup_id], :owner_id => @current_user.get_correct_owner_id})
else
cardgroup = card.cardgroup
end
if cardgroup
if cardgroup.id != card.cardgroup_id
#3 * We find card1 by callerid and cardgroup2 by cardgroup_id, then we check If card1.cardgroup != cardgroup2, then we create card_n in cardgroup2 , card_n.callerid = Caller_id, card_n.balance = amount + card1.balance, card_n.sold , card1.disable
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
original_balance = card.balance
card.add_to_balance(card.balance * -1)
card.disable
card.callerid = nil
amount = values[:amount].to_f * Currency.count_exchange_rate(cardgroup.tell_balance_in_currency, Currency.get_default).to_f
if card.save
card_n = cardgroup.create_card({:balance => original_balance + amount, :callerid => values[:callerid]})
if card_n.sell and card_n.save
respond_to_successful_card_operation(doc, card_n)
else
doc.error {
card_n.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
else
doc.error {
card.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
else
#2 * We find card1 by callerid and cardgroup by card1, we check if cardgroup is allowed for user then then card1.balance += amount
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
amount = values[:amount].to_f * Currency.count_exchange_rate(card.cardgroup.tell_balance_in_currency, Currency.get_default).to_f
if card.add_to_balance(amount)
respond_to_successful_card_operation(doc, card)
else
doc.error("Failed to make transaction")
end
end
else
doc.error("You do not have permission to access cardgroup")
end
else
#1 * We check if callerid_id is free. If it is free then we search cardgroup by cardgroup_id, then we create card_n in cardgroup, card_n.callerid = Caller_id, card_n.balance = amount, card_n.sold
logger.fatal "I%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
logger.fatal values.to_yaml
cardgroup = Cardgroup.find(:first, :conditions => {:id => values[:cardgroup_id], :owner_id => @current_user.get_correct_owner_id})
if cardgroup
logger.fatal cardgroup.tell_balance_in_currency
amount = values[:amount].to_f * Currency.count_exchange_rate(cardgroup.tell_balance_in_currency, Currency.get_default).to_f
amount = cardgroup.get_tax.count_amount_without_tax(amount)
card_n = cardgroup.create_card({:balance => amount, :callerid => values[:callerid]})
if card_n.sell and card_n.save
respond_to_successful_card_operation(doc, card_n)
else
doc.error {
card_n.errors.each { |key, value|
doc.error(_(value))
} if card.respond_to?(:errors)
}
end
else
doc.error("Supplied Cardgroup_id is invalid")
end
end
else
doc.error("You do not have permission to access card")
end
end
else
doc.error("You do not have permission to add to user's balance")
end
end
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
display info about calling card group
*Params*
+id+ - card group id
+autorization+
*Returns*
+xml_object+ - name, image_link, description, price, price_with_tax, currency, pin_length, number_length, groups salable cards size
=end
def show_calling_card_group
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
cg = Cardgroup.find(:first, :include => [:tariff, :lcr, :location, :tax], :conditions => ["cardgroups.id = ? and cardgroups.owner_id = ? and hidden=0", @values[:id], @current_user.get_correct_owner_id])
if cg
doc.cardgroup {
doc.name(cg.name)
doc.iamge_link("#{Web_Dir}/cards/#{cg.image}")
doc.description(cg.description)
doc.price(nice_number(cg.price))
doc.price_with_tax(nice_number(cg.price + cg.get_tax.count_tax_amount(cg.price)))
doc.currency(Currency.get_default.name)
doc.free_cards_size(cg.free_cards_size)
doc.pin_length(cg.pin_length)
doc.number_length(cg.number_length)
}
else
doc = API.return_error("Cardgroup was not found", doc)
end
}
send_xml_data(out_string, params[:test].to_i)
end
=begin
display info about calling card group
*Params*
+id+ - card group id
+autorization+
+buy_size+ - cards quantity to buy
*Returns*
+xml_object+ - cards : pin, number, balance, currency, balance_with_tax
=end
def buy_card_from_callingroup
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
cg = Cardgroup.find(:first, :include => [:tariff, :lcr, :location, :tax], :conditions => ["cardgroups.id = ? and cardgroups.owner_id = ? and hidden = 0", @values[:id], @current_user.get_correct_owner_id])
cards_size = @values[:quantity].to_i < 1 ? 1 : @values[:quantity].to_i
if cg
cards = cg.cards.find(:all, :conditions => {:sold => 0}, :limit => cards_size, :order => "rand()")
if cards
doc.cards {
for card in cards
if card.sell
if params[:email]
order = Ccorder.new()
order.amount = card.balance
order.currency = Currency.get_default.name
order.ordertype = 'unspecified'
order.date_added = Time.now
order.completed = 1
order.email = params[:email]
order.tax_percent = 0
order.save
line_item = Cclineitem.new()
line_item.cardgroup_id = card.cardgroup_id
line_item.quantity = 1
line_item.ccorder_id = order.id
line_item.price = card.balance
line_item.card_id = card.id
line_item.save
thread = Thread.new(order) { |order|
EmailsController::send_to_users_paypal_email(order)
}
end
Action.add_action_hash(@current_user, {:action => 'card_sell_over_api', :target_id => card.id, :target_type => 'Card'})
doc.card {
doc.pin(card.pin)
doc.number(card.number)
doc.balance_without_vat(card.balance)
doc.currency(Currency.get_default.name)
}
else
doc = API.return_error("Card error", doc)
end
end
}
else
doc = API.return_error("Free cards was not found", doc)
end
else
doc = API.return_error("Cardgroup was not found", doc)
end
}
send_xml_data(out_string, params[:test].to_i)
end
def send_sms
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow == true
check_user(params[:u], params[:p])
if @user
@lcr = Lcr.find_by_id(params[:lcr_id])
if @user.sms_service_active == 1
if @lcr and (@lcr.user_id == @user.owner_id)
if params[:dst]
if params[:src]
if params[:message] # atskirai
@user_tariff = SmsTariff.find_by_id(@user.sms_tariff_id)
@number_of_messages = (URI.unescape(params[:message]).size.to_f / 160).ceil
sms = SmsMessage.new
sms.sending_date = Time.now
sms.user_id = @user.id
sms.reseller_id = @user.owner_id
sms.number = params[:dst]
sms.save
begin
sms.sms_send(@user, @user_tariff, params[:dst], @lcr, @number_of_messages.to_f, URI.unescape(params[:message]))
if sms.status_code.to_s == "0"
doc.response {
doc.status('ok')
doc.message{
doc.message_id(sms.id)
doc.sms_status_code_tip(sms.sms_status_code_tip)
@curr = Currency.find_by_id(@user.currency_id)
if @user.usertype == 'reseller'
doc.price(nice_number sms.reseller_price)
else
doc.price(nice_number sms.user_price)
end
doc.currency(@curr.name)
}
}
else
doc.error(){
doc.message{
doc.message_id(sms.id)
doc.sms_status_code_tip(sms.sms_status_code_tip)
}
}
end
rescue Errno::ECONNRESET => exception
doc.error(){
doc.message{
doc.message_id(sms.id)
doc.error_message(exception.message)
}
}
end
else
doc.error("There is no message or it is empty")
end
else
doc.error("Wrong source")
end
else
doc.error("Wrong destination")
end
else
doc.error("There is no such LCR")
end
else
doc.error("User is not subscribed to sms service")
end
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
def check_sms_addon
unless sms_active?
send_xml_data(API.return_error('Dont be so smart'), params[:test].to_i)
return false
end
end
def get_version
allow, values = API::check_params_with_all_keys(params, request)
doc = Builder::XmlMarkup.new(:target => out_string = "", :indent => 2)
doc.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
doc.page{
if allow
check_user(params[:u], params[:p])
if @user
version = (mor_11_extend? ? '12' : '11')
doc.version(version)
else
doc.error("Bad login")
end
else
doc.error("Incorrect hash")
end
}
send_xml_data(out_string, params[:test].to_i)
end
private
def respond_to_successful_card_operation(doc, card)
doc.response {
doc.status('ok')
doc.card {
doc.id(card.id)
doc.cardgroup_id(card.cardgroup_id)
doc.balance(nice_number(card.balance))
doc.balance_with_vat(nice_number(card.balance_with_vat))
doc.callerid(card.callerid)
doc.pin(card.pin)
doc.number(card.number)
}
}
end
=begin rdoc
Checks if API is allowed.
=end
def check_allow_api
if Confline.get_value("Allow_API").to_i != 1
send_xml_data(API.return_error('API Requests are disabled'), params[:test].to_i)
end
end
=begin rdoc
Checks if GET method is allowed.
*Returns*
Error message if method is GET and it is not allowed
=end
def check_send_method
if request.get? and Confline.get_value("Allow_GET_API").to_i != 1
send_xml_data(API.return_error('GET Requests are disabled'), params[:test].to_i)
end
end
=begin rdoc
Sends XML or HTML data. Checks confline XML_API_Extension to determin whitch should be sent.
=end
def send_xml_data(out_string, test = 0, name = "mor_api_response.xml", zip = false)
if test.to_i == 1
MorLog.my_debug out_string
render :text => out_string and return false
else
if !zip #or out_string.length.to_i < Confline.get_value('Api_response_size').to_i
if confline("XML_API_Extension").to_i == 1
send_data(out_string, :type => "text/xml", :filename => name)
else
send_data(out_string, :type => "text/html", :filename => "mor_api_response.html")
end
else
path = '/tmp'
`rm -rf #{path}/#{name}`
ff = File.open('/tmp/'+name, "wb")
ff.write(out_string)
ff.close
`rm -rf #{path}/#{name}.zip`
`cd #{path}; zip #{name}.zip #{name}`
`rm -rf #{path}/#{name}`
fsrc = "#{path}/#{name}.zip"
send_file(fsrc, :type => "application/zip")
end
end
end
=begin
Obsolete method. Used in former authentication.
=end
def check_user(login='', password='')
@user = User.find(:first, :conditions => ["username = ? and password = ?", login.to_s, Digest::SHA1.hexdigest(password.to_s)])
if @user
User.current = @user
end
return @user
end
=begin
Log method. Used for all API requests.
=end
def log_access
MorLog.my_debug(" ********************** API ACCESS : #{params[:action]} **********************", 1)
MorLog.my_debug request.request_uri.to_s
MorLog.my_debug request.remote_addr.to_s
MorLog.my_debug request.remote_ip
end
def last_calls_stats_set_variables(options, values)
options.merge(values.reject { |key, value| value.nil? })
end
def last_calls_stats_parse_params
default = {
:s_direction => "outgoing",
:s_call_type => "all",
:s_device => "all",
:s_provider => "all",
:s_hgc => 0,
:s_user => "all",
:user => nil,
:s_did => "all",
:s_destination => "",
:order_by => "time",
:order_desc => 0,
:s_country => '',
:only_did => 0
}
options = default
default.each { |key, value| options[key] = params[key] if params[key] }
options[:order_by_full] = options[:order_by] + (options[:order_desc] == 1 ? " DESC" : " ASC")
options[:order] = Call.calls_order_by(params, options)
options[:direction] = options[:s_direction]
options[:call_type] = options[:s_call_type]
options[:destination] = (options[:s_destination].to_s.strip.match(/\A[0-9%]+\Z/) ? options[:s_destination].to_s.strip : "")
options[:column_dem] = "."
options
end
def find_current_user_for_api
@current_user = check_user(params[:u], params[:p])
unless @current_user
send_xml_data(API.return_error('Bad login'), params[:test].to_i)
return false
end
end
def check_mor_11_extend
unless mor_11_extend?
send_xml_data(API.return_error('Dont be so smart'), params[:test].to_i)
return false
end
end
def check_api_parrams_with_hash
allow, @values = API::check_params_with_all_keys(params, request)
if allow != true
send_xml_data(API.return_error('Incorrect hash'), params[:test].to_i)
return false
end
end
def check_calling_card_addon
if !calling_cards_active? or @current_user.is_user? or (@current_user.is_accountant? and !@current_user.accountant_allow_read('callingcard_manage')) or (@current_user.is_reseller? and !@current_user.reseller_allow_read('calling_cards'))
send_xml_data(API.return_error('Dont be so smart'), params[:test].to_i)
return false
end
end
end