# Path: shared_schema_tenants/helpers/tenants.py
# def get_current_tenant():
#     from shared_schema_tenants.middleware import TenantMiddleware
#     return TenantMiddleware.get_current_tenant()
# 
# Path: shared_schema_tenants_custom_data/managers.py
# class TenantSpecificFieldsModelManager(
#         TenantSpecificFieldsModelBaseManager.from_queryset(TenantSpecificFieldsQueryset)):
#     data_type_fields = {
#         'integer': models.IntegerField(),
#         'char': models.CharField(max_length=255),
#         'text': models.TextField(),
#         'float': models.FloatField(),
#         'datetime': models.DateTimeField(),
#         'date': models.DateField(),
#     }
# 
#     def get_queryset(self, *args, **kwargs):
#         from shared_schema_tenants_custom_data.models import TenantSpecificTableRow
# 
#         if self.model != TenantSpecificTableRow:
#             kwargs.pop('table_id', None)
#         else:
#             if not hasattr(self, 'table_id'):
#                 self.table_id = kwargs.get('table_id', -1)
#             else:
#                 kwargs['table_id'] = self.table_id
# 
#         custom_fields_annotations = self._get_custom_fields_annotations()
#         queryset = super(TenantSpecificFieldsModelManager, self).get_queryset(*args, **kwargs)
# 
#         if len(custom_fields_annotations.keys()) > 0:
#             if self.model == TenantSpecificTableRow:
#                 return (
#                     queryset
#                     .annotate(**custom_fields_annotations)
#                     .filter(table_id=self.table_id)
#                 )
#             return queryset.annotate(**custom_fields_annotations)
# 
#         if self.model == TenantSpecificTableRow:
#             return queryset.filter(table_id=self.table_id)
#         return queryset
# 
#     def _get_custom_fields_annotations(self):
#         from shared_schema_tenants_custom_data.models import (
#             TenantSpecificFieldDefinition, TenantSpecificTable, TenantSpecificTableRow)
# 
#         if self.model == TenantSpecificTableRow:
#             definitions = TenantSpecificFieldDefinition.objects.filter(
#                 table_content_type=ContentType.objects.get_for_model(TenantSpecificTable),
#                 table_id=self.table_id)
#         else:
#             definitions = TenantSpecificFieldDefinition.objects.filter(
#                 table_content_type=ContentType.objects.get_for_model(self.model))
#         definitions_by_name = {d.name: d for d in definitions}
# 
#         custom_fields_annotations = {}
# 
#         for key, definition in definitions_by_name.items():
#             if get_complete_version()[1] >= 11:
#                 from django.db.models import Subquery, OuterRef
#                 definitions_values = (
#                     _get_pivot_table_class_for_data_type(definition.data_type).objects
#                     .filter(definition__id=definition.id, row_id=OuterRef('pk'))
#                     .values('value')
#                 )
# 
#                 custom_fields_annotations[key] = Subquery(
#                     queryset=definitions_values,
#                     output_field=self.data_type_fields[definition.data_type]
#                 )
#             else:
#                 from django.db.models.expressions import RawSQL
#                 model_content_type = ContentType.objects.get_for_model(self.model)
#                 model_table_name = (model_content_type.app_label + '_' + model_content_type.model)
#                 PivotTableClass = _get_pivot_table_class_for_data_type(definition.data_type)
#                 pivot_table_name = PivotTableClass._meta.db_table
#                 custom_fields_annotations[key] = RawSQL(
#                     """
#                         select p.value
#                         from """ + pivot_table_name + """ p
#                         where definition_id = %s and
#                             p.row_id = """ + '"' + model_table_name + '"."' + self.model._meta.pk.name + '"',
#                     [definition.id],
#                     output_field=self.data_type_fields[definition.data_type])
# 
#         return custom_fields_annotations
# 
# Path: shared_schema_tenants_custom_data/helpers/custom_tables_helpers.py
# def _get_pivot_table_class_for_data_type(data_type):
#     from shared_schema_tenants_custom_data.models import (
#         TenantSpecificFieldIntegerPivot,
#         TenantSpecificFieldCharPivot,
#         TenantSpecificFieldTextPivot,
#         TenantSpecificFieldFloatPivot,
#         TenantSpecificFieldDatePivot,
#         TenantSpecificFieldDateTimePivot
#     )
# 
#     if data_type == 'integer':
#         return TenantSpecificFieldIntegerPivot
#     elif data_type == 'char':
#         return TenantSpecificFieldCharPivot
#     elif data_type == 'text':
#         return TenantSpecificFieldTextPivot
#     elif data_type == 'float':
#         return TenantSpecificFieldFloatPivot
#     elif data_type == 'date':
#         return TenantSpecificFieldDatePivot
#     elif data_type == 'datetime':
#         return TenantSpecificFieldDateTimePivot


from django.db import models
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from shared_schema_tenants.helpers.tenants import get_current_tenant
from shared_schema_tenants_custom_data.managers import TenantSpecificFieldsModelManager
from shared_schema_tenants_custom_data.helpers.custom_tables_helpers import (
    _get_pivot_table_class_for_data_type)
        from shared_schema_tenants_custom_data.models import TenantSpecificFieldDefinition, TenantSpecificTable



class TenantSpecificFieldsModelMixin(models.Model):
    objects = TenantSpecificFieldsModelManager()

    def __init__(self, *args, **kwargs):

