| @@ -85,11 +85,11 @@ get '/services/:slug/payments.csv' do | |||||
| end | end | ||||
| get '/services/:slug.json' do | |||||
| @service = Service.first(:slug => params[:slug]) | |||||
| headers "Content-Type" => "application/json" | |||||
| @service.to_json(:relationships => { :payments => { :include => :all }, :directorate => { :include => :all } }) | |||||
| end | |||||
| # get '/services/:slug.json' do | |||||
| # @service = Service.first(:slug => params[:slug]) | |||||
| # headers "Content-Type" => "application/json" | |||||
| # @service.to_json(:relationships => { :payments => { :include => :all }, :directorate => { :include => :all } }) | |||||
| # end | |||||
| get '/services/:slug' do | get '/services/:slug' do | ||||
| @service = Service.first(:slug => params[:slug]) | @service = Service.first(:slug => params[:slug]) | ||||
| @@ -0,0 +1,112 @@ | |||||
| require 'lib/models' | |||||
| require 'fastercsv' | |||||
| # Before running this script with a CSV file, prepare it so: | |||||
| # - There is only a single line of column headings on the first line of the file | |||||
| # - There are no spaces before or after the column headings | |||||
| # - The column headings correspond with the key names in the columns{} hash below | |||||
| # - The data starts on line 2 | |||||
| def slugify(name) | |||||
| output = name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| output.gsub(/---/, '-') | |||||
| end | |||||
| months = %w[ dummy Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ] | |||||
| columns = | |||||
| { | |||||
| 'Directorate' => nil, | |||||
| 'Updated' => nil, | |||||
| 'Service' => nil, | |||||
| 'Supplier' => nil, | |||||
| 'Amount' => nil, | |||||
| 'Transaction Number' => nil, | |||||
| } | |||||
| directorate_replacements = | |||||
| [ | |||||
| ] | |||||
| service_replacements = | |||||
| [ | |||||
| ] | |||||
| count = 0 | |||||
| if ARGV[0].nil? | |||||
| puts "Specify the filename of the CSV file to import on the command line" | |||||
| exit | |||||
| end | |||||
| FasterCSV.foreach(ARGV[0]) do |row| | |||||
| count += 1 | |||||
| if (count > 1) # skip first line that doesn't contain data | |||||
| p row | |||||
| unless row[columns['Directorate']].nil? | |||||
| directorate_name = row[columns['Directorate']].strip.gsub(/&/, "and") | |||||
| end | |||||
| service_name = row[columns['Service']].strip.gsub(/&/, "and") | |||||
| supplier_name = row[columns['Supplier']].strip.gsub(/&/, "and") | |||||
| for replacement in directorate_replacements | |||||
| if directorate_name == replacement[0] | |||||
| directorate_name = replacement[1] | |||||
| end | |||||
| end | |||||
| for replacement in service_replacements | |||||
| if service_name == replacement[0] | |||||
| service_name = replacement[1] | |||||
| end | |||||
| end | |||||
| if directorate_name.nil? | |||||
| directorate = nil | |||||
| else | |||||
| directorate = Directorate.first_or_create(:name => directorate_name, :slug => slugify(directorate_name)) | |||||
| directorate.save | |||||
| end | |||||
| service = Service.first_or_create(:name => service_name, :directorate => directorate, :slug => slugify(service_name)) | |||||
| service.save | |||||
| supplier = Supplier.first_or_create(:name => supplier_name, :slug => slugify(supplier_name)) | |||||
| supplier.save | |||||
| dt = row[columns['Updated']].strip.split(' ') | |||||
| d = Date.new(dt[2].to_i, months.index(dt[1]), dt[0].to_i) | |||||
| # Using Payment.new rather than Payment.first_or_new allows us to create genuine duplicates | |||||
| # so don't run the importer more than once with the same set of data | |||||
| payment = Payment.new( | |||||
| 'service' => service, | |||||
| 'supplier' => supplier, | |||||
| 'amount' => row[columns['Amount']].strip.gsub(/,/, ''), | |||||
| 'd' => d, | |||||
| 'transaction_id' => row[columns['Transaction Number']].strip.to_i | |||||
| ) | |||||
| unless payment.save # save runs callbacks/hooks, save! doesn't | |||||
| puts "ERROR: Failed to save payment" | |||||
| payment.errors.each do |e| | |||||
| puts e | |||||
| end | |||||
| end | |||||
| else | |||||
| # Get the column headings | |||||
| position = 0 | |||||
| for column in row | |||||
| columns[column] = position | |||||
| position += 1 | |||||
| end | |||||
| puts columns.inspect | |||||
| end | |||||
| end | |||||
| @@ -1,4 +1,5 @@ | |||||
| require 'rubygems' | require 'rubygems' | ||||
| require 'datamapper' | |||||
| require 'dm-core' | require 'dm-core' | ||||
| require 'dm-validations' | require 'dm-validations' | ||||
| require 'dm-timestamps' | require 'dm-timestamps' | ||||
| @@ -16,6 +17,7 @@ class Payment | |||||
| property :supplier_id, Integer, :required => true | property :supplier_id, Integer, :required => true | ||||
| property :amount, BigDecimal, :precision => 10, :scale => 2, :required => true # ex VAT | property :amount, BigDecimal, :precision => 10, :scale => 2, :required => true # ex VAT | ||||
| property :d, Date, :required => true # transaction date | property :d, Date, :required => true # transaction date | ||||
| property :transaction_id, Integer # May not be unique per payment as one transaction could have several payments | |||||
| belongs_to :service | belongs_to :service | ||||
| belongs_to :supplier | belongs_to :supplier | ||||
| @@ -34,16 +36,17 @@ class Directorate | |||||
| property :created_at, DateTime | property :created_at, DateTime | ||||
| property :updated_at, DateTime | property :updated_at, DateTime | ||||
| property :name, String, :length => 255, :required => true | property :name, String, :length => 255, :required => true | ||||
| property :slug, String, :length => 255 | |||||
| property :slug, String, :length => 255, :required => true | |||||
| has n, :services, :order => ['name'] | has n, :services, :order => ['name'] | ||||
| has n, :suppliers, { :through => :services, :order => ['name'] } | has n, :suppliers, { :through => :services, :order => ['name'] } | ||||
| before :save, :slugify | |||||
| def slugify | |||||
| @slug = @name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| end | |||||
| # before :save, :slugify | |||||
| # | |||||
| # def slugify | |||||
| # @slug = @name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| # puts "I've just been slugified" | |||||
| # end | |||||
| end | end | ||||
| class Service | class Service | ||||
| @@ -52,19 +55,20 @@ class Service | |||||
| property :id, Serial | property :id, Serial | ||||
| property :created_at, DateTime | property :created_at, DateTime | ||||
| property :updated_at, DateTime | property :updated_at, DateTime | ||||
| property :directorate_id, Integer, :required => true | |||||
| property :directorate_id, Integer | |||||
| property :name, String, :length => 255, :required => true | property :name, String, :length => 255, :required => true | ||||
| property :slug, String, :length => 255 | |||||
| property :slug, String, :length => 255, :required => true | |||||
| has n, :payments, :order => ['d'] | has n, :payments, :order => ['d'] | ||||
| has n, :suppliers, { :through => :payments, :order => ['name'] } | has n, :suppliers, { :through => :payments, :order => ['name'] } | ||||
| belongs_to :directorate | |||||
| before :save, :slugify | |||||
| def slugify | |||||
| @slug = @name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| end | |||||
| belongs_to :directorate, :required => false | |||||
| # before :save, :slugify | |||||
| # | |||||
| # def slugify | |||||
| # @slug = @name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| # puts "I've just been slugified" | |||||
| # end | |||||
| end | end | ||||
| class Supplier | class Supplier | ||||
| @@ -74,17 +78,17 @@ class Supplier | |||||
| property :created_at, DateTime | property :created_at, DateTime | ||||
| property :updated_at, DateTime | property :updated_at, DateTime | ||||
| property :name, String, :length => 255, :required => true | property :name, String, :length => 255, :required => true | ||||
| property :slug, String, :length => 255 | |||||
| property :slug, String, :length => 255, :required => true | |||||
| has n, :payments, :order => ['d'] | has n, :payments, :order => ['d'] | ||||
| has n, :services, { :through => :payments, :order => ['name'] } | has n, :services, { :through => :payments, :order => ['name'] } | ||||
| has n, :directorates, { :through => :payments } | has n, :directorates, { :through => :payments } | ||||
| before :save, :slugify | |||||
| def slugify | |||||
| @slug = @name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| end | |||||
| # before :save, :slugify | |||||
| # | |||||
| # def slugify | |||||
| # @slug = @name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase | |||||
| # end | |||||
| end | end | ||||
| class Council | class Council | ||||
| @@ -115,15 +119,17 @@ end | |||||
| class Setting | class Setting | ||||
| include DataMapper::Resource | include DataMapper::Resource | ||||
| property :id, Serial | |||||
| property :site_name, String, :length => 255, :required => true | |||||
| property :site_tagline, String, :length => 255 | |||||
| property :site_url, String, :length => 255 | |||||
| property :org_name, String, :length => 255 | |||||
| property :org_url, String, :length => 255 | |||||
| property :data_url, String, :length => 255 | |||||
| property :disqus_shortname, String, :length => 255 | |||||
| property :id, Serial | |||||
| property :site_name, String, :length => 255, :required => true | |||||
| property :site_tagline, String, :length => 255 | |||||
| property :site_url, String, :length => 255 | |||||
| property :org_name, String, :length => 255 | |||||
| property :org_url, String, :length => 255 | |||||
| property :data_url, String, :length => 255 | |||||
| property :disqus_shortname, String, :length => 255 | |||||
| property :google_analytics_id, String, :length => 255 | |||||
| end | end | ||||
| # DataMapper.setup(:default, ENV['DATABASE_URL'] || "mysql://root@localhost/armchairauditor_sutton") | |||||
| DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db.sqlite3") | DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db.sqlite3") | ||||
| DataMapper.auto_upgrade! | DataMapper.auto_upgrade! | ||||
| @@ -1,9 +1,5 @@ | |||||
| .grid_12 | .grid_12 | ||||
| -# | |||||
| %ul#breadcrumb | |||||
| %li.home | |||||
| .clear | .clear | ||||
| .grid_6 | .grid_6 | ||||
| @@ -11,15 +11,16 @@ | |||||
| %script{:type => 'text/javascript', :src => 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'} | %script{:type => 'text/javascript', :src => 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'} | ||||
| %script{:type => 'text/javascript', :src => '/js/jquery.cookie.js'} | %script{:type => 'text/javascript', :src => '/js/jquery.cookie.js'} | ||||
| :javascript | |||||
| var _gaq = _gaq || []; | |||||
| _gaq.push(['_setAccount', 'UA-3042981-18']); | |||||
| _gaq.push(['_trackPageview']); | |||||
| (function() { | |||||
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | |||||
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | |||||
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | |||||
| })(); | |||||
| - if SETTING.google_analytics_id | |||||
| :javascript | |||||
| var _gaq = _gaq || []; | |||||
| _gaq.push(['_setAccount', "#{SETTING.google_analytics_id}"]); | |||||
| _gaq.push(['_trackPageview']); | |||||
| (function() { | |||||
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | |||||
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | |||||
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | |||||
| })(); | |||||
| %body | %body | ||||
| .container_12 | .container_12 | ||||
| @@ -6,10 +6,14 @@ | |||||
| %td Date | %td Date | ||||
| %td= nicedate(@payment.d) | %td= nicedate(@payment.d) | ||||
| %tr | %tr | ||||
| %td Directorate | |||||
| %td | |||||
| %a{ :href => "/directorates/#{@payment.service.directorate.slug}" } | |||||
| = @payment.service.directorate.name | |||||
| %td Transaction | |||||
| %td= @payment.transaction_id | |||||
| - unless @payment.service.directorate.nil? | |||||
| %tr | |||||
| %td Directorate | |||||
| %td | |||||
| %a{ :href => "/directorates/#{@payment.service.directorate.slug}" } | |||||
| = @payment.service.directorate.name | |||||
| %tr | %tr | ||||
| %td Service | %td Service | ||||
| %td | %td | ||||
| @@ -9,11 +9,12 @@ | |||||
| %h2= @page_title = @service.name | %h2= @page_title = @service.name | ||||
| %p | |||||
| A service in the | |||||
| %a{ :href => '/directorates/' + @service.directorate.slug } | |||||
| = @service.directorate.name | |||||
| Directorate | |||||
| - unless @service.directorate.nil? | |||||
| %p | |||||
| A service in the | |||||
| %a{ :href => '/directorates/' + @service.directorate.slug } | |||||
| = @service.directorate.name | |||||
| Directorate | |||||
| %p.noprint | %p.noprint | ||||
| %a{ :href => "/services/#{@service.slug}/payments" } | %a{ :href => "/services/#{@service.slug}/payments" } | ||||
| @@ -32,11 +32,12 @@ | |||||
| %h2= @page_title = "#{@service.name}: Payments to Suppliers" | %h2= @page_title = "#{@service.name}: Payments to Suppliers" | ||||
| %p | |||||
| A service in the | |||||
| %a{ :href => '/directorates/' + @service.directorate.slug } | |||||
| = @service.directorate.name | |||||
| Directorate | |||||
| - unless @service.directorate.nil? | |||||
| %p | |||||
| A service in the | |||||
| %a{ :href => '/directorates/' + @service.directorate.slug } | |||||
| = @service.directorate.name | |||||
| Directorate | |||||
| %p.noprint | %p.noprint | ||||
| %a{ :href => "/services/#{@service.slug}" } | %a{ :href => "/services/#{@service.slug}" } | ||||
| @@ -2,6 +2,7 @@ | |||||
| %tr | %tr | ||||
| %th Date | %th Date | ||||
| %th Ref. | %th Ref. | ||||
| %th Transaction | |||||
| %th Supplier | %th Supplier | ||||
| %th.right £ | %th.right £ | ||||
| @@ -11,6 +12,7 @@ | |||||
| %td.right | %td.right | ||||
| %a{ :href => "/payments/#{payment.id}" } | %a{ :href => "/payments/#{payment.id}" } | ||||
| = payment.id | = payment.id | ||||
| %td.right= payment.transaction_id | |||||
| %td | %td | ||||
| %a{ :href => '/suppliers/' + payment.supplier.slug } | %a{ :href => '/suppliers/' + payment.supplier.slug } | ||||
| = payment.supplier.name | = payment.supplier.name | ||||
| @@ -45,6 +45,7 @@ | |||||
| %tr | %tr | ||||
| %th Date | %th Date | ||||
| %th Ref. | %th Ref. | ||||
| %th Transaction | |||||
| %th Directorate | %th Directorate | ||||
| %th Service | %th Service | ||||
| %th.right £ | %th.right £ | ||||
| @@ -55,9 +56,11 @@ | |||||
| %td | %td | ||||
| %a{ :href => "/payments/#{payment.id}" } | %a{ :href => "/payments/#{payment.id}" } | ||||
| = payment.id | = payment.id | ||||
| %td= payment.transaction_id | |||||
| %td | %td | ||||
| %a{ :href => '/directorates/' + payment.service.directorate.slug } | |||||
| = payment.service.directorate.name | |||||
| - unless payment.service.directorate.nil? | |||||
| %a{ :href => '/directorates/' + payment.service.directorate.slug } | |||||
| = payment.service.directorate.name | |||||
| %td | %td | ||||
| %a{ :href => '/services/' + payment.service.slug } | %a{ :href => '/services/' + payment.service.slug } | ||||
| = payment.service.name | = payment.service.name | ||||