diff --git a/Gemfile b/Gemfile index 4080fe1..db4230d 100644 --- a/Gemfile +++ b/Gemfile @@ -76,3 +76,5 @@ gem "authentication-zero", "~> 4.0" gem "rqrcode", "~> 3.2" + +gem "csv", "~> 3.3" diff --git a/Gemfile.lock b/Gemfile.lock index 4ca31e4..84fc20d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -107,6 +107,7 @@ GEM concurrent-ruby (1.3.6) connection_pool (3.0.2) crass (1.0.6) + csv (3.3.5) date (3.5.1) debug (1.11.1) irb (~> 1.10) @@ -423,6 +424,7 @@ DEPENDENCIES brakeman bundler-audit capybara + csv (~> 3.3) debug hotwire-spark image_processing (~> 1.2) @@ -479,6 +481,7 @@ CHECKSUMS concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d + csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6 dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d diff --git a/app/controllers/items_controller.rb b/app/controllers/items_controller.rb index 97a922b..ac9c618 100644 --- a/app/controllers/items_controller.rb +++ b/app/controllers/items_controller.rb @@ -4,6 +4,19 @@ class ItemsController < ApplicationController # GET /items or /items.json def index @items = Item.all.includes(:category, :user, :room).order(created_at: :desc) + + respond_to do |format| + format.html # Rendert ganz normal deine Bestandsliste im Browser + format.csv do + # Dateiname generieren, z.B. "inventar_export_2026-05-22.csv" + filename = "inventar_export_#{Time.current.strftime('%Y-%m-%d')}.csv" + + # Daten generieren und als Download an den Browser senden + send_data Item.to_csv, + filename: filename, + type: "text/csv; charset=utf-8; header=present" + end + end end # GET /items/1 or /items/1.json diff --git a/app/models/item.rb b/app/models/item.rb index faf1108..c0e7a96 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -1,4 +1,5 @@ require "rqrcode" +require "csv" class Item < ApplicationRecord belongs_to :category @@ -31,6 +32,41 @@ class Item < ApplicationRecord ).html_safe # Sagt Rails, dass das HTML unbedenklich ausgegeben werden darf end + def self.to_csv + # Die Spaltenüberschriften, die in der Excel-Datei erscheinen sollen + headers = [ "ID", "Artikelname", "SKU", "Seriennummer", "Sticker_ID", "Einkaufspreis", "Kategorie", "Aktueller_Standort", "Notizen", "Registriert_am" ] + + CSV.generate(headers: true, col_sep: ";", encoding: "UTF-8") do |csv| + # 1. Kopfzeile schreiben + csv << headers + + # 2. Datenzeilen schreiben (includes verhindert langsame N+1 Datenbankabfragen) + all.includes(:category, :user, :room).each do |item| + # Dynamischen Standort-Text ermitteln + current_location = if item.user.present? + "👤 #{item.user.name}" + elsif item.room.present? + "📍 #{item.room.name_with_building}" + else + "📦 Im Hauptlager" + end + + csv << [ + item.id, + item.name, + item.sku, + item.serial_number, + item.sticker_id, + item.price, + item.category&.name, + current_location, + item.notes, + item.created_at.strftime("%d.%m.%Y %H:%M") + ] + end + end + end + private def either_user_or_room diff --git a/app/views/items/_search_bar.html.erb b/app/views/items/_search_bar.html.erb index 21b8263..ac960cd 100644 --- a/app/views/items/_search_bar.html.erb +++ b/app/views/items/_search_bar.html.erb @@ -16,7 +16,7 @@ <%= link_to items_path(format: :csv), class: "py-2 px-3 border border-gray-300 rounded-lg text-sm font-medium bg-white text-gray-700 hover:bg-gray-50 flex items-center gap-1.5 transition shadow-sm", title: "Liste als Excel/CSV exportieren" do %> - Daten exportieren + CSV <% end %> <% end %>