File: "base_models.py"
```
import datetime as dtLib

from django.db import models
from django.contrib.auth import get_user_model


User = get_user_model()


class TrackableDateModel(models.Model):
    """Abstract model to Track the creation/updated date for a model."""
    # Ask https://stackoverflow.com/questions/78263861/can-i-declare-two-foreignkey-to-the-same-table-in-one-django-orm-abstract-model
    create_date = models.DateTimeField(auto_now_add=True, help_text="Время создания", verbose_name="Созданно", null=True, blank=True)
    create_user = models.ForeignKey(User, related_name="create_user_%(app_label)s_%(class)s_related", on_delete=models.CASCADE, help_text="Кто создал", verbose_name="Автор", null=True, blank=True)
    update_date = models.DateTimeField(auto_now=True, help_text="Время изменения", verbose_name="Изменено", null=True, blank=True)
    update_user = models.ForeignKey(User, related_name="update_user_%(app_label)s_%(class)s_related", on_delete=models.CASCADE, help_text="Кто изменял", verbose_name="Автор изменений", null=True, blank=True)

    class Meta:
        abstract = True


class BaseShop(models.Model):
    '''Модель (ДЛЯ ПАРСЕРА ТОЛЬКО?) магазинов'''
   
    # class ShopType(models.TextChoices):
    #     '''Model for choice shop'''
    #     DISCAUNTER  = 'D', _('Дискаунтер') # 'D'
    #     FRESHMARKET = 'F', _('Фрешмаркет')  # 'F'
    #     SUPERSTOR   = 'S', _('Суперстор' )  # 'S'
    #     UNKNOWN     = 'U', _('НЕТ ДАННЫХ')
        # SHOP_TYPES = [(DISCAUNTER, 'Дискаунтер'), (FRESHMARKET, 'Фрешмаркет'), (SUPERSTOR, 'Суперстор'),] # FIXME USE DICT WHEN UPDATE TO DJANGO 5.2

        # @staticmethod
        # def getShopType(shop_type: str):
        #     '''Return ShopTypeType from str'''
        #     for s in Shops.ShopType.choices:
        #         if s[0] == shop_type:
        #              return s[0]

    sheet_row_idx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True) # DEPRECATED
    shop_index = models.IntegerField(help_text="Порядковый номер магазина", verbose_name="SN", unique=True, null=True)           # DEPRECATED
    shop_code = models.CharField(max_length=50, help_text="Код Торговой Точки", verbose_name="Код ТТ", unique=True, null=True, blank=True)
    shop_type = models.CharField(max_length=50, null=True, blank=True, help_text="Формат Торговой Точки", verbose_name="Формат",) #, choices=ShopType.choices, # FIXME LENGHT MUST BE 1 !!! #  models.CharField(max_length=1, choices=SHOP_TYPES,  null=True, blank=True, )
    shop_director = models.CharField(max_length=500, help_text="Данные директора магазина", null=True, blank=True, verbose_name="Директор")
    workplace_address = models.CharField(max_length=500, help_text="Адрес Торговой Точки", null=True, blank=True, verbose_name="Адрес ТТ")
    priority = models.BooleanField(help_text="Приоритетная ТТ?", verbose_name="Приоритет", default=False)
    shop_region = models.ForeignKey('Locations', on_delete = models.PROTECT, help_text="Направление обслуживания", verbose_name="Регион", null=True, blank=True)
    # user = models.OneToOneField(User, on_delete=models.PROTECT, help_text="Связь с аккаунтом", null=True, blank=True) #### FIXME NOW null must be false

    class Meta:
        ordering = ["shop_code"]
        abstract = True

    def __unicode__(self):
        return self.shop_code

    def __str__(self):
        return self.shop_code


class BaseShopUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.PROTECT, unique=True)

    class Meta:
        abstract = True


class BaseWorkSheets(TrackableDateModel): 
    created = models.DateTimeField(auto_now_add=True, null=True,  # FIXME
        help_text="Дата создания заявки", verbose_name="TimeStamp") # DEPRECATED FIXME NEED DELETE
    date_for_work = models.DateField(auto_now=False,  default=dtLib.date(1970, 1, 1),  # null=True,  # FIXME
        help_text="Дата начала работы", verbose_name="Дата заявки")
    lying_worker_id = models.IntegerField(help_text="Табельный номер сотрудника в заявке", verbose_name="Табельный номер", null=True, blank=True) #default=Workers.get_default_pk()) # FIXME
    start_work = models.TimeField(auto_now=False,    default=dtLib.time(0,0,0),   # null=True,  # FIXME
        help_text="Время начала заявки", verbose_name="Начало заявки")
    end_work = models.TimeField(auto_now=False,   default=dtLib.time(0,0,0),  # null=True,  # FIXME
        help_text="Время окончиания заявки", verbose_name="Конец заявки")
    confirmation_app = models.BooleanField(help_text="Подтверждение заявки магазином", verbose_name="Подтверждение заявки", default=False) #CharField(max_length=50, help_text="Подтверждение заявки", null=True, blank=True, verbose_name="Подтверждение") # FIXME IS NEED IT ME HERE OR 121 IN ANOTHER TABLE?
    workplace_app_note = models.CharField(max_length=1000, help_text="Пояснение по видам работ", null=True, blank=True, verbose_name="Пояснение работы")
    workplace_note = models.CharField(max_length=1000, help_text="Примечание от ТТ", null=True, blank=True, verbose_name="Примечание") # ALL NOTE MUST BE OneToOne!!!
    time_last_change_note_by_shop = models.DateTimeField(auto_now=False, null=True, blank=True, help_text="Время последнего изменения комментария", verbose_name="Время коментария магазина")  # ALL NOTE MUST BE OneToOne!!!
    note_from_SR = models.CharField(max_length=500, help_text="Ответ от контрагента", null=True, blank=True, verbose_name="Ответ для ТТ") # ALL NOTE MUST BE OneToOne!!!
    is_cancel = models.BooleanField(help_text="Отмена заявки магазином", verbose_name="Отмена заявки", default=False)

    class Meta:
        ordering = ["date_for_work"]
        abstract = True

        # FIX IT PLEASE!!!
        indexes = [ models.Index(fields=['lying_worker_id']), 
                    models.Index(fields=['date_for_work']),
                    models.Index(fields=['date_for_work', 'shop_code']),
                    models.Index(fields=['shop_code']),
                    models.Index(fields=['created']),
                    ]

    def __str__(self):
        return f'id={self.id} {self.date_for_work} на {self.shop_code} с {self.start_work} по {self.end_work} для {self.lying_worker_id}' 


class BaseTimeSheets(TrackableDateModel):
    '''#### FIXME'''
    timestamp = models.DateTimeField(auto_now_add=True,  null=True,  # FIXME
        help_text="Дата создания ЛУВРа", verbose_name="TimeStamp", ) # DEPRECATED FIXME NEED DELETE
    start_work = models.TimeField(auto_now=False,  default=dtLib.time(0,0,0),  #### FIXME
        help_text="Время начала работы", verbose_name="Время, в которое работник приступил к выполнению работы")
    end_work = models.TimeField(auto_now=False,  default=dtLib.time(0,0,0),    #### FIXME
        help_text="Время окончиания заявки", verbose_name="Время, в которое работник окончил выполнение работы")
    # Actual paid time. AutoGenerated. # FIXME Need to find out how it is rounded
    amount_of_work_time = models.DecimalField(help_text="Количество оплачиваемых часов", verbose_name="Часы работы",
                                              max_digits=3, decimal_places=1, default=0) # DEFAULT = 0 (???) # FIXME
    grade = models.ForeignKey('Grades', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Оценка выполненной работы", verbose_name="Оценка") 
    is_worker_skip_work = models.BooleanField(help_text="Сотрудник не вышел на работу", verbose_name="Прогул?", null=True, blank=True)
    
    class Meta:
        abstract = True
        # FIXME ARE YOU REALY NEED THIS INDEXES?
        indexes = [ models.Index(fields=['worker_id']), 
                    models.Index(fields=['grade']),]
  

class BaseExport4Payment(TrackableDateModel):
    date_exported_to_excel = models.DateTimeField(auto_now_add=True, help_text="Дата Выгрузки", verbose_name="Дата выгрузки в excel", null=True, blank=True) # DEPRECATED FIXME NEED DELETE
    is_exported = models.BooleanField(help_text="Выгружено?", verbose_name="Выгружено?", default=False)
    
    class Meta:
        abstract = True


class BaseWorkers(TrackableDateModel):    
    """    Parse Google Sheets Table with work employee     """
    sheet_row_idx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True)
    worker_id = models.IntegerField(help_text="Табельный номер сотрудника", verbose_name="Табельный номер", unique=True) 
    worker_full_name = models.CharField(max_length=500, help_text="ФИО сотрудника", verbose_name="ФИО")
    # workerPhone = models.CharField(max_length=50, help_text="Номер телефона сотрудника", null=True, blank=True, verbose_name="Номер телефона") # FIXME INTEGERFIELD
    # workerPhoneFormula = models.CharField(max_length=200, null=True, blank=True,
    #             help_text="Формула для звонка сотруднику (заполняется автоматически)",
    #             verbose_name="Формула номера телефона") # FIXME (Что-то придумать тут)
    # workerBirthDate = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, 
    #                                        help_text="Дата рождения сотрудника", verbose_name="Дата Рождения")
    # workerPassportRegistration = models.CharField(max_length=500, help_text="Прописка сотрудника", null=True, blank=True, verbose_name="Прописка")
    # noteAboutWorker = models.CharField(max_length=1000, help_text="Примечание", null=True, blank=True, verbose_name="Примечание")
    # avaibleWorkForWorkers =  models.CharField(max_length=500, help_text="Профессия сотрудника", null=True, blank=True, verbose_name="Должности")
    # workerPassportNumber = models.CharField(max_length=50, help_text="Серия и номер пасспорта сотрудника", null=True, blank=True, verbose_name="Серия Номер пасспорта")    # FIXME?
    # placeOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Место выдчи пасспорта", null=True, blank=True, verbose_name="Пасспорт выдан")
    # idPlaceOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Код подразделения", null=True, blank=True, verbose_name="Код подразделения")
    # workersHireDate = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, 
    #                                        help_text="Дата найма сотрудника", verbose_name="Нанят")
    # workerLivePlace = models.CharField(max_length=500, help_text="Приоритетный район для поиска работы", null=True, blank=True, verbose_name="Район проживания") # FIXME FK TO LOCALS?
    # workersBankDetails = models.CharField(max_length=500, help_text="Платежные реквизиты сотрудника", null=True, blank=True, verbose_name="Банковские реквизиты")
    date_Of_Dismissal = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, help_text="Дата увольнения сотрудника", verbose_name="Дата увольнения")
    payment_type = models.ForeignKey('PaymentType', on_delete = models.PROTECT, help_text="Кто оплачивает", verbose_name="Оплата", null=True, blank=True)
    INN = models.CharField(max_length=200, help_text="ИНН Сотрудника", null=True, blank=True, verbose_name="ИНН") # FIXME INTEGER?
    # countWorkerIDFromGSheets = models.CharField(max_length=2, help_text="Количество повторов табельного номера", null=True, blank=True, verbose_name="Количество повторов табельного номера") # FIXME MUST AUTOCOUNT

    class Meta:
        abstract = True
        indexes = [ models.Index(fields=['worker_id']), 
                    models.Index(fields=['worker_full_name']),]
    # @classmethod
    # def get_default_pk(cls):
    #     worker, created = cls.objects.get_or_create(worker_id=0, defaults={'workerFullName': 'Несуществующий сотрудник', 'rawRowIdx' : 0},)
    #     return worker.pk

    # def get_absolute_url(self):
    #      return reverse('model-detail-view', args=[str(self.worker_id)])

    def __str__(self):
        return f"{self.worker_id}: {self.worker_full_name}"


### TABLE 4 RELATIONS
class BaseTypeOfWork(models.Model):
    type_of_work = models.CharField(help_text="Название вакансии", verbose_name="Тип", 
                                  max_length=500, unique=True, default="FIXME!")
    location = models.ForeignKey('Locations', on_delete = models.SET_NULL, blank=True, null=True)

    class Meta:
        abstract = True
        ordering = ["id"]

    def __unicode__(self):
        return str(self.type_of_work)

    def __str__(self):
        return str(self.type_of_work)
```



