An open source, stand-alone, customisable public spending data web app.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

sutton.rb 3.1 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. require './app'
  2. require 'csv'
  3. require 'date'
  4. # Before running this script with a CSV file, prepare it so:
  5. # - There is only a single line of column headings on the first line of the file
  6. # - There are no spaces before or after the column headings
  7. # - The column headings correspond with the key names in the columns{} hash below
  8. # - The data starts on line 2
  9. def slugify(name)
  10. output = name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  11. output.gsub(/---/, '-')
  12. end
  13. months = %w[ dummy Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]
  14. columns =
  15. {
  16. 'Directorate' => nil,
  17. 'Updated' => nil,
  18. 'Service' => nil,
  19. 'Supplier' => nil,
  20. 'Amount' => nil,
  21. 'Transaction Number' => nil,
  22. }
  23. directorate_replacements =
  24. [
  25. ]
  26. service_replacements =
  27. [
  28. ]
  29. count = 0
  30. if ARGV[0].nil?
  31. puts "Specify the filename of the CSV file to import on the command line"
  32. exit
  33. end
  34. CSV.foreach(ARGV[0]) do |row|
  35. count += 1
  36. if (count > 1) # skip first line that doesn't contain data
  37. p row
  38. unless row[columns['Directorate']].nil?
  39. directorate_name = row[columns['Directorate']].strip.gsub(/&/, "and")
  40. end
  41. service_name = row[columns['Service']].strip.gsub(/&/, "and")
  42. supplier_name = row[columns['Supplier']].strip.gsub(/&/, "and")
  43. for replacement in directorate_replacements
  44. if directorate_name == replacement[0]
  45. directorate_name = replacement[1]
  46. end
  47. end
  48. for replacement in service_replacements
  49. if service_name == replacement[0]
  50. service_name = replacement[1]
  51. end
  52. end
  53. if directorate_name.nil?
  54. directorate = nil
  55. else
  56. directorate = Directorate.first_or_create(:name => directorate_name, :slug => slugify(directorate_name))
  57. directorate.save
  58. end
  59. service = Service.first_or_create(:name => service_name, :directorate => directorate, :slug => slugify(service_name))
  60. service.save
  61. supplier = Supplier.first_or_create(:name => supplier_name, :slug => slugify(supplier_name))
  62. supplier.save
  63. # dt = row[columns['Updated']].strip.split(' ')
  64. # d = Date.new(dt[2].to_i, months.index(dt[1]), dt[0].to_i)
  65. dt = row[columns['Updated']].strip
  66. if dt =~ /\d{4}-\d{2}-\d{2}/
  67. d = Date.iso8601(dt)
  68. end
  69. # Using Payment.new rather than Payment.first_or_new allows us to create genuine duplicates
  70. # so don't run the importer more than once with the same set of data
  71. payment = Payment.new(
  72. 'service' => service,
  73. 'supplier' => supplier,
  74. 'amount' => row[columns['Amount']].strip.gsub(/,/, ''),
  75. 'd' => d,
  76. 'transaction_id' => row[columns['Transaction Number']].strip.to_i
  77. )
  78. unless payment.save # save runs callbacks/hooks, save! doesn't
  79. puts "ERROR: Failed to save payment"
  80. payment.errors.each do |e|
  81. puts e
  82. end
  83. end
  84. else
  85. # Get the column headings
  86. position = 0
  87. for column in row
  88. columns[column] = position
  89. position += 1
  90. end
  91. puts columns.inspect
  92. end
  93. end