from django.db import models import uuid from django.db.models import JSONField # Create your models here. #==================================================================================== def generate_increment_code(model_class, prefix="CODE", padding=4, code_field="code"): """ model_class: Model sẽ sinh mã (ví dụ Customer, Product,...) prefix: tiền tố (CUS, PRD...) padding: số lượng chữ số (0001, 0010...) code_field: tên trường lưu mã """ last = model_class.objects.order_by('-id').first() next_id = (last.id + 1) if last else 1 return f"{prefix}{next_id:0{padding}d}" class AutoCodeModel(models.Model): code_prefix = "CODE" code_padding = 5 class Meta: abstract = True def save(self, *args, **kwargs): if not self.code: self.code = generate_increment_code( model_class=self.__class__, prefix=self.code_prefix, padding=self.code_padding ) super().save(*args, **kwargs) class Money_Unit(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'money_unit' class Block_Reason(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'block_reason' class User_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'user_type' class Auth_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'auth_status' class Auth_Method(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'auth_method' class Register_Method(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'register_method' class Duration(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.TextField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'duration' class Ownership_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'ownership_type' class Transaction_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.TextField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction_type' class Transaction_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.TextField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction_status' class Project_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'project_status' class Sale_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) color = models.CharField(max_length=20, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'sale_status' class Product_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) color = models.CharField(max_length=20, null=True) index = models.IntegerField(null=True, default=1) sale_status = models.ForeignKey(Sale_Status, null=True, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'product_status' class Customer_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'customer_type' class Customer_Segment(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'customer_segment' class Payment_Method(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'payment_method' class Investor(models.Model): name = models.CharField(max_length=255) tax_code = models.CharField(max_length=20, null=False) address = models.TextField(null=False) phone = models.CharField(max_length=15, null=True) email = models.CharField(max_length=50, null=True) bank_account = models.CharField(max_length=20, null=True) bank_name = models.CharField(max_length=100, null=True) representative = models.CharField(max_length=100, null=True) website = models.URLField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'investor' class Project(models.Model): code = models.CharField(max_length=20, unique=True) name = models.CharField(max_length=255) investor = models.ForeignKey(Investor, null=False, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Project_Status, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'project' class Zone_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'zone_type' class Product_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'product_type' class Land_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'land_type' class Company_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'company_type' class Direction(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'direction' class Value_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'value_type' class Discount_Method(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'discount_method' class Discount_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) value = models.IntegerField() type = models.ForeignKey(Value_Type, null=False, related_name='+', on_delete=models.PROTECT) method = models.ForeignKey(Discount_Method, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'discount_type' class Gift(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.TextField(null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'gift' class Sale_Policy(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) deposit = models.DecimalField(max_digits=15, decimal_places=2) method = models.ForeignKey(Payment_Method, null=False, related_name='+', on_delete=models.PROTECT) enable = models.BooleanField(default=True) contract_allocation_percentage = models.IntegerField(null=True,blank=True,default=100) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'sale_policy' class Payment_Plan(models.Model): policy = models.ForeignKey(Sale_Policy, null=False, related_name='+', on_delete=models.PROTECT) cycle = models.IntegerField() value = models.IntegerField() type = models.ForeignKey(Value_Type, null=False, related_name='+', on_delete=models.PROTECT) days = models.IntegerField() payment_note = models.TextField() due_note = models.TextField() create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'payment_plan' unique_together = ('policy', 'cycle') class User(models.Model): username = models.CharField(max_length=50, null=False, unique=True) password = models.CharField(max_length=100, null=False) email = models.CharField(max_length=100, null=True, unique=True) avatar = models.CharField(max_length=100, null=True) fullname = models.CharField(max_length=50, null=False) display_name = models.CharField(max_length=50, null=True) type = models.ForeignKey(User_Type, null=True, related_name='+', on_delete=models.PROTECT, default=1) blocked = models.BooleanField(default=False) block_reason = models.ForeignKey(Block_Reason, null=True, related_name='+', on_delete=models.PROTECT) blocked_by = models.PositiveIntegerField(null=True) last_login = models.DateTimeField(null=True) auth_method = models.ForeignKey(Auth_Method, null=False, related_name='+', on_delete=models.PROTECT) auth_status = models.ForeignKey(Auth_Status, null=False, related_name='+', on_delete=models.PROTECT) register_method = models.ForeignKey(Register_Method, null=False, related_name='+', on_delete=models.PROTECT) pin = models.CharField(max_length=100, null=True) is_admin = models.BooleanField(null=True, default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'user' class Token(models.Model): token = models.CharField(max_length=100, null=False, unique=True) fcmtoken = models.CharField(max_length=200, null=True) browser = models.TextField(null=False) browser_version = models.CharField(max_length=100, null=False) os = models.CharField(max_length=100, null=False) ip = models.CharField(max_length=100, null=False) platform = models.CharField(max_length=100, null=False) expiry = models.BooleanField(default=False) city = models.CharField(max_length=100, null=True) region = models.CharField(max_length=100, null=True) country = models.CharField(max_length=100, null=True) loc = models.CharField(max_length=100, null=True) org = models.CharField(max_length=100, null=True) postal = models.CharField(max_length=100, null=True) timezone = models.CharField(max_length=100, null=True) user = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'token' class Setting_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'setting_type' class Setting_Choice(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'setting_choice' class Setting_Class(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'setting_class' class Currency(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) rate = models.FloatField(null=False) decimal = models.IntegerField(null=False, default=0) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'currency' class Bank(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'bank' class User_Setting(models.Model): name = models.CharField(max_length=200, null=False, unique=True) detail = models.JSONField(null=False) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) type = models.ForeignKey(Setting_Type, null=False, related_name='+', on_delete=models.PROTECT) classify = models.ForeignKey(Setting_Class, null=False, related_name='+', on_delete=models.PROTECT) note = models.TextField(null=True) default = models.BooleanField(default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) view = models.PositiveIntegerField(null=True) like = models.PositiveIntegerField(null=True) share = models.PositiveIntegerField(null=True) on_menu = models.BooleanField(default=False) my_menu = models.BooleanField(default=False) deleted = models.BooleanField(default=False) class Meta: db_table = 'user_setting' class Filter_Choice(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'filter_choice' class Color_Choice(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'color_choice' class Data_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'data_type' class Text_Align(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'text_align' class Placement(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'placement' class Color_Scheme(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'color_scheme' class Text_Color(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'text_color' class Filter_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'filter_type' class Sort_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'sort_type' class Table_Setting(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'table_setting' class Share_Choice(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'share_choice' class Menu_Choice(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'menu_choice' class Lang_Choice(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'lang_choice' class Common(models.Model): category = models.CharField(max_length=100, null=False) classify = models.CharField(max_length=100, null=False) code = models.CharField(max_length=100, null = False) vi = models.TextField(null=False) en = models.TextField(null=True) image = models.TextField(null=True) icon = models.TextField(null=True) link = models.TextField(null=True) detail = models.JSONField(null=True) index = models.IntegerField(null=True, default=0) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'common' unique_together = ('category', 'classify', 'code') class System_Setting(models.Model): category = models.CharField(max_length=100, null=False) classify = models.CharField(max_length=100, null=False) code = models.CharField(max_length=100, null = False) vi = models.TextField(null=False) en = models.TextField(null=True) image = models.TextField(null=True) icon = models.TextField(null=True) link = models.TextField(null=True) detail = models.JSONField(null=True) detail_en = models.JSONField(null=True) index = models.IntegerField(null=True, default=0) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'system_setting' unique_together = ('category', 'classify', 'code') class User_Auth(models.Model): user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) code = models.CharField(max_length=30, null=False, unique=True) expiry = models.BooleanField(default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'user_auth' class Account_Recovery(models.Model): user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) code = models.CharField(max_length=30, null=False, unique=True) expiry = models.BooleanField(default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'account_recovery' class File_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'file_type' class Document_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'document_type' class File(AutoCodeModel): code_prefix = "FILE" code_padding = 5 code = models.CharField(max_length=20, null=True, unique=True) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) type = models.ForeignKey(File_Type, null=False, related_name='+', on_delete=models.PROTECT) doc_type = models.ForeignKey(Document_Type, null=True, related_name='+', on_delete=models.PROTECT) name = models.CharField(max_length=200, null=False) file = models.CharField(max_length=200, null=False) hashtag= models.CharField(max_length=200, null=True) size = models.IntegerField(null=False) caption = models.CharField(max_length=200, null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'file' class Sex(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'sex' class Legal_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'legal_type' class Notification_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'notification_status' class Approve_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) color = models.CharField(max_length=20, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'approve_status' class Category(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'category' class Display_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'display_status' class Payment_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'payment_status' class Dealer(AutoCodeModel): code_prefix = "DL" code_padding = 2 code = models.CharField(max_length=20, null=True, unique=True) user = models.OneToOneField(User, null=True, related_name='dealer_profile', on_delete=models.SET_NULL) name = models.CharField(max_length=100, null=False) phone = models.CharField(max_length=20, null=True, db_index=True) email = models.CharField(max_length=50, null=True) address = models.CharField(max_length=255, null=True) sale_amount = models.DecimalField(max_digits=15, decimal_places=2,null=True) pay_sale = models.DecimalField(max_digits=15, decimal_places=2,null=True) commission_amount = models.DecimalField(max_digits=15, decimal_places=2,null=True) pay_commission = models.DecimalField(max_digits=15, decimal_places=2,null=True) commission_remain = models.DecimalField(max_digits=15, decimal_places=2,null=True) batch_date = models.DateTimeField(null=True) count_sale = models.IntegerField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'dealer' class Cart(AutoCodeModel): code_prefix = "GH" code_padding = 3 code = models.CharField(max_length=20, null=True, unique=True) name = models.CharField(max_length=255) dealer = models.ForeignKey(Dealer, null=True, related_name='+', on_delete=models.PROTECT) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'cart' class Product(AutoCodeModel): code_prefix = "SP" code_padding = 5 code = models.CharField(max_length=20, null=True, unique=True) land_lot_code = models.CharField(max_length=255) zone_code = models.CharField(max_length=255) trade_code = models.CharField(max_length=20, null=True) zone_type = models.ForeignKey(Zone_Type, null=False, related_name='+', on_delete=models.PROTECT) lot_area = models.DecimalField(max_digits=15, decimal_places=2) building_area = models.DecimalField(max_digits=15, decimal_places=2) total_built_area = models.DecimalField(max_digits=15, decimal_places=2) number_of_floors = models.IntegerField() land_lot_size = models.CharField(max_length=255) direction = models.ForeignKey(Direction, null=False, related_name='+', on_delete=models.PROTECT) villa_model = models.CharField(max_length=255, null=True) type = models.ForeignKey(Product_Type, null=False, related_name='+', on_delete=models.PROTECT) project = models.ForeignKey(Project, null=False, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Product_Status, null=False, related_name='+', on_delete=models.PROTECT) cart = models.ForeignKey(Cart, null=True, related_name='prdcart', on_delete=models.PROTECT) dealer = models.ForeignKey(Dealer, null=True, related_name='+', on_delete=models.PROTECT) policy = models.ForeignKey(Sale_Policy, null=True, related_name='+', on_delete=models.PROTECT) note = models.TextField(null=True) origin_price = models.DecimalField(max_digits=15, decimal_places=2, null=True) price_excluding_vat = models.DecimalField(max_digits=15, decimal_places=2, null=True) product_type = models.CharField(max_length=255, null=True) template_name = models.CharField(max_length=255, null=True) link = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, null=True) locked_until = models.DateTimeField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'product' class Product_File(models.Model): product = models.ForeignKey(Product, null=False, related_name='prdfile', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'product_file' unique_together = ('product', 'file') class Project_File(models.Model): project = models.ForeignKey(Project, null=False, related_name='prjfile', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'project_file' unique_together = ('project', 'file') class Product_Note(models.Model): ref = models.ForeignKey(Product, null=False, related_name='prdnote', on_delete=models.PROTECT) detail = models.TextField() files = models.JSONField(null=True) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) deleted = models.BooleanField(null=True, default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'product_note' class News(models.Model): title = models.CharField(max_length=200, null=False) subtitle = models.CharField(max_length=500, null=False) image = models.CharField(max_length=300, null=False) header = models.JSONField(null=True) content = models.JSONField(null=True) link = models.CharField(max_length=200, null=True) canonical = models.CharField(max_length=200, null=True) category = models.ForeignKey(Category, null=False, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Display_Status, null=False, related_name='+', on_delete=models.PROTECT) language = models.ForeignKey(Lang_Choice, null=False, related_name='+', on_delete=models.PROTECT) valid_from = models.DateTimeField(null=True) valid_to = models.DateTimeField(null=True) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'news' class Message_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) title = models.CharField(max_length=200, null=True) title_en = models.CharField(max_length=200, null=True) content = models.TextField(null=False) content_en = models.TextField(null=False) category = models.CharField(max_length=50, null=False) link = models.TextField(null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'message_type' class Message(models.Model): code = models.CharField(max_length=30, null=False, unique=True) ref_code = models.CharField(max_length=20, null=False) type = models.ForeignKey(Message_Type, null=False, related_name='+', on_delete=models.PROTECT) title = models.CharField(max_length=200, null=True) title_en = models.CharField(max_length=200, null=True) content = models.TextField(null=False) content_en = models.TextField(null=False) link = models.TextField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'message' class Message_Receiver(models.Model): message = models.ForeignKey(Message, null=False, related_name='msgrecv', on_delete=models.PROTECT) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Notification_Status, null=False, related_name='+', on_delete=models.PROTECT, default=1) seen = models.BooleanField(default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'message_receiver' unique_together = ('message', 'user') class Schedule_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'schedule_type' class Cycle_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'cycle_type' class Task_Category(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'task_category' class Task_Result(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'task_result' class Alert_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'alert_type' class Script_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'script_type' class Noti_Theme(models.Model): title = models.TextField(null=True) content = models.TextField(null=True) image = models.CharField(max_length=200, null=True) link = models.TextField(null=True) receiver = models.JSONField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'noti_theme' class Group(models.Model): creator = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) name = models.CharField(max_length=100, null=False) note = models.TextField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'group' unique_together = ('creator', 'name') class User_Group(models.Model): group = models.ForeignKey(Group, null=False, related_name='grus', on_delete=models.PROTECT) user = models.ForeignKey(User, null=False, related_name='usgr', on_delete=models.PROTECT) deleted = models.BooleanField(default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'user_group' unique_together = ('group', 'user') #=================================================================== class User_Session(models.Model): token = models.ForeignKey(Token, null=False, related_name='userlog', on_delete=models.PROTECT) session = models.BigIntegerField(null=False) start_time = models.DateTimeField(null=False) end_time = models.DateTimeField(null=True) duration = models.IntegerField(null=True) click_count = models.IntegerField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'user_session' #=================================================================== class User_Log(models.Model): session = models.ForeignKey(User_Session, null=False, related_name='+', on_delete=models.PROTECT) link = models.TextField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'user_log' class Biz_Setting(models.Model): category = models.CharField(max_length=100, null=False) classify = models.CharField(max_length=100, null=False) code = models.CharField(max_length=100, null = False) vi = models.TextField(null=False) en = models.TextField(null=True) image = models.TextField(null=True) icon = models.TextField(null=True) link = models.TextField(null=True) detail = models.JSONField(null=True) detail_en = models.JSONField(null=True) index = models.IntegerField(null=True, default=0) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'biz_setting' unique_together = ('category', 'classify', 'code') class Dealer_Setting(models.Model): category = models.CharField(max_length=100, null=False) classify = models.CharField(max_length=100, null=False) code = models.CharField(max_length=100, null = False) vi = models.TextField(null=False) en = models.TextField(null=True) image = models.TextField(null=True) icon = models.TextField(null=True) link = models.TextField(null=True) detail = models.JSONField(null=True) detail_en = models.JSONField(null=True) index = models.IntegerField(null=True, default=0) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'dealer_setting' unique_together = ('category', 'classify', 'code') class Info_Setting(models.Model): category = models.CharField(max_length=100, null=False) classify = models.CharField(max_length=100, null=False) code = models.CharField(max_length=100, null = False) vi = models.TextField(null=False) en = models.TextField(null=True) image = models.TextField(null=True) icon = models.TextField(null=True) link = models.TextField(null=True) detail = models.JSONField(null=True) detail_en = models.JSONField(null=True) index = models.IntegerField(null=True, default=0) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'info_setting' unique_together = ('category', 'classify', 'code') class Biz_Rights(models.Model): setting = models.ForeignKey(Biz_Setting, null=False, related_name='+', on_delete=models.PROTECT) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'biz_rights' unique_together = ('setting', 'user') class Dealer_Rights(models.Model): setting = models.ForeignKey(Dealer_Setting, null=False, related_name='+', on_delete=models.PROTECT) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'dealer_rights' unique_together = ('setting', 'user') class Group_Rights(models.Model): setting = models.ForeignKey(Biz_Setting, null=False, related_name='+', on_delete=models.PROTECT) group = models.ForeignKey(User_Type, null=False, related_name='+', on_delete=models.PROTECT) is_edit = models.BooleanField(null=True, default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'group_rights' unique_together = ('setting', 'group') class Account_Setting(models.Model): category = models.CharField(max_length=100, null=False) classify = models.CharField(max_length=100, null=False) code = models.CharField(max_length=100, null=False) vi = models.TextField(null=False) en = models.TextField(null=True) image = models.TextField(null=True) icon = models.TextField(null=True) link = models.TextField(null=True) detail = models.JSONField(null=True) detail_en = models.JSONField(null=True) index = models.IntegerField(null=True, default=0) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'account_setting' unique_together = ('category', 'classify', 'code') class Relation(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'relation' class Branch_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'branch_type' class Country(models.Model): code = models.CharField(max_length=30, null=False, unique=False) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'country' class Issued_Place(models.Model): code = models.CharField(max_length=30, null=True, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'issued_place' class Company(AutoCodeModel): code_prefix = "CP" code_padding = 5 code = models.CharField(max_length=20, null=True, unique=True, db_index=True) tax_code = models.CharField(max_length=20, null=True, unique=True) fullname = models.CharField(max_length=300, null=False, db_index=True) shortname = models.CharField(max_length=50, null=True, db_index=True) phone = models.CharField(max_length=20, null=True, db_index=True) email = models.CharField(max_length=50, null=True) website = models.CharField(max_length=100, null=True) country = models.ForeignKey(Country, null=True, related_name='+', on_delete=models.PROTECT, default=1) address = models.CharField(max_length=200, null=True) contact_address = models.CharField(max_length=200, null=True) note = models.TextField(null=True) creator = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) updater = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) deleted = models.BooleanField(null=False, default=False, db_index=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'company' class People(AutoCodeModel): code_prefix = "RE" code_padding = 5 code = models.CharField(max_length=20, null=True, unique=True, db_index=True) fullname = models.CharField(max_length=50, null=False) phone = models.CharField(max_length=20, null=False) email = models.CharField(max_length=100, null=True) dob = models.DateField(null=True) sex = models.ForeignKey(Sex, null=True, related_name='+', on_delete=models.PROTECT) legal_type = models.ForeignKey(Legal_Type, null=True, related_name='+', on_delete=models.PROTECT) legal_code = models.CharField(max_length=20, null=True) issued_date = models.DateField(null=True) issued_place = models.ForeignKey(Issued_Place, null=True, related_name='+', on_delete=models.PROTECT) address = models.CharField(max_length=200, null=True) contact_address = models.CharField(max_length=200, null=True) taxcode = models.CharField(max_length=100, null=True) note = models.TextField(null=True) country = models.ForeignKey(Country, null=True, related_name='+', on_delete=models.PROTECT, default=1) company = models.ForeignKey(Company, null=True, related_name='+', on_delete=models.PROTECT) creator = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) updater = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) deleted = models.BooleanField(null=False, default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'people' class Branch(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) address = models.CharField(max_length=300, null=False) logo = models.CharField(max_length=300, null=True) phone = models.CharField(max_length=20, null=False) email = models.CharField(max_length=100, null=True) note = models.TextField(null=True) type = models.ForeignKey(Branch_Type, null=False, related_name='+', on_delete=models.PROTECT) manager = models.ForeignKey(People, null=True, related_name='+', on_delete=models.PROTECT) signature = models.ForeignKey(People, null=True, related_name='+', on_delete=models.PROTECT) start_date = models.DateField(null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'branch' class Document_Audit(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'document_audit' class Transaction_Phase(models.Model): code = models.CharField(max_length=30, null=True, unique=True) name = models.CharField(max_length=100, null=False) color = models.IntegerField(null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'transaction_phase' class Phase_Doctype(models.Model): phase = models.ForeignKey(Transaction_Phase, null=False, related_name='phasedoc', on_delete=models.PROTECT) doctype = models.ForeignKey(Document_Type, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'phase_doctype' class Customer(AutoCodeModel): code_prefix = "KH" code_padding = 5 code = models.CharField(max_length=20, null=True, unique=True, db_index=True) fullname = models.CharField(max_length=200, null=False, db_index=True) phone = models.CharField(max_length=20, null=False, unique=True, db_index=True) email = models.CharField(max_length=50, null=True, unique=True) legal_type = models.ForeignKey(Legal_Type, null=True, related_name='+', on_delete=models.PROTECT) legal_code = models.CharField(max_length=20, null=True, unique=True) issued_place = models.ForeignKey(Issued_Place, null=True, related_name='+', on_delete=models.PROTECT) issued_date = models.DateField(null=True) country = models.ForeignKey(Country, null=False, related_name='+', on_delete=models.PROTECT) address = models.CharField(max_length=200, null=True) contact_address = models.CharField(max_length=200, null=True) note = models.TextField(null=True) type = models.ForeignKey(Customer_Type, null=False, related_name='+', on_delete=models.PROTECT) dealer = models.ForeignKey(Dealer, null=True, related_name='+', on_delete=models.PROTECT) creator = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) updater = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) deleted = models.BooleanField(null=False, default=False, db_index=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'customer' class Individual(models.Model): customer = models.ForeignKey(Customer, null=False, related_name='indvcust', on_delete=models.PROTECT) dob = models.DateField(null=True) sex = models.ForeignKey(Sex, null=True, related_name='+', on_delete=models.PROTECT) zalo = models.CharField(max_length=20, null=True) facebook = models.CharField(max_length=200, null=True) company = models.ForeignKey(Company, null=True, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'individual' class Organization(models.Model): customer = models.ForeignKey(Customer, null=False, related_name='orgncust', on_delete=models.PROTECT) shortname = models.CharField(max_length=50, null=True) established_date = models.DateField(null=True) website = models.CharField(max_length=200, null=True) bank_account = models.CharField(max_length=50, null=True) bank_name = models.CharField(max_length=100, null=True) type = models.ForeignKey(Company_Type, null=True, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'organization' class Legal_Rep(models.Model): organization = models.ForeignKey(Organization, null=False, related_name='orgrep', on_delete=models.PROTECT) people = models.ForeignKey(People, null=False, related_name='+', on_delete=models.PROTECT) relation = models.ForeignKey(Relation, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'legal_rep' class Transaction(AutoCodeModel): code_prefix = "GD" code_padding = 5 code = models.CharField(max_length=30, null=True, unique=True) customer = models.ForeignKey(Customer, null=False, related_name='txncust', on_delete=models.PROTECT) product = models.ForeignKey(Product, null=False, related_name='txnprd', on_delete=models.PROTECT) policy = models.ForeignKey(Sale_Policy, null=False, related_name='txnplc', on_delete=models.PROTECT) phase = models.ForeignKey(Transaction_Phase, null=False, related_name='+', on_delete=models.PROTECT) date = models.DateField() origin_price = models.DecimalField(max_digits=15, decimal_places=2, null=True) discount_amount = models.DecimalField(max_digits=15, decimal_places=2, null=True) sale_price = models.DecimalField(max_digits=15, decimal_places=2, null=True) deposit_amount = models.DecimalField(max_digits=15, decimal_places=2, null=True) deposit_received = models.DecimalField(max_digits=15, decimal_places=2, null=True) deposit_remaining = models.DecimalField(max_digits=15, decimal_places=2, null=True) amount_received = models.DecimalField(max_digits=15, decimal_places=2, null=True) amount_remain = models.DecimalField(max_digits=15, decimal_places=2, null=True) ovd_days = models.IntegerField(null=True) penalty_amount = models.DecimalField(null=True, max_digits=15, decimal_places=2) early_discount_amount = models.DecimalField(max_digits=15, decimal_places=2, null=True) payment_plan = models.JSONField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction' class Transaction_Detail(AutoCodeModel): code_prefix = "CT" code_padding = 5 code = models.CharField(max_length=30, null=True, unique=True) date = models.DateField() amount = models.DecimalField(max_digits=15, decimal_places=2, null=True) amount_remaining = models.DecimalField(max_digits=15, decimal_places=2, null=True) amount_received = models.DecimalField(max_digits=15, decimal_places=2, null=True) due_date = models.DateField(null=True) customer_old = models.ForeignKey(Customer, null=True, related_name='+', on_delete=models.PROTECT) customer_new = models.ForeignKey(Customer, null=True, related_name='+', on_delete=models.PROTECT) transaction = models.ForeignKey(Transaction, null=False, related_name='resvtxn', on_delete=models.PROTECT) phase = models.ForeignKey(Transaction_Phase, null=False, related_name='+', on_delete=models.PROTECT) creator = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Transaction_Status, null=True, related_name='+', on_delete=models.PROTECT, default=1) approver = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) approve_time = models.DateTimeField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction_detail' class Transaction_Current(models.Model): transaction = models.OneToOneField(Transaction, null=False, related_name='txncurrent', on_delete=models.PROTECT) detail = models.ForeignKey(Transaction_Detail, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction_current' unique_together = ('transaction', 'detail') class Transaction_File(models.Model): txn_detail = models.ForeignKey(Transaction_Detail, null=False, related_name='txnfile', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction_file' unique_together = ('txn_detail', 'file') class Product_Booked(models.Model): product = models.OneToOneField(Product, null=False, related_name='prdbk', on_delete=models.PROTECT) transaction = models.ForeignKey(Transaction, null=False, related_name='transbk', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'product_booked' unique_together = ('product', 'transaction') class Contract_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'contract_status' class Contract(models.Model): transaction = models.ForeignKey(Transaction, null=False, related_name='+', on_delete=models.PROTECT) signature = models.ForeignKey(File, null=True, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Contract_Status, null=True, related_name='+', on_delete=models.PROTECT, default=1) user = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) link = models.UUIDField(default=uuid.uuid4, editable=False, unique=False, null=True) document = models.JSONField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'contract' class Customer_File(models.Model): ref = models.ForeignKey(Customer, null=False, related_name='custfile', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'customer_file' unique_together = ('ref', 'file') class Customer_Note(models.Model): ref = models.ForeignKey(Customer, null=False, related_name='custnote', on_delete=models.PROTECT) detail = models.JSONField(null=False) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'customer_note' class People_File(models.Model): ref = models.ForeignKey(People, null=False, related_name='+', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'people_file' unique_together = ('ref', 'file') class Payment_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'payment_type' class Fee_Method(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'fee_method' class Fee_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) type = models.ForeignKey(Value_Type, null=False, related_name='+', on_delete=models.PROTECT) value = models.FloatField(null=False) method = models.ForeignKey(Fee_Method, null=True, related_name='+', on_delete=models.PROTECT) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'fee_type' class Account_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'account_type' class Internal_Account(models.Model): code = models.CharField(max_length=30, null=False, unique=True) balance = models.FloatField(null=False) type = models.ForeignKey(Account_Type, null=False, related_name='+', on_delete=models.PROTECT) currency = models.ForeignKey(Currency, null=False, related_name='+', on_delete=models.PROTECT) branch = models.ForeignKey(Branch, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'internal_account' unique_together = ('branch', 'type', 'currency') class Account_Book(models.Model): system_date = models.DateField(null=False) account = models.ForeignKey(Internal_Account, null=False, related_name='+', on_delete=models.PROTECT) current_date = models.DateField(null=False) start_balance = models.FloatField(null=True) end_balance = models.FloatField(null=True) credit = models.FloatField(null=True) debit = models.FloatField(null=True) number_credit = models.IntegerField(null=True) number_debit = models.IntegerField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'account_book' unique_together = ('system_date', 'account') class Interest_Base(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=200, null=True) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) detail = models.TextField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'interest_base' class Entry_Type(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'entry_type' class Entry_Category(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'entry_category' class Internal_Entry(AutoCodeModel): code_prefix = "BT" code_padding = 6 code = models.CharField(max_length=30, null=True, unique=True, db_index=True) content = models.TextField(null=False) amount = models.FloatField(null=False) type = models.ForeignKey(Entry_Type, null=False, related_name='+', on_delete=models.PROTECT) category = models.ForeignKey(Entry_Category, null=False, related_name='entrycate', on_delete=models.PROTECT) balance_before = models.FloatField(null=True) balance_after = models.FloatField(null=False) approver = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) inputer = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) account = models.ForeignKey(Internal_Account, null=False, related_name='+', on_delete=models.PROTECT) date = models.DateField(null=False) ref = models.CharField(max_length=30, null=True) customer = models.ForeignKey(Customer, null=True, related_name='+', on_delete=models.PROTECT) product = models.ForeignKey(Product, null=True, related_name='+', on_delete=models.PROTECT) allocation_amount = models.DecimalField(null=True, max_digits=15, decimal_places=2) allocation_detail = models.JSONField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'internal_entry' class Entry_File(models.Model): ref = models.ForeignKey(Internal_Entry, null=False, related_name='entryfile', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'entry_file' unique_together = ('ref', 'file') class Payment_Schedule(AutoCodeModel): code_prefix = "SH" code_padding = 5 code = models.CharField(max_length=30, null=True, unique=True) from_date = models.DateField(null=False) to_date = models.DateField(null=False) amount = models.DecimalField(max_digits=15, decimal_places=2) paid_amount = models.DecimalField(null=True, max_digits=15, decimal_places=2) remain_amount = models.DecimalField(null=True, max_digits=15, decimal_places=2) cycle = models.IntegerField(null=False) cycle_days = models.IntegerField(null=False) txn_detail = models.ForeignKey(Transaction_Detail, null=False, related_name='psh', on_delete=models.PROTECT) type = models.ForeignKey(Payment_Type, null=False, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Payment_Status, null=False, related_name='+', on_delete=models.PROTECT) updater = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) entry = models.JSONField(null=True) detail = models.JSONField(null=True) batch_date = models.DateField(null=True) ovd_days = models.IntegerField(null=True) penalty_amount = models.DecimalField(null=True, max_digits=15, decimal_places=2) penalty_paid = models.DecimalField(null=True, max_digits=15, decimal_places=2) penalty_reduce = models.DecimalField(null=True, max_digits=15, decimal_places=2) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'payment_schedule' class Phone_Otp(models.Model): code = models.CharField(max_length=30, null=False, unique=True) phone = models.CharField(max_length=10, null=False) otp = models.CharField(max_length=10, null=False) valid_to = models.DateTimeField(null=True) expiry = models.BooleanField(default=False) sms_content = models.TextField(null=True) sms_fee = models.IntegerField(null=True) sms_info = models.JSONField(null=True) result = models.ForeignKey(Task_Result, null=True, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Auth_Status, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'phone_otp' class Apps(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) logo = models.CharField(max_length=500, null=True) link = models.CharField(max_length=500, null=True) active = models.BooleanField(default=True) detail = models.TextField(null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'apps' class User_Apps(models.Model): apps = models.ForeignKey(Apps, null=False, related_name='+', on_delete=models.PROTECT) user = models.ForeignKey(User, null=False, related_name='userapps', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'user_apps' unique_together = ('apps', 'user') class Staff_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'staff_status' class Staff(models.Model): code = models.CharField(max_length=20, null=False, unique=True, db_index=True) fullname = models.CharField(max_length=50, null=False, db_index=True) phone = models.CharField(max_length=20, null=False, unique=True, db_index=True) email = models.CharField(max_length=50, null=True, unique=True) dob = models.DateField(null=True) sex = models.ForeignKey(Sex, null=True, related_name='+', on_delete=models.PROTECT) legal_type = models.ForeignKey(Legal_Type, null=True, related_name='+', on_delete=models.PROTECT) legal_code = models.CharField(max_length=20, null=True, unique=True) issued_place = models.CharField(max_length=200, null=True) issued_date = models.DateField(null=True) country = models.ForeignKey(Country, null=False, related_name='+', on_delete=models.PROTECT) province = models.CharField(max_length=200, null=True) district = models.CharField(max_length=200, null=True) address = models.CharField(max_length=200, null=True) note = models.TextField(null=True) zalo = models.CharField(max_length=20, null=True) facebook = models.CharField(max_length=100, null=True) branch = models.ForeignKey(Branch, null=True, related_name='+', on_delete=models.PROTECT) creator = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) deleted = models.BooleanField(null=False, default=False, db_index=True) updater = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) status = models.ForeignKey(Staff_Status, null=False, related_name='+', on_delete=models.PROTECT) user = models.ForeignKey(User, null=True, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'staff' class Customer_People(models.Model): customer = models.ForeignKey(Customer, null=False, related_name='custpeople', on_delete=models.PROTECT) people = models.ForeignKey(People, null=False, related_name='+', on_delete=models.PROTECT) relation = models.ForeignKey(Relation, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'customer_people' unique_together = ('customer', 'people') class Staff_File(models.Model): ref = models.ForeignKey(Staff, null=False, related_name='stafffile', on_delete=models.PROTECT) file = models.ForeignKey(File, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'staff_file' unique_together = ('ref', 'file') class Task_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) en = models.CharField(max_length=100, null=True) index = models.IntegerField(null=True, default=1) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'task_status' class Batch_Log(models.Model): system_date = models.DateField(null=False) start_time = models.DateTimeField(null=False) end_time = models.DateTimeField(null=True) duration = models.IntegerField(null=True) log = models.JSONField(null=True) status = models.ForeignKey(Task_Status, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'batch_log' class Sms(models.Model): session_id = models.CharField(max_length=300, null=False) request_id = models.CharField(max_length=300, null=False) brandname = models.CharField(max_length=20, null=False) phone = models.CharField(max_length=11, null=False) message = models.CharField(max_length=300, null=False) type = models.CharField(max_length=30, null=False) agent = models.CharField(max_length=30, null=False) telco = models.CharField(max_length=30, null=False) status = models.CharField(max_length=30, null=False) price = models.IntegerField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'sms' class Customer_Sms(models.Model): ref = models.ForeignKey(Customer, null=False, related_name='custsms', on_delete=models.PROTECT) sms = models.ForeignKey(Sms, null=False, related_name='+', on_delete=models.PROTECT) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'customer_sms' class Backup(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=200, null=False) file = models.CharField(max_length=200, null=True) status = models.ForeignKey(Task_Status, null=False, related_name='+', on_delete=models.PROTECT) note = models.TextField(null=True) start_time = models.DateTimeField(null=True) end_time = models.DateTimeField(null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'backup' class Ssh(models.Model): name = models.CharField(max_length=300, null=False) host = models.CharField(max_length=30, null=False) port = models.IntegerField(null=False) username = models.CharField(max_length=50, null=False) password = models.CharField(max_length=50, null=False) path = models.CharField(max_length=300, null=False) deleted = models.BooleanField(default=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'ssh' class Document_Configuration(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=200, null=False) template_path = models.CharField(max_length=200, null=False) mappings = models.JSONField (default=list) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'document_configuration' class Import_Setting(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) detail = models.JSONField(null=False) note = models.TextField(null=True) template = models.TextField(null=True) api = models.CharField(max_length=100, null=False) call_api = models.CharField(max_length=100, null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'import_setting' class Layer_Setting(AutoCodeModel): code_prefix = "LS" code_padding = 4 code = models.CharField(max_length=20, null=True, unique=True) name = models.CharField(max_length=200, null=False) detail = models.JSONField(null=False) user = models.ForeignKey(User, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'layer_setting' #========================================================================== class Send_Status(models.Model): code = models.CharField(max_length=30, null=False, unique=True) name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) class Meta: db_table = 'send_status' class Email_Setup(models.Model): email = models.CharField(max_length=100, null=False, unique=True) password = models.CharField(max_length=30, null=False) smtp = models.CharField(max_length=100, null=False) port = models.IntegerField(null=False) display_name = models.CharField(max_length=100, null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'email_setup' class Email_Sent(models.Model): receiver = models.TextField(null=False) subject = models.TextField(null=False) content = models.TextField(null=False) status = models.ForeignKey(Send_Status, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'email_sent' class Email_List(models.Model): name = models.CharField(max_length=200, null=False, unique=True) email = models.TextField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'email_list' class Email_Template(models.Model): name = models.CharField(max_length=200, null=False, unique=True) content = models.JSONField(null=False) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True) class Meta: db_table = 'email_template' class Email_Job(models.Model): name = models.CharField(max_length=200, null=False) model_name = models.CharField(max_length=100, null=False, help_text="e.g., app.Transaction_Detail") template = models.ForeignKey(Email_Template, null=False, related_name='+', on_delete=models.PROTECT) trigger_on_create = models.BooleanField(default=False) trigger_on_update = models.BooleanField(default=False) active = models.BooleanField(default=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'email_job' class Transaction_Discount(models.Model): transaction = models.ForeignKey(Transaction, null=False, related_name='txndiscount', on_delete=models.PROTECT) discount = models.ForeignKey(Discount_Type, null=False, related_name='+', on_delete=models.PROTECT) type = models.ForeignKey(Value_Type, null=False, related_name='+', on_delete=models.PROTECT) value = models.DecimalField(max_digits=15, decimal_places=2, null=True) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'transaction_discount' class Co_Ownership(models.Model): transaction = models.ForeignKey(Transaction, null=False, related_name='co_op', on_delete=models.PROTECT) people = models.ForeignKey(People, null=False, related_name='+', on_delete=models.PROTECT) create_time = models.DateTimeField(null=True, auto_now_add=True) update_time = models.DateTimeField(null=True, auto_now=True) class Meta: db_table = 'co_ownership' unique_together = ('transaction', 'people') class Workflow(models.Model): """ Bảng Workflow: Quản lý các luồng chính (multi-flow cho dự án). Ví dụ: 'RESERVATION' cho giữ chỗ, 'LOAN_APPROVAL' cho duyệt vay. """ code = models.CharField(max_length=50, unique=True) # e.g., 'RESERVATION' name = models.CharField(max_length=200) description = models.TextField(blank=True) is_active = models.BooleanField(default=True) initial_step = models.ForeignKey('StepAction', null=True, blank=True, on_delete=models.SET_NULL, related_name='initial_workflows') create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: db_table = 'workflow' verbose_name = 'Workflow' verbose_name_plural = 'Workflows' def __str__(self): return f"{self.name} ({self.code})" class StepAction(models.Model): """ Bảng Step/Action: Định nghĩa các bước/hành động trong Workflow. Liên kết với Workflow, lưu chi tiết actions (JSON: list of dicts). Ví dụ: Step 'create_reservation' có actions: [{'type': 'create_record', 'model': 'app.Transaction', 'fields': {...}}] """ workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, related_name='steps') step_code = models.CharField(max_length=50, unique=True) # e.g., 'create_reservation', 'approve_detail' name = models.CharField(max_length=200) description = models.TextField(blank=True) order = models.PositiveIntegerField(default=0) # Thứ tự chạy trong workflow trigger_event = models.CharField(max_length=50, choices=[ ('create', 'Create'), ('update', 'Update'), ('approve', 'Approve'), ('advance', 'Advance'), ('confirm', 'Confirm'), ('custom', 'Custom') ]) target_model = models.CharField(max_length=100, blank=True, help_text="Model chính, e.g., 'app.Transaction'") # Actions: List chi tiết hành động (dynamic, multi-model) actions = JSONField(default=list, blank=True) # e.g., [{'type': 'create_record', 'model': 'app.Product', 'fields': {'status': 'reserved'}}] # Config extra: e.g., {'auto_advance': True, 'required_fields': ['customer_id']} config = JSONField(default=dict, blank=True) is_active = models.BooleanField(default=True) create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: db_table = 'step_action' ordering = ['order'] unique_together = ('workflow', 'step_code') verbose_name = 'Step/Action' verbose_name_plural = 'Steps/Actions' def __str__(self): return f"{self.workflow.name} - {self.name} ({self.step_code})" class Rule(models.Model): """ Bảng Rule: Định nghĩa điều kiện (conditions) và quy luật ràng buộc cho Step/Action. Liên kết với StepAction, dùng cho validation/constraints. Ví dụ: Condition: {'field': 'a_a', 'operator': '==', 'value': 'specific_value'} → Chỉ thực hiện nếu match. Constraint: {'after_action': 'create_record', 'must_update': {'model': 'app.Product', 'field': 'status', 'to': 'reserved'}} """ step_action = models.ForeignKey(StepAction, on_delete=models.CASCADE, related_name='rules') rule_code = models.CharField(max_length=50, unique=True) # e.g., 'validate_customer_vip' name = models.CharField(max_length=200) description = models.TextField(blank=True) # Conditions: List conditions để check trước action conditions = JSONField(default=list, blank=True) # e.g., [ # {'field': 'customer__segment__code', 'operator': '==', 'value': 'VIP', 'related_model': 'app.Customer'}, # {'field': 'amount', 'operator': '>=', 'value': 1000000}] # Constraints: Quy luật sau/before action (ràng buộc) constraints = JSONField(default=list, blank=True) # e.g., [ # {'trigger': 'after_create', 'type': 'must_update', 'model': 'app.Transaction_Detail', 'fields': {'status': 'new'}}, # {'trigger': 'before_approve', 'type': 'require_approval', 'min_count': 2}] # Utility linkage: Liên kết với Utility nếu cần reuse utility = models.ForeignKey('Utility', null=True, blank=True, on_delete=models.SET_NULL, related_name='rules') is_active = models.BooleanField(default=True) create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: db_table = 'rule' unique_together = ('step_action', 'rule_code') verbose_name = 'Rule' verbose_name_plural = 'Rules' def __str__(self): return f"{self.step_action.name} - {self.name} ({self.rule_code})" class Utility(models.Model): """ Bảng Utility: Chứa các action có sẵn, liên kết với hệ thống khác (e.g., API mail, CRUD data). Dùng để reuse trong StepAction/Rule (e.g., gửi mail → gọi send_email API; create record → gọi /data/ endpoint). """ code = models.CharField(max_length=50, unique=True) # e.g., 'SEND_EMAIL', 'CRUD_DATA' name = models.CharField(max_length=200) description = models.TextField(blank=True) # Type: Phân loại utility (e.g., 'email', 'crud', 'payment') utility_type = models.CharField(max_length=50, choices=[ ('email', 'Email API'), ('crud', 'Data CRUD'), ('payment', 'Payment API'), ('document', 'Document Gen'), ('notification', 'Notification'), ('custom', 'Custom') ]) # Endpoint/API linkage: e.g., {'url': '/send-email/', 'method': 'POST', 'params': {'template': '[template]'}} api_config = JSONField(default=dict, blank=True) # Config gọi API (dynamic placeholders như [user_id]) # Params template: Mẫu params khi gọi params_template = JSONField(default=dict, blank=True) # e.g., {'receiver': '[customer_email]', 'subject': 'Approval'} # External integration: e.g., liên kết với Email_Job hoặc account_entry_api integration_module = models.CharField(max_length=100, blank=True, help_text="e.g., 'app.email.send_email'") is_active = models.BooleanField(default=True) create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: db_table = 'utility' verbose_name = 'Utility' verbose_name_plural = 'Utilities' def __str__(self): return f"{self.name} ({self.code}) - Type: {self.utility_type}" class Batch_Job(models.Model): name = models.CharField(max_length=255) workflow = models.ForeignKey(Workflow, on_delete=models.PROTECT, help_text="Workflow to execute") cron_schedule = models.CharField(max_length=100, help_text="Cron-like schedule (e.g., '0 0 * * *' for daily at midnight)") parameters = models.JSONField(default=dict, blank=True, help_text="Parameters to find data for the workflow context") is_active = models.BooleanField(default=True, db_index=True) last_run_at = models.DateTimeField(null=True, blank=True) next_run_at = models.DateTimeField(null=True, blank=True, db_index=True) create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Meta: db_table = 'batch_job'