132 lines
5.2 KiB
Python
132 lines
5.2 KiB
Python
from django.db import models
|
|
from django.contrib.auth.models import AbstractUser
|
|
|
|
class Organization(models.Model):
|
|
name = models.CharField(max_length=255)
|
|
logo = models.ImageField(upload_to='organization_logos/', null=True, blank=True)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
class User(AbstractUser):
|
|
ROLE_CHOICES = [
|
|
('ORG_ADMIN', 'Org admin'),
|
|
('SUPER_ADMIN', 'Super admin'),
|
|
('JUNIOR_APPRAISER', 'Junior appraiser'),
|
|
('SENIOR_APPRAISER', 'Senior appraiser'),
|
|
('DESIGNATED_APPRAISER', 'Designated appraiser'),
|
|
('CLIENT_USER', 'Client user'),
|
|
('CLIENT_MANAGER', 'Client manager'),
|
|
('CLIENT_ADMIN', 'Client admin'),
|
|
]
|
|
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name='users', null=True, blank=True)
|
|
user_type = models.CharField(max_length=10, choices=[('internal', 'Internal'), ('client', 'Client')])
|
|
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='CLIENT_USER')
|
|
|
|
# Add related_name to avoid clashes with default User model's groups and user_permissions
|
|
groups = models.ManyToManyField(
|
|
'auth.Group',
|
|
verbose_name='groups',
|
|
blank=True,
|
|
help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
|
|
related_name="core_user_set",
|
|
related_query_name="user",
|
|
)
|
|
user_permissions = models.ManyToManyField(
|
|
'auth.Permission',
|
|
verbose_name='user permissions',
|
|
blank=True,
|
|
help_text='Specific permissions for this user.',
|
|
related_name="core_user_set",
|
|
related_query_name="user",
|
|
)
|
|
|
|
class Property(models.Model):
|
|
PROPERTY_TYPE_CHOICES = [
|
|
('SINGLE_FAMILY', 'Single Family'),
|
|
('MULTI_FAMILY', 'Multi-Family'),
|
|
('COMMERCIAL', 'Commercial'),
|
|
]
|
|
STATUS_CHOICES = [
|
|
('FOR_SALE', 'For Sale'),
|
|
('FOR_RENT', 'For Rent'),
|
|
('SOLD', 'Sold'),
|
|
]
|
|
organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name='properties')
|
|
name = models.CharField(max_length=255)
|
|
address = models.CharField(max_length=255)
|
|
city = models.CharField(max_length=255)
|
|
state = models.CharField(max_length=2)
|
|
zip_code = models.CharField(max_length=10)
|
|
property_type = models.CharField(max_length=20, choices=PROPERTY_TYPE_CHOICES)
|
|
square_footage = models.PositiveIntegerField()
|
|
bedrooms = models.PositiveIntegerField()
|
|
bathrooms = models.DecimalField(max_digits=3, decimal_places=1)
|
|
year_built = models.PositiveIntegerField()
|
|
description = models.TextField()
|
|
status = models.CharField(max_length=20, choices=STATUS_CHOICES)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
class PropertyPhoto(models.Model):
|
|
property = models.ForeignKey(Property, on_delete=models.CASCADE, related_name='photos')
|
|
image = models.ImageField(upload_to='property_photos/')
|
|
caption = models.CharField(max_length=255, blank=True)
|
|
|
|
def __str__(self):
|
|
return f"Photo for {self.property.name}"
|
|
|
|
class Invoice(models.Model):
|
|
STATUS_CHOICES = [
|
|
('DRAFT', 'Draft'),
|
|
('SENT', 'Sent'),
|
|
('PAID', 'Paid'),
|
|
('CANCELLED', 'Cancelled'),
|
|
]
|
|
client = models.ForeignKey('User', on_delete=models.CASCADE, related_name='invoices', null=True, blank=True)
|
|
invoice_number = models.CharField(max_length=50)
|
|
amount = models.DecimalField(max_digits=10, decimal_places=2)
|
|
due_date = models.DateField()
|
|
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='DRAFT')
|
|
|
|
def __str__(self):
|
|
return f"Invoice {self.invoice_number}"
|
|
|
|
class Order(models.Model):
|
|
STATUS_CHOICES = [
|
|
('PENDING', 'Pending'),
|
|
('IN_PROGRESS', 'In Progress'),
|
|
('COMPLETED', 'Completed'),
|
|
('CANCELLED', 'Cancelled'),
|
|
]
|
|
client = models.ForeignKey('User', on_delete=models.CASCADE, related_name='orders')
|
|
order_date = models.DateField(auto_now_add=True)
|
|
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='PENDING')
|
|
description = models.TextField(blank=True)
|
|
|
|
def __str__(self):
|
|
return f"Order #{self.id} for {self.client.username}"
|
|
|
|
class Project(models.Model):
|
|
client = models.ForeignKey(User, on_delete=models.CASCADE, related_name='projects')
|
|
name = models.CharField(max_length=255)
|
|
description = models.TextField(blank=True)
|
|
start_date = models.DateField()
|
|
end_date = models.DateField(null=True, blank=True)
|
|
invoice = models.ForeignKey(Invoice, on_delete=models.SET_NULL, null=True, blank=True, related_name='projects')
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
class Appraisal(models.Model):
|
|
property = models.ForeignKey(Property, on_delete=models.CASCADE, related_name='appraisals')
|
|
appraiser = models.ForeignKey(User, on_delete=models.CASCADE, related_name='appraisals')
|
|
appraisal_date = models.DateField()
|
|
appraised_value = models.DecimalField(max_digits=12, decimal_places=2)
|
|
notes = models.TextField(blank=True)
|
|
|
|
order = models.ForeignKey(Order, on_delete=models.SET_NULL, related_name='appraisals', null=True, blank=True)
|
|
|
|
def __str__(self):
|
|
return f"Appraisal for {self.property.name} on {self.appraisal_date}" |