An open source, stand-alone, customisable public spending data web app.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

119 lines
3.1 KiB

  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