diff --git a/app/controllers/admin/settings/exports_controller.rb b/app/controllers/admin/settings/exports_controller.rb
new file mode 100644
index 000000000..e9733f109
--- /dev/null
+++ b/app/controllers/admin/settings/exports_controller.rb
@@ -0,0 +1,23 @@
+class Admin::Settings::ExportsController < Admin::BaseController
+ include ActionController::Live
+
+ def index
+ end
+
+ def create
+ now = Time.current.rfc3339
+ filename = "all-items-#{now}.csv"
+
+ send_file_headers!(
+ type: "text/csv",
+ disposition: "attachment",
+ filename: filename
+ )
+ response.headers["Last-Modified"] = Time.now.httpdate
+
+ exporter = ItemExporter.new(Item.all)
+ exporter.export(response.stream)
+ ensure
+ response.stream.close
+ end
+end
diff --git a/app/lib/item_exporter.rb b/app/lib/item_exporter.rb
new file mode 100644
index 000000000..5a4145cb1
--- /dev/null
+++ b/app/lib/item_exporter.rb
@@ -0,0 +1,38 @@
+require "csv"
+
+class ItemExporter
+ def initialize(items)
+ @items = items
+ end
+
+ def export(stream)
+ columns = %w[
+ id name description size brand model serial strength power_source
+ other_names quantity checkout_notice status
+ location_area location_shelf
+ purchase_link purchase_price myturn_item_type url
+ created_at updated_at
+ ]
+ headers = [
+ "complete_number",
+ "code",
+ "number",
+ "categories",
+ "item_url",
+ *columns
+ ]
+ stream.write(CSV.generate_line(headers))
+ @items.includes(:borrow_policy, :category_nodes, :rich_text_description).in_batches(of: 100) do |items|
+ items.each do |item|
+ stream.write(CSV.generate_line([
+ item.complete_number,
+ item.borrow_policy.code,
+ item.number,
+ item.category_nodes.map { |cn| cn.path_names.join("//") }.sort.join("; "),
+ "https://app.chicagotoollibrary.org/admin/items/#{item.id}",
+ *columns.map { |c| item.send(c) }
+ ]))
+ end
+ end
+ end
+end
diff --git a/app/views/admin/settings/exports/index.html.erb b/app/views/admin/settings/exports/index.html.erb
new file mode 100644
index 000000000..35be55283
--- /dev/null
+++ b/app/views/admin/settings/exports/index.html.erb
@@ -0,0 +1,12 @@
+<%= content_for :header do %>
+ <%= index_header "Item Export" %>
+<% end %>
+
+
Export all items to CSV
+
+<%= link_to "Download CSV", admin_settings_exports_path, method: :post, class: "btn btn-lg", data: {turbolinks: false} %>
+
+
diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb
index a132fb137..d868ba049 100644
--- a/app/views/layouts/admin.html.erb
+++ b/app/views/layouts/admin.html.erb
@@ -59,8 +59,9 @@
<%= link_to "Categories", admin_categories_path %>
<% if current_user.admin? %>
<%= link_to "Documents", admin_documents_path %>
+ <%= link_to "Email Settings", admin_settings_email_settings_path %>
+ <%= link_to "Item Export", admin_settings_exports_path %>
<% end %>
- <%= link_to "Email Settings", admin_settings_email_settings_path %>
<%= link_to "Gift Memberships", admin_gift_memberships_path %>
<% if current_user.admin? %>
<%= link_to "Library Updates", admin_settings_library_updates_path %>
@@ -151,6 +152,7 @@
<% if current_user.has_role?(:admin) %>
+
<% end %>
<% if current_user.has_role?(:admin) %>
diff --git a/config/routes.rb b/config/routes.rb
index 1c68ea71a..2a0857549 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -139,6 +139,7 @@
get :preview, on: :member
end
resources :library_updates
+ resources :exports, only: [:index, :create]
end
resources :holds, only: [:index]
diff --git a/lib/tasks/export.rake b/lib/tasks/export.rake
index d09b835cb..1d902c80d 100644
--- a/lib/tasks/export.rake
+++ b/lib/tasks/export.rake
@@ -101,37 +101,6 @@ namespace :export do
end
end
- desc "Export items to CSV"
- task items_to_csv: :environment do
- now = Time.current.rfc3339
- path = Rails.root + "exports" + "all-items-#{now}.csv"
- puts "writing items to #{path}"
- columns = %w[
- id name description size brand model serial strength
- quantity checkout_notice status created_at updated_at
- ]
- CSV.open(path, "wb") do |csv|
- csv << [
- "complete_number",
- "code",
- "number",
- "categories",
- *columns
- ]
- Item.includes(:borrow_policy, :category_nodes).in_batches(of: 100) do |items|
- items.each do |item|
- csv << [
- item.complete_number,
- item.borrow_policy.code,
- item.number,
- item.category_nodes.map { |cn| cn.path_names.join("//") }.sort.join("; "),
- *item.attributes.values_at(*columns)
- ]
- end
- end
- end
- end
-
desc "Export seeds to CSV"
task seeds_to_csv: :environment do
now = Time.current.rfc3339
@@ -173,16 +142,14 @@ namespace :export do
csv << [
"id",
"name",
- "complete_name",
- "items_count"
+ "complete_name"
]
CategoryNode.in_batches(of: 100) do |nodes|
nodes.each do |node|
csv << [
node.id,
node.name,
- node.path_names.join("//"),
- node.categorizations_count
+ node.path_names.join("//")
]
end
end
diff --git a/test/lib/item_exporter_test.rb b/test/lib/item_exporter_test.rb
new file mode 100644
index 000000000..f0b381f12
--- /dev/null
+++ b/test/lib/item_exporter_test.rb
@@ -0,0 +1,18 @@
+require "test_helper"
+
+class ItemExporterTest < ActiveSupport::TestCase
+ setup do
+ end
+
+ test "exports items" do
+ create(:item)
+
+ exporter = ItemExporter.new(Item.all)
+ stream = StringIO.new
+ exporter.export(stream)
+
+ stream.rewind
+
+ assert_equal 2, stream.read.lines.size
+ end
+end