91 lines
3.1 KiB
Ruby
91 lines
3.1 KiB
Ruby
require "rqrcode"
|
|
require "csv"
|
|
|
|
class Item < ApplicationRecord
|
|
belongs_to :category
|
|
belongs_to :user, optional: true # Optional, falls im Raum oder Lager
|
|
belongs_to :room, optional: true # Optional, falls beim User oder Lager
|
|
has_many :assignment_logs, dependent: :destroy
|
|
|
|
validates :name, :sku, presence: true
|
|
validates :sticker_id, :serial_number, presence: true, uniqueness: true
|
|
|
|
# Validierung: Darf nicht gleichzeitig einem User UND einem Raum gehören
|
|
validate :either_user_or_room
|
|
|
|
# Überwacht Besitzer- oder Raumwechsel für die Historie
|
|
before_save :track_assignment_changes, if: -> { will_save_change_to_user_id? || will_save_change_to_room_id? }
|
|
|
|
def generate_qr_code
|
|
return if sticker_id.blank?
|
|
|
|
# Erzeugt das QR-Code-Objekt basierend auf deiner vorgedruckten Sticker-ID
|
|
qrcode = RQRCode::QRCode.new(sticker_id.to_s)
|
|
|
|
# Rendert den QR-Code als SVG-Vektorgrafik (perfekt scharf für Bildschirme)
|
|
qrcode.as_svg(
|
|
color: "000", # Farbe: Schwarz
|
|
shape_rendering: "crispEdges", # Erzwingt scharfe Kanten im Browser
|
|
module_size: 4, # Kompakte Größe
|
|
standalone: true,
|
|
use_path: true
|
|
).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
|
|
if user_id.present? && room_id.present?
|
|
errors.add(:base, "Ein Artikel kann nicht gleichzeitig einem Benutzer und einem Raum zugewiesen sein.")
|
|
end
|
|
end
|
|
|
|
def track_assignment_changes
|
|
# 1. Altes Log-Buch schließen, falls es eine vorherige Zuweisung gab
|
|
if user_id_was.present? || room_id_was.present?
|
|
last_log = assignment_logs.find_by(user_id: user_id_was, room_id: room_id_was, returned_at: nil)
|
|
last_log&.update(returned_at: Time.current)
|
|
end
|
|
|
|
# 2. Neues Log-Buch öffnen für den neuen Inhaber oder den neuen Raum
|
|
if user_id.present? || room_id.present?
|
|
assignment_logs.build(user_id: user_id, room_id: room_id, assigned_at: Time.current)
|
|
end
|
|
end
|
|
end
|