File: "models.py"
```
# import time as timeLib
# import datetime as dtLib

from django.db import models
# from django.contrib.auth.models import User # 4 Extending
from django.contrib.auth import get_user_model
# from django.utils.translation import gettext_lazy as _
from auditlog.registry import auditlog

from .base_models import TrackableDateModel, BaseWorkSheets, BaseTimeSheets, BaseExport4Payment, BaseWorkers, BaseTypeOfWork, BaseShop, BaseShopUser


User = get_user_model()


class KShop(BaseShop):
    pass


class KShopUser(BaseShopUser):
    shop = models.ForeignKey(KShop, related_name="shopuser_%(app_label)s_%(class)s_related", on_delete=models.CASCADE)


### Komandor Worker Table
class KWorkSheets(BaseWorkSheets):
    work_type = models.ForeignKey('KTypeOfWork', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Название вакансии", verbose_name="Вид Работ")
    shop_code = models.ForeignKey('KShop', related_name="worksheets_shop_code_%(app_label)s_%(class)s_related", on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Код Торговой Точки", verbose_name="Код ТТ")

class KTimeSheets(BaseTimeSheets):
    workSheet = models.OneToOneField('KWorkSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)
    worker_id = models.ForeignKey('KWorkers', related_name="timesheets_worker_id_%(app_label)s_%(class)s_related", on_delete = models.PROTECT, null=True,
        help_text="Табельный номер работавшего сотрудника", verbose_name="Табельный номер") #default=Workers.get_default_pk()) #### FIXME worker_id must be null=False, blank=False


class KExport4Payment(BaseExport4Payment):
    timesheet = models.OneToOneField('KTimeSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)


class KWorkers(BaseWorkers):
    pass


class KTypeOfWork(BaseTypeOfWork):
    pass


### Security Service Komandor Table
class SSWorkSheets(BaseWorkSheets):
    work_type = models.ForeignKey('SSTypeOfWork', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Название вакансии", verbose_name="Вид Работ")
    shop_code = models.ForeignKey('KShop', related_name="worksheets_shop_code_%(app_label)s_%(class)s_related", on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Код Торговой Точки", verbose_name="Код ТТ")


class SSTimeSheets(BaseTimeSheets):
    workSheet = models.OneToOneField('SSWorkSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)
    worker_id = models.ForeignKey('SSWorkers', related_name="timesheets_worker_id_%(app_label)s_%(class)s_related", on_delete = models.PROTECT, null=True,
        help_text="Табельный номер работавшего сотрудника", verbose_name="Табельный номер") #default=Workers.get_default_pk()) #### FIXME worker_id must be null=False, blank=False


class SSExport4Payment(BaseExport4Payment):
    timesheet = models.OneToOneField('SSTimeSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)


class SSWorkers(BaseWorkers):
    pass


class SSTypeOfWork(BaseTypeOfWork):
    pass


### Razgulay Worker Table
class RazgulayShop(BaseShop):
    pass


class RazgulayShopUser(BaseShopUser):
    shop = models.ForeignKey(RazgulayShop, related_name="shopuser_%(app_label)s_%(class)s_related", on_delete=models.CASCADE)


class RazgulayWorkSheets(BaseWorkSheets):
    work_type = models.ForeignKey('RazgulayTypeOfWork', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Название вакансии", verbose_name="Вид Работ")
    shop_code = models.ForeignKey('RazgulayShop', related_name="worksheets_shop_code_%(app_label)s_%(class)s_related", on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Код Торговой Точки", verbose_name="Код ТТ")


class RazgulayTimeSheets(BaseTimeSheets):
    workSheet = models.OneToOneField('RazgulayWorkSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)
    worker_id = models.ForeignKey('RazgulayWorkers', related_name="timesheets_worker_id_%(app_label)s_%(class)s_related", on_delete = models.PROTECT, null=True,
        help_text="Табельный номер работавшего сотрудника", verbose_name="Табельный номер") #default=Workers.get_default_pk()) #### FIXME worker_id must be null=False, blank=False


class RazgulayExport4Payment(BaseExport4Payment):
    timesheet = models.OneToOneField('RazgulayTimeSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)


class RazgulayWorkers(BaseWorkers):
    pass


class RazgulayTypeOfWork(BaseTypeOfWork):
    pass


class Locations(models.Model):
    location = models.CharField(help_text="Направление обслуживания", verbose_name="Направление", 
                                max_length=500, unique=True, default="Красноярск") # FIXME DEFAULT WTF?
    payment_prefix = models.CharField(help_text="Префикс для таблиц оплаты", verbose_name="Префикс", 
                                max_length=500, unique=True, null=True, blank=True) # FIXME DEFAULT WTF?

    def __unicode__(self):
        return str(self.location)

    def __str__(self):
        return str(self.location)


class Grades(models.Model):
    grade_num = models.IntegerField(help_text="Оценка (цифра, используется для формул)", verbose_name="Оценка", unique=True)
    grade_desc = models.CharField(help_text="Отображаемый текст оценки", verbose_name="Текст оценки", max_length=100, unique=True)

    class Meta:
        ordering = ["-grade_num"]

    def __unicode__(self):
        return str(f'{self.grade_num}) {self.grade_desc}')

    def __str__(self):
        return str(f'{self.grade_num}) {self.grade_desc}')


class PaymentType(models.Model):
    payment_type = models.CharField(max_length=100, help_text="Кто и как оплачивает", null=True, blank=True, verbose_name="Кто оплачивает")    # FIXME FK?

    def __unicode__(self):
        return str(f'{self.payment_type}')

    def __str__(self):
        return str(f'{self.payment_type}')


class ExtendAccount(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    last_filter_data = models.JSONField(default=dict)
    last_sort_data   = models.JSONField(default=list)
    changed_password = models.CharField(max_length=128, null=True, blank=True,)

    # @staticmethod
    # def get_default_filter():
    #     return {'filter': {}, 'sort': []}


auditlog.register(KWorkSheets)
auditlog.register(KTimeSheets)
auditlog.register(KExport4Payment)
auditlog.register(KWorkers)
auditlog.register(SSWorkSheets)
auditlog.register(SSTimeSheets)
auditlog.register(SSExport4Payment)
auditlog.register(SSWorkers)
auditlog.register(RazgulayWorkSheets)
auditlog.register(RazgulayTimeSheets)
auditlog.register(RazgulayExport4Payment)
auditlog.register(RazgulayWorkers)

############################################################
### TARIFFS
############################################################
# class BaseTarif(models.Model):
#     '''# FIXME '''
#     # kontr_agent = models.ForeignKey('KontrAgent', on_delete = models.SET_NULL, blank=True, null=True) # FIXME
#     location = models.ForeignKey('Locations', on_delete = models.SET_NULL, blank=True, null=True)
#     work_type = models.ForeignKey('TypeOfWork', on_delete = models.SET_NULL, blank=True, null=True)
#     taxation_type = models.ForeignKey('TypeOfTaxation', on_delete = models.SET_NULL, blank=True, null=True,)
#     сounterparty_payment = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Оплата за ед. от контрагента", verbose_name="Доход", )
#     employee_payment     = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Оплата за ед. сотруднику",     verbose_name="Расход",)


# class PersonalBonus(models.Model):
#     bonus = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Для штрафа поставьте знак минус",     verbose_name="Премия", )
#     timesheet = models.OneToOneField('TimeSheets', on_delete=models.CASCADE)


# class GradeBonus(models.Model):
#     # kontr_agent = models.ForeignKey('KontrAgent', on_delete = models.SET_NULL, blank=True, null=True) # FIXME
#     location = models.ForeignKey('Locations', on_delete = models.SET_NULL, blank=True, null=True)
#     grade = models.ForeignKey('Grade', on_delete = models.SET_NULL, blank=True, null=True)
#     taxation_type = models.ForeignKey('TypeOfTaxation', on_delete = models.SET_NULL, blank=True, null=True,)
#     bonus = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Для штрафа поставьте знак минус",     verbose_name="Премия", )


# class TypeOfTaxation(models.Model):
#     taxation_type = models.CharField(help_text="Как трудоустроен сотрудник", verbose_name="Вид договора (самозанятый?)", max_length=100, unique=True)











# class ExtendsShopManagerAccounts(models.Model):
#     user = models.OneToOneField(User, on_delete=models.CASCADE)
#     snShop = models.OneToOneField('Shops', on_delete=models.CASCADE)


# class ViUsers(models.Model):
#     """    Viber Users and base information about chats    """, 
#     viberChatID = models.CharField(max_length=24, unique=True, null=True,
#                                    help_text="ID чата с этим вибер-аккаунтом",
#                                    verbose_name="ID Чата Вибер") # FIXME (Мне хватит символов?)
#     # DEFAULT_BIG_BANG_TIME = dtLib.datetime(dtLib.datetime.min.year,    # FIXME ?
#     #                                             dtLib.datetime.min.month,    # IS IT NEED ME?
#     #                                             dtLib.datetime.min.day, 
#     #                                             dtLib.datetime.min.hour, 
#     #                                             dtLib.datetime.min.minute)   
#     timeSubscribe = models.DateTimeField(auto_now=False, auto_now_add=True, null=True, blank=True,
#                                          help_text="Время первого сообщения с этим вибер-аккаунтом", 
#                                          verbose_name="Подписан",  )
#     timeUnSubscribe = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, 
#                                            help_text="Время отписки",
#                                            verbose_name="Отписан")
#     JUST_WORKER                 = 'JW'
#     ABSOLUTE_ADMINISTRATOR      = 'AA'
#     SPECRESURS_MANAGER          = 'SR'
#     KOMMANDORS_MANAGER          = 'KM'
#     viROLEList = [(JUST_WORKER,                'WORKER'),
#                   (ABSOLUTE_ADMINISTRATOR,     'ADMIN'),
#                   (SPECRESURS_MANAGER,         'SR_MANAGER'),
#                   (KOMMANDORS_MANAGER,         'KOMMANDORS_MANAGER')]
#     viROLE = models.CharField(max_length=2, help_text="Роль", choices=viROLEList, default=JUST_WORKER, verbose_name="Роль") # IT'S MUST BE AT SHEET? FIXME 

# class Meta:
#     ordering = ["-timeSubscribe"]

# def get_absolute_url(self):
#      return reverse('model-detail-view', args=[str(self.id)])

# def __str__(self):
#     return f'Chat = "{self.viberChatID}"'

# def addNewUser(self, ChatID, viROLE=JUST_WORKER): # GOOD IDEA  BAD IMPLEMENTATION # FIXME
#     self.viberChatID = str(ChatID)
#     self.viROLE = viROLE
#     # self.workerID = wID_FK # FIXME
#     self.save()


# class ViUserMessage(models.Model):
#     '''ViberUser Message's'''
#     ViUserID = models.ForeignKey('ViUsers', on_delete = models.SET_NULL, null=True, blank=True)
#     lastMessageID = models.BigIntegerField(help_text="ID последнего сообщения с этим вибер-аккаунтом", 
#                                      null=True, blank=True, verbose_name="ID посл. сообщ. Вибер") # FIXME (Это сломается, если у вибера uint64 тут... BigIntegerField -- это int64!!! (В 2 раза меньше max_int)
#     timeLastMessage = models.DateTimeField(auto_now=False, auto_now_add=True,
#                                            help_text="Время последнего сообщения с этим вибер-аккаунтом", null=True, blank=True, verbose_name="Время последнего сообщения")

#     def get_absolute_url(self):
#         return reverse('model-detail-view', args=[str(self.ViUserID)])

#     def __str__(self):
#         return f'Chat = "{self.ViUserID}"   MID = "{self.lastMessageID}"    TMID = "{self.timeLastMessage}"'
#     # In THIS (??) PLACE NEED SAVE MESSAGES_FROM_USER_TO_BOT AND MESSAGES_FROM_BOT_TO_USER     # FIXME 



# class DUTY_Workers(models.Model):    
#     """    Parse Google Sheets Table with work employee     """
#     rawRowIdx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True)
#     workerID = models.CharField(max_length=50, help_text="Табельный номер сотрудника", null=True, blank=True, verbose_name="Табельный номер") 
#     workerFullName = models.CharField(max_length=100, help_text="ФИО сотрудника", null=True, blank=True, verbose_name="ФИО")
#     workerPhone = models.CharField(max_length=50, help_text="Номер телефона сотрудника", null=True, blank=True, verbose_name="Номер телефона")
#     workerPhoneFormula = models.CharField(max_length=200, help_text="Формула для звонка сотруднику (заполняется автоматически)", null=True, blank=True, verbose_name="Формула номера телефона") # FIXME (Что-то придумать тут)
#     workerBirthDate = models.CharField(max_length=50, help_text="Дата рождения сотрудника", null=True, blank=True, verbose_name="Дата рождения")
#     workerPassportRegistration = models.CharField(max_length=500, help_text="Прописка сотрудника", null=True, blank=True, verbose_name="Прописка")
#     noteAboutWorker = models.CharField(max_length=1000, help_text="Примечание", null=True, blank=True, verbose_name="Примечание")
#     avaibleWorkForWorkers =  models.CharField(max_length=500, help_text="Профессия сотрудника", null=True, blank=True, verbose_name="ID Чата Вибер")
#     workerPassportNumber = models.CharField(max_length=50, help_text="Серия и номер пасспорта сотрудника", null=True, blank=True, verbose_name="Серия Номер пасспорта")
#     placeOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Место выдчи пасспорта", null=True, blank=True, verbose_name="Пасспорт выдан")
#     idPlaceOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Код подразделения", null=True, blank=True, verbose_name="Код подразделения")
#     workersHireDate = models.CharField(max_length=50, help_text="Дата найма сотрудника", null=True, blank=True, verbose_name="Дата найма")
#     workerLivePlace = models.CharField(max_length=500, help_text="Приоритетный район для поиска работы", null=True, blank=True, verbose_name="Район проживания")
#     workersBankDetails = models.CharField(max_length=500, help_text="Платежные реквизиты сотрудника", null=True, blank=True, verbose_name="Банковские реквизиты")
#     dateOfDismissal = models.CharField(max_length=50, help_text="Дата увольнения сотрудника", null=True, blank=True, verbose_name="Дата увольнения")
#     paymentType = models.CharField(max_length=500, help_text="Кто и как оплачивает", null=True, blank=True, verbose_name="Кто оплачивает")
#     INN = models.CharField(max_length=200, help_text="ИНН Сотрудника", null=True, blank=True, verbose_name="ИНН")
#     countWorkerIDFromGSheets = models.CharField(max_length=2, help_text="Количество повторов табельного номера", null=True, blank=True, verbose_name="Количество повторов табельного номера")


# def get_absolute_url(self):
#      return reverse('model-detail-view', args=[str(self.workerID)])

# def __str__(self):
#     return self.workerFullName


# class RAWKommandorWorksFromGSheets(models.Model):    
#     """    Parse Google Sheets Table with works    """
#     rawRowIdx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True) 
#     timeStamp = models.CharField(max_length=50, help_text="Время заполнения заявки", null=True, blank=True, verbose_name="Отметка времени")
#     dateForWork = models.CharField(max_length=50, help_text="Дата начала работы", null=True, blank=True, verbose_name="Дата заявки")
#     workerID = models.CharField(max_length=50, help_text="Табельный номер сотрудника в заявке", null=True, blank=True, verbose_name="Табельный номер")
#     workerFullName = models.CharField(max_length=500, help_text="ФИО сотрудника", null=True, blank=True, verbose_name="ФИО")
#     workType = models.CharField(max_length=500, help_text="Название вакансии", null=True, blank=True, verbose_name="Вид Работ")
#     startTimeWork = models.CharField(max_length=50, help_text="Время начала заявки", null=True, blank=True, verbose_name="Начало заявки")
#     endTimeWork = models.CharField(max_length=50, help_text="Время окончиания заявки", null=True, blank=True, verbose_name="Конец заявки")
#     amountOfWorkTime = models.CharField(max_length=50, help_text="Количество часов в заявке", null=True, blank=True, verbose_name="К-во часов в заявке")
#     workPlaceName = models.CharField(max_length=50, help_text="Код Торговой Точки", null=True, blank=True, verbose_name="Код ТТ")
#     workPlaceType = models.CharField(max_length=50, help_text="Тип Торговой Точки", null=True, blank=True, verbose_name="Тип ТТ")
#     workPlaceAddress = models.CharField(max_length=500, help_text="Адрес Торговой Точки", null=True, blank=True, verbose_name="Адрес ТТ")
#     closingConfirmation = models.CharField(max_length=50, help_text="Подтверждение заявки", null=True, blank=True, verbose_name="Подтверждение")
#     workPlaceNote = models.CharField(max_length=1000, help_text="Примечание от магазина", null=True, blank=True, verbose_name="Примечание")
#     ourNote = models.CharField(max_length=500, help_text="Ответ от контрагента", null=True, blank=True, verbose_name="Ответ для ТТ")
#     lastTimeWorkPlaceNoteChange = models.CharField(max_length=50, help_text="Время последнего изменения комментария", null=True, blank=True, verbose_name="Время коментария магазина")
#     INN = models.CharField(max_length=100, help_text="ИНН Сотрудника", null=True, blank=True, verbose_name="ИНН")
#     theCreatorID = models.CharField(max_length=50, help_text="ID Творца", null=True, blank=True, verbose_name="ID Творца")
#     serialNumberForMe = models.IntegerField(help_text="Серийный номер придуманный мной", verbose_name="S/N Заявки", unique=True, null=True) 

#     def getKommandorDataFromGSheets():
#         pass

#     def get_absolute_url(self):
#          return reverse('model-detail-view', args=[str(self.id)])

#     def __str__(self):
#         return f'{self.dateForWork} на {self.workPlaceName} для {self.workerID}'


# class WorkPlacesFromGSheets(models.Model): 
#     """    Parse Google Sheets Table with Work Places    """
#     sheetsID = models.CharField(max_length=3, help_text="Порядковый номер торговой точки в таблице", null=True, blank=True, verbose_name="ID ТТ")
#     workPlaceName = models.CharField(max_length=20, help_text="Код Торговой Точки", null=True, blank=True, verbose_name="Код ТТ")
#     workPlaceType = models.CharField(max_length=19, help_text="Тип Торговой Точки", null=True, blank=True, verbose_name="Тип ТТ")
#     workPlaceDirector = models.CharField(max_length=100, help_text="ФИО и номер директора ТТ", null=True, blank=True, verbose_name="Директор")
#     workPlaceAddress = models.CharField(max_length=19, help_text="Адрес Торговой Точки", null=True, blank=True, verbose_name="Адрес ТТ")

#     def getWorkPlacesFromGsheets():
#         pass

#     def get_absolute_url(self):
#          return reverse('model-detail-view', args=[str(self.workPlaceName)])

#     def __str__(self):
#         return str(self.workPlaceName)


# class RAWKommandorEmployeeTimeSheetFromGSheets(models.Model):    
#     """    Parse Google Sheets Table with Employeers TimeSheets    """
#     rawRowIdx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True) 
#     timeStamp = models.CharField(max_length=50, help_text="Время заполнения заявки", null=True, blank=True, verbose_name="Отметка времени")
#     dateForWork = models.CharField(max_length=50, help_text="Дата начала работы", null=True, blank=True, verbose_name="Дата заявки")
#     workPlaceName = models.CharField(max_length=50, help_text="Код Торговой Точки", null=True, blank=True, verbose_name="Код ТТ")
#     workerID = models.CharField(max_length=50, help_text="Табельный номер сотрудника в заявке", null=True, blank=True, verbose_name="Табельный номер")
#     workType = models.CharField(max_length=500, help_text="Название вакансии", null=True, blank=True, verbose_name="Вид Работ")
#     startTimeWork = models.CharField(max_length=50, help_text="Время начала заявки", null=True, blank=True, verbose_name="Начало заявки")
#     endTimeWork = models.CharField(max_length=50, help_text="Время окончиания заявки", null=True, blank=True, verbose_name="Конец заявки")
#     amountOfWorkTime = models.CharField(max_length=50, help_text="Количество часов в заявке", null=True, blank=True, verbose_name="К-во часов в заявке")
#     statusWorker = models.CharField(max_length=200, help_text="Статус сотрудника", null=True, blank=True, verbose_name="Статус")
#     rateWorker = models.CharField(max_length=500, help_text="Оценка сотрудника", null=True, blank=True, verbose_name="Оценка")
#     noteRate = models.CharField(max_length=1000, help_text="Коментарий к оценке", null=True, blank=True, verbose_name="Коментарий оценки")
#     workerFullName = models.CharField(max_length=500, help_text="ФИО сотрудника", null=True, blank=True, verbose_name="ФИО")
#     KommangorMananerNote = models.CharField(max_length=500, help_text="Дата выгрузки?", null=True, blank=True, verbose_name="Комментарий менеджера коммандора")
#     isKey = models.CharField(max_length=50, help_text="Что мне с ним делать?", null=True, blank=True, verbose_name="МойКлюч?")
#     serialNumberForMe = models.IntegerField(help_text="Серийный номер придуманный мной", verbose_name="S/N Заявки", unique=True, null=True) 

#     def get_absolute_url(self):
#          return reverse('model-detail-view', args=[str(self.id)])

#     def __str__(self):
#         return f'{self.dateForWork} на {self.workPlaceName} для {self.workerID}'


# class RelationKRSKKommandorWorksToEmployeeTimeSheets(models.Model):
#     '''My BADEST implementation M:N Relation'''
#     worksIDX = models.IntegerField(help_text="Серийный номер придуманный мной из таблицы заявок", verbose_name="S/N Заявки", unique=True, null=True)
#     timeSheetIDX = models.IntegerField(help_text="Серийный номер придуманный мной из таблицы с ЛУВРами", verbose_name="S/N ЛУВРа", unique=True, null=True) 




# class WorkingHours(models.Model):
#     workingHours = models.DecimalField(help_text="Количество оплачиваемых часов", verbose_name="Часы работы",
#                                        max_digits=3, decimal_places=1, unique=True, default=0)
    
#     class Meta:
#         ordering = ["workingHours"]

#     def __unicode__(self):
#         return str(self.workingHours)

#     def __str__(self):
#         return str(self.workingHours)
```

