alcehmy and event functions updated

This commit is contained in:
2024-11-09 22:31:12 +03:00
parent e7a9b8c313
commit 1f75e49a07
23 changed files with 709 additions and 505 deletions

View File

@@ -1,15 +1,17 @@
import datetime
from decimal import Decimal
from sqlalchemy import (
TIMESTAMP,
NUMERIC,
func,
Identity,
text,
UUID,
String,
Integer,
Boolean,
SmallInteger,
)
from sqlalchemy.orm import (
Mapped,
mapped_column,
@@ -63,6 +65,18 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
"updated_by_id",
"replication_id",
)
__system_default_model__ = [
"cryp_uu_id",
"is_confirmed",
"deleted",
"is_notification_send",
"replication_id",
"is_email_send",
"confirmed_by_id",
"confirmed_by",
"updated_by_id",
"created_by_id",
]
creds: Credentials = None # The credentials to use in the model.
client_arrow: DateTimeLocal = None # The arrow to use in the model.
@@ -74,6 +88,17 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
TIMESTAMP, default="2099-12-31", server_default="2099-12-31"
)
@classmethod
def remove_non_related_inputs(cls, kwargs):
"""
Removes the non-related inputs from the given attributes.
"""
return {
key: value
for key, value in kwargs.items()
if key in cls.columns + cls.hybrid_properties + cls.settable_relations
}
@classmethod
def extract_system_fields(cls, filter_kwargs: dict, create: bool = True):
"""
@@ -87,6 +112,47 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
system_fields.pop(field, None)
return system_fields
@classmethod
def iterate_over_variables(cls, val, key):
key_ = cls.__annotations__.get(key, None)
is_primary, value_type = key in cls.primary_keys, type(val)
row_attr = bool(getattr(getattr(cls, key), "foreign_keys", None))
if is_primary or row_attr and key_ == Mapped[int]:
return None
if key_:
if key_ == Mapped[int]:
return int(val) if val else None
elif key_ == Mapped[bool]:
return bool(val) if val else None
elif key_ == Mapped[float] or key_ == Mapped[NUMERIC]:
return round(float(val), 3) if val else None
elif key_ == Mapped[int]:
return int(val) if val else None
elif key_ == Mapped[TIMESTAMP]:
formatted_date = client_arrow.get(str(val)).format(
"DD-MM-YYYY HH:mm:ss"
)
return str(formatted_date) if val else None
else:
if isinstance(val, datetime.datetime):
formatted_date = client_arrow.get(str(val)).format(
"DD-MM-YYYY HH:mm:ss"
)
print(key, "isinstance(value_type, datetime) | ", formatted_date)
return str(formatted_date) if val else None
elif isinstance(value_type, bool):
return bool(val) if val else None
elif isinstance(value_type, float) or isinstance(value_type, Decimal):
return round(float(val), 3) if val else None
elif isinstance(value_type, int):
return int(val) if val else None
elif isinstance(value_type, str):
return str(val) if val else None
elif isinstance(value_type, type(None)):
return None
return str(val) if val else None
@classmethod
def find_or_create(cls, **kwargs):
from api_library.date_time_actions.date_functions import system_arrow
@@ -97,19 +163,18 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
is_found can be used to check if the record was found or created.
"""
check_kwargs = cls.extract_system_fields(kwargs)
cls.pre_query = cls.query.filter(
system_arrow.get(cls.expiry_ends).date() < system_arrow.now().date()
)
already_record = cls.filter_by_one(**check_kwargs)
cls.pre_query = cls.query.filter(cls.expiry_ends < system_arrow.now().date())
already_record = cls.filter_by_one(**check_kwargs, system=True)
cls.pre_query = None
if already_record := already_record.data:
if already_record.is_deleted:
if already_record.deleted:
cls.raise_http_exception(
status_code="HTTP_406_NOT_ACCEPTABLE",
error_case="DeletedRecord",
data=check_kwargs,
message="Record exits but is deleted. Contact with authorized user",
)
elif already_record.is_confirmed:
elif not already_record.is_confirmed:
cls.raise_http_exception(
status_code="HTTP_406_NOT_ACCEPTABLE",
error_case="IsNotConfirmed",
@@ -122,6 +187,7 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
data=check_kwargs,
message="Record already exits. Refresh data and try again",
)
check_kwargs = cls.remove_non_related_inputs(check_kwargs)
created_record = cls()
for key, value in check_kwargs.items():
setattr(created_record, key, value)
@@ -130,28 +196,8 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
cls.created_by = cls.creds.person_name
return created_record
@classmethod
def iterate_over_variables(cls, val, key):
key_ = cls.__annotations__.get(key, None)
is_primary, is_foreign_key = key in cls.primary_keys and bool(getattr(cls, key).foreign_keys)
if is_primary or is_foreign_key and key_ == Mapped[int]:
return None
elif key_ == Mapped[UUID]:
return str(val) if val else None
elif key_ == Mapped[int]:
return int(val) if val else None
elif key_ == Mapped[bool]:
return bool(val) if val else None
elif key_ == Mapped[float] or key_ == Mapped[NUMERIC]:
return float(val) if val else None
elif key_ == Mapped[int]:
return int(val) if val else None
elif key_ == Mapped[TIMESTAMP]:
return str(client_arrow.get(val).format("DD-MM-YYYY HH:mm:ss")) if val else None
return str(val) if val else None
def update(self, **kwargs):
check_kwargs = self.remove_non_related_inputs(kwargs)
"""Updates the record with the given attributes."""
is_confirmed_argument = kwargs.get("is_confirmed", None)
if is_confirmed_argument and not len(kwargs) == 1:
@@ -161,7 +207,7 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
data=kwargs,
message="Confirm field can not be updated with other fields",
)
check_kwargs = self.extract_system_fields(kwargs, create=False)
check_kwargs = self.extract_system_fields(check_kwargs, create=False)
for key, value in check_kwargs.items():
setattr(self, key, value)
@@ -178,24 +224,48 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
self, exclude: list = None, include: list = None, include_joins: list = None
):
return_dict = {}
if exclude:
exclude.extend(list(set(self.__exclude__fields__).difference(exclude)))
else:
exclude = self.__exclude__fields__
include = include or []
if include:
include.extend(["uu_id", "active"])
include = list(set(include).difference(self.__exclude__fields__))
for key, val in self.to_dict().items():
if key in include:
if value_of_database := self.iterate_over_variables(val, key):
return_dict[key] = value_of_database
exclude_list = [
element
for element in self.__system_default_model__
if str(element)[-2:] == "id"
]
columns_include_list = list(set(include).difference(set(exclude_list)))
columns_include_list.extend(["uu_id", "active"])
for key in list(columns_include_list):
val = getattr(self, key)
value_of_database = self.iterate_over_variables(val, key)
if value_of_database is not None:
return_dict[key] = value_of_database
elif exclude:
exclude.extend(
list(set(self.__exclude__fields__ or []).difference(exclude))
)
for i in self.__system_default_model__:
print("i", str(i)[-2:])
exclude.extend(
[
element
for element in self.__system_default_model__
if str(element)[-2:] == "id"
]
)
columns_excluded_list = set(self.columns).difference(set(exclude))
for key in list(columns_excluded_list):
val = getattr(self, key)
value_of_database = self.iterate_over_variables(val, key)
if value_of_database is not None:
return_dict[key] = value_of_database
else:
exclude.extend(["is_confirmed", "deleted", "cryp_uu_id"])
for key, val in self.to_dict().items():
if key not in exclude:
if value_of_database := self.iterate_over_variables(val, key):
return_dict[key] = value_of_database
exclude_list = (
self.__exclude__fields__ or [] + self.__system_default_model__
)
columns_list = list(set(self.columns).difference(set(exclude_list)))
for key in list(columns_list):
val = getattr(self, key)
value_of_database = self.iterate_over_variables(val, key)
if value_of_database is not None:
return_dict[key] = value_of_database
all_arguments = [
record
@@ -218,15 +288,15 @@ class CrudMixin(Base, SmartQueryMixin, SessionMixin, FilterAttributes):
return_dict[all_argument] = (
populate_arg.get_dict() if populate_arg else []
)
return return_dict
return dict(sorted(return_dict.items(), reverse=False))
class BaseMixin(CrudMixin, ReprMixin, SerializeMixin):
class BaseMixin(CrudMixin, ReprMixin, SerializeMixin, FilterAttributes):
__abstract__ = True
class BaseCollection(CrudMixin, BaseMixin):
class BaseCollection(BaseMixin):
__abstract__ = True
__repr__ = ReprMixin.__repr__
@@ -234,14 +304,14 @@ class BaseCollection(CrudMixin, BaseMixin):
id: Mapped[int] = mapped_column(primary_key=True)
class CrudCollection(CrudMixin, BaseMixin, SmartQueryMixin):
class CrudCollection(BaseMixin, SmartQueryMixin):
__abstract__ = True
__repr__ = ReprMixin.__repr__
id: Mapped[int] = mapped_column(primary_key=True)
uu_id: Mapped[UUID] = mapped_column(
UUID, server_default=func.text("gen_random_uuid()"), index=True, unique=True
UUID, server_default=text("gen_random_uuid()"), index=True, unique=True
)
ref_id: Mapped[UUID] = mapped_column(String(100), nullable=True, index=True)