Chore: Renamed the auth tables to remove the prefix
This commit is contained in:
parent
ca352649f0
commit
074e45fe69
71
brewman/alembic/versions/0363f582ab28_rename_auth.py
Normal file
71
brewman/alembic/versions/0363f582ab28_rename_auth.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
"""rename auth
|
||||||
|
|
||||||
|
Revision ID: 0363f582ab28
|
||||||
|
Revises: ad8b2d208492
|
||||||
|
Create Date: 2021-09-11 05:32:56.683107
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "0363f582ab28"
|
||||||
|
down_revision = "ad8b2d208492"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.rename_table("auth_clients", "clients")
|
||||||
|
op.drop_constraint("uq_auth_clients_code", "clients", type_="unique")
|
||||||
|
op.drop_constraint("uq_auth_clients_name", "clients", type_="unique")
|
||||||
|
op.create_unique_constraint(op.f("uq_clients_code"), "clients", ["code"])
|
||||||
|
op.create_unique_constraint(op.f("uq_clients_name"), "clients", ["name"])
|
||||||
|
|
||||||
|
op.rename_table("auth_login_history", "login_history")
|
||||||
|
op.drop_constraint("uq_auth_login_history_user_id", "login_history", type_="unique")
|
||||||
|
op.create_unique_constraint(op.f("uq_login_history_user_id"), "login_history", ["user_id", "client_id", "date"])
|
||||||
|
|
||||||
|
op.rename_table("auth_permissions", "permissions")
|
||||||
|
op.drop_constraint("uq_auth_permissions_name", "permissions", type_="unique")
|
||||||
|
op.create_unique_constraint(op.f("uq_permissions_name"), "permissions", ["name"])
|
||||||
|
|
||||||
|
op.rename_table("auth_roles", "roles")
|
||||||
|
op.drop_constraint("uq_auth_roles_name", "roles", type_="unique")
|
||||||
|
op.create_unique_constraint(op.f("uq_roles_name"), "roles", ["name"])
|
||||||
|
|
||||||
|
op.rename_table("auth_users", "users")
|
||||||
|
op.drop_constraint("uq_auth_users_username", "users", type_="unique")
|
||||||
|
op.create_unique_constraint(op.f("uq_users_username"), "users", ["username"])
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
|
||||||
|
op.rename_table("users", "auth_users")
|
||||||
|
op.drop_constraint(op.f("uq_users_username"), "users", type_="unique")
|
||||||
|
op.create_unique_constraint("uq_auth_users_username", "users", ["username"])
|
||||||
|
|
||||||
|
op.rename_table("roles", "auth_roles")
|
||||||
|
op.drop_constraint(op.f("uq_roles_name"), "roles", type_="unique")
|
||||||
|
op.create_unique_constraint("uq_auth_roles_name", "roles", ["name"])
|
||||||
|
|
||||||
|
op.rename_table("permissions", "auth_permissions")
|
||||||
|
op.drop_constraint(op.f("uq_permissions_name"), "permissions", type_="unique")
|
||||||
|
op.create_unique_constraint("uq_auth_permissions_name", "permissions", ["name"])
|
||||||
|
|
||||||
|
op.rename_table("login_history", "auth_login_history")
|
||||||
|
op.drop_constraint(op.f("uq_login_history_user_id"), "login_history", type_="unique")
|
||||||
|
op.create_unique_constraint("uq_auth_login_history_user_id", "login_history", ["user_id", "client_id", "date"])
|
||||||
|
|
||||||
|
op.rename_table("clients", "auth_clients")
|
||||||
|
op.drop_constraint(op.f("uq_clients_name"), "clients", type_="unique")
|
||||||
|
op.drop_constraint(op.f("uq_clients_code"), "clients", type_="unique")
|
||||||
|
op.create_unique_constraint("uq_auth_clients_name", "clients", ["name"])
|
||||||
|
op.create_unique_constraint("uq_auth_clients_code", "clients", ["code"])
|
||||||
|
# ### end Alembic commands ###
|
@ -27,7 +27,7 @@ class Attendance(Base):
|
|||||||
attendance_type = Column("attendance_type", Integer)
|
attendance_type = Column("attendance_type", Integer)
|
||||||
amount = Column("amount", Numeric(precision=5, scale=2))
|
amount = Column("amount", Numeric(precision=5, scale=2))
|
||||||
creation_date = Column("creation_date", DateTime())
|
creation_date = Column("creation_date", DateTime())
|
||||||
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"))
|
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"))
|
||||||
is_valid = Column("is_valid", Boolean)
|
is_valid = Column("is_valid", Boolean)
|
||||||
|
|
||||||
user = relationship("User", primaryjoin="User.id==Attendance.user_id")
|
user = relationship("User", primaryjoin="User.id==Attendance.user_id")
|
||||||
|
@ -16,7 +16,7 @@ from .meta import Base
|
|||||||
|
|
||||||
|
|
||||||
class Client(Base):
|
class Client(Base):
|
||||||
__tablename__ = "auth_clients"
|
__tablename__ = "clients"
|
||||||
|
|
||||||
id = Column("client_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column("client_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
code = Column("code", Integer, unique=True, nullable=False)
|
code = Column("code", Integer, unique=True, nullable=False)
|
||||||
|
@ -13,14 +13,14 @@ from .meta import Base
|
|||||||
|
|
||||||
|
|
||||||
class LoginHistory(Base):
|
class LoginHistory(Base):
|
||||||
__tablename__ = "auth_login_history"
|
__tablename__ = "login_history"
|
||||||
__table_args__ = (UniqueConstraint("user_id", "client_id", "date"),)
|
__table_args__ = (UniqueConstraint("user_id", "client_id", "date"),)
|
||||||
id = Column("login_history_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column("login_history_id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"), nullable=False)
|
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
|
||||||
client_id = Column(
|
client_id = Column(
|
||||||
"client_id",
|
"client_id",
|
||||||
UUID(as_uuid=True),
|
UUID(as_uuid=True),
|
||||||
ForeignKey("auth_clients.client_id"),
|
ForeignKey("clients.client_id"),
|
||||||
nullable=False,
|
nullable=False,
|
||||||
)
|
)
|
||||||
date = Column("date", DateTime(), nullable=False)
|
date = Column("date", DateTime(), nullable=False)
|
||||||
|
@ -14,7 +14,7 @@ from .role_permission import role_permission
|
|||||||
|
|
||||||
|
|
||||||
class Permission(Base):
|
class Permission(Base):
|
||||||
__tablename__ = "auth_permissions"
|
__tablename__ = "permissions"
|
||||||
|
|
||||||
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
name = Column("name", Unicode(255), unique=True)
|
name = Column("name", Unicode(255), unique=True)
|
||||||
|
124
brewman/brewman/models/rate_contract.py
Normal file
124
brewman/brewman/models/rate_contract.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
from sqlalchemy import (
|
||||||
|
Boolean,
|
||||||
|
Column,
|
||||||
|
ForeignKey,
|
||||||
|
Integer,
|
||||||
|
Numeric,
|
||||||
|
Unicode,
|
||||||
|
UniqueConstraint,
|
||||||
|
case,
|
||||||
|
func,
|
||||||
|
select,
|
||||||
|
)
|
||||||
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
|
from sqlalchemy.orm import Session, relationship
|
||||||
|
|
||||||
|
from .meta import Base
|
||||||
|
|
||||||
|
|
||||||
|
class Product(Base):
|
||||||
|
__tablename__ = "products"
|
||||||
|
__table_args__ = (UniqueConstraint("name", "units"),)
|
||||||
|
|
||||||
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
|
code = Column("code", Integer, unique=True)
|
||||||
|
name = Column("name", Unicode(255), nullable=False)
|
||||||
|
units = Column("units", Unicode(255), nullable=False)
|
||||||
|
fraction = Column("fraction", Numeric(precision=15, scale=5), nullable=False)
|
||||||
|
fraction_units = Column("fraction_units", Unicode(255), nullable=False)
|
||||||
|
product_yield = Column("product_yield", Numeric(precision=15, scale=5), nullable=False)
|
||||||
|
product_group_id = Column(
|
||||||
|
"product_group_id",
|
||||||
|
UUID(as_uuid=True),
|
||||||
|
ForeignKey("product_groups.id"),
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
|
account_id = Column("account_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False)
|
||||||
|
price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False)
|
||||||
|
sale_price = Column("sale_price", Numeric(precision=15, scale=2), nullable=False)
|
||||||
|
is_active = Column("is_active", Boolean, nullable=False)
|
||||||
|
is_fixture = Column("is_fixture", Boolean, nullable=False)
|
||||||
|
is_purchased = Column("is_purchased", Boolean, nullable=False)
|
||||||
|
is_sold = Column("is_sold", Boolean, nullable=False)
|
||||||
|
|
||||||
|
product_group = relationship("ProductGroup", back_populates="products")
|
||||||
|
batches = relationship("Batch", back_populates="product")
|
||||||
|
inventories = relationship("Inventory", back_populates="product")
|
||||||
|
recipes = relationship("Recipe", back_populates="product")
|
||||||
|
account = relationship("Account", primaryjoin="Account.id==Product.account_id", back_populates="products")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
code=None,
|
||||||
|
name=None,
|
||||||
|
units=None,
|
||||||
|
fraction=None,
|
||||||
|
fraction_units=None,
|
||||||
|
product_yield=None,
|
||||||
|
product_group_id=None,
|
||||||
|
account_id=None,
|
||||||
|
price=None,
|
||||||
|
sale_price=None,
|
||||||
|
is_active=None,
|
||||||
|
is_purchased=None,
|
||||||
|
is_sold=None,
|
||||||
|
id_=None,
|
||||||
|
is_fixture=False,
|
||||||
|
):
|
||||||
|
self.code = code
|
||||||
|
self.name = name
|
||||||
|
self.units = units
|
||||||
|
self.fraction = fraction
|
||||||
|
self.fraction_units = fraction_units
|
||||||
|
self.product_yield = product_yield
|
||||||
|
self.product_group_id = product_group_id
|
||||||
|
self.account_id = account_id
|
||||||
|
self.price = price
|
||||||
|
self.sale_price = sale_price
|
||||||
|
self.is_active = is_active
|
||||||
|
self.is_purchased = is_purchased
|
||||||
|
self.is_sold = is_sold
|
||||||
|
self.id = id_
|
||||||
|
self.is_fixture = is_fixture
|
||||||
|
|
||||||
|
@hybrid_property
|
||||||
|
def full_name(self):
|
||||||
|
return f"{self.name} ({self.units})" if self.units else self.name
|
||||||
|
|
||||||
|
@full_name.expression
|
||||||
|
def full_name(cls):
|
||||||
|
return cls.name + case([(cls.units != "", " (" + cls.units + ")")], else_="")
|
||||||
|
|
||||||
|
def create(self, db: Session):
|
||||||
|
self.code = db.execute(select(func.coalesce(func.max(Product.code), 0) + 1)).scalar_one()
|
||||||
|
db.add(self)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def can_delete(self, advanced_delete: bool):
|
||||||
|
if self.is_fixture:
|
||||||
|
return False, f"{self.name} is a fixture and cannot be edited or deleted."
|
||||||
|
if self.is_active:
|
||||||
|
return False, "Product is active"
|
||||||
|
if len(self.inventories) > 0 and not advanced_delete:
|
||||||
|
return False, "Product has entries"
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def query(cls, q, is_purchased: bool = None, active: bool = None, db: Session = None):
|
||||||
|
query_ = select(cls)
|
||||||
|
if active is not None:
|
||||||
|
query_ = query_.filter(cls.is_active == active)
|
||||||
|
if is_purchased is not None:
|
||||||
|
query_ = query_.filter(cls.is_purchased == is_purchased)
|
||||||
|
if q is not None:
|
||||||
|
for item in q.split():
|
||||||
|
if item.strip() != "":
|
||||||
|
query_ = query_.filter(cls.name.ilike(f"%{item}%"))
|
||||||
|
return db.execute(query_).scalars().all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suspense(cls):
|
||||||
|
return uuid.UUID("aa79a643-9ddc-4790-ac7f-a41f9efb4c15")
|
119
brewman/brewman/models/rate_contract_item.py
Normal file
119
brewman/brewman/models/rate_contract_item.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
from sqlalchemy import (
|
||||||
|
Boolean,
|
||||||
|
Column,
|
||||||
|
ForeignKey,
|
||||||
|
Integer,
|
||||||
|
Numeric,
|
||||||
|
Unicode,
|
||||||
|
UniqueConstraint,
|
||||||
|
case,
|
||||||
|
func,
|
||||||
|
select, DateTime, Date,
|
||||||
|
)
|
||||||
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
|
from sqlalchemy.orm import Session, relationship
|
||||||
|
|
||||||
|
from .meta import Base
|
||||||
|
|
||||||
|
|
||||||
|
class RateContract(Base):
|
||||||
|
__tablename__ = "rate_contracts"
|
||||||
|
__table_args__ = (UniqueConstraint("name", "units"),)
|
||||||
|
|
||||||
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
|
|
||||||
|
user = relationship("User", primaryjoin="User.id==Voucher.user_id", cascade=None)
|
||||||
|
creation_date = Column("creation_date", DateTime(), nullable=False)
|
||||||
|
last_edit_date = Column("last_edit_date", DateTime(), nullable=False)
|
||||||
|
|
||||||
|
vendor_id = Column("vendor_id", UUID(as_uuid=True), ForeignKey("accounts.id"), nullable=False)
|
||||||
|
|
||||||
|
# product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
|
||||||
|
# price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False)
|
||||||
|
|
||||||
|
valid_from = Column("valid_from", Date(), nullable=True)
|
||||||
|
valid_till = Column("valid_till", Date(), nullable=True)
|
||||||
|
|
||||||
|
user = relationship("User")
|
||||||
|
vendor = relationship("Account", back_populates="rate_contracts")
|
||||||
|
|
||||||
|
# batches = relationship("Batch", back_populates="product")
|
||||||
|
# inventories = relationship("Inventory", back_populates="product")
|
||||||
|
# recipes = relationship("Recipe", back_populates="product")
|
||||||
|
# account = relationship("Account", primaryjoin="Account.id==Product.account_id", back_populates="products")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
code=None,
|
||||||
|
name=None,
|
||||||
|
units=None,
|
||||||
|
fraction=None,
|
||||||
|
fraction_units=None,
|
||||||
|
product_yield=None,
|
||||||
|
product_group_id=None,
|
||||||
|
account_id=None,
|
||||||
|
price=None,
|
||||||
|
sale_price=None,
|
||||||
|
is_active=None,
|
||||||
|
is_purchased=None,
|
||||||
|
is_sold=None,
|
||||||
|
id_=None,
|
||||||
|
is_fixture=False,
|
||||||
|
):
|
||||||
|
self.code = code
|
||||||
|
self.name = name
|
||||||
|
self.units = units
|
||||||
|
self.fraction = fraction
|
||||||
|
self.fraction_units = fraction_units
|
||||||
|
self.product_yield = product_yield
|
||||||
|
self.product_group_id = product_group_id
|
||||||
|
self.account_id = account_id
|
||||||
|
self.price = price
|
||||||
|
self.sale_price = sale_price
|
||||||
|
self.is_active = is_active
|
||||||
|
self.is_purchased = is_purchased
|
||||||
|
self.is_sold = is_sold
|
||||||
|
self.id = id_
|
||||||
|
self.is_fixture = is_fixture
|
||||||
|
|
||||||
|
@hybrid_property
|
||||||
|
def full_name(self):
|
||||||
|
return f"{self.name} ({self.units})" if self.units else self.name
|
||||||
|
|
||||||
|
@full_name.expression
|
||||||
|
def full_name(cls):
|
||||||
|
return cls.name + case([(cls.units != "", " (" + cls.units + ")")], else_="")
|
||||||
|
|
||||||
|
def create(self, db: Session):
|
||||||
|
self.code = db.execute(select(func.coalesce(func.max(Product.code), 0) + 1)).scalar_one()
|
||||||
|
db.add(self)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def can_delete(self, advanced_delete: bool):
|
||||||
|
if self.is_fixture:
|
||||||
|
return False, f"{self.name} is a fixture and cannot be edited or deleted."
|
||||||
|
if self.is_active:
|
||||||
|
return False, "Product is active"
|
||||||
|
if len(self.inventories) > 0 and not advanced_delete:
|
||||||
|
return False, "Product has entries"
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def query(cls, q, is_purchased: bool = None, active: bool = None, db: Session = None):
|
||||||
|
query_ = select(cls)
|
||||||
|
if active is not None:
|
||||||
|
query_ = query_.filter(cls.is_active == active)
|
||||||
|
if is_purchased is not None:
|
||||||
|
query_ = query_.filter(cls.is_purchased == is_purchased)
|
||||||
|
if q is not None:
|
||||||
|
for item in q.split():
|
||||||
|
if item.strip() != "":
|
||||||
|
query_ = query_.filter(cls.name.ilike(f"%{item}%"))
|
||||||
|
return db.execute(query_).scalars().all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suspense(cls):
|
||||||
|
return uuid.UUID("aa79a643-9ddc-4790-ac7f-a41f9efb4c15")
|
@ -11,7 +11,7 @@ from .role_permission import role_permission
|
|||||||
|
|
||||||
|
|
||||||
class Role(Base):
|
class Role(Base):
|
||||||
__tablename__ = "auth_roles"
|
__tablename__ = "roles"
|
||||||
|
|
||||||
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
name = Column("name", Unicode(255), unique=True)
|
name = Column("name", Unicode(255), unique=True)
|
||||||
|
@ -13,6 +13,6 @@ role_permission = Table(
|
|||||||
"role_permissions",
|
"role_permissions",
|
||||||
Base.metadata,
|
Base.metadata,
|
||||||
Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
|
Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
|
||||||
Column("permission_id", UUID(as_uuid=True), ForeignKey("auth_permissions.id")),
|
Column("permission_id", UUID(as_uuid=True), ForeignKey("permissions.id")),
|
||||||
Column("role_id", UUID(as_uuid=True), ForeignKey("auth_roles.id")),
|
Column("role_id", UUID(as_uuid=True), ForeignKey("roles.id")),
|
||||||
)
|
)
|
||||||
|
@ -20,7 +20,7 @@ def encrypt(val):
|
|||||||
|
|
||||||
|
|
||||||
class User(Base):
|
class User(Base):
|
||||||
__tablename__ = "auth_users"
|
__tablename__ = "users"
|
||||||
|
|
||||||
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
name = Column("username", Unicode(255), unique=True)
|
name = Column("username", Unicode(255), unique=True)
|
||||||
|
@ -13,6 +13,6 @@ user_role = Table(
|
|||||||
"user_roles",
|
"user_roles",
|
||||||
Base.metadata,
|
Base.metadata,
|
||||||
Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
|
Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4),
|
||||||
Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id")),
|
Column("user_id", UUID(as_uuid=True), ForeignKey("users.id")),
|
||||||
Column("role_id", UUID(as_uuid=True), ForeignKey("auth_roles.id")),
|
Column("role_id", UUID(as_uuid=True), ForeignKey("roles.id")),
|
||||||
)
|
)
|
||||||
|
@ -21,9 +21,9 @@ class Voucher(Base):
|
|||||||
creation_date = Column("creation_date", DateTime(), nullable=False)
|
creation_date = Column("creation_date", DateTime(), nullable=False)
|
||||||
last_edit_date = Column("last_edit_date", DateTime(), nullable=False)
|
last_edit_date = Column("last_edit_date", DateTime(), nullable=False)
|
||||||
_type = Column("voucher_type", Integer, nullable=False)
|
_type = Column("voucher_type", Integer, nullable=False)
|
||||||
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("auth_users.id"), nullable=False)
|
user_id = Column("user_id", UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
|
||||||
posted = Column("is_posted", Boolean, nullable=False)
|
posted = Column("is_posted", Boolean, nullable=False)
|
||||||
poster_id = Column("poster_id", UUID(as_uuid=True), ForeignKey("auth_users.id"))
|
poster_id = Column("poster_id", UUID(as_uuid=True), ForeignKey("users.id"))
|
||||||
|
|
||||||
user = relationship("User", primaryjoin="User.id==Voucher.user_id", cascade=None)
|
user = relationship("User", primaryjoin="User.id==Voucher.user_id", cascade=None)
|
||||||
poster = relationship("User", primaryjoin="User.id==Voucher.poster_id", cascade=None)
|
poster = relationship("User", primaryjoin="User.id==Voucher.poster_id", cascade=None)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user