File: "helpers.py"
```
import re

from datetime                           import time

from django.db.models                   import Q
from django.http                        import JsonResponse

from .models                            import KWorkers,  KWorkSheets,  KTimeSheets,  KExport4Payment,  KTypeOfWork,  KShop,  KShopUser
from .models                            import SSWorkers, SSWorkSheets, SSTimeSheets, SSExport4Payment, SSTypeOfWork
from .models                            import RazgulayWorkers, RazgulayWorkSheets, RazgulayTimeSheets, RazgulayExport4Payment, RazgulayTypeOfWork, RazgulayShop, RazgulayShopUser

VIEW_PERMISSIONS   = ['KRSK_WorkSheets.view_ktimesheets',   'KRSK_WorkSheets.view_sstimesheets',   'KRSK_WorkSheets.view_razgulaytimesheets']
CHANGE_PERMISSIONS = ['KRSK_WorkSheets.change_ktimesheets', 'KRSK_WorkSheets.change_sstimesheets', 'KRSK_WorkSheets.change_razgulaytimesheets']
DELETE_PERMISSIONS = ['KRSK_WorkSheets.delete_ktimesheets', 'KRSK_WorkSheets.delete_sstimesheets', 'KRSK_WorkSheets.delete_razgulaytimesheets']

BASE_KWORKSHEET_LIST_FIELDS  =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'ktimesheets__worker_id__worker_id',   'ktimesheets__start_work',  'ktimesheets__end_work',  'ktimesheets__amount_of_work_time',  'ktimesheets__worker_id__worker_full_name',  'ktimesheets__grade__grade_num',  'ktimesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel',   'ktimesheets__kexport4payment__is_exported',  'ktimesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id',  'ktimesheets__worker_id__payment_type__id']
BASE_SSWORKSHEET_LIST_FIELDS =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'sstimesheets__worker_id__worker_id', 'sstimesheets__start_work', 'sstimesheets__end_work', 'sstimesheets__amount_of_work_time', 'sstimesheets__worker_id__worker_full_name', 'sstimesheets__grade__grade_num', 'sstimesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'sstimesheets__ssexport4payment__is_exported', 'sstimesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id', 'sstimesheets__worker_id__payment_type__id']
BASE_RAZGULAYWORKSHEET_LIST_FIELDS =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'razgulaytimesheets__worker_id__worker_id', 'razgulaytimesheets__start_work', 'razgulaytimesheets__end_work', 'razgulaytimesheets__amount_of_work_time', 'razgulaytimesheets__worker_id__worker_full_name', 'razgulaytimesheets__grade__grade_num', 'razgulaytimesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'razgulaytimesheets__razgulayexport4payment__is_exported', 'razgulaytimesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id', 'razgulaytimesheets__worker_id__payment_type__id']

TABLE_RELATION_BY_USER = {
        'Отдел обслуживания': { 'WorkSheets'        : KWorkSheets, 
                                'TimeSheets'        : KTimeSheets, 
                                'Export4Payment'    : KExport4Payment,
                                'TypeOfWork'        : KTypeOfWork,
                                'Workers'           : KWorkers,    
                                'Shops'             : KShop,
                                'ShopUser'          : KShopUser,           
                                'BASE_WORKSHEET_LIST_FIELDS': BASE_KWORKSHEET_LIST_FIELDS,
                                'GROUP'             : 'Отдел обслуживания',
                                'SHOP_PREFIX'       : '',
                                'field_prefix'      : 'k',
                                },
        'Служба Контроля':    { 'WorkSheets'        : SSWorkSheets, 
                                'TimeSheets'        : SSTimeSheets, 
                                'Export4Payment'    : SSExport4Payment,
                                'TypeOfWork'        : SSTypeOfWork,
                                'Workers'           : SSWorkers,     
                                'Shops'             : KShop,
                                'ShopUser'          : KShopUser,                        
                                'BASE_WORKSHEET_LIST_FIELDS': BASE_SSWORKSHEET_LIST_FIELDS,
                                'GROUP'             : 'Служба Контроля',
                                'SHOP_PREFIX'       : 'С',
                                'field_prefix'      : 'ss',
                                },
        'Разгуляй':         {   'WorkSheets'        : RazgulayWorkSheets, 
                                'TimeSheets'        : RazgulayTimeSheets, 
                                'Export4Payment'    : RazgulayExport4Payment,
                                'TypeOfWork'        : RazgulayTypeOfWork,
                                'Workers'           : RazgulayWorkers,                             
                                'Shops'             : RazgulayShop,
                                'ShopUser'          : RazgulayShopUser,   
                                'BASE_WORKSHEET_LIST_FIELDS': BASE_RAZGULAYWORKSHEET_LIST_FIELDS,
                                'GROUP'             : 'Разгуляй',
                                'SHOP_PREFIX'       : '',
                                'field_prefix'      : 'razgulay',
                                },
                        }


def getWorkingHours(startTime, endTime):
    '''  # FIXME '''
    start_in_minute = startTime.minute + startTime.hour * 60
    end_in_minute   =   endTime.minute +   endTime.hour * 60
    subtract_in_minute = end_in_minute - start_in_minute if (end_in_minute - start_in_minute) > 0 else end_in_minute + 1440 - start_in_minute
    if subtract_in_minute > 390 and subtract_in_minute < 540:
        subtract_in_minute -= 30
    elif subtract_in_minute >= 540 and subtract_in_minute < 750:
        subtract_in_minute -= 60
    elif subtract_in_minute >= 750:
        subtract_in_minute -= 90
    return subtract_in_minute


def getSheetByGroup(user, table: str):
    '''  # FIXME'''
    # try:
    if True:
        if user.groups.filter(name='Отдел обслуживания').exists():  # FIXME!!! THIS VERY PERFORMANCE DEGRATED
            return TABLE_RELATION_BY_USER['Отдел обслуживания'][table]
        elif user.groups.filter(name='Служба Контроля').exists():
            return TABLE_RELATION_BY_USER['Служба Контроля'][table]
        elif user.groups.filter(name='Разгуляй').exists():
            return TABLE_RELATION_BY_USER['Разгуляй'][table]
        else:
            raise AssertionError('ERROR IN getSheetByGroup()')
    # except BaseException:
    #     return JsonResponse({'message': 'OK'})


def has_any_permissions(user, perms: list):
    return any((user.has_perm(perm) for perm in perms))


def has_all_permissions(user, perms: list):
    return all((user.has_perm(perm) for perm in perms))


def originalizeField(text):
    pattern = r'(k|ss|razgulay)(workers|worksheets|timesheets|export4payment|typeofwork)'
    replacement = r'\2'  # заменяем на вторую группу (без префикса)
    return re.sub(pattern, replacement, text)


# def userizeField(user, text):
#     pattern = r"\b(workers|worksheets|timesheets|export4payment)\b"
#     replacement = r"k\1"  # getSheetByGroup(user, 'field_prefix') + r"\1"
#     ans = re.sub(pattern, replacement, text)
#     print(f'''replacement = "{replacement}"    ||    userizeField({user}, {text}) = {ans} ''')
#     return ans


def userizeField(user, text):
    repl = getSheetByGroup(user, 'field_prefix')
    magic_words = ['workers', 'worksheets', 'timesheets', 'export4payment']
    for word in magic_words:  # FIXME!!! PERFORMANCE GEGRADED
        text = text.replace(word, repl + word)    
    return text


def userizeDictKeys(user, d: dict):
    return {userizeField(user, k): v for k, v in d.items()}  # FIXME!!! PERFORMANCE GEGRADED


def originalieDictKeys(d: dict):
    return {originalizeField(k): v for k, v in d.items()}  # FIXME!!! PERFORMANCE GEGRADED
```



