@@ -85,11 +85,11 @@ get '/services/:slug/payments.csv' do | |||
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 | |||
@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 'datamapper' | |||
require 'dm-core' | |||
require 'dm-validations' | |||
require 'dm-timestamps' | |||
@@ -16,6 +17,7 @@ class Payment | |||
property :supplier_id, Integer, :required => true | |||
property :amount, BigDecimal, :precision => 10, :scale => 2, :required => true # ex VAT | |||
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 :supplier | |||
@@ -34,16 +36,17 @@ class Directorate | |||
property :created_at, DateTime | |||
property :updated_at, DateTime | |||
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, :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 | |||
class Service | |||
@@ -52,19 +55,20 @@ class Service | |||
property :id, Serial | |||
property :created_at, DateTime | |||
property :updated_at, DateTime | |||
property :directorate_id, Integer, :required => true | |||
property :directorate_id, Integer | |||
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, :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 | |||
class Supplier | |||
@@ -74,17 +78,17 @@ class Supplier | |||
property :created_at, DateTime | |||
property :updated_at, DateTime | |||
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, :services, { :through => :payments, :order => ['name'] } | |||
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 | |||
class Council | |||
@@ -115,15 +119,17 @@ end | |||
class Setting | |||
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 | |||
# DataMapper.setup(:default, ENV['DATABASE_URL'] || "mysql://root@localhost/armchairauditor_sutton") | |||
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db.sqlite3") | |||
DataMapper.auto_upgrade! |
@@ -1,9 +1,5 @@ | |||
.grid_12 | |||
-# | |||
%ul#breadcrumb | |||
%li.home | |||
.clear | |||
.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 => '/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 | |||
.container_12 | |||
@@ -6,10 +6,14 @@ | |||
%td Date | |||
%td= nicedate(@payment.d) | |||
%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 | |||
%td Service | |||
%td | |||
@@ -9,11 +9,12 @@ | |||
%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 | |||
%a{ :href => "/services/#{@service.slug}/payments" } | |||
@@ -32,11 +32,12 @@ | |||
%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 | |||
%a{ :href => "/services/#{@service.slug}" } | |||
@@ -2,6 +2,7 @@ | |||
%tr | |||
%th Date | |||
%th Ref. | |||
%th Transaction | |||
%th Supplier | |||
%th.right £ | |||
@@ -11,6 +12,7 @@ | |||
%td.right | |||
%a{ :href => "/payments/#{payment.id}" } | |||
= payment.id | |||
%td.right= payment.transaction_id | |||
%td | |||
%a{ :href => '/suppliers/' + payment.supplier.slug } | |||
= payment.supplier.name | |||
@@ -45,6 +45,7 @@ | |||
%tr | |||
%th Date | |||
%th Ref. | |||
%th Transaction | |||
%th Directorate | |||
%th Service | |||
%th.right £ | |||
@@ -55,9 +56,11 @@ | |||
%td | |||
%a{ :href => "/payments/#{payment.id}" } | |||
= payment.id | |||
%td= payment.transaction_id | |||
%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 | |||
%a{ :href => '/services/' + payment.service.slug } | |||
= payment.service.name | |||