| @@ -0,0 +1,3 @@ | |||||
| data/ | |||||
| *sqlite3 | |||||
| @@ -0,0 +1,111 @@ | |||||
| require 'rubygems' | |||||
| require 'sinatra' | |||||
| require 'sinatra-helpers/haml/partials' | |||||
| require 'haml' | |||||
| require 'lib/models' | |||||
| get '/' do | |||||
| @directorates = Directorate.all | |||||
| # @results = repository(:default).adapter.query(" | |||||
| # SELECT p.name, | |||||
| # sum(c.votes_2010) AS votes, | |||||
| # p.colour | |||||
| # | |||||
| # FROM parties p, | |||||
| # councilcandidates c | |||||
| # | |||||
| # WHERE p.id = c.party_id | |||||
| # | |||||
| # GROUP BY p.name, p.colour | |||||
| # | |||||
| # ORDER BY votes desc | |||||
| # ;") | |||||
| # select p.name, count(c.*) AS seats | |||||
| # FROM parties p, councilcandidates c | |||||
| # GROUP BY p.id | |||||
| haml :home | |||||
| end | |||||
| get '/directorates/:id' do | |||||
| @directorate = Directorate.get(params[:id]) | |||||
| haml :directorate | |||||
| end | |||||
| get '/suppliers/:id.csv' do | |||||
| @supplier = Supplier.get(params[:id]) | |||||
| headers "Content-Disposition" => "attachment;filename=supplier#{@supplier.id}.csv", | |||||
| "Content-Type" => "application/octet-stream" | |||||
| result = "Date,Trans No,Directorate,Service,Amount ex. VAT\n" | |||||
| for payment in @supplier.payments | |||||
| result += "#{payment.d.strftime("%d %b %Y")},#{payment.trans_no},\"#{payment.directorate.name}\",#{payment.service.name},#{sprintf("%0.2f", payment.amount)}\n" | |||||
| end | |||||
| result | |||||
| end | |||||
| get '/suppliers/:id' do | |||||
| @supplier = Supplier.get(params[:id]) | |||||
| haml :supplier | |||||
| end | |||||
| get '/suppliers/?' do | |||||
| @suppliers = Supplier.all( :order => ['name'] ) | |||||
| haml :suppliers | |||||
| end | |||||
| get '/services/:id.csv' do | |||||
| @service = Service.get(params[:id]) | |||||
| headers "Content-Disposition" => "attachment;filename=service#{@service.id}.csv", | |||||
| "Content-Type" => "application/octet-stream" | |||||
| result = "Date,Trans No,Directorate,Supplier,Amount ex. VAT\n" | |||||
| for payment in @service.payments | |||||
| result += "#{payment.d.strftime("%d %b %Y")},#{payment.trans_no},\"#{payment.directorate.name}\",#{payment.supplier.name},#{sprintf("%0.2f", payment.amount)}\n" | |||||
| end | |||||
| result | |||||
| end | |||||
| get '/services/:id' do | |||||
| @service = Service.get(params[:id]) | |||||
| haml :service | |||||
| end | |||||
| get '/services/?' do | |||||
| @services = Service.all( :order => ['name'] ) | |||||
| haml :services | |||||
| end | |||||
| get '/wards/:slug/postcode/:postcode/?' do | |||||
| @ward = Ward.first(:slug => params[:slug]) | |||||
| @postcode = params[:postcode] | |||||
| haml :wards | |||||
| end | |||||
| get '/wards/:slug/?' do | |||||
| @ward = Ward.first(:slug => params[:slug]) | |||||
| haml :wards | |||||
| end | |||||
| get '/error' do | |||||
| haml :error | |||||
| end | |||||
| get '/about' do | |||||
| haml :about | |||||
| end | |||||
| not_found do | |||||
| haml :not_found | |||||
| end | |||||
| @@ -0,0 +1,45 @@ | |||||
| require 'lib/models' | |||||
| require 'csv' | |||||
| count = 0 | |||||
| CSV::Reader.parse(File.open('data/2009Q4.csv', 'rb')) do |row| | |||||
| # 2009Q4 Columns: | |||||
| # 0: Directorate | |||||
| # 1: Updated | |||||
| # 2: TransNo | |||||
| # 3: Service | |||||
| # 4: Cost Centre | |||||
| # 5: Supplier Name | |||||
| # 6: Amount excl vat | |||||
| # 7: Type | |||||
| count += 1 | |||||
| if (count > 4) # skip first four lines that don't contain data | |||||
| p row | |||||
| directorate = Directorate.first_or_create(:name => row[0].strip) | |||||
| service = Service.first_or_create(:name => row[3].strip) | |||||
| supplier = Supplier.first_or_create(:name => row[5].strip) | |||||
| payment = Payment.first_or_create( | |||||
| 'trans_no' => row[2], | |||||
| 'directorate' => directorate, | |||||
| 'service' => service, | |||||
| 'supplier' => supplier, | |||||
| 'cost_centre' => row[4].strip, | |||||
| 'amount' => row[6].strip.gsub(/,/, ''), | |||||
| 'd' => row[1], | |||||
| 'tyype' => row[7].strip | |||||
| ) | |||||
| unless payment.save | |||||
| puts "ERROR: Failed to save payment" | |||||
| payment.errors.each do |e| | |||||
| puts e | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,39 @@ | |||||
| require 'lib/models' | |||||
| require 'csv' | |||||
| count = 0 | |||||
| # 2010Q1: 0-Directorate,1-Updated,2-Service,3-Supplier Name,4-Amount excl vat £,5-Type | |||||
| CSV::Reader.parse(File.open('data/2010Q1.csv', 'rb')) do |row| | |||||
| count += 1 | |||||
| if (count > 4) # skip first four lines that don't contain data | |||||
| p row | |||||
| directorate = Directorate.first_or_create(:name => row[0].strip) | |||||
| service = Service.first_or_create(:name => row[2].strip) | |||||
| supplier = Supplier.first_or_create(:name => row[3].strip) | |||||
| dt = row[1].strip.split('/') | |||||
| payment = Payment.first_or_create( | |||||
| 'directorate' => directorate, | |||||
| 'service' => service, | |||||
| 'supplier' => supplier, | |||||
| 'amount' => row[4].strip.gsub(/,/, ''), | |||||
| 'd' => Date.new(dt[2].to_i, dt[1].to_i, dt[0].to_i), | |||||
| 'tyype' => row[5].strip | |||||
| ) | |||||
| unless payment.save | |||||
| puts "ERROR: Failed to save payment" | |||||
| payment.errors.each do |e| | |||||
| puts e | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,58 @@ | |||||
| require 'rubygems' | |||||
| require 'dm-core' | |||||
| require 'dm-validations' | |||||
| require 'dm-timestamps' | |||||
| require 'dm-aggregates' | |||||
| class Payment | |||||
| include DataMapper::Resource | |||||
| property :id, Serial | |||||
| property :trans_no, Integer, :required => false # "TransNo" in RBWM CSV files | |||||
| property :directorate_id, Integer, :required => true | |||||
| property :service_id, Integer, :required => true | |||||
| property :supplier_id, Integer, :required => true | |||||
| property :cost_centre, String, :required => false | |||||
| property :amount, BigDecimal, :precision => 10, :scale => 2, :required => true # ex VAT | |||||
| property :d, Date, :required => true # "Updated" in RBWM CSV files | |||||
| property :tyype, String, :required => true # Capital or Revenue | |||||
| belongs_to :directorate | |||||
| belongs_to :service | |||||
| belongs_to :supplier | |||||
| end | |||||
| class Directorate | |||||
| include DataMapper::Resource | |||||
| property :id, Serial | |||||
| property :name, String, :length => 255, :required => true | |||||
| has n, :payments, :order => ['d'] | |||||
| end | |||||
| class Service | |||||
| include DataMapper::Resource | |||||
| property :id, Serial | |||||
| property :name, String, :length => 255, :required => true | |||||
| has n, :payments, :order => ['d'] | |||||
| end | |||||
| class Supplier | |||||
| include DataMapper::Resource | |||||
| property :id, Serial | |||||
| property :name, String, :length => 255, :required => true | |||||
| has n, :payments, :order => ['d'] | |||||
| # def self.slugify(name) | |||||
| # name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| # end | |||||
| end | |||||
| DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db.sqlite3") | |||||
| DataMapper.auto_upgrade! | |||||
| @@ -0,0 +1,42 @@ | |||||
| #breadcrumb { | |||||
| font: 11px Arial, Helvetica, sans-serif; | |||||
| background-image:url('/breadcrumb/bc_bg.gif'); | |||||
| background-repeat:repeat-x; | |||||
| height:30px; | |||||
| line-height:30px; | |||||
| color:#888; | |||||
| border:solid 1px #cacaca; | |||||
| width:100%; | |||||
| overflow:hidden; | |||||
| margin:0px; | |||||
| padding:0px; | |||||
| } | |||||
| #breadcrumb li { | |||||
| list-style-type:none; | |||||
| padding-left:10px; | |||||
| display:inline-block; | |||||
| float:left; | |||||
| } | |||||
| #breadcrumb a { | |||||
| display:inline-block; | |||||
| background-image:url('/breadcrumb/bc_separator.gif'); | |||||
| background-repeat:no-repeat; | |||||
| background-position:right; | |||||
| padding-right: 15px; | |||||
| text-decoration: none; | |||||
| color:#333333; | |||||
| outline:none; | |||||
| } | |||||
| .home { | |||||
| border:none; | |||||
| margin: 7px 0px; | |||||
| background-image:url('/breadcrumb/bc_separator.gif'); | |||||
| } | |||||
| #breadcrumb a:hover { | |||||
| color:#35acc5; | |||||
| } | |||||
| @@ -0,0 +1,338 @@ | |||||
| /* | |||||
| Variable Grid System. | |||||
| Learn more ~ http://www.spry-soft.com/grids/ | |||||
| Based on 960 Grid System - http://960.gs/ | |||||
| Licensed under GPL and MIT. | |||||
| */ | |||||
| /* Containers | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .container_12 { | |||||
| margin-left: auto; | |||||
| margin-right: auto; | |||||
| width: 960px; | |||||
| } | |||||
| /* Grid >> Global | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .grid_1, | |||||
| .grid_2, | |||||
| .grid_3, | |||||
| .grid_4, | |||||
| .grid_5, | |||||
| .grid_6, | |||||
| .grid_7, | |||||
| .grid_8, | |||||
| .grid_9, | |||||
| .grid_10, | |||||
| .grid_11, | |||||
| .grid_12 { | |||||
| display:inline; | |||||
| float: left; | |||||
| position: relative; | |||||
| margin-left: 15px; | |||||
| margin-right: 15px; | |||||
| } | |||||
| /* Grid >> Children (Alpha ~ First, Omega ~ Last) | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .alpha { | |||||
| margin-left: 0; | |||||
| } | |||||
| .omega { | |||||
| margin-right: 0; | |||||
| } | |||||
| /* Grid >> 12 Columns | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .container_12 .grid_1 { | |||||
| width:50px; | |||||
| } | |||||
| .container_12 .grid_2 { | |||||
| width:130px; | |||||
| } | |||||
| .container_12 .grid_3 { | |||||
| width:210px; | |||||
| } | |||||
| .container_12 .grid_4 { | |||||
| width:290px; | |||||
| } | |||||
| .container_12 .grid_5 { | |||||
| width:370px; | |||||
| } | |||||
| .container_12 .grid_6 { | |||||
| width:450px; | |||||
| } | |||||
| .container_12 .grid_7 { | |||||
| width:530px; | |||||
| } | |||||
| .container_12 .grid_8 { | |||||
| width:610px; | |||||
| } | |||||
| .container_12 .grid_9 { | |||||
| width:690px; | |||||
| } | |||||
| .container_12 .grid_10 { | |||||
| width:770px; | |||||
| } | |||||
| .container_12 .grid_11 { | |||||
| width:850px; | |||||
| } | |||||
| .container_12 .grid_12 { | |||||
| width:930px; | |||||
| } | |||||
| /* Prefix Extra Space >> 12 Columns | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .container_12 .prefix_1 { | |||||
| padding-left:80px; | |||||
| } | |||||
| .container_12 .prefix_2 { | |||||
| padding-left:160px; | |||||
| } | |||||
| .container_12 .prefix_3 { | |||||
| padding-left:240px; | |||||
| } | |||||
| .container_12 .prefix_4 { | |||||
| padding-left:320px; | |||||
| } | |||||
| .container_12 .prefix_5 { | |||||
| padding-left:400px; | |||||
| } | |||||
| .container_12 .prefix_6 { | |||||
| padding-left:480px; | |||||
| } | |||||
| .container_12 .prefix_7 { | |||||
| padding-left:560px; | |||||
| } | |||||
| .container_12 .prefix_8 { | |||||
| padding-left:640px; | |||||
| } | |||||
| .container_12 .prefix_9 { | |||||
| padding-left:720px; | |||||
| } | |||||
| .container_12 .prefix_10 { | |||||
| padding-left:800px; | |||||
| } | |||||
| .container_12 .prefix_11 { | |||||
| padding-left:880px; | |||||
| } | |||||
| /* Suffix Extra Space >> 12 Columns | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .container_12 .suffix_1 { | |||||
| padding-right:80px; | |||||
| } | |||||
| .container_12 .suffix_2 { | |||||
| padding-right:160px; | |||||
| } | |||||
| .container_12 .suffix_3 { | |||||
| padding-right:240px; | |||||
| } | |||||
| .container_12 .suffix_4 { | |||||
| padding-right:320px; | |||||
| } | |||||
| .container_12 .suffix_5 { | |||||
| padding-right:400px; | |||||
| } | |||||
| .container_12 .suffix_6 { | |||||
| padding-right:480px; | |||||
| } | |||||
| .container_12 .suffix_7 { | |||||
| padding-right:560px; | |||||
| } | |||||
| .container_12 .suffix_8 { | |||||
| padding-right:640px; | |||||
| } | |||||
| .container_12 .suffix_9 { | |||||
| padding-right:720px; | |||||
| } | |||||
| .container_12 .suffix_10 { | |||||
| padding-right:800px; | |||||
| } | |||||
| .container_12 .suffix_11 { | |||||
| padding-right:880px; | |||||
| } | |||||
| /* Push Space >> 12 Columns | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .container_12 .push_1 { | |||||
| left:80px; | |||||
| } | |||||
| .container_12 .push_2 { | |||||
| left:160px; | |||||
| } | |||||
| .container_12 .push_3 { | |||||
| left:240px; | |||||
| } | |||||
| .container_12 .push_4 { | |||||
| left:320px; | |||||
| } | |||||
| .container_12 .push_5 { | |||||
| left:400px; | |||||
| } | |||||
| .container_12 .push_6 { | |||||
| left:480px; | |||||
| } | |||||
| .container_12 .push_7 { | |||||
| left:560px; | |||||
| } | |||||
| .container_12 .push_8 { | |||||
| left:640px; | |||||
| } | |||||
| .container_12 .push_9 { | |||||
| left:720px; | |||||
| } | |||||
| .container_12 .push_10 { | |||||
| left:800px; | |||||
| } | |||||
| .container_12 .push_11 { | |||||
| left:880px; | |||||
| } | |||||
| /* Pull Space >> 12 Columns | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| .container_12 .pull_1 { | |||||
| left:-80px; | |||||
| } | |||||
| .container_12 .pull_2 { | |||||
| left:-160px; | |||||
| } | |||||
| .container_12 .pull_3 { | |||||
| left:-240px; | |||||
| } | |||||
| .container_12 .pull_4 { | |||||
| left:-320px; | |||||
| } | |||||
| .container_12 .pull_5 { | |||||
| left:-400px; | |||||
| } | |||||
| .container_12 .pull_6 { | |||||
| left:-480px; | |||||
| } | |||||
| .container_12 .pull_7 { | |||||
| left:-560px; | |||||
| } | |||||
| .container_12 .pull_8 { | |||||
| left:-640px; | |||||
| } | |||||
| .container_12 .pull_9 { | |||||
| left:-720px; | |||||
| } | |||||
| .container_12 .pull_10 { | |||||
| left:-800px; | |||||
| } | |||||
| .container_12 .pull_11 { | |||||
| left:-880px; | |||||
| } | |||||
| /* Clear Floated Elements | |||||
| ----------------------------------------------------------------------------------------------------*/ | |||||
| /* http://sonspring.com/journal/clearing-floats */ | |||||
| .clear { | |||||
| clear: both; | |||||
| display: block; | |||||
| overflow: hidden; | |||||
| visibility: hidden; | |||||
| width: 0; | |||||
| height: 0; | |||||
| } | |||||
| /* http://perishablepress.com/press/2008/02/05/lessons-learned-concerning-the-clearfix-css-hack */ | |||||
| .clearfix:after { | |||||
| clear: both; | |||||
| content: ' '; | |||||
| display: block; | |||||
| font-size: 0; | |||||
| line-height: 0; | |||||
| visibility: hidden; | |||||
| width: 0; | |||||
| height: 0; | |||||
| } | |||||
| .clearfix { | |||||
| display: inline-block; | |||||
| } | |||||
| * html .clearfix { | |||||
| height: 1%; | |||||
| } | |||||
| .clearfix { | |||||
| display: block; | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| .noprint, #footer, #breadcrumb | |||||
| { | |||||
| display: none; | |||||
| } | |||||
| body | |||||
| { | |||||
| margin: 0 auto; | |||||
| } | |||||
| @@ -0,0 +1,121 @@ | |||||
| body | |||||
| { | |||||
| background-color: #fff; | |||||
| color: #555; | |||||
| font-family: Helvetica, Arial, sans-serif; | |||||
| font-size: 100%; | |||||
| line-height: 1.5em; | |||||
| } | |||||
| p | |||||
| { | |||||
| font-size: 110%; | |||||
| } | |||||
| input | |||||
| { | |||||
| font-size: 130%; | |||||
| background-color: #fff; | |||||
| } | |||||
| #main | |||||
| { | |||||
| margin: 30px 0; | |||||
| } | |||||
| #footer | |||||
| { | |||||
| font-size: 100%; | |||||
| background-color: #fff; | |||||
| text-align: left; | |||||
| margin: 40px 0 40px 0; | |||||
| } | |||||
| a | |||||
| { | |||||
| background-color: #dce9b0; | |||||
| padding: 1px 4px; | |||||
| color: #111; | |||||
| text-decoration: none; | |||||
| } | |||||
| a:visited | |||||
| { | |||||
| background-color: #eee; | |||||
| padding: 1px 4px; | |||||
| color: #111; | |||||
| text-decoration: none; | |||||
| } | |||||
| a:hover | |||||
| { | |||||
| background-color: #4f4f4f; | |||||
| color: #fff; | |||||
| } | |||||
| h1 | |||||
| { | |||||
| margin-top: 20px; | |||||
| line-height: 1.4em; | |||||
| font-weight: bold; | |||||
| color: #86a11d; | |||||
| } | |||||
| h2 | |||||
| { | |||||
| margin-top: 20px; | |||||
| line-height: 1.5em; | |||||
| font-weight: bold; | |||||
| color: #86a11d; | |||||
| } | |||||
| form | |||||
| { | |||||
| font-size: 150%; | |||||
| } | |||||
| .highlight | |||||
| { | |||||
| background-color: #fff7c0; | |||||
| padding: 5px; | |||||
| } | |||||
| strong | |||||
| { | |||||
| color: #000; | |||||
| } | |||||
| table | |||||
| { | |||||
| border-collapse: collapse; | |||||
| } | |||||
| td, th | |||||
| { | |||||
| padding: 6px; | |||||
| } | |||||
| th | |||||
| { | |||||
| text-align: left; | |||||
| } | |||||
| tr | |||||
| { | |||||
| border-bottom: 1px solid #eee; | |||||
| } | |||||
| .right | |||||
| { | |||||
| text-align: right; | |||||
| } | |||||
| .noborder | |||||
| { | |||||
| border: 0; | |||||
| } | |||||
| @@ -0,0 +1,55 @@ | |||||
| .grid_9 | |||||
| %h1= @page_title = "About this website" | |||||
| %blockquote | |||||
| The swift and simple changes we are calling for today [to encourage councils to publish spending data] will unleash an army of armchair auditors and quite rightly make those charged with doling out the pennies stop and think twice about whether they are getting value for money. | |||||
| %p.right — Eric Pickles, Communities & Local Government Secretary, 5 June 2010 | |||||
| <!-- http://news.bbc.co.uk/1/hi/politics/10241522.stm --> | |||||
| %p.vcard | |||||
| This website was designed and written by | |||||
| %a.fn.url{ :href => 'http://adrianshort.co.uk' } Adrian Short | |||||
| \. | |||||
| You can contact me by email at | |||||
| %a.email{ :href => "mailto:adrian.short@gmail.com" } adrian.short@gmail.com | |||||
| and | |||||
| %a.url{ :href => "http://twitter.com/adrianshort" } follow me on Twitter | |||||
| \. | |||||
| %p.highlight | |||||
| This site is made with | |||||
| %a{ :href => 'http://www.rbwm.gov.uk/web/finance_payments_to_suppliers.htm' } | |||||
| the Royal Borough of Windsor and Maidenhead's spending data | |||||
| and is entirely indepdendent of the council. The council did not commission or pay for this website. | |||||
| %p Every page on this website prints beautifully. | |||||
| %p | |||||
| This site is written in | |||||
| %a{ :href => "http://www.ruby-lang.org/en/" }Ruby | |||||
| \ using the | |||||
| %a{ :href => "http://www.sinatrarb.com/" }Sinatra framework. | |||||
| %p | |||||
| The code for this website is | |||||
| %a{ :href => "http://github.com/adrianshort/Sutton-Elections" }open source and managed on Github. | |||||
| It is hosted by | |||||
| %a{ :href => "http://heroku.com/" }Heroku. | |||||
| %p | |||||
| The page templates use | |||||
| %a{ :href => "http://haml-lang.com/" }Haml | |||||
| and SprySoft's | |||||
| %a{ :href => "http://www.spry-soft.com/grids/" }Variable Grid System | |||||
| \. The database is | |||||
| %a{ :href => "http://www.sqlite.org/" }SQLite | |||||
| for development and | |||||
| %a{ :href => "http://www.postgresql.org/" }PostgreSQL | |||||
| for production, abstracted through | |||||
| %a{ :href => "http://datamapper.org/" }DataMapper. | |||||
| %p | |||||
| Source control and deployment is done with | |||||
| %a{ :href => "http://git-scm.com/" }Git. | |||||
| @@ -0,0 +1,30 @@ | |||||
| .grid_12 | |||||
| %h2= @page_title = @directorate.name + " Directorate" | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| %a{ :href => '/'} Home | |||||
| %li | |||||
| %a{ :href => '/directorates' } Directorates | |||||
| %li | |||||
| = @directorate.name | |||||
| %table | |||||
| %tr | |||||
| %th Date | |||||
| %th Service | |||||
| %th Supplier | |||||
| %th £ | |||||
| - for payment in @directorate.payments | |||||
| %tr | |||||
| %td= payment.d.strftime("%d %b %Y") | |||||
| %td | |||||
| %a{ :href => '/services/' + payment.service.id.to_s } | |||||
| = payment.service.name | |||||
| %td | |||||
| %a{ :href => '/suppliers/' + payment.supplier.id.to_s } | |||||
| = payment.supplier.name | |||||
| %td.right= sprintf("%0d", payment.amount) | |||||
| @@ -0,0 +1,5 @@ | |||||
| .grid_12 | |||||
| %h1 Invalid postcode | |||||
| %p | |||||
| %a{ :href => "/" }Please go back and try again | |||||
| @@ -0,0 +1,11 @@ | |||||
| .grid_12 | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| %h2 Directorates | |||||
| - for directorate in @directorates | |||||
| %p | |||||
| %a{ :href=> "/directorates/#{directorate.id}" } | |||||
| = directorate.name | |||||
| @@ -0,0 +1,26 @@ | |||||
| !!! XML | |||||
| !!! | |||||
| %html | |||||
| %head | |||||
| %title= @page_title ? @page_title + " - Armchair Auditor" : "Armchair Auditor" | |||||
| %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/style.css' } | |||||
| %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/breadcrumb/breadcrumb.css' } | |||||
| %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/print.css', :media => 'print' } | |||||
| %link{ :rel => 'stylesheet', :type => 'text/css', :href => '/grid.css' } | |||||
| %body | |||||
| .container_12 | |||||
| .grid_12 | |||||
| %h1 Royal Borough of Windsor & Maidenhead Armchair Auditor | |||||
| = yield | |||||
| .clear | |||||
| #footer | |||||
| .grid_12 | |||||
| %p | |||||
| %a{ :href => '/' } Home | |||||
| %p | |||||
| %a{ :href => '/services' } Services | |||||
| %p | |||||
| %a{ :href => '/suppliers' } Suppliers | |||||
| %p | |||||
| %a{ :href => '/about' } About this website | |||||
| @@ -0,0 +1,7 @@ | |||||
| .grid_9 | |||||
| %h1 Not Found | |||||
| %p Oops, we can't find that page. | |||||
| %p | |||||
| %a{ :href => '/' }Go back to the home page | |||||
| @@ -0,0 +1,33 @@ | |||||
| .grid_12 | |||||
| %h2= @page_title = @service.name + " (Service)" | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| %a{ :href => '/'} Home | |||||
| %li | |||||
| %a{ :href => '/services' } Services | |||||
| %li | |||||
| = @service.name | |||||
| %p | |||||
| %a{ :href => "/services/#{@service.id}.csv" } | |||||
| Download data as CSV | |||||
| %table | |||||
| %tr | |||||
| %th Date | |||||
| %th Directorate | |||||
| %th Supplier | |||||
| %th £ | |||||
| - for payment in @service.payments | |||||
| %tr | |||||
| %td= payment.d.strftime("%d %b %Y") | |||||
| %td | |||||
| %a{ :href => '/directorates/' + payment.directorate.id.to_s } | |||||
| = payment.directorate.name | |||||
| %td | |||||
| %a{ :href => '/suppliers/' + payment.supplier.id.to_s } | |||||
| = payment.supplier.name | |||||
| %td.right= sprintf("%0d", payment.amount) | |||||
| @@ -0,0 +1,13 @@ | |||||
| .grid_12 | |||||
| %h2 Services | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| %a{ :href => '/'} Home | |||||
| %li | |||||
| Services | |||||
| - for service in @services | |||||
| %p | |||||
| %a{ :href=> "/services/#{service.id}" } | |||||
| = service.name | |||||
| @@ -0,0 +1,34 @@ | |||||
| .grid_12 | |||||
| %h2= @page_title = @supplier.name + " (Supplier)" | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| %a{ :href => '/'} Home | |||||
| %li | |||||
| %a{ :href => '/suppliers' } Suppliers | |||||
| %li | |||||
| = @supplier.name | |||||
| %p.noprint | |||||
| %a{ :href => "/suppliers/#{@supplier.id}.csv" } | |||||
| Download data as CSV | |||||
| %table | |||||
| %tr | |||||
| %th Date | |||||
| %th Directorate | |||||
| %th Service | |||||
| %th £ | |||||
| - for payment in @supplier.payments | |||||
| %tr | |||||
| %td= payment.d.strftime("%d %b %Y") | |||||
| %td | |||||
| %a{ :href => '/directorates/' + payment.directorate.id.to_s } | |||||
| = payment.directorate.name | |||||
| %td | |||||
| %a{ :href => '/services/' + payment.service.id.to_s } | |||||
| = payment.service.name | |||||
| %td.right= sprintf("%0d", payment.amount) | |||||
| @@ -0,0 +1,13 @@ | |||||
| .grid_12 | |||||
| %h2 Suppliers | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| %a{ :href => '/'} Home | |||||
| %li | |||||
| Suppliers | |||||
| - for supplier in @suppliers | |||||
| %p | |||||
| %a{ :href=> "/suppliers/#{supplier.id}" } | |||||
| = supplier.name | |||||