Part of File: "FF_LUVR.py"
```
import json
import time
import datetime as dtLib
import pandas   as pd
import numpy    as np

from decimal import Decimal, getcontext
getcontext().prec = 1

# from django.conf                        import settings
# from django.contrib.auth.decorators     import permission_required
from django.contrib.auth.decorators     import user_passes_test
# from django.contrib.auth.models         import User # FIXME USE User from User = get_user_model()
from django.contrib.auth                import get_user_model
from django.contrib.postgres.aggregates import ArrayAgg
from django.shortcuts                   import render
from django.views.decorators.http       import require_http_methods
from django.http                        import JsonResponse, HttpResponse# ,HttpResponseRedirect
from django.db.models                   import Q, F, Func, Sum, DecimalField, Exists, OuterRef,  Case, Value, When, BooleanField, CharField
from django.db.models.functions         import Concat

from .models                            import Grades, ExtendAccount, Locations
from .helpers                           import getWorkingHours, getSheetByGroup, has_any_permissions, originalizeField, userizeField, userizeDictKeys
from .helpers                           import VIEW_PERMISSIONS, CHANGE_PERMISSIONS, DELETE_PERMISSIONS
from .FF_LUVR_filter                    import deserializeSortAndFilter, getSortAndFilter
from myconfig.config                    import PERIOD_RECONCILIATION_OF_RESULTS


ORIGINAL_WORKSHEET_LIST_FIELDS  =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'timesheets__worker_id__worker_id',   'timesheets__start_work',  'timesheets__end_work',  'timesheets__amount_of_work_time',  'timesheets__worker_id__worker_full_name',  'timesheets__grade__grade_num',  'timesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel',   'timesheets__export4payment__is_exported',  'timesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id',  'timesheets__worker_id__payment_type__id']
# HEAD_WORKSHEET_LIST_FIELDS =  ['id', 'created', 'date_for_work',  'shop_code',  'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'timesheets__worker_id__worker_id', 'timesheets__start_work', 'timesheets__end_work', 'timesheets__amount_of_work_time', 'timesheets__worker_id__worker_full_name', 'timesheets__grade__grade_num', 'timesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'timesheets__export4payment__is_exported', 'timesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id', 'timesheets__worker_id__payment_type__id']
# SHOPS_FIELDS = ['id', 'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work',]
DEBUG_THIS_FUNC = False
# USER = settings.AUTH_USER_MODEL
User = get_user_model()


class UnixTimestamp(Func):
    # Функция для преобразования datetime в unixtime
    function = 'EXTRACT'
    template = "%(function)s('epoch' FROM %(expressions)s)"


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def FF_LUVR_View(request):
    '''JUST GET MAIN PAGE'''
    response = render(request, 'KRSK_WorkSheets/FF_LUVR.html', context={'title':'ЛУВРЫ'})
    return response


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def FF_Exporting_page_View(request):
    '''JUST GET MAIN PAGE'''
    response = render(request, 'KRSK_WorkSheets/FF_Exporting_page.html', context={'title':'ЛУВРЫ'})
    return response


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def FF_LUVR_getHead(request):
    '''DATA FOR FILTERS:
    input: #FIXME DOC
    output: #FIXME DOC'''

    # perf = time.perf_counter_ns()
    json_reqest = json.loads(request.body)
    location = json_reqest.get('shop_code__shop_region__id', []) 
    location_filter_data = { 'shop_code__shop_region__id': location }

    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    USER_WORKSHEET_LIST_FIELDS = [userizeField(request.user, field) for field in ORIGINAL_WORKSHEET_LIST_FIELDS]

    data_for_extended_account = {'last_filter_data': {**location_filter_data}, 'last_sort_data': []}
    ea, is_ea_created = ExtendAccount.objects.get_or_create( user=request.user, 
                                                             defaults=data_for_extended_account)
    
    if ea.last_filter_data.get('shop_code__shop_region__id') != location and json_reqest.get("status") != 'START':
        ea.last_filter_data = location_filter_data
        ea.save()

    result_data_for_filter = ea.last_filter_data if not is_ea_created else {}
    result_sort_data       = ea.last_sort_data   if not is_ea_created else []

    sort_list, filter_kwargs, q_objects, list_fields = deserializeSortAndFilter(
        raw_sort    = None, 
        raw_filter  = location_filter_data, # ea.last_filter_data, # json_reqest.get('FILTER_DATA'), 
        user        = request.user, 
        list_fields = ORIGINAL_WORKSHEET_LIST_FIELDS[:],)
    filter_kwargs, list_fields = userizeDictKeys(request.user, filter_kwargs), [userizeField(request.user, field) for field in list_fields]
    # print(f"FILTER = {filter_kwargs}\nFilter = {BASE_WORKSHEET_LIST_FIELDS[:]}")

    qs = WorkSheets.objects.all()
    qs = qs.filter(*q_objects, **filter_kwargs)
    # print(f"list_fields = {list_fields}")
    qs = qs.aggregate(**{f'values_{ff}': ArrayAgg(ff, distinct=True) for ff in list_fields})
    qs2 = [qs[f'values_{ff}'] for ff in list_fields] # не помню, почему не могу values_list здесь....

    payload = { 'ROLE' : list(request.user.groups.values_list('name')),  # FIXME bad data
                'FILTER_DATA' : list(qs2),
                'OLD_SORT_AND_FILTER_DATA': {'sort': result_sort_data, 'filter': result_data_for_filter},
                'LOCATIONS' : list(Locations.objects.all().values_list('id', 'location')),
                'OLD_LOCATIONS' : ea.last_filter_data.get('shop_code__shop_region__id', []),
                'FIELDS': [originalizeField(field) for field in list_fields],                }

    response = JsonResponse(payload, safe=False)
```


Это часть моего проекта на Django.

У меня есть несколько таблиц с Workers, Worksheets, Timesheets.
В файле helpers.py есть переключение таблиц в зависимости от пользователя.

Предложи как можно изменить архитектуру проекта, чтоб при добавлении новых контрагентов было проще