| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- from __future__ import annotations
- from django.contrib.auth import get_user_model
- from django.contrib.sites.models import Site
- from django.db import models
- User = get_user_model()
- class TimestampedModel(models.Model):
- created_at = models.DateTimeField(auto_now_add=True)
- updated_at = models.DateTimeField(auto_now=True)
- class Meta:
- abstract = True
- class Organization(TimestampedModel):
- name = models.CharField(max_length=255)
- code = models.CharField(max_length=32, unique=True)
- # Minimal curated choices for simplicity; expand as needed
- TZ_CHOICES = (
- ("UTC", "UTC"),
- ("Asia/Bangkok", "Asia/Bangkok"),
- ("Asia/Singapore", "Asia/Singapore"),
- ("Asia/Jakarta", "Asia/Jakarta"),
- ("Europe/Berlin", "Europe/Berlin"),
- ("America/New_York", "America/New_York"),
- )
- timezone = models.CharField(max_length=64, choices=TZ_CHOICES, default="UTC")
- CURRENCY_CHOICES = (
- ("USD", "USD — US Dollar"),
- ("THB", "THB — Thai Baht"),
- ("EUR", "EUR — Euro"),
- ("SGD", "SGD — Singapore Dollar"),
- ("IDR", "IDR — Indonesian Rupiah"),
- )
- currency_code = models.CharField(max_length=8, choices=CURRENCY_CHOICES, default="USD")
- # Weigh ticket reconciliation settings
- ticket_tolerance_abs_kg = models.DecimalField(max_digits=10, decimal_places=3, default=0.500)
- ticket_tolerance_pct = models.DecimalField(max_digits=5, decimal_places=2, default=1.00)
- allow_adjust_net_to_lines = models.BooleanField(default=True)
- allow_add_residual_line = models.BooleanField(default=True)
- def __str__(self) -> str:
- return self.name
- class OrganizationSite(models.Model):
- organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="sites")
- site = models.OneToOneField(Site, on_delete=models.CASCADE, related_name="organization_site")
- def __str__(self) -> str:
- return f"{self.site.domain} -> {self.organization.code}"
- class UserProfile(TimestampedModel):
- ROLE_OWNER = "owner"
- ROLE_MANAGER = "manager"
- ROLE_DRIVER = "driver"
- ROLE_CUSTOMER = "customer"
- ROLE_AUDITOR = "auditor"
- ROLE_CHOICES = (
- (ROLE_OWNER, "Owner"),
- (ROLE_MANAGER, "Manager"),
- (ROLE_DRIVER, "Driver"),
- (ROLE_CUSTOMER, "Customer"),
- (ROLE_AUDITOR, "Auditor"),
- )
- user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="recycle_profile")
- organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="users")
- role = models.CharField(max_length=16, choices=ROLE_CHOICES, default=ROLE_MANAGER)
- my_photo = models.ImageField(upload_to="user_photos/", blank=True, null=True)
- # Contact and profile details
- phone = models.CharField(max_length=32, blank=True)
- job_title = models.CharField(max_length=128, blank=True)
- department = models.CharField(max_length=128, blank=True)
- preferred_language = models.CharField(max_length=10, blank=True)
- # Address fields
- address_line1 = models.CharField(max_length=255, blank=True)
- address_line2 = models.CharField(max_length=255, blank=True)
- city = models.CharField(max_length=128, blank=True)
- state = models.CharField(max_length=128, blank=True)
- postal_code = models.CharField(max_length=32, blank=True)
- country = models.CharField(max_length=64, blank=True)
- def __str__(self) -> str:
- return f"{self.user.username} ({self.role})"
|