Files
thrillwiki_django_no_react/backend/apps/rides/models/company.py
pacnpal fe960e8b62 w
2026-01-08 13:44:37 -05:00

163 lines
5.8 KiB
Python

import pghistory
from django.conf import settings
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
from apps.core.choices.fields import RichChoiceField
from apps.core.history import HistoricalSlug
from apps.core.models import TrackedModel
@pghistory.track()
class Company(TrackedModel):
name = models.CharField(max_length=255, help_text="Company name")
slug = models.SlugField(max_length=255, unique=True, help_text="URL-friendly identifier")
roles = ArrayField(
RichChoiceField(choice_group="company_roles", domain="rides", max_length=20),
default=list,
blank=True,
help_text="Company roles (manufacturer, designer, etc.)",
)
description = models.TextField(blank=True, help_text="Detailed company description")
website = models.URLField(blank=True, help_text="Company website URL")
# Person/Entity type
PERSON_TYPE_CHOICES = [
("company", "Company"),
("individual", "Individual"),
("firm", "Firm"),
("organization", "Organization"),
]
person_type = models.CharField(
max_length=20,
choices=PERSON_TYPE_CHOICES,
blank=True,
default="company",
help_text="Type of entity (company, individual, firm, organization)",
)
# General company info
founded_date = models.DateField(null=True, blank=True, help_text="Date the company was founded")
founded_date_precision = models.CharField(
max_length=20,
choices=[
("exact", "Exact"),
("month", "Month"),
("year", "Year"),
("decade", "Decade"),
("century", "Century"),
("approximate", "Approximate"),
],
blank=True,
default="",
help_text="Precision of the founded date",
)
founded_year = models.PositiveIntegerField(
null=True,
blank=True,
help_text="Year the company was founded (alternative to founded_date)",
)
headquarters_location = models.CharField(
max_length=200,
blank=True,
help_text="Headquarters location description (e.g., 'Los Angeles, CA, USA')",
)
# Location relationship (optional)
location = models.ForeignKey(
"parks.ParkLocation",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="companies",
help_text="Linked location record for headquarters",
)
# Image settings - stored as Cloudflare image IDs/URLs
banner_image_id = models.CharField(
max_length=255,
blank=True,
help_text="Cloudflare image ID for banner image",
)
card_image_id = models.CharField(
max_length=255,
blank=True,
help_text="Cloudflare image ID for card image",
)
# Manufacturer-specific fields
rides_count = models.IntegerField(default=0, help_text="Number of rides manufactured (auto-calculated)")
coasters_count = models.IntegerField(default=0, help_text="Number of coasters manufactured (auto-calculated)")
# Frontend URL
url = models.URLField(blank=True, help_text="Frontend URL for this company")
# Submission metadata fields (from frontend schema)
source_url = models.URLField(
blank=True,
help_text="Source URL for the data (e.g., official website, Wikipedia)",
)
is_test_data = models.BooleanField(
default=False,
help_text="Whether this is test/development data",
)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
# Generate frontend URL based on primary role
# CRITICAL: Only MANUFACTURER and DESIGNER are for rides domain
# OPERATOR and PROPERTY_OWNER are for parks domain and handled separately
if self.roles:
frontend_domain = getattr(settings, "FRONTEND_DOMAIN", "https://thrillwiki.com")
primary_role = self.roles[0] # Use first role as primary
if primary_role == "MANUFACTURER":
self.url = f"{frontend_domain}/rides/manufacturers/{self.slug}/"
elif primary_role == "DESIGNER":
self.url = f"{frontend_domain}/rides/designers/{self.slug}/"
# OPERATOR and PROPERTY_OWNER URLs are handled by parks domain, not here
super().save(*args, **kwargs)
def get_absolute_url(self):
# This will need to be updated to handle different roles
return reverse("companies:detail", kwargs={"slug": self.slug})
@classmethod
def get_by_slug(cls, slug):
"""Get company by current or historical slug"""
try:
return cls.objects.get(slug=slug), False
except cls.DoesNotExist:
# Check pghistory first
try:
from django.apps import apps
history_model = apps.get_model("rides", f"{cls.__name__}Event")
history_entry = history_model.objects.filter(slug=slug).order_by("-pgh_created_at").first()
if history_entry:
return cls.objects.get(id=history_entry.pgh_obj_id), True
except LookupError:
# History model doesn't exist, skip pghistory check
pass
# Check manual slug history as fallback
try:
historical = HistoricalSlug.objects.get(content_type__model="company", slug=slug)
return cls.objects.get(pk=historical.object_id), True
except (HistoricalSlug.DoesNotExist, cls.DoesNotExist):
raise cls.DoesNotExist("No company found with this slug") from None
class Meta(TrackedModel.Meta):
app_label = "rides"
verbose_name = "Company"
verbose_name_plural = "Companies"
ordering = ["name"]