feat(client,setting): complete Phase 2 with partitioned client_follow_logs
- apps/client (11 models): Client, ClientContact, ClientRequirement, ClientSchoolPreference, ClientFollowLog (partitioned), ClientFollowLogAttachment, ClientViewing, ClientPropertyMatch, ClientStatusLog, ClientFavoriteFolder, ClientFolderItem - apps/client/0002 RunSQL: PARTITION BY RANGE(created_at) for client_follow_logs + monthly partitions + default; triggers update_client_last_follow + update_client_viewing_progress; partial unique index on client_no WHERE deleted_at IS NULL - apps/setting (4 models): LookupGroup, LookupItem, TenantSetting, FieldRequirementRule (tenant schema only per spec) manage.py check green; all 9 Phase 2 apps complete.
This commit is contained in:
147
apps/client/models/core.py
Normal file
147
apps/client/models/core.py
Normal file
@@ -0,0 +1,147 @@
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.db import models
|
||||
|
||||
from core.enums import (
|
||||
ClientActivityLevel,
|
||||
ClientBuyingPurpose,
|
||||
ClientGrade,
|
||||
ClientIdType,
|
||||
ClientInvalidReason,
|
||||
ClientPaymentMethod,
|
||||
ClientPropertiesOwned,
|
||||
ClientPropertyUsage,
|
||||
ClientStatus,
|
||||
ClientTransactedPropertyType,
|
||||
ClientTransactedType,
|
||||
ClientTransferToPublicType,
|
||||
ClientType,
|
||||
)
|
||||
from core.models.base import AuditedModel
|
||||
|
||||
|
||||
class Client(AuditedModel):
|
||||
client_no = models.CharField(max_length=30, unique=True)
|
||||
client_type = models.CharField(
|
||||
max_length=20, choices=ClientType.choices, default=ClientType.PRIVATE
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=20, choices=ClientStatus.choices, default=ClientStatus.BUYING
|
||||
)
|
||||
grade = models.CharField(
|
||||
max_length=5, choices=ClientGrade.choices, default=ClientGrade.C
|
||||
)
|
||||
property_usage = models.CharField(
|
||||
max_length=30,
|
||||
choices=ClientPropertyUsage.choices,
|
||||
default=ClientPropertyUsage.RESIDENTIAL,
|
||||
)
|
||||
buying_purpose = ArrayField(
|
||||
models.CharField(max_length=20, choices=ClientBuyingPurpose.choices),
|
||||
blank=True,
|
||||
default=list,
|
||||
)
|
||||
payment_method = models.CharField(
|
||||
max_length=30, choices=ClientPaymentMethod.choices, blank=True, default=""
|
||||
)
|
||||
properties_owned = models.CharField(
|
||||
max_length=20, choices=ClientPropertiesOwned.choices, blank=True, default=""
|
||||
)
|
||||
has_loan_record = models.BooleanField(null=True, blank=True)
|
||||
|
||||
id_type = models.CharField(
|
||||
max_length=20, choices=ClientIdType.choices, blank=True, default=""
|
||||
)
|
||||
id_number_enc = models.BinaryField(null=True, blank=True)
|
||||
|
||||
source = models.CharField(max_length=50, blank=True, default="")
|
||||
remarks = models.TextField(blank=True, default="")
|
||||
|
||||
is_starred = models.BooleanField(default=False)
|
||||
is_pinned = models.BooleanField(default=False)
|
||||
is_big_value = models.BooleanField(default=False)
|
||||
is_protected = models.BooleanField(default=False)
|
||||
prefers_new_house = models.BooleanField(null=True, blank=True)
|
||||
|
||||
transfer_to_public_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=ClientTransferToPublicType.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
)
|
||||
transferred_public_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
invalid_reason = models.CharField(
|
||||
max_length=30, choices=ClientInvalidReason.choices, blank=True, default=""
|
||||
)
|
||||
invalidated_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
transacted_at = models.DateField(null=True, blank=True)
|
||||
transacted_property = models.ForeignKey(
|
||||
"fonrey_property.Property",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="transacted_clients",
|
||||
)
|
||||
transacted_price = models.DecimalField(
|
||||
max_digits=12, decimal_places=2, null=True, blank=True
|
||||
)
|
||||
transacted_type = models.CharField(
|
||||
max_length=20, choices=ClientTransactedType.choices, blank=True, default=""
|
||||
)
|
||||
transacted_property_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=ClientTransactedPropertyType.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
)
|
||||
|
||||
first_recorder = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="first_recorded_clients",
|
||||
)
|
||||
owner = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="owned_clients",
|
||||
)
|
||||
org_unit = models.ForeignKey(
|
||||
"org.OrgUnit",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="clients",
|
||||
)
|
||||
|
||||
activity_level = models.CharField(
|
||||
max_length=20, choices=ClientActivityLevel.choices, blank=True, default=""
|
||||
)
|
||||
last_active_at = models.DateTimeField(null=True, blank=True)
|
||||
last_follow_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
commission_date = models.DateField(null=True, blank=True)
|
||||
entrust_count = models.SmallIntegerField(default=1)
|
||||
|
||||
version = models.IntegerField(default=1)
|
||||
|
||||
class Meta:
|
||||
db_table = "clients"
|
||||
indexes = [
|
||||
models.Index(fields=["client_type", "status"], name="idx_clients_type_stat"),
|
||||
models.Index(fields=["owner"], name="idx_clients_owner"),
|
||||
models.Index(fields=["org_unit"], name="idx_clients_org_unit"),
|
||||
models.Index(
|
||||
fields=["activity_level", "-last_active_at"],
|
||||
name="idx_clients_activity",
|
||||
),
|
||||
models.Index(fields=["grade"], name="idx_clients_grade"),
|
||||
models.Index(
|
||||
fields=["-transferred_public_at"], name="idx_clients_transferred"
|
||||
),
|
||||
models.Index(fields=["-last_follow_at"], name="idx_clients_last_follow"),
|
||||
]
|
||||
Reference in New Issue
Block a user