# Path: shared_schema_tenants/helpers/tenants.py
# def get_current_tenant():
#     from shared_schema_tenants.middleware import TenantMiddleware
#     return TenantMiddleware.get_current_tenant()
# 
# Path: shared_schema_tenants_custom_data/managers.py
# class TenantSpecificFieldsModelManager(
#         TenantSpecificFieldsModelBaseManager.from_queryset(TenantSpecificFieldsQueryset)):
#     data_type_fields = {
#         'integer': models.IntegerField(),
#         'char': models.CharField(max_length=255),
#         'text': models.TextField(),
#         'float': models.FloatField(),
#         'datetime': models.DateTimeField(),
#         'date': models.DateField(),
#     }
# 
#     def get_queryset(self, *args, **kwargs):
#         from shared_schema_tenants_custom_data.models import TenantSpecificTableRow
# 
#         if self.model != TenantSpecificTableRow:
#             kwargs.pop('table_id', None)
#         else:
#             if not hasattr(self, 'table_id'):
#                 self.table_id = kwargs.get('table_id', -1)
#             else:
#                 kwargs['table_id'] = self.table_id
# 
#         custom_fields_annotations = self._get_custom_fields_annotations()
#         queryset = super(TenantSpecificFieldsModelManager, self).get_queryset(*args, **kwargs)
# 
#         if len(custom_fields_annotations.keys()) > 0:
#             if self.model == TenantSpecificTableRow:
#                 return (
#                     queryset
#                     .annotate(**custom_fields_annotations)
#                     .filter(table_id=self.table_id)
#                 )
#             return queryset.annotate(**custom_fields_annotations)
# 
#         if self.model == TenantSpecificTableRow:
#             return queryset.filter(table_id=self.table_id)
#         return queryset
# 
#     def _get_custom_fields_annotations(self):
#         from shared_schema_tenants_custom_data.models import (
#             TenantSpecificFieldDefinition, TenantSpecificTable, TenantSpecificTableRow)
# 
#         if self.model == TenantSpecificTableRow:
#             definitions = TenantSpecificFieldDefinition.objects.filter(
#                 table_content_type=ContentType.objects.get_for_model(TenantSpecificTable),
#                 table_id=self.table_id)
#         else:
#             definitions = TenantSpecificFieldDefinition.objects.filter(
#                 table_content_type=ContentType.objects.get_for_model(self.model))
#         definitions_by_name = {d.name: d for d in definitions}
# 
#         custom_fields_annotations = {}
# 
#         for key, definition in definitions_by_name.items():
#             if get_complete_version()[1] >= 11:
#                 from django.db.models import Subquery, OuterRef
#                 definitions_values = (
#                     _get_pivot_table_class_for_data_type(definition.data_type).objects
#                     .filter(definition__id=definition.id, row_id=OuterRef('pk'))
#                     .values('value')
#                 )
# 
#                 custom_fields_annotations[key] = Subquery(
#                     queryset=definitions_values,
#                     output_field=self.data_type_fields[definition.data_type]
#                 )
#             else:
#                 from django.db.models.expressions import RawSQL
#                 model_content_type = ContentType.objects.get_for_model(self.model)
#                 model_table_name = (model_content_type.app_label + '_' + model_content_type.model)
#                 PivotTableClass = _get_pivot_table_class_for_data_type(definition.data_type)
#                 pivot_table_name = PivotTableClass._meta.db_table
#                 custom_fields_annotations[key] = RawSQL(
#                     """
#                         select p.value
#                         from """ + pivot_table_name + """ p
#                         where definition_id = %s and
#                             p.row_id = """ + '"' + model_table_name + '"."' + self.model._meta.pk.name + '"',
#                     [definition.id],
#                     output_field=self.data_type_fields[definition.data_type])
# 
#         return custom_fields_annotations
# 
# Path: shared_schema_tenants_custom_data/helpers/custom_tables_helpers.py
# def _get_pivot_table_class_for_data_type(data_type):
#     from shared_schema_tenants_custom_data.models import (
#         TenantSpecificFieldIntegerPivot,
#         TenantSpecificFieldCharPivot,
#         TenantSpecificFieldTextPivot,
#         TenantSpecificFieldFloatPivot,
#         TenantSpecificFieldDatePivot,
#         TenantSpecificFieldDateTimePivot
#     )
# 
#     if data_type == 'integer':
#         return TenantSpecificFieldIntegerPivot
#     elif data_type == 'char':
#         return TenantSpecificFieldCharPivot
#     elif data_type == 'text':
#         return TenantSpecificFieldTextPivot
#     elif data_type == 'float':
#         return TenantSpecificFieldFloatPivot
#     elif data_type == 'date':
#         return TenantSpecificFieldDatePivot
#     elif data_type == 'datetime':
#         return TenantSpecificFieldDateTimePivot


# Path: shared_schema_tenants_custom_data/mixins.py
from django.db import models
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from shared_schema_tenants.helpers.tenants import get_current_tenant
from shared_schema_tenants_custom_data.managers import TenantSpecificFieldsModelManager
from shared_schema_tenants_custom_data.helpers.custom_tables_helpers import (
    _get_pivot_table_class_for_data_type)
        from shared_schema_tenants_custom_data.models import TenantSpecificFieldDefinition, TenantSpecificTable




class TenantSpecificFieldsModelMixin(models.Model):
    objects = TenantSpecificFieldsModelManager()

    def __init__(self, *args, **kwargs):

        table_id = kwargs.get('table_id', getattr(kwargs.get('table'), 'id', None))