Skip to content

Commit

Permalink
much faster branch graphs for the dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
svs committed Jun 1, 2009
1 parent 445c8db commit e188168
Show file tree
Hide file tree
Showing 22 changed files with 712 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -20,3 +20,4 @@ gems/gems/*
gems/specifications/*
merb_profile_results
misfit_fixtures/*
config/database.yml
73 changes: 71 additions & 2 deletions app/controllers/graph_data.rb
Expand Up @@ -72,7 +72,7 @@ def branch(id)
start_date = @branch.centers.clients.loans.min(:scheduled_disbursal_date)
end_date = Date.today # (@client.loans.map { |l| l.last_loan_history_date }).max
loan_ids = @branch.centers.clients.loans.all(:fields => [:id]).map { |x| x.id }
common_aggregate_loan_graph(loan_ids, start_date, end_date)
weekly_aggregate_loan_graph(loan_ids, start_date, end_date)
end

def total
Expand Down Expand Up @@ -125,6 +125,7 @@ def aggregate_loan_graph(loan_ids, start_date, end_date)
end

def common_aggregate_loan_graph(loan_ids, start_date, end_date) # __DEPRECATED__
debugger
days = (end_date - start_date).to_i
step_size = 1; i = 0 # make a nice round step size, not more than 20 steps
while days/step_size > 50
Expand All @@ -135,8 +136,8 @@ def common_aggregate_loan_graph(loan_ids, start_date, end_date) # __DEPRECATED__
steps.times { |i| dates << start_date + step_size * i }

@labels, @stacks, max_amount = [], [], 0
p dates
dates.each_with_index do |date, index|
t0 =Time.now
future = date > Date.today
s = LoanHistory.sum_outstanding_for(date, loan_ids)[0]
scheduled_outstanding = (s['scheduled_outstanding_total'].to_i or 0) # or *_principal
Expand All @@ -155,12 +156,80 @@ def common_aggregate_loan_graph(loan_ids, start_date, end_date) # __DEPRECATED__
{ :val => [-overpaid, 0].max, :colour => (future ? '#ff5588' : '#aa0000'),
:tip => "#{tip_base} shortfall of #{-overpaid} (#{percentage})" } ]
@labels << ((index % step_size == 0) ? date.strftime("%b%d'%y") : '')
puts "Did t#{index} in total #{Time.now - t0} secs"
end
render_loan_graph('aggregate loan graph', @stacks, @labels, step_size, max_amount)
end

def weekly_aggregate_loan_graph(loan_ids, start_date, end_date)
t0 =Time.now
step_size = 12
structs = repository.adapter.query(%Q{
SELECT da_te as date, weeknum,
SUM(scheduled_outstanding_principal) AS scheduled_outstanding_principal,
SUM(scheduled_outstanding_total) AS scheduled_outstanding_total,
SUM(actual_outstanding_principal) AS actual_outstanding_principal,
SUM(actual_outstanding_total) AS actual_outstanding_total
FROM (SELECT da_te, weeknum,
scheduled_outstanding_principal,
scheduled_outstanding_total,
actual_outstanding_principal,
actual_outstanding_total
FROM (SELECT loan_id,
max(date) as da_te,
concat(year(date),'_',week(date)) AS weeknum
FROM loan_history
WHERE loan_id IN (#{loan_ids.join(",")})
GROUP BY loan_id, weeknum) AS dt,
loan_history lh
WHERE lh.loan_id = dt.loan_id
AND lh.date = dt.da_te) AS dt1 GROUP BY weeknum ORDER BY date;})

puts "Finished query in #{Time.now - t0}"
@labels, @stacks, max_amount = [], [], 0
@t = nil
structs.each_with_index do |s, index|
# there is a problem with the week that spans two years as it gets spilt into 2008_52 and 2009_0 or similar
puts index
if @t
s['scheduled_outstanding_total'] += @t['scheduled_outstanding_total']
s['actual_outstanding_total'] += @t['actual_outstanding_total']
@t = nil
end
if index < structs.size - 1 and structs[index + 1]['weeknum'].index("_0")
@t = s
next
end
date = s['date']
future = date > Date.today
# s = LoanHistory.sum_outstanding_for(date, loan_ids)[0]
scheduled_outstanding = (s['scheduled_outstanding_total'].to_i or 0) # or *_principal
actual_outstanding = future ? scheduled_outstanding : (s['actual_outstanding_total'].to_i or 0) # or *_principal
max_amount = [max_amount, scheduled_outstanding, actual_outstanding].max
overpaid = scheduled_outstanding - actual_outstanding # negative means shortfall
tip_base = "##{index+1}, #{date.strftime("%a %b %d %Y")}#{(future ? ' (future)' : '')}<br>"
percentage = scheduled_outstanding == 0 ? '0' : (overpaid.abs.to_f/scheduled_outstanding*100).round.to_s + '%'
@stacks << [
{ :val => [scheduled_outstanding, actual_outstanding].min, :colour => (future ? '#55aaff' : '#003d4a'),
:tip => tip_base + (future ?
"#{scheduled_outstanding.round} scheduled outstanding" :
"#{actual_outstanding.round} outstanding (#{percentage} #{overpaid > 0 ? 'overpaid' : 'shortfall'})") },
{ :val => [overpaid, 0].max, :colour => (future ? '#55ff55' : '#00aa00'),
:tip => "#{tip_base} overpaid #{ overpaid} (#{percentage})" },
{ :val => [-overpaid, 0].max, :colour => (future ? '#ff5588' : '#aa0000'),
:tip => "#{tip_base} shortfall of #{-overpaid} (#{percentage})" } ]
@labels << ((index % step_size == 0) ? date.strftime("%b%d'%y") : '')
puts "Did t#{index} in total #{Time.now - t0} secs"
end
render_loan_graph('aggregate loan graph', @stacks, @labels, step_size, max_amount)
end







def render_loan_graph(description, stacks, labels, step_size, max_amount)
<<-JSON
{ "elements": [ {
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/search.rb
@@ -0,0 +1,12 @@
class Search < Application

def index
debugger
model = Kernel.const_get(params[:model])
parameter = params[:by].snake_case.to_sym
@object = model.all( parameter => params[:value])[0]
raise NotFound unless @object
redirect "/#{model.to_s.snake_case.pluralize}/#{@object.id}"
end

end
5 changes: 5 additions & 0 deletions app/helpers/search_helper.rb
@@ -0,0 +1,5 @@
module Merb
module SearchHelper

end
end # Merb
36 changes: 36 additions & 0 deletions app/models/#client.rb#
@@ -0,0 +1,36 @@
93235-55017 sandeep
class Client
include DataMapper::Resource
include Paperclip::Resource
before :valid?, :parse_dates

property :id, Serial
property :reference, String, :length => 100, :nullable => false
property :name, String, :length => 100, :nullable => false
property :spouse_name, String, :length => 100
property :date_of_birth, Date
property :address, Text
property :active, Boolean, :default => true, :nullable => false
property :date_joined, Date

has_attached_file :picture,
:styles => {:medium => "300x300>", :thumb => "60x60#"},
:url => "/uploads/:class/:id/:attachment/:style/:basename.:extension",
:path => "#{Merb.root}/public/uploads/:class/:id/:attachment/:style/:basename.:extension"

has_attached_file :application_form,
:styles => {:medium => "300x300>", :thumb => "60x60#"},
:url => "/uploads/:class/:id/:attachment/:style/:basename.:extension",
:path => "#{Merb.root}/public/uploads/:class/:id/:attachment/:style/:basename.:extension"

has n, :loans
belongs_to :center

validates_length :name, :min => 3
validates_present :center
validates_is_unique :reference


private
include DateParser # mixin for the hook "before :valid?, :parse_dates"
end
4 changes: 0 additions & 4 deletions app/views/branches/index.html.haml
Expand Up @@ -2,10 +2,6 @@
/ .graph
/ = ofc2(430, 200, 'http://' + (request.env['HTTP_HOST'] or 'example.org') + url(:graph_data, :action => 'total', :scope_unit => 'months', :scope_size => 3) )
%form#loan_search{:action => "javascript:document.location='/loans/' + document.forms[0].loan_id.value;"}
Search for loan by id:
%input{:name => "loan_id"}
%input{:type => "submit"}
%h1 Overview of all branches

Expand Down
20 changes: 19 additions & 1 deletion app/views/layout/application.html.haml
Expand Up @@ -37,8 +37,26 @@
&nbsp;|&nbsp;
%b= link_to 'staff members', url(:staff_members)
&nbsp;|&nbsp;
%b= link_to 'search', '#', :onclick => "javascript:document.getElementById('search_div').style.display='block';"
&nbsp;|&nbsp;
%b= link_to 'data entry', url(:data_entry)

#search_div{:style => 'margin: 2px; background:lightyellow;padding: 4px;'}
%form{:action => '/search'}
Search for
%select{:name => 'model'}
- ['Branch','Client','Center','Loan'].each do |model|
%option{:value => model}
= model
with
%select{:name => 'by'}
- ['Id','Name','Reference'].each do |by|
%option{:value => by}
= by
%input{:name => 'value'}
%a{:href => '#', :onclick => "document.getElementById('search_div').style.display='none';"}
Hide search
%br
%input{:type => 'submit', :value=>'search'}
#content
#breadcrums= breadcrums

Expand Down
2 changes: 2 additions & 0 deletions app/views/payments/create.xml.haml
@@ -0,0 +1,2 @@
%status
= @payment.status
15 changes: 15 additions & 0 deletions app/views/reports/#index.html.haml#
@@ -0,0 +1,15 @@
%h1
Reports

%table#mytable{:width => "100%"}
%tr
- @reports.each do |report|
%tr
%td
= report.name
%td
= link_to 'Show', url(:report, report)
%td
= link_to 'Edit', url(:edit_report, report)

= link_to 'New', url(:new_report)
104 changes: 104 additions & 0 deletions app/views/reports/_default_report.html.haml.bak
@@ -0,0 +1,104 @@
%h2
= @report.name

- @branch_loans = {}
- Branch.all.each do |branch|
- @branch_loans[branch.id] = Loan.all('client.center.branch_id' => branch.id)

%table
%tr
%th
Parameter
%th
All Branches
- Branch.all.each do |branch|
%th
= branch.name
%tr
%th
No. of CM
%td
= Center.all.manager.uniq.count
- Branch.all.each do |branch|
%td
= Center.all(:branch_id => branch.id).manager.uniq.count
%tr
%th
No. of Centers
%td
= Center.all.count
- Branch.all.each do |branch|
%td
= Center.all(:branch_id => branch.id).count
%tr
%th
No. of Clients
%td
= Client.all.count
- Branch.all.each do |branch|
%td
= Client.all('center.branch_id' => branch.id).count
%tr
%th
No. of Clients
%td
= Client.all.count
- Branch.all.each do |branch|
%td
= Client.all('center.branch_id' => branch.id).count
%tr
%th
No. of Borowers
%td
= repository(:default).adapter.query("SELECT COUNT(DISTINCT(client_id)) FROM loans")[0]
- Branch.all.each do |branch|
%td
= repository.adapter.query("SELECT COUNT(DISTINCT(client_id)) FROM loans,clients,centers,branches WHERE loans.client_id = clients.id AND clients.center_id = centers.id AND centers.branch_id = branches.id AND branches.id = #{branch.id}")[0]
%tr
%th
Loans for next week (number)
%td
= Loan.all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => Date.today + 7).count
- Branch.all.each do |branch|
%td
= @branch_loans[branch.id].all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => (Date.today + 7)).count
%tr
%th
Loans for next week (amount)
%td
= Loan.all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => Date.today + 7).sum(:amount) || 0
- Branch.all.each do |branch|
%td
= @branch_loans[branch.id].all(:scheduled_disbursal_date.gt => Date.today, :scheduled_disbursal_date.lt => (Date.today + 7)).sum(:amount) || 0
%tr
%th
Waiting Clients (number)
%td
= Loan.all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil).count
- Branch.all.each do |branch|
%td
= @branch_loans[branch.id].all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil, 'client.center.branch_id' => branch.id).count
%tr
%th
Waiting Clients (amount)
%td
= Loan.all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil).sum(:amount)
- Branch.all.each do |branch|
%td
= @branch_loans[branch.id].all(:scheduled_disbursal_date.not => nil, :disbursal_date => nil, 'client.center.branch_id' => branch.id).sum(:amount)
%tr
%th
Defaulted Loans (Count)
%td
= LoanHistory.all(:current => true, :amount_in_default.not => 0).count
- Branch.all.each do |branch|
%td
= LoanHistory.all(:current => true, :amount_in_default.not => 0, 'loan.client.center.branch_id' => branch.id).count
%tr
%th
Defaulted Loans (Amount)
%td
= LoanHistory.all(:current => true, :amount_in_default.not => 0).sum(:amount_in_default)
- Branch.all.each do |branch|
%td
= LoanHistory.all(:current => true, :amount_in_default.not => 0, 'loan.client.center.branch_id' => branch.id).sum(:amount_in_default)
1 change: 1 addition & 0 deletions app/views/search/index.html.haml
@@ -0,0 +1 @@
You're in index of the Search controller.

0 comments on commit e188168

Please sign in to comment.