diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index c421b7d..fe756fa 100755 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -44,40 +44,40 @@ class PagesController < ApplicationController @promoter_events = current_user.events.includes(:orders, :tickets) .order(created_at: :desc) .limit(5) - + # Revenue metrics for promoter @total_revenue = current_user.events .joins(:orders) - .where(orders: { status: ['paid', 'completed'] }) - .sum('orders.total_amount_cents') / 100.0 - + .where(orders: { status: [ "paid", "completed" ] }) + .sum("orders.total_amount_cents") / 100.0 + @total_tickets_sold = current_user.events .joins(:tickets) - .where(tickets: { status: 'active' }) + .where(tickets: { status: "active" }) .count - - @active_events_count = current_user.events.where(state: 'published').count - @draft_events_count = current_user.events.where(state: 'draft').count - + + @active_events_count = current_user.events.where(state: "published").count + @draft_events_count = current_user.events.where(state: "draft").count + # Recent orders for promoter events @recent_orders = Order.joins(:event) .where(events: { user: current_user }) - .where(status: ['paid', 'completed']) + .where(status: [ "paid", "completed" ]) .includes(:event, :user, tickets: :ticket_type) .order(created_at: :desc) .limit(10) - + # Monthly revenue trend (last 6 months) @monthly_revenue = (0..5).map do |months_ago| start_date = months_ago.months.ago.beginning_of_month end_date = months_ago.months.ago.end_of_month - + revenue = current_user.events .joins(:orders) - .where(orders: { status: ['paid', 'completed'] }) + .where(orders: { status: [ "paid", "completed" ] }) .where(orders: { created_at: start_date..end_date }) - .sum('orders.total_amount_cents') / 100.0 - + .sum("orders.total_amount_cents") / 100.0 + { month: start_date.strftime("%B %Y"), revenue: revenue diff --git a/app/models/event.rb b/app/models/event.rb index 9764da2..81d20e2 100755 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,7 +1,7 @@ # Event model representing nightlife events and events # Manages event details, location data, and publication state -require 'net/http' -require 'json' +require "net/http" +require "json" class Event < ApplicationRecord # Define states for Event lifecycle management @@ -24,24 +24,24 @@ class Event < ApplicationRecord # === Callbacks === before_validation :geocode_address, if: :venue_address_changed? - + # === Instance Methods === - + # Check if coordinates were successfully geocoded or are fallback coordinates def geocoding_successful? return false if latitude.blank? || longitude.blank? - + # Check if coordinates are exactly the fallback coordinates fallback_lat = 46.603354 fallback_lng = 1.888334 - + !(latitude == fallback_lat && longitude == fallback_lng) end - + # Get a user-friendly status message about geocoding def geocoding_status_message return nil if geocoding_successful? - + "Les coordonnées exactes n'ont pas pu être déterminées automatiquement. Une localisation approximative a été utilisée." end @@ -80,7 +80,7 @@ class Event < ApplicationRecord # Automatically geocode address to get latitude and longitude def geocode_address return if venue_address.blank? - + # If we already have coordinates and this is an update, try to geocode # If it fails, keep the existing coordinates original_lat = latitude @@ -90,24 +90,24 @@ class Event < ApplicationRecord # Use OpenStreetMap Nominatim API for geocoding encoded_address = URI.encode_www_form_component(venue_address.strip) uri = URI("https://nominatim.openstreetmap.org/search?q=#{encoded_address}&format=json&limit=1") - + response = Net::HTTP.get_response(uri) - - if response.code == '200' + + if response.code == "200" data = JSON.parse(response.body) - + if data.any? result = data.first - self.latitude = result['lat'].to_f.round(6) - self.longitude = result['lon'].to_f.round(6) + self.latitude = result["lat"].to_f.round(6) + self.longitude = result["lon"].to_f.round(6) Rails.logger.info "Geocoded address '#{venue_address}' to coordinates: #{latitude}, #{longitude}" return end end - + # If we reach here, geocoding failed handle_geocoding_failure(original_lat, original_lng) - + rescue => e Rails.logger.error "Geocoding failed for address '#{venue_address}': #{e.message}" handle_geocoding_failure(original_lat, original_lng) @@ -143,33 +143,33 @@ class Event < ApplicationRecord # Extract country/city from address and return approximate coordinates def get_fallback_coordinates_from_address address_lower = venue_address.downcase - + # Common French cities with approximate coordinates french_cities = { - 'paris' => { lat: 48.8566, lng: 2.3522 }, - 'lyon' => { lat: 45.7640, lng: 4.8357 }, - 'marseille' => { lat: 43.2965, lng: 5.3698 }, - 'toulouse' => { lat: 43.6047, lng: 1.4442 }, - 'nice' => { lat: 43.7102, lng: 7.2620 }, - 'nantes' => { lat: 47.2184, lng: -1.5536 }, - 'montpellier' => { lat: 43.6110, lng: 3.8767 }, - 'strasbourg' => { lat: 48.5734, lng: 7.7521 }, - 'bordeaux' => { lat: 44.8378, lng: -0.5792 }, - 'lille' => { lat: 50.6292, lng: 3.0573 } + "paris" => { lat: 48.8566, lng: 2.3522 }, + "lyon" => { lat: 45.7640, lng: 4.8357 }, + "marseille" => { lat: 43.2965, lng: 5.3698 }, + "toulouse" => { lat: 43.6047, lng: 1.4442 }, + "nice" => { lat: 43.7102, lng: 7.2620 }, + "nantes" => { lat: 47.2184, lng: -1.5536 }, + "montpellier" => { lat: 43.6110, lng: 3.8767 }, + "strasbourg" => { lat: 48.5734, lng: 7.7521 }, + "bordeaux" => { lat: 44.8378, lng: -0.5792 }, + "lille" => { lat: 50.6292, lng: 3.0573 } } - + # Check if any known city is mentioned in the address french_cities.each do |city, coords| if address_lower.include?(city) return coords end end - + # Check for common country indicators - if address_lower.include?('france') || address_lower.include?('french') + if address_lower.include?("france") || address_lower.include?("french") return { lat: 46.603354, lng: 1.888334 } # Center of France end - + nil end end