An open source, stand-alone, customisable public spending data web app.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

14 年之前
9 年之前
14 年之前
9 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
14 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. require 'sinatra'
  2. # require 'sinatra-helpers/haml/partials'
  3. require 'haml'
  4. require 'data_mapper'
  5. require './models'
  6. SETTING = Setting.first # Could also do this with Sinatra filters before/do
  7. PAYMENTS_FILTER_MIN = 1000
  8. helpers do
  9. def commify(amount)
  10. amount.to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse
  11. end
  12. def yesno(boolean)
  13. boolean == true ? 'Yes' : 'No'
  14. end
  15. def nicedate(d)
  16. d.strftime("%d %b %Y")
  17. end
  18. end
  19. get '/' do
  20. @directorates = Directorate.all( :order => ['name'] )
  21. @payments_count = Payment.count
  22. @suppliers_count = Supplier.count
  23. @services_count = Service.count
  24. haml :home
  25. end
  26. get '/directorates/:slug' do
  27. @directorate = Directorate.first(:slug => params[:slug])
  28. haml :directorate
  29. end
  30. get '/suppliers/:slug.csv' do
  31. @supplier = Supplier.first(:slug => params[:slug])
  32. headers "Content-Disposition" => "attachment;filename=supplier-#{@supplier.slug}.csv",
  33. "Content-Type" => "application/octet-stream"
  34. result = "Date,Ref.,URL,Directorate,Service,Amount ex. VAT\n"
  35. for payment in @supplier.payments
  36. result += "#{payment.d.strftime("%d %b %Y")},#{payment.id},#{payment.url},\"#{payment.service.directorate.name}\",#{payment.service.name},#{sprintf("%0.2f", payment.amount)}\n"
  37. end
  38. result
  39. end
  40. get '/suppliers/:slug' do
  41. @supplier = Supplier.first(:slug => params[:slug])
  42. @total = @supplier.payments.sum(:amount)
  43. @count = @supplier.payments.size # Payment.count(:supplier_id => @supplier.id) ?
  44. @avg = @supplier.payments.avg(:amount)
  45. @max = @supplier.payments.max(:amount)
  46. @min = @supplier.payments.min(:amount)
  47. @d_start = @supplier.payments.min(:d)
  48. @d_end = @supplier.payments.max(:d)
  49. haml :supplier
  50. end
  51. get '/suppliers/?' do
  52. @suppliers = Supplier.all( :order => ['name'] )
  53. haml :suppliers
  54. end
  55. get '/services/:slug/payments.csv' do
  56. @service = Service.first(:slug => params[:slug])
  57. headers "Content-Disposition" => "attachment;filename=service-#{@service.slug}.csv",
  58. "Content-Type" => "application/octet-stream"
  59. result = "Date,Ref.,URL,Directorate,Supplier,Amount ex. VAT\n"
  60. for payment in @service.payments
  61. result += "#{payment.d.strftime("%d %b %Y")},#{payment.id},#{payment.url},\"#{payment.service.directorate.name}\",#{payment.supplier.name},#{sprintf("%0.2f", payment.amount)}\n"
  62. end
  63. result
  64. end
  65. # get '/services/:slug.json' do
  66. # @service = Service.first(:slug => params[:slug])
  67. # headers "Content-Type" => "application/json"
  68. # @service.to_json(:relationships => { :payments => { :include => :all }, :directorate => { :include => :all } })
  69. # end
  70. get '/services/:slug' do
  71. @service = Service.first(:slug => params[:slug])
  72. @total = @service.payments.sum(:amount)
  73. @count = @service.payments.size
  74. @avg = @service.payments.avg(:amount)
  75. @max = @service.payments.max(:amount)
  76. @min = @service.payments.min(:amount)
  77. @d_start = @service.payments.min(:d)
  78. @d_end = @service.payments.max(:d)
  79. @results = repository(:default).adapter.query("
  80. SELECT s.name AS supplier_name, s.slug AS supplier_slug, SUM(p.amount) AS total
  81. FROM payments p, suppliers s
  82. WHERE p.supplier_id = s.id
  83. AND p.service_id = #{@service.id}
  84. GROUP BY s.name, s.slug
  85. ORDER BY total DESC")
  86. haml :service
  87. end
  88. get '/services/:slug/payments' do
  89. @FILTER_VALUES = %w[ 500 1000 2500 5000 10000 20000 ]
  90. @service = Service.first(:slug => params[:slug])
  91. # payments_filter_min cookie persists user selection of filter value
  92. unless @min = request.cookies["payments_filter_min"]
  93. @min = PAYMENTS_FILTER_MIN
  94. response.set_cookie(
  95. "payments_filter_min",
  96. { :value => @min, :expires => Time.now + (60 * 24 * 60 * 60) }
  97. ) # 60 days
  98. end
  99. @payments = Payment.all(:service_id => @service.id, :amount.gte => @min, :order => [ 'd' ])
  100. @total = @payments.sum(:amount)
  101. haml :servicepayments
  102. end
  103. get '/services/:slug/paymentsdetail' do
  104. @service = Service.first(:slug => params[:slug])
  105. min = PAYMENTS_FILTER_MIN
  106. if params[:min].to_i > 0
  107. min = params[:min].to_i
  108. end
  109. @payments = Payment.all(:service_id => @service.id, :amount.gte => min, :order => [ 'd' ])
  110. @total = @payments.sum(:amount)
  111. haml :servicepaymentsdetail, :layout => false
  112. end
  113. get '/services/?' do
  114. @services = Service.all( :order => ['name'] )
  115. haml :services
  116. end
  117. get '/payments/:id' do
  118. @payment = Payment.get(params[:id])
  119. haml :payment
  120. end
  121. get '/error' do
  122. haml :error
  123. end
  124. get '/about' do
  125. haml :about
  126. end
  127. get '/scoreboard.csv' do
  128. redirect '/scoreboard'
  129. end
  130. get '/scoreboard' do
  131. haml :scoreboard
  132. end
  133. not_found do
  134. haml :not_found
  135. end