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