# Copyright (C) 2024-2025 LibreWeddingPlanner contributors # frozen_string_literal: true class TablesArrangementsController < ApplicationController def index query = TablesArrangement .order(valid: :desc) .order(discomfort: :asc) .select(:id, :name, :discomfort, :status, :progress) .select("digest = '#{current_digest}'::uuid OR discomfort IS NULL as valid") .limit((params[:limit].presence&.to_i || 20).clamp(1..20)) query = query.where(status: params[:status]) if params[:status].present? render json: query .as_json(only: %i[id name discomfort valid status progress]) end def stats scope = TablesArrangement.where('digest = ?::uuid OR discomfort IS NULL', current_digest) render json: { count: scope.group(:status).count, in_progress: scope.where(status: :in_progress).limit(10).order(progress: :desc).pluck(:progress) } end def show Guest.joins(:seats, :group) .where(seats: { tables_arrangement_id: params[:id] }) .select('guests.*', 'groups.color', 'seats.table_number') .group_by(&:table_number) .map { |number, guests| format(number:, guests:) } .then { |result| render json: { id: params[:id], tables: result } } end def create ActiveRecord::Base.transaction do tables_arrangement = TablesArrangement.create!(status: :not_started) TableSimulatorJob.perform_later(current_tenant.id, tables_arrangement.id) end render json: {}, status: :created end private def current_digest @current_digest ||= Tables::Distribution.digest(current_tenant) end def format(number:, guests:) { number: number, discomfort: discomfort(guests: guests), guests: guests.as_json(only: %i[id name color]) } end def discomfort(guests:) table = Tables::Table.new(guests) table.min_per_table = TableSimulatorJob::MIN_PER_TABLE table.max_per_table = TableSimulatorJob::MAX_PER_TABLE calculator = Tables::DiscomfortCalculator.new(table:) { discomfort: calculator.calculate, breakdown: calculator.breakdown } end end