-
+
-
+ Get started by editing{" "}
+
+ src/app/page.tsx ++ . +
+ - + Save and see your changes instantly. + +
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae315e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,164 @@ +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +.pdm.toml + +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ +.idea/ + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/ServicesApi/Schemas/__init__.py b/ServicesApi/Schemas/__init__.py new file mode 100644 index 0000000..10125b6 --- /dev/null +++ b/ServicesApi/Schemas/__init__.py @@ -0,0 +1,209 @@ +from schemas.account.account import ( + AccountBooks, + AccountCodes, + AccountCodeParser, + AccountMaster, + AccountDetail, + AccountRecordExchanges, + AccountRecords, +) +from schemas.account.iban import ( + BuildIbans, + BuildIbanDescription, +) +from schemas.address.address import ( + RelationshipEmployee2PostCode, + AddressPostcode, + Addresses, + AddressGeographicLocations, + AddressCountry, + AddressState, + AddressCity, + AddressDistrict, + AddressLocality, + AddressNeighborhood, + AddressStreet, +) +from schemas.building.build import ( + BuildTypes, + Part2Employee, + RelationshipEmployee2Build, + Build, + BuildParts, + BuildLivingSpace, + BuildManagement, + BuildArea, + BuildSites, + BuildCompaniesProviding, + BuildPersonProviding, +) +from schemas.building.decision_book import ( + BuildDecisionBook, + BuildDecisionBookInvitations, + BuildDecisionBookPerson, + BuildDecisionBookPersonOccupants, + BuildDecisionBookItems, + BuildDecisionBookItemsUnapproved, + BuildDecisionBookPayments, + BuildDecisionBookLegal, + BuildDecisionBookProjects, + BuildDecisionBookProjectPerson, + BuildDecisionBookProjectItems, +) +from schemas.building.budget import ( + DecisionBookBudgetBooks, + DecisionBookBudgetCodes, + DecisionBookBudgetMaster, + DecisionBookBudgets, +) +from schemas.company.company import ( + Companies, + RelationshipDutyCompany, +) +from schemas.company.employee import ( + Employees, + EmployeesSalaries, + EmployeeHistory, + Staff, +) +from schemas.company.department import ( + Duty, + Duties, + Departments, +) +from schemas.event.event import ( + Modules, + Services, + Service2Events, + Service2Application, + Events, + Event2Occupant, + Event2Employee, + Event2OccupantExtra, + Event2EmployeeExtra, + Applications, + Application2Employee, + Application2Occupant, + Application2EmployeeExtra, + Application2OccupantExtra, +) +from schemas.identity.identity import ( + UsersTokens, + OccupantTypes, + People, + Users, + Credentials, + RelationshipDutyPeople, + Contracts, +) +from schemas.address.address import ( + Addresses, + AddressCity, + AddressStreet, + AddressLocality, + AddressDistrict, + AddressNeighborhood, + AddressState, + AddressCountry, + AddressPostcode, + AddressGeographicLocations, + RelationshipEmployee2PostCode, +) +from schemas.others.enums import ( + ApiEnumDropdown, +) +from schemas.rules.rules import ( + EndpointRestriction, +) + +__all__ = [ + "AccountBooks", + "AccountCodes", + "AccountCodeParser", + "AccountMaster", + "AccountDetail", + "AccountRecordExchanges", + "AccountRecords", + "BuildIbans", + "BuildIbanDescription", + "RelationshipEmployee2PostCode", + "AddressPostcode", + "Addresses", + "AddressGeographicLocations", + "AddressCountry", + "AddressState", + "AddressCity", + "AddressDistrict", + "AddressLocality", + "AddressNeighborhood", + "AddressStreet", + "BuildTypes", + "Part2Employee", + "RelationshipEmployee2Build", + "Build", + "BuildParts", + "BuildLivingSpace", + "BuildManagement", + "BuildArea", + "BuildSites", + "BuildCompaniesProviding", + "BuildPersonProviding", + "BuildDecisionBook", + "BuildDecisionBookInvitations", + "BuildDecisionBookPerson", + "BuildDecisionBookPersonOccupants", + "BuildDecisionBookItems", + "BuildDecisionBookItemsUnapproved", + "BuildDecisionBookPayments", + "BuildDecisionBookLegal", + "BuildDecisionBookProjects", + "BuildDecisionBookProjectPerson", + "BuildDecisionBookPersonOccupants", + "BuildDecisionBookProjectItems", + "DecisionBookBudgetBooks", + "DecisionBookBudgetCodes", + "DecisionBookBudgetMaster", + "DecisionBookBudgets", + "Companies", + "RelationshipDutyCompany", + "Employees", + "EmployeesSalaries", + "EmployeeHistory", + "Staff", + "Duty", + "Duties", + "Departments", + "Modules", + "Services", + "Service2Events", + "Events", + "Event2Occupant", + "Event2Employee", + "Event2OccupantExtra", + "Event2EmployeeExtra", + "Applications", + "Application2Employee", + "Application2Occupant", + "Addresses", + "AddressCity", + "AddressStreet", + "AddressLocality", + "AddressDistrict", + "AddressNeighborhood", + "AddressState", + "AddressCountry", + "AddressPostcode", + "AddressGeographicLocations", + "UsersTokens", + "OccupantTypes", + "People", + "Users", + "Credentials", + "RelationshipDutyPeople", + "RelationshipEmployee2PostCode", + "Contracts", + "ApiEnumDropdown", + "EndpointRestriction", + "RelationshipEmployee2Build", + # ------------------------------------------------ +] diff --git a/ServicesApi/Schemas/account/account.py b/ServicesApi/Schemas/account/account.py new file mode 100644 index 0000000..22d60f5 --- /dev/null +++ b/ServicesApi/Schemas/account/account.py @@ -0,0 +1,575 @@ +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, +) + + +class AccountBooks(CrudCollection): + + __tablename__ = "account_books" + __exclude__fields__ = [] + + country: Mapped[str] = mapped_column(String, nullable=False) + branch_type: Mapped[int] = mapped_column(SmallInteger, server_default="0") + + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=False) + company_uu_id: Mapped[str] = mapped_column(String, nullable=False) + branch_id: Mapped[int] = mapped_column(ForeignKey("companies.id")) + branch_uu_id: Mapped[str] = mapped_column(String, comment="Branch UU ID") + + __table_args__ = ( + Index("account_companies_book_ndx_00", company_id, "expiry_starts"), + {"comment": "Account Book Information"}, + ) + + +class AccountCodes(CrudCollection): + + __tablename__ = "account_codes" + __exclude__fields__ = [] + + account_code: Mapped[str] = mapped_column( + String(48), nullable=False, comment="Account Code" + ) + comment_line: Mapped[str] = mapped_column( + String(128), nullable=False, comment="Comment Line" + ) + + is_receive_or_debit: Mapped[bool] = mapped_column(Boolean) + product_id: Mapped[int] = mapped_column(Integer, server_default="0") + nvi_id: Mapped[str] = mapped_column(String(48), server_default="") + status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") + account_code_seperator: Mapped[str] = mapped_column(String(1), server_default=".") + + system_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") + locked: Mapped[int] = mapped_column(SmallInteger, server_default="0") + + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id")) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Company UU ID" + ) + customer_id: Mapped[int] = mapped_column(ForeignKey("companies.id")) + customer_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Customer UU ID" + ) + person_id: Mapped[int] = mapped_column(ForeignKey("people.id")) + person_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Person UU ID" + ) + + __table_args__ = ({"comment": "Account Code Information"},) + + +class AccountCodeParser(CrudCollection): + + __tablename__ = "account_code_parser" + __exclude__fields__ = [] + + account_code_1: Mapped[str] = mapped_column(String, nullable=False, comment="Order") + account_code_2: Mapped[str] = mapped_column(String, nullable=False, comment="Order") + account_code_3: Mapped[str] = mapped_column(String, nullable=False, comment="Order") + account_code_4: Mapped[str] = mapped_column(String, server_default="") + account_code_5: Mapped[str] = mapped_column(String, server_default="") + account_code_6: Mapped[str] = mapped_column(String, server_default="") + + account_code_id: Mapped[int] = mapped_column( + ForeignKey("account_codes.id"), nullable=False + ) + account_code_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Account Code UU ID" + ) + + __table_args__ = ( + Index("_account_code_parser_ndx_00", account_code_id), + {"comment": "Account Code Parser Information"}, + ) + + @property + def get_account_code(self): + return f"{self.account_codes.account_code_seperator}".join( + [ + getattr(self, f"account_code_{i}") + for i in range(1, 7) + if getattr(self, f"account_code_{i}") + ] + ) + + +class AccountMaster(CrudCollection): + """ + AccountCodes class based on declarative_base and CrudCollection via session + """ + + __tablename__ = "account_master" + __exclude__fields__ = [] + + doc_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Document Date" + ) + plug_type: Mapped[str] = mapped_column(String, nullable=False, comment="Plug Type") + plug_number: Mapped[int] = mapped_column( + Integer, nullable=False, comment="Plug Number" + ) + + special_code: Mapped[str] = mapped_column(String(12), server_default="") + authorization_code: Mapped[str] = mapped_column(String(12), server_default="") + + doc_code: Mapped[str] = mapped_column(String(12), server_default="") + doc_type: Mapped[int] = mapped_column(SmallInteger, server_default="0") + + comment_line1: Mapped[str] = mapped_column(String, server_default="") + comment_line2: Mapped[str] = mapped_column(String, server_default="") + comment_line3: Mapped[str] = mapped_column(String, server_default="") + comment_line4: Mapped[str] = mapped_column(String, server_default="") + comment_line5: Mapped[str] = mapped_column(String, server_default="") + comment_line6: Mapped[str] = mapped_column(String, server_default="") + project_code: Mapped[str] = mapped_column(String(12), server_default="") + module_no: Mapped[str] = mapped_column(String, server_default="") + journal_no: Mapped[int] = mapped_column(Integer, server_default="0") + + status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") + canceled: Mapped[bool] = mapped_column(Boolean, server_default="0") + print_count: Mapped[int] = mapped_column(SmallInteger, server_default="0") + total_active: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_passive: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_active_1: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_passive_1: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_active_2: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_passive_2: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_active_3: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_passive_3: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_active_4: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + total_passive_4: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + cross_ref: Mapped[int] = mapped_column(Integer, server_default="0") + data_center_id: Mapped[str] = mapped_column(String, server_default="") + data_center_rec_num: Mapped[int] = mapped_column(Integer, server_default="0") + + account_header_id: Mapped[int] = mapped_column( + ForeignKey("account_books.id"), nullable=False + ) + account_header_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Account Header UU ID" + ) + project_item_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_projects.id") + ) + project_item_uu_id: Mapped[str] = mapped_column( + String, comment="Project Item UU ID" + ) + department_id: Mapped[int] = mapped_column(ForeignKey("departments.id")) + department_uu_id: Mapped[str] = mapped_column(String, comment="Department UU ID") + + __table_args__ = ( + Index("_account_master_ndx_00", doc_date, account_header_id), + {"comment": "Account Master Information"}, + ) + + +class AccountDetail(CrudCollection): + """ + AccountCodes class based on declarative_base and CrudCollection via session + """ + + __tablename__ = "account_detail" + __exclude__fields__ = [] + __enum_list__ = [("plug_type", "AccountingReceiptTypes", "M")] + + doc_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Document Date" + ) + line_no: Mapped[int] = mapped_column( + SmallInteger, nullable=False, comment="Line Number" + ) + receive_debit: Mapped[str] = mapped_column( + String(1), nullable=False, comment="Receive Debit" + ) + debit: Mapped[float] = mapped_column( + Numeric(20, 6), nullable=False, comment="Debit" + ) + + department: Mapped[str] = mapped_column(String(24), server_default="") + special_code: Mapped[str] = mapped_column(String(12), server_default="") + account_ref: Mapped[int] = mapped_column(Integer, server_default="0") + account_fiche_ref: Mapped[int] = mapped_column(Integer, server_default="0") + center_ref: Mapped[int] = mapped_column(Integer, server_default="0") + general_code: Mapped[str] = mapped_column(String(32), server_default="") + credit: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + currency_type: Mapped[str] = mapped_column(String(4), server_default="TL") + exchange_rate: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + debit_cur: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + credit_cur: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + discount_cur: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + amount: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + cross_account_code: Mapped[float] = mapped_column(String(32), server_default="") + inf_index: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + not_inflated: Mapped[int] = mapped_column(SmallInteger, server_default="0") + not_calculated: Mapped[int] = mapped_column(SmallInteger, server_default="0") + comment_line1: Mapped[str] = mapped_column(String(64), server_default="") + comment_line2: Mapped[str] = mapped_column(String(64), server_default="") + comment_line3: Mapped[str] = mapped_column(String(64), server_default="") + comment_line4: Mapped[str] = mapped_column(String(64), server_default="") + comment_line5: Mapped[str] = mapped_column(String(64), server_default="") + comment_line6: Mapped[str] = mapped_column(String(64), server_default="") + owner_acc_ref: Mapped[int] = mapped_column(Integer, server_default="0") + from_where: Mapped[int] = mapped_column(Integer, server_default="0") + orj_eid: Mapped[int] = mapped_column(Integer, server_default="0") + canceled: Mapped[int] = mapped_column(SmallInteger, server_default="0") + cross_ref: Mapped[int] = mapped_column(Integer, server_default="0") + data_center_id: Mapped[str] = mapped_column(String, server_default="") + data_center_rec_num: Mapped[int] = mapped_column(Integer, server_default="0") + status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") + + plug_type_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + plug_type_uu_id = mapped_column(String, nullable=False, comment="Plug Type UU ID") + account_header_id: Mapped[int] = mapped_column( + ForeignKey("account_books.id"), nullable=False + ) + account_header_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Account Header UU ID" + ) + account_code_id: Mapped[int] = mapped_column( + ForeignKey("account_codes.id"), nullable=False + ) + account_code_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Account Code UU ID" + ) + account_master_id: Mapped[int] = mapped_column( + ForeignKey("account_master.id"), nullable=False + ) + account_master_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Account Master UU ID" + ) + project_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_projects.id") + ) + project_uu_id: Mapped[str] = mapped_column(String, comment="Project UU ID") + + __table_args__ = ( + Index( + "_account_detail_ndx_00", + account_master_id, + doc_date, + line_no, + account_header_id, + unique=True, + ), + {"comment": "Account Detail Information"}, + ) + + +class AccountRecordExchanges(CrudCollection): + + __tablename__ = "account_record_exchanges" + __exclude__fields__ = [] + + are_currency: Mapped[str] = mapped_column( + String(5), nullable=False, comment="Unit of Currency" + ) + are_exchange_rate: Mapped[float] = mapped_column( + Numeric(18, 6), nullable=False, server_default="1" + ) + usd_exchange_rate_value: Mapped[float] = mapped_column( + Numeric(18, 6), + nullable=True, + server_default="0", + comment="It will be written by multiplying the usd exchange rate with the current value result.", + ) + eur_exchange_rate_value: Mapped[float] = mapped_column( + Numeric(18, 6), + nullable=True, + server_default="0", + comment="It will be written by multiplying the eur exchange rate with the current value result.", + ) + gbp_exchange_rate_value: Mapped[float] = mapped_column( + Numeric(18, 6), + nullable=True, + server_default="0", + comment="It will be written by multiplying the gpd exchange rate with the current value result.", + ) + cny_exchange_rate_value: Mapped[float] = mapped_column( + Numeric(18, 6), + nullable=True, + server_default="0", + comment="It will be written by multiplying the cny exchange rate with the current value result.", + ) + + account_records_id: Mapped[int] = mapped_column(ForeignKey("account_records.id")) + account_records_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Account Record UU ID" + ) + + __table_args__ = ( + Index("_account_record_exchanges_ndx_00", account_records_id), + {"comment": "Account Record Exchanges Information"}, + ) + + +class AccountRecords(CrudCollection): + """ + build_decision_book_id = kaydın sorumlu olduğu karar defteri + send_company_id = kaydı gönderen firma, send_person_id = gönderen kişi + customer_id = sorumlu kullanıcı bilgisi, company_id = sorumlu firma + """ + + __tablename__ = "account_records" + __exclude__fields__ = [] + __enum_list__ = [ + ("receive_debit", "DebitTypes", "D"), + ("budget_type", "BudgetType", "B"), + ] + + iban: Mapped[str] = mapped_column( + String(64), nullable=False, comment="IBAN Number of Bank" + ) + bank_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Bank Transaction Date" + ) + + currency_value: Mapped[float] = mapped_column( + Numeric(20, 6), nullable=False, comment="Currency Value" + ) + bank_balance: Mapped[float] = mapped_column( + Numeric(20, 6), nullable=False, comment="Bank Balance" + ) + currency: Mapped[str] = mapped_column( + String(5), nullable=False, comment="Unit of Currency" + ) + additional_balance: Mapped[float] = mapped_column( + Numeric(20, 6), nullable=False, comment="Additional Balance" + ) + channel_branch: Mapped[str] = mapped_column( + String(120), nullable=False, comment="Branch Bank" + ) + process_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Bank Process Type Name" + ) + process_type: Mapped[str] = mapped_column( + String, nullable=False, comment="Bank Process Type" + ) + process_comment: Mapped[str] = mapped_column( + String, nullable=False, comment="Transaction Record Comment" + ) + process_garbage: Mapped[str] = mapped_column( + String, nullable=True, comment="Transaction Record Garbage" + ) + bank_reference_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Bank Reference Code" + ) + + add_comment_note: Mapped[str] = mapped_column(String, server_default="") + is_receipt_mail_send: Mapped[bool] = mapped_column(Boolean, server_default="0") + found_from = mapped_column(String, server_default="") + similarity: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + remainder_balance: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + + bank_date_y: Mapped[int] = mapped_column(Integer) + bank_date_m: Mapped[int] = mapped_column(SmallInteger) + bank_date_w: Mapped[int] = mapped_column(SmallInteger) + bank_date_d: Mapped[int] = mapped_column(SmallInteger) + + approving_accounting_record: Mapped[bool] = mapped_column( + Boolean, server_default="0" + ) + accounting_receipt_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="1900-01-01 00:00:00" + ) + accounting_receipt_number: Mapped[int] = mapped_column(Integer, server_default="0") + status_id: Mapped[int] = mapped_column(SmallInteger, server_default="0") + + approved_record: Mapped[bool] = mapped_column(Boolean, server_default="0") + import_file_name: Mapped[str] = mapped_column( + String, nullable=True, comment="XLS Key" + ) + + receive_debit: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + receive_debit_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Debit UU ID" + ) + budget_type: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + budget_type_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Budget Type UU ID" + ) + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=True) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Company UU ID" + ) + send_company_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=True + ) + send_company_uu_id = mapped_column( + String, nullable=True, comment="Send Company UU ID" + ) + + send_person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True) + send_person_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Send Person UU ID" + ) + approving_accounting_person: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=True + ) + approving_accounting_person_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Approving Accounting Person UU ID" + ) + + living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=True + ) + living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Living Space UU ID" + ) + customer_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True) + customer_uu_id = mapped_column(String, nullable=True, comment="Customer UU ID") + + build_id: Mapped[int] = mapped_column(ForeignKey("build.id"), nullable=True) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build UU ID" + ) + build_parts_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), nullable=True + ) + build_parts_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build Parts UU ID" + ) + build_decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=True + ) + build_decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build Decision Book UU ID" + ) + + __table_args__ = ( + Index("_budget_records_ndx_00", is_receipt_mail_send, bank_date), + Index( + "_budget_records_ndx_01", + iban, + bank_date, + bank_reference_code, + bank_balance, + unique=True, + ), + Index("_budget_records_ndx_02", status_id, bank_date), + { + "comment": "Bank Records that are related to building and financial transactions" + }, + ) + + # def payment_budget_record_close(self): + # from database_sql_models import ( + # DecisionBookProjectPaymentsMaster, + # ApiEnumDropdown, + # BuildDecisionBook, + # BuildDecisionBookPaymentsMaster, + # ) + # + # budget_record = self + # if self.receive_debit == ApiEnumDropdown.uuid_of_enum( + # enum_class="DebitTypes", key="R" + # ): + # print( + # "This record is not debit. Debit:", + # self.receive_debit, + # "DebitTypes.R.name", + # # str(DebitTypes.R.name), + # ) + # return + # if abs(budget_record.currency_value + budget_record.remainder_balance) > 0: + # payment_dict = { + # "budget_records_id": self.id, + # "build_decision_book_id": budget_record.build_decision_book_id, + # "build_parts_id": budget_record.build_parts_id, + # "start_date": budget_record.bank_date, + # "paid_value": budget_record.currency_value + # - budget_record.remainder_balance, + # "is_all": False, + # } + # (paid_value, start_paid_value, balance) = ( + # float(budget_record.currency_value - budget_record.remainder_balance), + # float(budget_record.currency_value - budget_record.remainder_balance), + # float(budget_record.remainder_balance), + # ) + # print( + # "self.id", + # self.id, + # "paid_value", + # paid_value, + # "start_paid_value", + # start_paid_value, + # "balance", + # balance, + # self.receive_debit, + # ) + # + # if not BuildDecisionBook.find_one( + # id=payment_dict["build_decision_book_id"] + # ): + # return paid_value + # + # if budget_record.replication_id == 55: + # if paid_value > 0: + # payment_dict["dues_type"] = ApiEnumDropdown.uuid_of_enum( + # enum_class="BuildDuesTypes", key="L" + # ) + # paid_value = ( + # DecisionBookProjectPaymentsMaster.pay_law_and_ren_of_build_part( + # **payment_dict + # ) + # ) + # print("dues_type", payment_dict["dues_type"], paid_value) + # if paid_value > 0: + # payment_dict.pop("dues_type", None) + # paid_value = BuildDecisionBookPaymentsMaster.pay_dues_of_build_part( + # **payment_dict + # ) + # print("dues_type", None, paid_value) + # if paid_value > 0: + # payment_dict["dues_type"] = ApiEnumDropdown.uuid_of_enum( + # enum_class="BuildDuesTypes", key="R" + # ) + # paid_value = ( + # DecisionBookProjectPaymentsMaster.pay_law_and_ren_of_build_part( + # **payment_dict + # ) + # ) + # print("dues_type", payment_dict["dues_type"], paid_value) + # payment_dict["is_all"] = True + # if paid_value > 0: + # payment_dict["dues_type"] = ApiEnumDropdown.uuid_of_enum( + # enum_class="BuildDuesTypes", key="L" + # ) + # paid_value = ( + # DecisionBookProjectPaymentsMaster.pay_law_and_ren_of_build_part( + # **payment_dict + # ) + # ) + # print("is all dues_type", payment_dict["dues_type"], paid_value) + # if paid_value > 0: + # payment_dict.pop("dues_type", None) + # paid_value = BuildDecisionBookPaymentsMaster.pay_dues_of_build_part( + # **payment_dict + # ) + # print("is all dues_type", None, paid_value) + # if paid_value > 0: + # payment_dict["dues_type"] = ApiEnumDropdown.uuid_of_enum( + # enum_class="BuildDuesTypes", key="R" + # ) + # paid_value = ( + # DecisionBookProjectPaymentsMaster.pay_law_and_ren_of_build_part( + # **payment_dict + # ) + # ) + # print("is all dues_type", payment_dict["dues_type"], paid_value) diff --git a/ServicesApi/Schemas/account/iban.py b/ServicesApi/Schemas/account/iban.py new file mode 100644 index 0000000..124512a --- /dev/null +++ b/ServicesApi/Schemas/account/iban.py @@ -0,0 +1,83 @@ +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, +) + + +class BuildIbans(CrudCollection): + """ + BuildParts class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_ibans" + __exclude__fields__ = [] + + iban: Mapped[str] = mapped_column( + String(40), server_default="", nullable=False, comment="IBAN number" + ) + start_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Bank Transaction Start Date" + ) + stop_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="2900-01-01 00:00:00" + ) + bank_code: Mapped[str] = mapped_column(String(24), server_default="TR0000000000000") + xcomment: Mapped[str] = mapped_column(String(64), server_default="????") + build_id: Mapped[int] = mapped_column( + ForeignKey("build.id"), nullable=True, comment="Building ID" + ) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Building UUID", index=True + ) + + __table_args__ = ( + Index("_build_ibans_ndx_01", iban, start_date, unique=True), + {"comment": "IBANs related to money transactions due to building objects"}, + ) + + +class BuildIbanDescription(CrudCollection): + """ + SearchComments class based on declarative_base and CrudCollection via session + """ + + __tablename__ = "build_iban_description" + __exclude__fields__ = [] + + iban: Mapped[str] = mapped_column(String, nullable=False, comment="IBAN Number") + group_id: Mapped[int] = mapped_column( + SmallInteger, nullable=False, comment="Group ID" + ) + search_word: Mapped[str] = mapped_column( + String, nullable=False, comment="Search Word", index=True + ) + customer_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True) + customer_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Customer UUID" + ) + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=True) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Company UUID" + ) + build_parts_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), nullable=True + ) + build_parts_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build Parts UUID" + ) + + __table_args__ = ( + Index( + "_search_iban_description_ndx_00", iban, search_word, group_id, unique=True + ), + {"comment": "Search Iban Description Information"}, + ) diff --git a/ServicesApi/Schemas/address/address.py b/ServicesApi/Schemas/address/address.py new file mode 100644 index 0000000..6af5809 --- /dev/null +++ b/ServicesApi/Schemas/address/address.py @@ -0,0 +1,575 @@ +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, + BigInteger, + Text, +) + +class RelationshipEmployee2PostCode(CrudCollection): + """ + Build2EmployeeRelationship class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "relationship_employee2postcode" + __exclude__fields__ = [] + __include__fields__ = [] + + company_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=True + ) # 1, 2, 3 + employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) + member_id: Mapped[int] = mapped_column( + ForeignKey("address_postcode.id"), nullable=False + ) + + relationship_type: Mapped[str] = mapped_column( + String, nullable=True, server_default="Employee" + ) # Commercial + show_only: Mapped[bool] = mapped_column(Boolean, server_default="0") + + __table_args__ = ({"comment": "Build2Employee Relationship Information"},) + + +class AddressPostcode(CrudCollection): + """ + Postcode class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_postcode" + __exclude__fields__ = [] + __access_by__ = [] + __many__table__ = RelationshipEmployee2PostCode + + street_id: Mapped[int] = mapped_column(ForeignKey("address_street.id")) + street_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Street UUID" + ) + postcode: Mapped[str] = mapped_column( + String(32), nullable=False, comment="Postcode" + ) + + __table_args__ = ({"comment": "Postcode Information"},) + + +class Addresses(CrudCollection): + """ + Address class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "addresses" + __exclude__fields__ = [] + + build_number: Mapped[str] = mapped_column( + String(24), nullable=False, comment="Build Number" + ) + door_number: Mapped[str] = mapped_column( + String(24), nullable=True, comment="Door Number" + ) + floor_number: Mapped[str] = mapped_column( + String(24), nullable=True, comment="Floor Number" + ) + + comment_address: Mapped[str] = mapped_column( + String, nullable=False, comment="Address" + ) + letter_address: Mapped[str] = mapped_column( + String, nullable=False, comment="Address" + ) + short_letter_address: Mapped[str] = mapped_column( + String, nullable=False, comment="Address" + ) + + latitude: Mapped[float] = mapped_column(Numeric(20, 12), server_default="0") + longitude: Mapped[float] = mapped_column(Numeric(20, 12), server_default="0") + + street_id: Mapped[int] = mapped_column( + ForeignKey("address_street.id"), nullable=False + ) + street_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Street UUID" + ) + + __table_args__ = ( + # Index("_address_ndx_00", country_code, b_state, city, district), + {"comment": "Address Information"}, + ) + + @classmethod + def list_via_employee(cls, token_dict, filter_expr=None): + with cls.new_session() as db_session: + post_code_list = RelationshipEmployee2PostCode.filter_all( + RelationshipEmployee2PostCode.employee_id + == token_dict.selected_company.employee_id, + db=db_session, + ).data + post_code_id_list = [post_code.member_id for post_code in post_code_list] + if not post_code_id_list: + raise ValueError( + "User has no post code registered. User can not list addresses." + ) + # raise HTTPException( + # status_code=404, + # detail="User has no post code registered. User can not list addresses.", + # ) + cls.pre_query = cls.filter_all( + cls.post_code_id.in_(post_code_id_list), db=db_session + ).query + filter_cls = cls.filter_all(*filter_expr or [], db=db_session) + cls.pre_query = None + return filter_cls.data + + # buildings: Mapped["Build"] = relationship( + # "Build", back_populates="addresses", foreign_keys="Build.address_id" + # ) + # site: Mapped["BuildSites"] = relationship( + # "BuildSites", back_populates="addresses", foreign_keys="BuildSites.address_id" + # ) + # official_companies: Mapped["Companies"] = relationship( + # "Company", + # back_populates="official_address", + # foreign_keys="Company.official_address_id", + # ) + + # @classmethod + # def create_action(cls, request, create_address: InsertAddress): + # from services.redis.auth_actions.token import parse_token_object_to_dict + # + # token_dict = parse_token_object_to_dict(request=request) + # data_dict = create_address.model_dump() + # post_code = AddressPostcode.find_one(uu_id=create_address.post_code_uu_id) + # if not post_code: + # raise HTTPException( + # status_code=404, + # detail="Post code not found.", + # ) + # if Employee2AddressRelationship.post_code_id.find_one( + # employee_id=token_dict.selected_company.employee_id, + # post_code_id=post_code.id, + # ): + # data_dict["post_code_id"] = post_code.id + # del data_dict["post_code_uu_id"] + # return cls.find_or_create(**create_address.model_dump()) + # raise HTTPException( + # status_code=401, + # detail=f"User is not qualified to create address at this post code {post_code.postcode}", + # ) + + # __table_args__ = ( + # Index("_address_ndx_00", country_code, b_state, city, district), + # {"comment": "Address Information"}, + # ) + + +class AddressGeographicLocations(CrudCollection): + """ + Country class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_geographic_locations" + __exclude__fields__ = [] + + geo_table: Mapped[str] = mapped_column( + String, nullable=False, comment="Address Table Name" + ) + geo_id: Mapped[int] = mapped_column( + Integer, nullable=False, comment="Address Table ID" + ) + geo_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Geographic Location Name" + ) + geo_latitude: Mapped[float] = mapped_column( + Numeric(20, 6), server_default="0", comment="Geographic Location Name" + ) + geo_longitude: Mapped[float] = mapped_column( + Numeric(20, 6), server_default="0", comment="Geographic Location Latitude" + ) + geo_altitude: Mapped[float] = mapped_column( + Numeric(20, 6), server_default="0", comment="Geographic Location Longitude" + ) + geo_description: Mapped[str] = mapped_column( + Text, nullable=False, comment="Geographic Location Description" + ) + geo_area_size: Mapped[float] = mapped_column( + Numeric(20, 2), + nullable=True, + server_default="0", + comment="Geographic Location Area Size", + ) + geo_population: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Geographic Location Population" + ) + # geo_geom_point = mapped_column(Geometry('POINT', srid=4326), nullable=True, comment="Geographic Location Points") + # geo_geom_polygon = mapped_column(Geometry('POLYGON', srid=4326), nullable=True, + # comment="Geographic Location Vector geographic information (polygon)") + # geo_centroid = mapped_column( GEOMETRY(POINT, 4326), nullable=True, + # comment="Geographic Location center of gravity of the region(points)") + + __table_args__ = ( + Index("_address_geographic_locations_ndx_00", geo_table, geo_id), + Index("_address_geographic_locations_ndx_01", geo_latitude, geo_longitude), + {"comment": "Geographic Location Information"}, + ) + + +class AddressCountry(CrudCollection): + """ + Country class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_country" + __exclude__fields__ = [] + + country_code: Mapped[str] = mapped_column( + String(16), nullable=False, comment="Country Code" + ) + country_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Country Name" + ) + money_code: Mapped[str] = mapped_column( + String(12), nullable=True, comment="Money Code" + ) + language: Mapped[str] = mapped_column( + String, nullable=True, comment="Language Code" + ) + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + + __table_args__ = ( + Index("_address_country_ndx_00", money_code), + Index("_address_country_ndx_01", country_code, unique=True), + {"comment": "Country Information"}, + ) + + +class AddressState(CrudCollection): + """ + State class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_state" + __exclude__fields__ = [] + + state_code: Mapped[str] = mapped_column( + String(16), nullable=False, comment="State Code" + ) + state_name: Mapped[str] = mapped_column( + String, nullable=False, comment="State Name" + ) + licence_plate: Mapped[str] = mapped_column( + String(24), nullable=True, comment="Sign Code" + ) + phone_code: Mapped[str] = mapped_column( + String(36), nullable=True, comment="Phone Code" + ) + gov_code: Mapped[str] = mapped_column( + String(128), nullable=True, comment="Government Code" + ) + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + + country_id: Mapped[int] = mapped_column(ForeignKey("address_country.id")) + country_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Country UUID" + ) + + __table_args__ = ( + Index( + "_address_state_ndx_01", + country_id, + state_code, + unique=True, + ), + {"comment": "State Information"}, + ) + + +class AddressCity(CrudCollection): + """ + City class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_city" + __exclude__fields__ = [] + + city_code: Mapped[str] = mapped_column( + String(24), nullable=False, comment="City Code" + ) + city_name: Mapped[str] = mapped_column(String, nullable=False, comment="City Name") + licence_plate: Mapped[str] = mapped_column( + String(24), nullable=True, comment="Sign Code" + ) + phone_code: Mapped[str] = mapped_column( + String(36), nullable=True, comment="Phone Code" + ) + gov_code: Mapped[str] = mapped_column( + String(128), nullable=True, comment="Government Code" + ) + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + + state_id: Mapped[int] = mapped_column(ForeignKey("address_state.id")) + state_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="State UUID" + ) + + __table_args__ = ( + Index( + "_address_city_ndx_01", + state_id, + city_code, + unique=True, + ), + {"comment": "City Information"}, + ) + + +class AddressDistrict(CrudCollection): + """ + District class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_district" + __exclude__fields__ = [] + + district_code: Mapped[str] = mapped_column( + String(16), nullable=False, comment="District Code" + ) + district_name: Mapped[str] = mapped_column( + String, nullable=False, comment="District Name" + ) + phone_code: Mapped[str] = mapped_column( + String(36), nullable=True, comment="Phone Code" + ) + gov_code: Mapped[str] = mapped_column( + String(128), nullable=True, comment="Government Code" + ) + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + + city_id: Mapped[int] = mapped_column( + ForeignKey("address_city.id"), nullable=False, comment="City ID" + ) + city_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="City UUID" + ) + + __table_args__ = ( + Index( + "_address_district_ndx_01", + city_id, + district_code, + unique=True, + ), + {"comment": "District Information"}, + ) + + +class AddressLocality(CrudCollection): + """ + Locality class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_locality" + __exclude__fields__ = [] + + locality_code: Mapped[str] = mapped_column( + String(16), nullable=False, comment="Locality Code" + ) + locality_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Locality Name" + ) + type_code: Mapped[str] = mapped_column(String, nullable=True, comment="Type Name") + type_description: Mapped[str] = mapped_column( + String, nullable=True, comment="Type Name" + ) + gov_code: Mapped[str] = mapped_column( + String(128), nullable=True, comment="Government Code" + ) + address_show: Mapped[bool] = mapped_column(Boolean, server_default="1") + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + + district_id: Mapped[int] = mapped_column( + ForeignKey("address_district.id"), nullable=False, comment="District ID" + ) + district_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="District UUID" + ) + + __table_args__ = ( + Index( + "_address_locality_ndx_01", + district_id, + locality_code, + unique=True, + ), + {"comment": "Locality Information"}, + ) + + +class AddressNeighborhood(CrudCollection): + """ + Neighborhood class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_neighborhood" + __exclude__fields__ = [] + + neighborhood_code: Mapped[str] = mapped_column( + String(16), nullable=False, comment="Neighborhood Code" + ) + neighborhood_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Neighborhood Name" + ) + type_code: Mapped[str] = mapped_column(String, nullable=True, comment="Type Name") + type_description: Mapped[str] = mapped_column( + String, nullable=True, comment="Type Name" + ) + gov_code: Mapped[str] = mapped_column( + String(128), nullable=True, comment="Government Code" + ) + address_show: Mapped[bool] = mapped_column(Boolean, server_default="1") + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + + district_id: Mapped[int] = mapped_column( + ForeignKey("address_district.id"), nullable=True, comment="District ID" + ) + district_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="District UUID" + ) + locality_id: Mapped[int] = mapped_column( + ForeignKey("address_locality.id"), nullable=True, comment="Locality ID" + ) + locality_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Locality UUID" + ) + + __table_args__ = ( + Index( + "_address_neighborhood_ndx_01", + locality_id, + neighborhood_code, + unique=True, + ), + {"comment": "Neighborhood Information"}, + ) + + +class AddressStreet(CrudCollection): + """ + Street class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "address_street" + __exclude__fields__ = [] + + street_code: Mapped[str] = mapped_column( + String(16), nullable=False, comment="Street Code" + ) + street_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Street Name" + ) + type_code: Mapped[str] = mapped_column(String, nullable=True, comment="Type Name") + type_description: Mapped[str] = mapped_column( + String, nullable=True, comment="Type Name" + ) + gov_code: Mapped[str] = mapped_column( + String(128), nullable=True, comment="Government Code" + ) + + address_geographic_id: Mapped[int] = mapped_column( + BigInteger, nullable=True, comment="Address Geographic Id" + ) + neighborhood_id: Mapped[int] = mapped_column( + ForeignKey("address_neighborhood.id"), nullable=False, comment="Neighborhood ID" + ) + neighborhood_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Neighborhood UUID" + ) + + __table_args__ = ( + Index("_address_street_ndx_01", neighborhood_id, street_code, unique=True), + {"comment": "Street Information"}, + ) + + @classmethod + def search_address_text(cls, search_text, token_dict=None): + field_dict = { + "AddressStreet.uu_id": cls.uu_id, + "AddressCountry.uu_id": AddressCountry.uu_id, + "AddressState.uu_id": AddressState.uu_id, + "AddressCity.uu_id": AddressCity.uu_id, + "AddressDistrict.uu_id": AddressDistrict.uu_id, + "AddressLocality.uu_id": AddressLocality.uu_id, + "AddressNeighborhood.uu_id": AddressNeighborhood.uu_id, + "AddressCountry.country_name": AddressCountry.country_name, + "AddressState.state_name": AddressState.state_name, + "AddressCity.city_name": AddressCity.city_name, + "AddressDistrict.district_name": AddressDistrict.district_name, + "AddressLocality.locality_name": AddressLocality.locality_name, + "AddressNeighborhood.neighborhood_name": AddressNeighborhood.neighborhood_name, + "AddressStreet.street_name": cls.street_name, + } + joined_data = ( + cls.session.query(*list(field_dict.values())) + .select_from(cls) + .join(AddressNeighborhood, AddressNeighborhood.id == cls.neighborhood_id) + .join( + AddressLocality, AddressLocality.id == AddressNeighborhood.locality_id + ) + .join(AddressDistrict, AddressDistrict.id == AddressLocality.district_id) + .join(AddressCity, AddressCity.id == AddressDistrict.city_id) + .join(AddressState, AddressState.id == AddressCity.state_id) + .join(AddressCountry, AddressCountry.id == AddressState.country_id) + .filter( + or_( + AddressNeighborhood.neighborhood_name.ilike( + f"%{str(search_text).upper()}%" + ), + AddressLocality.locality_name.ilike( + f"%{str(search_text).upper()}%" + ), + AddressDistrict.district_name.ilike( + f"%{str(search_text).upper()}%" + ), + # AddressCity.city_name.ilike(f"%{str(search_text).upper()}%"), + # AddressState.state_name.ilike(f"%{str(search_text).upper()}%"), + # AddressCountry.country_name.ilike(f"%{str(search_text).upper()}%"), + cls.street_name.ilike(f"%{str(search_text).upper()}%"), + ), + ) + ) + # select([mytable.c.id]).where( + # func.to_tsvector('english', mytable.c.title) \ + # .match('somestring', postgresql_regconfig='english') + # ) + joined_statement = joined_data + joined_data = joined_data.first() + if not joined_data: + raise ValueError( + "No address found with the given search text.", + ) + # raise HTTPException( + # status_code=404, + # detail="No address found with the given search text.", + # ) + return dict( + query=joined_statement, + schema=list(field_dict.keys()), + ) diff --git a/ServicesApi/Schemas/base_imports.py b/ServicesApi/Schemas/base_imports.py new file mode 100644 index 0000000..53b6d1d --- /dev/null +++ b/ServicesApi/Schemas/base_imports.py @@ -0,0 +1,24 @@ +from api_controllers.postgres.mixin import CrudCollection +from sqlalchemy.orm import mapped_column, Mapped, relationship +from sqlalchemy import ( + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + text, + or_, + and_, + func, + UUID, + JSON, + BigInteger, + Float, + Text, + LargeBinary, + PickleType, + DATETIME, +) diff --git a/ServicesApi/Schemas/building/budget.py b/ServicesApi/Schemas/building/budget.py new file mode 100644 index 0000000..7b082f7 --- /dev/null +++ b/ServicesApi/Schemas/building/budget.py @@ -0,0 +1,159 @@ +from schemas.base_imports import ( + CrudCollection, + String, + ForeignKey, + Index, + SmallInteger, + TIMESTAMP, + Text, + Numeric, + Integer, + mapped_column, + Mapped, + relationship, + func, +) + + +class DecisionBookBudgetBooks(CrudCollection): + + __tablename__ = "decision_book_budget_books" + __exclude__fields__ = [] + + country: Mapped[str] = mapped_column(String, nullable=False) + branch_type: Mapped[int] = mapped_column(SmallInteger, server_default="0") + + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=False) + company_uu_id: Mapped[str] = mapped_column(String, nullable=False) + branch_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=True) + branch_uu_id: Mapped[str] = mapped_column( + String, comment="Branch UU ID", nullable=True + ) + build_decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=False + ) + build_decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build Decision Book UU ID" + ) + + __table_args__ = ( + Index( + "_decision_book_budget_companies_book_ndx_00", + company_id, + "created_at", + ), + {"comment": "budget Book Information"}, + ) + + +class DecisionBookBudgetCodes(CrudCollection): + + __tablename__ = "decision_book_budget_codes" + __exclude__fields__ = [] + + budget_code: Mapped[str] = mapped_column( + String(48), nullable=False, comment="budget Code" + ) + comment_line: Mapped[str] = mapped_column( + Text, nullable=False, comment="Comment Line" + ) + + build_decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=True + ) + build_decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build Decision Book UU ID" + ) + + build_parts_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), nullable=True + ) + build_parts_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build Parts UU ID" + ) + + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=True) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Company UU ID" + ) + + __table_args__ = ( + Index("_decision_book_budget_codes_ndx_00", budget_code, "created_at"), + Index("_decision_book_budget_codes_ndx_01", company_id, "created_at"), + {"comment": "budget Book Information"}, + ) + + +class DecisionBookBudgetMaster(CrudCollection): + + __tablename__ = "decision_book_budget_master" + __exclude__fields__ = [] + + budget_type: Mapped[str] = mapped_column( + String(50), nullable=False + ) # Bütçe tipi (örneğin: Operasyonel, Yatırım) + currency: Mapped[str] = mapped_column( + String(8), server_default="TRY" + ) # Bütçe para birimi + total_budget: Mapped[float] = mapped_column( + Numeric(10, 2), nullable=False + ) # Toplam bütçe + + tracking_period_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + tracking_period_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Part Direction UUID" + ) + budget_books_id: Mapped[int] = mapped_column( + Integer, ForeignKey("decision_book_budget_books.id"), nullable=False + ) + budget_books_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Budget Books UU ID" + ) + department_id: Mapped[int] = mapped_column( + Integer, ForeignKey("departments.id"), nullable=False + ) # Departman ile ilişki + department_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Department UU ID" + ) + + __table_args__ = ({"comment": "budget Book Information"},) + + +class DecisionBookBudgets(CrudCollection): + + __tablename__ = "decision_book_budgets" + __exclude__fields__ = [] + + process_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False + ) # Başlangıç tarihi + budget_codes_id: Mapped[int] = mapped_column( + Integer, ForeignKey("decision_book_budget_codes.id"), nullable=False + ) + total_budget: Mapped[float] = mapped_column( + Numeric(10, 2), nullable=False + ) # Toplam bütçe + used_budget: Mapped[float] = mapped_column( + Numeric(10, 2), nullable=False, default=0.0 + ) # Kullanılan bütçe + remaining_budget: Mapped[float] = mapped_column( + Numeric(10, 2), nullable=False, default=0.0 + ) # Kullanılan bütçe + + decision_book_budget_master_id: Mapped[int] = mapped_column( + Integer, ForeignKey("decision_book_budget_master.id"), nullable=False + ) + decision_book_budget_master_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Budget Master UU ID" + ) + + __table_args__ = ( + Index( + "_decision_book_budgets_ndx_00", + decision_book_budget_master_uu_id, + process_date, + ), + {"comment": "budget Book Information"}, + ) diff --git a/ServicesApi/Schemas/building/build.py b/ServicesApi/Schemas/building/build.py new file mode 100644 index 0000000..85a9c6a --- /dev/null +++ b/ServicesApi/Schemas/building/build.py @@ -0,0 +1,602 @@ +import arrow +from datetime import timedelta +from typing import List, Union, Any +from schemas.base_imports import ( + CrudCollection, + mapped_column, + Mapped, + relationship, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Text, + Numeric, + or_, + and_, +) + + +class BuildTypes(CrudCollection): + """ + BuildTypes class based on declarative_base and BaseMixin via session + + """ + + __tablename__ = "build_types" + __exclude__fields__ = [] + __include__fields__ = [] + + function_code: Mapped[str] = mapped_column( + String(12), server_default="", nullable=False, comment="Function Code" + ) + type_code: Mapped[str] = mapped_column( + String(12), server_default="", nullable=False, comment="Structure Type Code" + ) + lang: Mapped[str] = mapped_column( + String(4), server_default="TR", nullable=False, comment="Language" + ) + type_name: Mapped[str] = mapped_column( + String(48), server_default="", nullable=False, comment="Type Name" + ) + + __table_args__ = ( + Index("_build_types_ndx_00", type_code, function_code, lang, unique=True), + {"comment": "Function group of building types with their language information"}, + ) + + +class Part2Employee(CrudCollection): + """ + Employee2Parts class based on declarative_base and BaseMixin via session + In between start and end date, a part can be assigned to only one employee + """ + + __tablename__ = "part2employee" + __exclude__fields__ = [] + __include__fields__ = [] + + build_id: Mapped[int] = mapped_column(Integer, comment="Building ID") + part_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), nullable=False, comment="Part ID" + ) + employee_id: Mapped[int] = mapped_column( + ForeignKey("employees.id"), nullable=False, comment="Employee ID" + ) + + __table_args__ = ( + Index("_part2employee_ndx_00", employee_id, part_id, unique=True), + {"comment": "Employee2Parts Information"}, + ) + + +class RelationshipEmployee2Build(CrudCollection): + """ + CompanyRelationship class based on declarative_base and CrudCollection via session + Company -> Sub Company -> Sub-Sub Company + + """ + + __tablename__ = "relationship_employee2build" + __exclude__fields__ = [] + + company_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=False + ) # 1, 2, 3 + employee_id: Mapped[int] = mapped_column( + ForeignKey("employees.id"), nullable=False + ) # employee -> (n)person Evyos LTD + member_id: Mapped[int] = mapped_column( + ForeignKey("build.id"), nullable=False + ) # 2, 3, 4 + + relationship_type: Mapped[str] = mapped_column( + String, nullable=True, server_default="Employee" + ) # Commercial + show_only: Mapped[bool] = mapped_column(Boolean, server_default="False") + + __table_args__ = ( + Index( + "relationship_build_employee_ndx_00", + company_id, + employee_id, + member_id, + relationship_type, + unique=True, + ), + {"comment": "Build & Employee Relationship Information"}, + ) + + +class Build(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build" + __exclude__fields__ = [] + __include__fields__ = [] + __access_by__ = [] + # __many__table__ = RelationshipEmployee2Build + + gov_address_code: Mapped[str] = mapped_column(String, server_default="", unique=True) + build_name: Mapped[str] = mapped_column(String, nullable=False, comment="Building Name") + build_no: Mapped[str] = mapped_column(String(8), nullable=False, comment="Building Number") + + max_floor: Mapped[int] = mapped_column(Integer, server_default="1", nullable=False, comment="Max Floor") + underground_floor: Mapped[int] = mapped_column(Integer, server_default="0", nullable=False, comment="Underground Floor") + build_date: Mapped[TIMESTAMP] = mapped_column(TIMESTAMP(timezone=True), server_default="1900-01-01") + decision_period_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), + server_default="1900-01-01", + comment="Building annual ordinary meeting period", + ) + tax_no: Mapped[str] = mapped_column(String(24), server_default="") + lift_count: Mapped[int] = mapped_column(Integer, server_default="0") + heating_system: Mapped[bool] = mapped_column(Boolean, server_default="True") + cooling_system: Mapped[bool] = mapped_column(Boolean, server_default="False") + hot_water_system: Mapped[bool] = mapped_column(Boolean, server_default="False") + block_service_man_count: Mapped[int] = mapped_column(Integer, server_default="0") + security_service_man_count: Mapped[int] = mapped_column(Integer, server_default="0") + garage_count: Mapped[int] = mapped_column(Integer, server_default="0", comment="Garage Count") + management_room_id: Mapped[int] = mapped_column(Integer, nullable=True, comment="Management Room ID") + + site_id: Mapped[int] = mapped_column(ForeignKey("build_sites.id"), nullable=True) + site_uu_id: Mapped[str] = mapped_column(String, comment="Site UUID", nullable=True) + address_id: Mapped[int] = mapped_column(ForeignKey("addresses.id"), nullable=False) + address_uu_id: Mapped[str] = mapped_column(String, comment="Address UUID", nullable=False) + build_types_id: Mapped[int] = mapped_column(ForeignKey("build_types.id"), nullable=False, comment="Building Type") + build_types_uu_id: Mapped[str] = mapped_column(String, comment="Building Type UUID") + + parts: Mapped[List["BuildParts"]] = relationship("BuildParts", back_populates="buildings", foreign_keys="BuildParts.build_id") + decision_books: Mapped[List["BuildDecisionBook"]] = relationship( + "BuildDecisionBook", + back_populates="buildings", + foreign_keys="BuildDecisionBook.build_id", + ) + + # build_ibans: Mapped["BuildIbans"] = relationship( + # "BuildIbans", back_populates="building", foreign_keys="BuildIbans.build_id" + # ) + # areas: Mapped["BuildArea"] = relationship( + # "BuildArea", back_populates="buildings", foreign_keys="BuildArea.build_id" + # ) + # response_companies: Mapped["Companies"] = relationship( + # "Companies", + # back_populates="response_buildings", + # foreign_keys=[response_company_id], + # ) + # addresses: Mapped[List["Address"]] = relationship( + # "Address", back_populates="buildings", foreign_keys=[address_id] + # ) + # peoples: Mapped["People"] = relationship( + # "People", back_populates="buildings", foreign_keys=[people_id] + # ) + # sites: Mapped["BuildSites"] = relationship( + # "BuildSites", back_populates="buildings", foreign_keys=[site_id] + # ) + + __table_args__ = ( + Index("_builds_ndx_00", gov_address_code), + Index("_builds_ndx_01", build_name, build_no), + { + "comment": "Build objects are building that are created for living and store purposes" + }, + ) + + @property + def management_room(self): + with self.new_session() as db_session: + if management_room := BuildParts.filter_by_one( + system=True, id=self.management_room_id, build_id=self.id, db=db_session + ).data: + return management_room + return None + + @property + def top_flat(self): + max_flat_no = 0 + for part in self.parts: + if part.part_no > self.max_floor: + max_flat_no = part.part_no + return max_flat_no + + @property + def bottom_flat(self): + min_flat_no = 0 + for part in self.parts: + if part.part_no < self.max_floor: + min_flat_no = part.part_no + return min_flat_no + + @property + def human_livable_parts(self) -> tuple: + parts = list(part for part in self.parts if part.human_livable) + return parts, len(parts) + + @property + def livable_part_count(self): + with self.new_session() as db_session: + livable_parts = BuildParts.filter_all( + BuildParts.build_id == self.id, + BuildParts.human_livable == True, + db=db_session, + ) + if not livable_parts.data: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="There is no livable part in this building.", + ) + return livable_parts.count + + @property + def part_type_count(self): + with self.new_session() as db_session: + building_types = None + for part in self.parts: + building_types = {} + build_type = BuildTypes.filter_by_one( + system=True, id=part.build_part_type_id, db=db_session + ).data + if build_type.type_code in building_types: + building_types[build_type.type_code]["list"].append(part.part_no) + else: + building_types[build_type.type_code] = {"list": [part.part_no]} + + # for key, val in building_types.items(): + # list_parts = val["list"] + # building_types[key] = { + # "list": list_parts, + # "min": min(list_parts), + # "max": max(list_parts), + # "count": len(list_parts), + # } + return building_types + + +class BuildParts(CrudCollection): + """ + BuildParts class based on declarative_base and BaseMixin via session + Attentions: Part_no is unique for each building and Every building must have a management section.!!! default no 0 + """ + + __tablename__ = "build_parts" + __exclude__fields__ = [] + __include__fields__ = [] + __enum_list__ = [("part_direction", "Directions", "NN")] + + # https://adres.nvi.gov.tr/VatandasIslemleri/AdresSorgu + address_gov_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Goverment Door Code" + ) + # part_name: Mapped[str] = mapped_column(String(24), server_default="", nullable=False, comment="Part Name") + part_no: Mapped[int] = mapped_column( + Integer, server_default="0", nullable=False, comment="Part Number" + ) + part_level: Mapped[int] = mapped_column( + Integer, server_default="0", comment="Building Part Level" + ) + part_code: Mapped[str] = mapped_column( + String, server_default="", nullable=False, comment="Part Code" + ) + part_gross_size: Mapped[int] = mapped_column( + Integer, server_default="0", comment="Part Gross Size" + ) + part_net_size: Mapped[int] = mapped_column( + Integer, server_default="0", comment="Part Net Size" + ) + default_accessory: Mapped[str] = mapped_column( + Text, server_default="0", comment="Default Accessory" + ) + human_livable: Mapped[bool] = mapped_column( + Boolean, server_default="1", comment="Human Livable" + ) + due_part_key: Mapped[str] = mapped_column( + String, server_default="", nullable=False, comment="Constant Payment Group" + ) + + build_id: Mapped[int] = mapped_column( + ForeignKey("build.id"), nullable=False, comment="Building ID" + ) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Building UUID" + ) + part_direction_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + part_direction_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Part Direction UUID" + ) + part_type_id: Mapped[int] = mapped_column( + ForeignKey("build_types.id"), nullable=False, comment="Building Part Type" + ) + part_type_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Building Part Type UUID" + ) + + buildings: Mapped["Build"] = relationship( + "Build", back_populates="parts", foreign_keys=[build_id] + ) + + __table_args__ = ( + Index("build_parts_ndx_1", build_id, part_no, unique=True), + {"comment": "Part objects that are belong to building objects"}, + ) + + def part_name(self, db): + if build_type := BuildTypes.filter_by_one( + system=True, id=self.part_type_id, db=db + ).data: + return f"{str(build_type.type_name).upper()} : {str(self.part_no).upper()}" + return f"Undefined:{str(build_type.type_name).upper()}" + + +class BuildLivingSpace(CrudCollection): + """ + LivingSpace class based on declarative_base and BaseMixin via session + Owner or live person = Occupant of the build part + + Query OR(owner_person_id == person_id, life_person_id == person_id) AND (now(date)) + """ + + __tablename__ = "build_living_space" + __exclude__fields__ = [] + __include__fields__ = [] + + fix_value: Mapped[float] = mapped_column( + Numeric(20, 6), + server_default="0", + comment="Fixed value is deducted from debit.", + ) + fix_percent: Mapped[float] = mapped_column( + Numeric(6, 2), + server_default="0", + comment="Fixed percent is deducted from debit.", + ) + + agreement_no: Mapped[str] = mapped_column( + String, server_default="", comment="Agreement No" + ) + marketing_process: Mapped[bool] = mapped_column(Boolean, server_default="False") + marketing_layer: Mapped[int] = mapped_column(Integer, server_default="0") + + build_parts_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), + nullable=False, + index=True, + comment="Build Part ID", + ) + build_parts_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Part UUID" + ) + person_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), + nullable=False, + index=True, + comment="Responsible People ID", + ) + person_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Responsible People UUID" + ) + occupant_type_id: Mapped[int] = mapped_column( + ForeignKey("occupant_types.id"), + nullable=False, + comment="Occupant Type", + ) + occupant_type_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Occupant Type UUID" + ) + + __table_args__ = ( + {"comment": "Living Space inside building parts that are related to people"}, + ) + + @classmethod + def find_living_from_customer_id( + cls, customer_id, process_date, add_days: int = 32 + ): + with cls.new_session() as db_session: + formatted_date = arrow.get(str(process_date)) + living_spaces = cls.filter_all( + or_( + cls.owner_person_id == customer_id, + cls.life_person_id == customer_id, + ), + cls.start_date < formatted_date - timedelta(days=add_days), + cls.stop_date > formatted_date + timedelta(days=add_days), + db=db_session, + ) + return living_spaces.data, living_spaces.count + + +class BuildManagement(CrudCollection): + + __tablename__ = "build_management" + __exclude__fields__ = [] + + discounted_percentage: Mapped[float] = mapped_column( + Numeric(6, 2), server_default="0.00" + ) # %22 + discounted_price: Mapped[float] = mapped_column( + Numeric(20, 2), server_default="0.00" + ) # Normal: 78.00 TL + calculated_price: Mapped[float] = mapped_column( + Numeric(20, 2), server_default="0.00" + ) # sana düz 75.00 TL yapar + + occupant_type: Mapped[int] = mapped_column( + ForeignKey("occupant_types.id"), + nullable=False, + comment="Occupant Type", + ) + occupant_type_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Occupant Type UUID" + ) + build_id: Mapped[int] = mapped_column( + ForeignKey("build.id"), nullable=False, comment="Building ID" + ) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Building UUID" + ) + build_parts_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), + nullable=False, + index=True, + comment="Build Part ID", + ) + build_parts_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Part UUID" + ) + + __table_args__ = ( + Index( + "build_management_ndx_00", + build_parts_id, + occupant_type, + "expiry_starts", + unique=True, + ), + {"comment": "Management of the building parts that are related to people"}, + ) + + +class BuildArea(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_area" + __exclude__fields__ = [] + + area_name: Mapped[str] = mapped_column(String, server_default="") + area_code: Mapped[str] = mapped_column(String, server_default="") + area_type: Mapped[str] = mapped_column(String, server_default="GREEN") + area_direction: Mapped[str] = mapped_column(String(2), server_default="NN") + area_gross_size: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + area_net_size: Mapped[float] = mapped_column(Numeric(20, 6), server_default="0") + width = mapped_column(Integer, server_default="0") + size = mapped_column(Integer, server_default="0") + + build_id: Mapped[int] = mapped_column(ForeignKey("build.id")) + build_uu_id: Mapped[str] = mapped_column(String, comment="Building UUID") + part_type_id: Mapped[int] = mapped_column( + ForeignKey("build_types.id"), nullable=True, comment="Building Part Type" + ) + part_type_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Building Part Type UUID" + ) + + # buildings: Mapped["Build"] = relationship( + # "Build", back_populates="areas", foreign_keys=[build_id] + # ) + + _table_args_ = ( + Index("_edm_build_parts_area_ndx_00", build_id, area_code, unique=True), + ) + + +class BuildSites(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_sites" + __exclude__fields__ = [] + __include__fields__ = [] + + site_name: Mapped[str] = mapped_column(String(24), nullable=False) + site_no: Mapped[str] = mapped_column(String(8), nullable=False) + + address_id: Mapped[int] = mapped_column(ForeignKey("addresses.id")) + address_uu_id: Mapped[str] = mapped_column(String, comment="Address UUID") + + # addresses: Mapped["Address"] = relationship( + # "Address", back_populates="site", foreign_keys=[address_id] + # ) + # buildings: Mapped["Build"] = relationship( + # "Build", back_populates="sites", foreign_keys="Build.site_id" + # ) + + __table_args__ = ( + Index("_sites_ndx_01", site_no, site_name), + {"comment": "Sites that groups building objets"}, + ) + + +class BuildCompaniesProviding(CrudCollection): + """ """ + + __tablename__ = "build_companies_providing" + __exclude__fields__ = [] + __include__fields__ = [] + + build_id = mapped_column( + ForeignKey("build.id"), nullable=False, comment="Building ID" + ) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Providing UUID" + ) + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id")) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Providing UUID" + ) + provide_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + provide_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Providing UUID" + ) + contract_id: Mapped[int] = mapped_column( + Integer, ForeignKey("companies.id"), nullable=True + ) + + __table_args__ = ( + Index( + "_build_companies_providing_ndx_00", + build_id, + company_id, + provide_id, + unique=True, + ), + {"comment": "Companies providing services for building"}, + ) + + +class BuildPersonProviding(CrudCollection): + """ """ + + __tablename__ = "build_person_providing" + __exclude__fields__ = [] + __include__fields__ = [] + + build_id = mapped_column( + ForeignKey("build.id"), nullable=False, comment="Building ID" + ) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Providing UUID" + ) + people_id: Mapped[int] = mapped_column(ForeignKey("people.id")) + people_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="People UUID" + ) + provide_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + provide_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Providing UUID" + ) + contract_id: Mapped[int] = mapped_column( + Integer, ForeignKey("companies.id"), nullable=True + ) + + __table_args__ = ( + Index( + "_build_person_providing_ndx_00", + build_id, + people_id, + provide_id, + unique=True, + ), + {"comment": "People providing services for building"}, + ) diff --git a/ServicesApi/Schemas/building/decision_book.py b/ServicesApi/Schemas/building/decision_book.py new file mode 100644 index 0000000..ed0f706 --- /dev/null +++ b/ServicesApi/Schemas/building/decision_book.py @@ -0,0 +1,888 @@ +import math +import arrow +from datetime import datetime, timedelta +from decimal import Decimal +from typing import List, Any +from fastapi import HTTPException, status + +from schemas.base_imports import ( + CrudCollection, + String, + ForeignKey, + Index, + SmallInteger, + Boolean, + TIMESTAMP, + Text, + Numeric, + Integer, + mapped_column, + Mapped, + relationship, +) + + +class BuildDecisionBook(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + The start dates of the decision log periods are determined from the 'decision_period_date' field in the decision log table within the building information. + decision_period_date = Her yıl yapılan karar toplantısı + 365 gün her yıl tekrar eden + decision_book_pdf_path: Karar defteri pdf dosyasının yolu + resp_company_fix_wage: Karar defterinin oluşmasını sağlayan dışardaki danışmanlık ücreti + is_out_sourced: Karar defterinin dışardan alınan hizmetle oluşturulup oluşturulmadığı + contact_agreement_path: Karar defterinin oluşmasını sağlayan dışardaki danışmanlık anlaşması dosyasının yolu + contact_agreement_date: Karar defterinin oluşmasını sağlayan dışardaki danışmanlık anlaşma tarihi + meeting_date: Karar defterinin oluşmasını sağlayan toplantı tarihi + decision_type: Karar defterinin tipi (Bina Yönetim Toplantısı (BYT), Yıllık Acil Toplantı (YAT) + """ + + __tablename__ = "build_decision_book" + __exclude__fields__ = [] + + decision_book_pdf_path: Mapped[str] = mapped_column( + String, server_default="", nullable=True + ) + resp_company_fix_wage: Mapped[float] = mapped_column( + Numeric(10, 2), server_default="0" + ) # + is_out_sourced: Mapped[bool] = mapped_column(Boolean, server_default="0") + meeting_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="1900-01-01" + ) + decision_type: Mapped[str] = mapped_column(String(3), server_default="RBM") + meeting_is_completed: Mapped[bool] = mapped_column(Boolean, server_default="0") + meeting_completed_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=True, comment="Meeting Completed Date" + ) + + build_id: Mapped[int] = mapped_column(ForeignKey("build.id"), nullable=False) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build UUID" + ) + resp_company_id: Mapped[int] = mapped_column(ForeignKey("companies.id")) + resp_company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Company UUID" + ) + contact_id: Mapped[int] = mapped_column( + ForeignKey("contracts.id"), nullable=True, comment="Contract id" + ) + contact_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Contract UUID" + ) + + buildings: Mapped["Build"] = relationship( + "Build", + back_populates="decision_books", + foreign_keys=build_id, + ) + decision_book_items: Mapped[List["BuildDecisionBookItems"]] = relationship( + "BuildDecisionBookItems", + back_populates="decision_books", + foreign_keys="BuildDecisionBookItems.build_decision_book_id", + ) + + __table_args__ = ( + Index("build_decision_book_ndx_011", meeting_date, build_id), + Index("build_decision_book_ndx_011", build_id, "expiry_starts", "expiry_ends"), + { + "comment": "Decision Book objects that are related to decision taken at building meetings" + }, + ) + + @classmethod + def retrieve_active_rbm(cls): + from Schemas.building.build import Build + + with cls.new_session() as db_session: + related_build = Build.find_one(id=cls.build_id) + related_date = arrow.get(related_build.build_date) + date_processed = related_date.replace( + year=arrow.now().date().year, month=related_date.month, day=1 + ) + if arrow.now().date() <= date_processed: + book = cls.filter_one( + cls.expiry_ends <= date_processed, + cls.decision_type == "RBM", + cls.build_id == related_build.id, + db=db_session, + ).data + if not book: + cls.raise_http_exception( + status_code="HTTP_404_NOT_FOUND", + error_case="NOTFOUND", + message=f"Decision Book is not found for {related_build.build_name}-RBM", + data=dict( + build_id=str(related_build.uu_id), + build_name=related_build.build_name, + decision_type="RBM", + ), + ) + return book + return + + @property + def semester(self): + start_format = "".join( + [str(self.expiry_starts.year), "-", str(self.expiry_starts.month)] + ) + end_format = "".join( + [str(self.expiry_ends.year), "-", str(self.expiry_ends.month)] + ) + return "".join([start_format, " ", end_format]) + + def check_book_is_valid(self, bank_date: str): + if all( + [True if letter in str(bank_date) else False for letter in ["-", " ", ":"]] + ): + bank_date = datetime.strptime(str(bank_date), "%Y-%m-%d %H:%M:%S") + date_valid = ( + arrow.get(self.expiry_starts) + < arrow.get(bank_date) + < arrow.get(self.expiry_ends) + ) + return date_valid and self.active and not self.deleted + + # @classmethod + # def retrieve_valid_book(cls, bank_date, iban): + # from Schemas import ( + # BuildIbans, + # ) + # with cls.new_session() as db_session: + # if all( + # [True if letter in str(bank_date) else False for letter in ["-", " ", ":"]] + # ): + # bank_date = datetime.strptime(str(bank_date), "%Y-%m-%d %H:%M:%S") + # build_iban = BuildIbans.find_one(iban=iban) + # decision_book: cls = cls.filter_one( + # cls.build_id == build_iban.build_id, + # cls.expiry_starts < bank_date, + # cls.expiry_ends > bank_date, + # cls.active == True, + # cls.deleted == False, + # db=db_session + # ).data + # decision_book.check_book_is_valid(bank_date.__str__()) + # return decision_book + # return + + +class BuildDecisionBookInvitations(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_decision_book_invitations" + __exclude__fields__ = [] + + build_id: Mapped[int] = mapped_column(Integer, nullable=False) + build_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Build UUID" + ) + decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=False + ) + decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book UUID" + ) + + invitation_type: Mapped[str] = mapped_column( + String, nullable=False, comment="Invite Type" + ) + invitation_attempt: Mapped[int] = mapped_column(SmallInteger, server_default="1") + living_part_count: Mapped[int] = mapped_column(SmallInteger, server_default="1") + living_part_percentage: Mapped[float] = mapped_column( + Numeric(10, 2), server_default="0.51" + ) + + message: Mapped[str] = mapped_column( + Text, nullable=True, comment="Invitation Message" + ) + planned_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Planned Meeting Date" + ) + planned_date_expires: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Planned Meeting Date Expires" + ) + + __table_args__ = ( + Index( + "_build_decision_book_invitations_ndx_01", + invitation_type, + planned_date, + invitation_attempt, + unique=True, + ), + {"comment": "People that are invited to building meetings."}, + ) + + @classmethod + def check_invites_are_ready_for_meeting(cls, selected_decision_book, token_dict): + with cls.new_session() as db_session: + first_book_invitation = BuildDecisionBookInvitations.filter_one( + BuildDecisionBookInvitations.build_id + == token_dict.selected_occupant.build_id, + BuildDecisionBookInvitations.decision_book_id + == selected_decision_book.id, + BuildDecisionBookInvitations.invitation_attempt == 1, + db=db_session, + ).data + if not first_book_invitation: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"First Meeting Invitation is not found for Decision Book UUID : {selected_decision_book.uu_id}", + ) + need_attend_count = int(first_book_invitation.living_part_count) * Decimal( + first_book_invitation.living_part_percentage + ) + valid_invite_count = ( + BuildDecisionBookPerson.filter_all_system( + BuildDecisionBookPerson.invite_id == first_book_invitation.id, + BuildDecisionBookPerson.build_decision_book_id + == selected_decision_book.id, + BuildDecisionBookPerson.is_attending == True, + db=db_session, + ) + .query.distinct(BuildDecisionBookPerson.person_id) + .count() + ) + + second_book_invitation = BuildDecisionBookInvitations.filter_one_system( + BuildDecisionBookInvitations.build_id + == token_dict.selected_occupant.build_id, + BuildDecisionBookInvitations.decision_book_id + == selected_decision_book.id, + BuildDecisionBookInvitations.invitation_attempt == 2, + db=db_session, + ).data + if ( + not valid_invite_count >= need_attend_count + and not second_book_invitation + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"In order meeting to be held, {math.ceil(need_attend_count)} people must attend " + f"to the meeting. Only {valid_invite_count} people are attending to the meeting.", + ) + return first_book_invitation or second_book_invitation + + +class BuildDecisionBookPerson(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + Karar Defteri toplantılarına katılan kişiler veya yetkililer + dues_percent_discount: Katılımcının aidat indirim oranı Aidatdan yüzde indirim alır + dues_fix_discount: Katılımcının aidat sabit miktarı Aidatdan sabit bir miktar indirim alır + dues_discount_approval_date: Bu kişinin indiriminin onayladığı tarih + management_typecode: Kişinin toplantı görevi + """ + + __tablename__ = "build_decision_book_person" + __exclude__fields__ = [] + __enum_list__ = [("management_typecode", "BuildManagementType", "bm")] + + dues_percent_discount: Mapped[int] = mapped_column(SmallInteger, server_default="0") + dues_fix_discount: Mapped[float] = mapped_column(Numeric(10, 2), server_default="0") + dues_discount_approval_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="1900-01-01 00:00:00" + ) + send_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Confirmation Date" + ) + is_attending: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Occupant is Attending to invitation" + ) + confirmed_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=True, comment="Confirmation Date" + ) + token: Mapped[str] = mapped_column( + String, server_default="", comment="Invitation Token" + ) + + vicarious_person_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=True, comment="Vicarious Person ID" + ) + vicarious_person_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Vicarious Person UUID" + ) + + invite_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_invitations.id"), nullable=False + ) + invite_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Invite UUID" + ) + + build_decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=False + ) + build_decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Decision Book UUID" + ) + build_living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + build_living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Living Space UUID" + ) + person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=False) + # person_uu_id: Mapped[str] = mapped_column(String, nullable=False, comment="Person UUID") + + __table_args__ = ( + Index( + "_build_decision_book_person_ndx_01", + build_decision_book_id, + invite_id, + build_living_space_id, + unique=True, + ), + {"comment": "People that are attended to building meetings."}, + ) + + def retrieve_all_occupant_types(self): + with self.new_session() as db_session: + all_decision_book_people = self.filter_all_system( + BuildDecisionBookPersonOccupants.invite_id == self.invite_id, + db=db_session, + ) + BuildDecisionBookPersonOccupants.pre_query = all_decision_book_people.query + return BuildDecisionBookPersonOccupants.filter_all_system( + db=db_session + ).data + + def get_occupant_types(self): + with self.new_session() as db_session: + if occupants := BuildDecisionBookPersonOccupants.filter_all( + BuildDecisionBookPersonOccupants.build_decision_book_person_id + == self.id, + db=db_session, + ).data: + return occupants + return + + def check_occupant_type(self, occupant_type): + with self.new_session() as db_session: + book_person_occupant_type = BuildDecisionBookPersonOccupants.filter_one( + BuildDecisionBookPersonOccupants.build_decision_book_person_id + == self.id, + BuildDecisionBookPersonOccupants.occupant_type_id == occupant_type.id, + BuildDecisionBookPersonOccupants.active == True, + BuildDecisionBookPersonOccupants.is_confirmed == True, + db=db_session, + ).data + if not book_person_occupant_type: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Occupant Type : {occupant_type.occupant_code} is not found in " + f"Decision Book Person UUID {self.uu_id}", + ) + + +class BuildDecisionBookPersonOccupants(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_decision_book_person_occupants" + __exclude__fields__ = [] + + build_decision_book_person_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_person.id"), nullable=False + ) + build_decision_book_person_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Person UUID" + ) + invite_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_invitations.id"), nullable=True + ) + invite_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Invite UUID" + ) + + occupant_type_id: Mapped[int] = mapped_column( + ForeignKey("occupant_types.id"), nullable=False + ) + occupant_type_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Occupant UUID" + ) + + __table_args__ = ( + Index( + "_build_decision_book_person_occupants_ndx_01", + build_decision_book_person_id, + occupant_type_id, + unique=True, + ), + {"comment": "Occupant Types of People that are attended to building meetings."}, + ) + + +class BuildDecisionBookItems(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + item_commentary = metine itiraz şerh maddesi için + item_order = maddelerin sıralanma numarası + item_objection = maddelerin itiraz şerhi Text şeklinde + """ + + __tablename__ = "build_decision_book_items" + __exclude__fields__ = [] + + item_order: Mapped[int] = mapped_column( + SmallInteger, nullable=False, comment="Order Number of Item" + ) + item_comment: Mapped[str] = mapped_column( + Text, nullable=False, comment="Comment Content" + ) + item_objection: Mapped[str] = mapped_column( + Text, nullable=True, comment="Objection Content" + ) + info_is_completed: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Info process is Completed" + ) + is_payment_created: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Are payment Records Created" + ) + + info_type_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + info_type_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Info Type UUID" + ) + + build_decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=False + ) + build_decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book UUID" + ) + item_short_comment: Mapped[str] = mapped_column( + String(24), + nullable=True, + comment="This field is reserved for use in grouping data or in the pivot heading.", + ) + + decision_books: Mapped["BuildDecisionBook"] = relationship( + "BuildDecisionBook", + back_populates="decision_book_items", + foreign_keys=[build_decision_book_id], + ) + decision_book_project: Mapped["BuildDecisionBookProjects"] = relationship( + "BuildDecisionBookProjects", + back_populates="build_decision_book_item", + foreign_keys="BuildDecisionBookProjects.build_decision_book_item_id", + ) + + __table_args__ = ( + Index("_build_decision_book_item_ndx_01", build_decision_book_id), + Index( + "_build_decision_book_item_ndx_02", + build_decision_book_id, + item_order, + unique=True, + ), + { + "comment": "Decision Book Items that are related to decision taken at building meetings" + }, + ) + + +class BuildDecisionBookItemsUnapproved(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session unapproved personnel + """ + + __tablename__ = "build_decision_book_items_unapproved" + __exclude__fields__ = [] + + item_objection: Mapped[str] = mapped_column( + Text, nullable=False, comment="Objection Content" + ) + item_order: Mapped[int] = mapped_column( + SmallInteger, nullable=False, comment="Order Number" + ) + + decision_book_item_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_items.id"), nullable=False + ) + decision_book_item_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Item" + ) + person_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=False) + person_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Person UUID" + ) + build_decision_book_item: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_items.id"), nullable=False + ) + build_decision_book_item_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Item UUID" + ) + + __table_args__ = ( + Index("_build_decision_book_item_unapproved_ndx_01", build_decision_book_item), + { + "comment": "People that are unapproved partially or completely in decision book items" + }, + ) + + +class BuildDecisionBookPayments(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + period_time = to_char(NEW.process_date, 'YYYY-MM'); + """ + + __tablename__ = "build_decision_book_payments" + __exclude__fields__ = [] + __enum_list__ = [("receive_debit", "DebitTypes", "D")] + + payment_plan_time_periods: Mapped[str] = mapped_column( + String(10), nullable=False, comment="Payment Plan Time Periods" + ) + process_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Payment Due Date" + ) + payment_amount: Mapped[float] = mapped_column( + Numeric(16, 2), nullable=False, comment="Payment Amount" + ) + currency: Mapped[str] = mapped_column(String(8), server_default="TRY") + + payment_types_id: Mapped[int] = mapped_column( + ForeignKey("api_enum_dropdown.id"), nullable=True + ) + payment_types_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Dues Type UUID" + ) + + period_time: Mapped[str] = mapped_column(String(12)) + process_date_y: Mapped[int] = mapped_column(SmallInteger) + process_date_m: Mapped[int] = mapped_column(SmallInteger) + + build_decision_book_item_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_items.id"), + nullable=False, + comment="Build Decision Book Item ID", + ) + build_decision_book_item_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Decision Book Item UUID" + ) + # build_decision_book_id: Mapped[int] = mapped_column( + # ForeignKey("build_decision_book.id"), nullable=True + # ) + # build_decision_book_uu_id: Mapped[str] = mapped_column( + # String, nullable=True, comment="Decision Book UUID" + # ) + build_parts_id: Mapped[int] = mapped_column( + ForeignKey("build_parts.id"), nullable=False + ) + build_parts_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Part UUID" + ) + decision_book_project_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_projects.id"), + nullable=True, + comment="Decision Book Project ID", + ) + decision_book_project_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Project UUID" + ) + account_records_id: Mapped[int] = mapped_column( + ForeignKey("account_records.id"), nullable=True + ) + account_records_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Account Record UU ID" + ) + + # budget_records_id: Mapped[int] = mapped_column(ForeignKey("account_records.id"), nullable=True) + # budget_records_uu_id: Mapped[str] = mapped_column( + # String, nullable=True, comment="Budget UUID" + # ) + # accounting_id: Mapped[int] = mapped_column(ForeignKey("account_detail.id"), nullable=True) + # accounting_uu_id: Mapped[str] = mapped_column( + # String, nullable=True, comment="Accounting UUID" + # ) + # receive_debit_id: Mapped[int] = mapped_column(ForeignKey("api_enum_dropdown.id"), nullable=True) + # receive_debit_uu_id: Mapped[str] = mapped_column(String, nullable=True, comment="Debit UUID") + + # accounting: Mapped["AccountDetail"] = relationship( + # "AccountDetail", + # back_populates="decision_book_payment_detail", + # foreign_keys=[accounting_id], + # ) + # + # decision_book_master: Mapped["BuildDecisionBookPaymentsMaster"] = relationship( + # "BuildDecisionBookPaymentsMaster", + # back_populates="decision_book_payment_detail", + # foreign_keys=[build_decision_book_payments_master_id], + # ) + # budget_records: Mapped["CompanyBudgetRecords"] = relationship( + # "CompanyBudgetRecords", + # back_populates="decision_book_payment_detail", + # foreign_keys=[budget_records_id], + # ) + + __table_args__ = ( + Index( + "build_decision_book_payments_detail_ndx_00", + build_decision_book_item_id, + build_parts_id, + payment_plan_time_periods, + process_date, + payment_types_id, + account_records_id, + unique=True, + ), + Index("build_decision_book_payments_detail_ndx_01", account_records_id), + {"comment": "Payment Details of Decision Book Payments"}, + ) + + +class BuildDecisionBookLegal(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + lawsuits_type C:Court Mehkeme M: mediator arabulucu + """ + + __tablename__ = "build_decision_book_legal" + __exclude__fields__ = [] + + period_start_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Start Date of Legal Period" + ) + lawsuits_decision_number: Mapped[str] = mapped_column( + String, nullable=False, comment="Lawsuits Decision Number" + ) + lawsuits_decision_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Lawsuits Decision Date" + ) + + period_stop_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="2099-12-31 23:59:59" + ) + decision_book_pdf_path: Mapped[str] = mapped_column( + String, server_default="", nullable=True + ) + resp_company_total_wage: Mapped[float] = mapped_column( + Numeric(10, 2), server_default="0", nullable=True + ) + contact_agreement_path: Mapped[str] = mapped_column( + String, server_default="", nullable=True + ) + contact_agreement_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="1900-01-01 00:00:00", nullable=True + ) + meeting_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="1900-01-01 00:00:00" + ) + lawsuits_type: Mapped[str] = mapped_column(String(1), server_default="C") + lawsuits_name: Mapped[str] = mapped_column(String(128)) + lawsuits_note: Mapped[str] = mapped_column(String(512)) + lawyer_cost: Mapped[float] = mapped_column(Numeric(20, 2)) + mediator_lawyer_cost: Mapped[float] = mapped_column(Numeric(20, 2)) + other_cost: Mapped[float] = mapped_column(Numeric(20, 2)) + legal_cost: Mapped[float] = mapped_column(Numeric(20, 2)) + approved_cost: Mapped[float] = mapped_column(Numeric(20, 2)) + total_price: Mapped[float] = mapped_column(Numeric(20, 2)) + + build_db_item_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_items.id"), nullable=False + ) + build_db_item_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Item UUID" + ) + resp_attorney_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=False + ) + resp_attorney_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Attorney UUID" + ) + resp_attorney_company_id: Mapped[int] = mapped_column(ForeignKey("companies.id")) + resp_attorney_company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Company UUID" + ) + mediator_lawyer_person_id: Mapped[int] = mapped_column(ForeignKey("people.id")) + mediator_lawyer_person_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Mediator Lawyer UUID" + ) + + __table_args__ = ( + Index("_build_decision_book_legal_ndx_00", meeting_date), + { + "comment": "Legal items related to decision book items recoreded at building meetings" + }, + ) + + +class BuildDecisionBookProjects(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + project_type = C:Court Mehkeme M: mediator arabulucu + """ + + __tablename__ = "build_decision_book_projects" + __exclude__fields__ = [] + + project_no: Mapped[str] = mapped_column( + String(12), nullable=True, comment="Project Number of Decision Book" + ) + project_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Project Name" + ) + project_start_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), nullable=False, comment="Project Start Date" + ) + project_stop_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="2099-12-31 23:59:59" + ) + project_type: Mapped[str] = mapped_column(String, server_default="C") + project_note: Mapped[str] = mapped_column(Text) + + decision_book_pdf_path: Mapped[str] = mapped_column( + String, server_default="", nullable=True + ) + is_completed: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Project is Completed" + ) + status_code: Mapped[int] = mapped_column(SmallInteger, nullable=True) + resp_company_fix_wage: Mapped[float] = mapped_column( + Numeric(10, 2), server_default="0" + ) + is_out_sourced: Mapped[bool] = mapped_column(Boolean, server_default="0") + + meeting_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), server_default="1900-01-01 00:00:00", index=True + ) + currency: Mapped[str] = mapped_column(String(8), server_default="TRY") + bid_price: Mapped[float] = mapped_column(Numeric(16, 4), server_default="0") + approved_price: Mapped[float] = mapped_column(Numeric(16, 4), server_default="0") + final_price: Mapped[float] = mapped_column(Numeric(16, 4), server_default="0") + + contact_id: Mapped[int] = mapped_column( + ForeignKey("contracts.id"), nullable=True, comment="Contract id" + ) + contact_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Contract UUID" + ) + build_decision_book_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book.id"), nullable=False + ) + build_decision_book_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book UUID" + ) + build_decision_book_item_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_items.id"), nullable=False + ) + build_decision_book_item_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Item UUID" + ) + project_response_living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), + nullable=True, + comment="Project Response Person ID", + ) + project_response_living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Project Response Person UUID" + ) + resp_company_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=True + ) + resp_company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Company UUID" + ) + + build_decision_book_item: Mapped["BuildDecisionBookItems"] = relationship( + "BuildDecisionBookItems", + back_populates="decision_book_project", + foreign_keys=[build_decision_book_item_id], + ) + + __table_args__ = ( + Index( + "_build_decision_book_project_ndx_00", + project_no, + project_start_date, + unique=True, + ), + { + "comment": "Project related to decision taken at building meetings on book items" + }, + ) + + @property + def get_project_year(self): + return self.decision_book_items.decision_books.period_start_date.year + + @property + def get_project_no(self): + return f"{self.get_project_year}-{str(self.id)[-4:].zfill(4)}" + + +class BuildDecisionBookProjectPerson(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_decision_book_project_person" + __exclude__fields__ = [] + # __enum_list__ = [("management_typecode", "ProjectTeamTypes", "PTT-EMP")] + + dues_percent_discount: Mapped[int] = mapped_column(SmallInteger, server_default="0") + job_fix_wage: Mapped[float] = mapped_column(Numeric(10, 2), server_default="0") + bid_price: Mapped[float] = mapped_column(Numeric(10, 2), server_default="0") + decision_price: Mapped[float] = mapped_column(Numeric(10, 2), server_default="0") + + build_decision_book_project_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_projects.id"), nullable=False + ) + build_decision_book_project_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Project UUID" + ) + living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Living Space UUID" + ) + + __table_args__ = ( + {"comment": "People that are attended to building project meetings."}, + ) + + +class BuildDecisionBookProjectItems(CrudCollection): + """ + Builds class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "build_decision_book_project_items" + __exclude__fields__ = [] + + item_header: Mapped[str] = mapped_column( + String, nullable=False, comment="Item Header" + ) + item_comment: Mapped[str] = mapped_column( + Text, nullable=False, comment="Item Comment" + ) + attachment_pdf_path: Mapped[str] = mapped_column( + String, server_default="", nullable=True, comment="Attachment PDF Path" + ) + item_estimated_cost: Mapped[float] = mapped_column( + Numeric(16, 2), server_default="0", comment="Estimated Cost" + ) + item_short_comment: Mapped[str] = mapped_column( + String(24), + nullable=True, + comment="This field is reserved for use in grouping data or in the pivot heading.", + ) + + build_decision_book_project_id: Mapped[int] = mapped_column( + ForeignKey("build_decision_book_projects.id"), nullable=False + ) + build_decision_book_project_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Decision Book Project UUID" + ) + + __table_args__ = ( + {"comment": "Project Items related to decision taken at building meetings"}, + ) diff --git a/ServicesApi/Schemas/company/company.py b/ServicesApi/Schemas/company/company.py new file mode 100644 index 0000000..6f99f4b --- /dev/null +++ b/ServicesApi/Schemas/company/company.py @@ -0,0 +1,235 @@ +from typing import Any +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, +) + +class RelationshipDutyCompany(CrudCollection): + """ + CompanyRelationship class based on declarative_base and CrudCollection via session + Company -> Sub Company -> Sub-Sub Company + + if owner_id == parent_id: can manipulate data of any record + else: Read-Only + duty_id = if relationship_type == base An organization / not operational / no responsible person + + relationship = company_id filter -> Action filter(company_id) relationship_type = Organization + relationship = company_id filter -> Action filter(company_id) relationship_type = Commercial + """ + + __tablename__ = "relationship_duty_company" + __exclude__fields__ = [] + + owner_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=False + ) # 1 + duties_id: Mapped[int] = mapped_column( + ForeignKey("duties.id"), nullable=False + ) # duty -> (n)employee Evyos LTD + + member_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=False + ) # 2, 3, 4 + parent_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=True + ) # None + + relationship_type: Mapped[str] = mapped_column( + String, nullable=True, server_default="Commercial" + ) # Commercial, Organization # Bulk + child_count: Mapped[int] = mapped_column(Integer) # 0 + show_only: Mapped[bool] = mapped_column(Boolean, server_default="0") + + # related_company: Mapped[List["Companies"]] = relationship( + # "Companies", + # back_populates="related_companies", + # foreign_keys=[related_company_id], + # ) + + @classmethod + def match_company_to_company_commercial(cls, data: Any, token): + from Schemas import Duties + + with cls.new_session() as db_session: + token_duties_id, token_company_id = token.get("duty_id"), token.get( + "company_id" + ) + list_match_company_id = [] + send_duties = Duties.filter_one( + Duties.uu_id == data.duty_uu_id, db=db_session + ) + send_user_duties = Duties.filter_one( + Duties.duties_id == send_duties.id, + Duties.company_id == token_duties_id, + db=db_session, + ) + if not send_user_duties: + raise Exception( + "Send Duty is not found in company. Please check duty uuid and try again." + ) + + for company_uu_id in list(data.match_company_uu_id): + company = Companies.filter_one( + Companies.uu_id == company_uu_id, db=db_session + ) + bulk_company = RelationshipDutyCompany.filter_one( + RelationshipDutyCompany.owner_id == token_company_id, + RelationshipDutyCompany.relationship_type == "Bulk", + RelationshipDutyCompany.member_id == company.id, + db=db_session, + ) + if not bulk_company: + raise Exception( + f"Bulk Company is not found in company. " + f"Please check company uuid {bulk_company.uu_id} and try again." + ) + list_match_company_id.append(bulk_company) + + for match_company_id in list_match_company_id: + RelationshipDutyCompany.find_or_create( + owner_id=token_company_id, + duties_id=send_user_duties.id, + member_id=match_company_id.id, + parent_id=match_company_id.parent_id, + relationship_type="Commercial", + show_only=False, + db=db_session, + ) + + @classmethod + def match_company_to_company_organization(cls, data: Any, token): + from Schemas import Duties + + with cls.new_session() as db_session: + token_duties_id, token_company_id = token.get("duty_id"), token.get( + "company_id" + ) + list_match_company_id = [] + send_duties = Duties.filter_one( + Duties.uu_id == data.duty_uu_id, db=db_session + ) + send_user_duties = Duties.filter_one( + Duties.duties_id == send_duties.id, + Duties.company_id == token_duties_id, + db=db_session, + ) + if not send_user_duties: + raise Exception( + "Send Duty is not found in company. Please check duty uuid and try again." + ) + + for company_uu_id in list(data.match_company_uu_id): + company = Companies.filter_one( + Companies.uu_id == company_uu_id, db=db_session + ) + bulk_company = RelationshipDutyCompany.filter_one( + RelationshipDutyCompany.owner_id == token_company_id, + RelationshipDutyCompany.relationship_type == "Bulk", + RelationshipDutyCompany.member_id == company.id, + db=db_session, + ) + if not bulk_company: + raise Exception( + f"Bulk Company is not found in company. " + f"Please check company uuid {bulk_company.uu_id} and try again." + ) + list_match_company_id.append(bulk_company) + + for match_company_id in list_match_company_id: + Duties.init_a_company_default_duties( + company_id=match_company_id.id, + company_uu_id=str(match_company_id.uu_id), + db=db_session, + ) + RelationshipDutyCompany.find_or_create( + owner_id=token_company_id, + duties_id=send_user_duties.id, + member_id=match_company_id.id, + parent_id=match_company_id.parent_id, + relationship_type="Organization", + show_only=False, + db=db_session, + ) + + __table_args__ = ( + Index( + "_company_relationship_ndx_01", + duties_id, + owner_id, + member_id, + relationship_type, + unique=True, + ), + {"comment": "Company Relationship Information"}, + ) + + +class Companies(CrudCollection): + """ + Company class based on declarative_base and CrudCollection via session + formal_name = Government register name by offical + public_name = Public registered name by User + nick_name = Search by nickname, commercial_type = Tüzel veya birey + """ + + __tablename__ = "companies" + + __exclude__fields__ = ["is_blacklist", "is_commercial"] + __access_by__ = [] + __many__table__ = RelationshipDutyCompany + + formal_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Formal Name" + ) + company_type: Mapped[str] = mapped_column( + String, nullable=False, comment="Company Type" + ) + commercial_type: Mapped[str] = mapped_column( + String, nullable=False, comment="Commercial Type" + ) + tax_no: Mapped[str] = mapped_column( + String, index=True, unique=True, nullable=False, comment="Tax No" + ) + + public_name: Mapped[str] = mapped_column(String, comment="Public Name of a company") + company_tag: Mapped[str] = mapped_column(String, comment="Company Tag") + default_lang_type: Mapped[str] = mapped_column(String, server_default="TR") + default_money_type: Mapped[str] = mapped_column(String, server_default="TL") + is_commercial: Mapped[bool] = mapped_column(Boolean, server_default="False") + is_blacklist: Mapped[bool] = mapped_column(Boolean, server_default="False") + parent_id = mapped_column(Integer, nullable=True) + workplace_no: Mapped[str] = mapped_column(String, nullable=True) + + official_address_id: Mapped[int] = mapped_column( + ForeignKey("addresses.id"), nullable=True + ) + official_address_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Official Address UUID" + ) + top_responsible_company_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=True + ) + top_responsible_company_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Top Responsible Company UUID" + ) + + # buildings: Mapped[List["Build"]] = relationship( + # "Build", + # back_populates="companies", + # foreign_keys="Build.company_id", + # ) + + __table_args__ = ( + Index("_company_ndx_01", tax_no, unique=True), + Index("_company_ndx_02", formal_name, public_name), + {"comment": "Company Information"}, + ) diff --git a/ServicesApi/Schemas/company/department.py b/ServicesApi/Schemas/company/department.py new file mode 100644 index 0000000..ffe7fd4 --- /dev/null +++ b/ServicesApi/Schemas/company/department.py @@ -0,0 +1,82 @@ +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, +) + + +class Departments(CrudCollection): + + __tablename__ = "departments" + __exclude__fields__ = [] + + parent_department_id = mapped_column(Integer, server_default="0") + department_code = mapped_column( + String(16), nullable=False, index=True, comment="Department Code" + ) + department_name: Mapped[str] = mapped_column( + String(128), nullable=False, comment="Department Name" + ) + department_description: Mapped[str] = mapped_column(String, server_default="") + + company_id: Mapped[int] = mapped_column(ForeignKey("companies.id"), nullable=False) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Company UUID" + ) + + __table_args__ = {"comment": "Departments Information"} + + +class Duty(CrudCollection): + + __tablename__ = "duty" + __exclude__fields__ = [] + + duty_name: Mapped[str] = mapped_column( + String, unique=True, nullable=False, comment="Duty Name" + ) + duty_code: Mapped[str] = mapped_column(String, nullable=False, comment="Duty Code") + duty_description: Mapped[str] = mapped_column(String, comment="Duty Description") + + __table_args__ = ({"comment": "Duty Information"},) + + +class Duties(CrudCollection): + + __tablename__ = "duties" + __exclude__fields__ = [] + + users_default_duty = mapped_column( + ForeignKey("duty.id"), nullable=True, comment="Default Duty for Users" + ) + company_id: Mapped[int] = mapped_column(Integer) + company_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Company UUID" + ) + duties_id: Mapped[int] = mapped_column(ForeignKey("duty.id"), nullable=False) + duties_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Duty UUID" + ) + department_id = mapped_column( + ForeignKey("departments.id"), nullable=False, comment="Department ID" + ) + department_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Department UUID" + ) + # priority_id: Mapped[int] = mapped_column(ForeignKey("priority.id"), nullable=True) + management_duty = mapped_column( + Boolean, server_default="0" + ) # is this a prime Company Duty ??? + + __table_args__ = ( + Index("duty_ndx_00", company_id, duties_id, department_id, unique=True), + {"comment": "Duty & Company & Department Information"}, + ) diff --git a/ServicesApi/Schemas/company/employee.py b/ServicesApi/Schemas/company/employee.py new file mode 100644 index 0000000..de9f3e1 --- /dev/null +++ b/ServicesApi/Schemas/company/employee.py @@ -0,0 +1,102 @@ +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, +) + + +class Staff(CrudCollection): + + __tablename__ = "staff" + __exclude__fields__ = [] + + staff_description: Mapped[str] = mapped_column( + String, server_default="", comment="Staff Description" + ) + staff_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Staff Name" + ) + staff_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Staff Code" + ) + + duties_id: Mapped[int] = mapped_column(ForeignKey("duties.id"), nullable=False) + duties_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Duty UUID" + ) + + __table_args__ = ({"comment": "Staff Information"},) + + +class Employees(CrudCollection): + + __tablename__ = "employees" + __exclude__fields__ = [] + + staff_id: Mapped[int] = mapped_column(ForeignKey("staff.id")) + staff_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Staff UUID" + ) + people_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=True) + people_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="People UUID" + ) + + __table_args__ = ( + Index("employees_ndx_00", people_id, staff_id, unique=True), + {"comment": "Employee Person Information"}, + ) + + +class EmployeeHistory(CrudCollection): + + __tablename__ = "employee_history" + __exclude__fields__ = [] + + staff_id: Mapped[int] = mapped_column( + ForeignKey("staff.id"), nullable=False, comment="Staff ID" + ) + staff_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Staff UUID" + ) + people_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=False, comment="People ID" + ) + people_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="People UUID" + ) + + __table_args__ = ( + Index("_employee_history_ndx_00", people_id, staff_id), + {"comment": "Employee History Information"}, + ) + + +class EmployeesSalaries(CrudCollection): + + __tablename__ = "employee_salaries" + __exclude__fields__ = [] + + gross_salary: Mapped[float] = mapped_column( + Numeric(20, 6), nullable=False, comment="Gross Salary" + ) + net_salary: Mapped[float] = mapped_column( + Numeric(20, 6), nullable=False, comment="Net Salary" + ) + people_id: Mapped[int] = mapped_column(ForeignKey("people.id"), nullable=False) + people_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="People UUID" + ) + + __table_args__ = ( + Index("_employee_salaries_ndx_00", people_id, "expiry_starts"), + {"comment": "Employee Salaries Information"}, + ) diff --git a/ServicesApi/Schemas/event/event.py b/ServicesApi/Schemas/event/event.py new file mode 100644 index 0000000..932622c --- /dev/null +++ b/ServicesApi/Schemas/event/event.py @@ -0,0 +1,559 @@ +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Numeric, + SmallInteger, + mapped_column, + Mapped, +) + + +class Applications(CrudCollection): + """ + Applications class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "applications" + __exclude__fields__ = [] + + name: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Name" + ) + site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") + application_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Code" + ) + application_type: Mapped[str] = mapped_column(String, comment="Application Type") + application_for: Mapped[str] = mapped_column( + String, server_default="EMP", comment="Application For" + ) + description: Mapped[str] = mapped_column(String, comment="Application Description") + + +class Events(CrudCollection): + """ + Events class based on declarative_base and BaseMixin via session + If Events2Occupants and Events2Employees are not found for user request, response 401 Unauthorized + """ + + __tablename__ = "events" + __exclude__fields__ = [] + + function_code: Mapped[str] = mapped_column( + String, nullable=False, comment="function code", unique=True + ) + function_class: Mapped[str] = mapped_column( + String, nullable=False, comment="class name" + ) + + # name: Mapped[str] = mapped_column(String, nullable=True) # form or page title + description: Mapped[str] = mapped_column(String, server_default="") + property_description: Mapped[str] = mapped_column(String, server_default="") + + marketing_layer = mapped_column(SmallInteger, server_default="3") + cost: Mapped[float] = mapped_column(Numeric(20, 2), server_default="0.00") + unit_price: Mapped[float] = mapped_column(Numeric(20, 2), server_default="0.00") + + endpoint_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Event Type" + ) + endpoint_id: Mapped[int] = mapped_column( + ForeignKey("endpoint_restriction.id"), nullable=True + ) + endpoint_uu_id: Mapped[str] = mapped_column( + String, nullable=True, comment="Endpoint UUID" + ) + + __table_args__ = ({"comment": "Events Information"},) + + +class Modules(CrudCollection): + """ + Modules class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "modules" + __exclude__fields__ = [] + + module_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Module Name" + ) + module_description: Mapped[str] = mapped_column(String, server_default="") + module_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Module Code" + ) + module_layer = mapped_column(Integer, nullable=False, comment="Module Layer") + is_default_module = mapped_column(Boolean, server_default="0") + + def retrieve_services(self): + services = Services.filter_all(Services.module_id == self.id).data + if not services: + self.raise_http_exception( + status_code="HTTP_404_NOT_FOUND", + error_case="RECORD_NOT_FOUND", + message=f"No services found for this module : {str(self.uu_id)}", + data={ + "module_uu_id": str(self.uu_id), + }, + ) + return services + + __table_args__ = ({"comment": "Modules Information"},) + + +class ModulePrice(CrudCollection): + """ + ModulePrice class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "module_price" + __exclude__fields__ = [] + + campaign_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Campaign Code" + ) + module_id: Mapped[int] = mapped_column(ForeignKey("modules.id"), nullable=False) + module_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Module UUID" + ) + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Service UUID" + ) + event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False) + event_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Event UUID" + ) + is_counted_percentage: Mapped[float] = mapped_column( + Numeric(6, 2), server_default="0.00" + ) # %22 + discounted_price: Mapped[float] = mapped_column( + Numeric(20, 2), server_default="0.00" + ) # Normal: 78.00 TL + calculated_price: Mapped[float] = mapped_column( + Numeric(20, 2), server_default="0.00" + ) # sana düz 75.00 TL yapar + + __table_args__ = ({"comment": "ModulePrice Information"},) + + +class Services(CrudCollection): + """ + Services class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "services" + __exclude__fields__ = [] + + module_id: Mapped[int] = mapped_column(ForeignKey("modules.id"), nullable=False) + module_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Module UUID" + ) + service_name: Mapped[str] = mapped_column( + String, nullable=False, comment="Service Name" + ) + service_description: Mapped[str] = mapped_column(String, server_default="") + service_code: Mapped[str] = mapped_column( + String, nullable=True, comment="Service Code" + ) + related_responsibility: Mapped[str] = mapped_column(String, server_default="") + + @classmethod + def retrieve_service_via_occupant_code(cls, occupant_code): + from Schemas import OccupantTypes + + with cls.new_session() as db_session: + occupant_type = OccupantTypes.filter_by_one( + system=True, occupant_code=occupant_code, db=db_session + ).data + if not occupant_type: + cls.raise_http_exception( + status_code="HTTP_404_NOT_FOUND", + error_case="RECORD_NOT_FOUND", + message=f"No occupant type found for this code : {occupant_code}", + data={ + "occupant_code": occupant_code, + }, + ) + return cls.filter_one( + cls.related_responsibility == occupant_type.occupant_code, db=db_session + ).data + + __table_args__ = ({"comment": "Services Information"},) + + +class Service2Events(CrudCollection): + """ + Service2Actions class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "services2events" + __exclude__fields__ = [] + + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id = mapped_column(String, nullable=False, comment="Service UUID") + event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False) + event_uu_id = mapped_column(String, nullable=False, comment="Event UUID") + + __table_args__ = ({"comment": "Service2Events Information"},) + + +class Service2Application(CrudCollection): + """ + Service2Application class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "services2applications" + __exclude__fields__ = [] + + application_id: Mapped[int] = mapped_column( + ForeignKey("applications.id"), nullable=False + ) + application_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Application UUID" + ) + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Service UUID" + ) + application_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Code" + ) + site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") + + __table_args__ = {"comment": "Service2Applications Information"} + + +class Event2OccupantExtra(CrudCollection): + + __tablename__ = "event2occupant_extra" + __exclude__fields__ = [] + + build_living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + build_living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Living Space UUID" + ) + event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False) + event_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Event UUID" + ) + + __table_args__ = ( + Index( + "event2occupant_extra_bind_event_to_occupant", + build_living_space_id, + event_id, + unique=True, + ), + {"comment": "Occupant2Event Information"}, + ) + + +class Event2EmployeeExtra(CrudCollection): + """ + Employee2Event class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "event2employee_extra" + __exclude__fields__ = [] + + employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) + employee_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Employee UUID" + ) + + event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False) + event_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Event UUID" + ) + + __table_args__ = ( + Index( + "event2employee_extra_employee_to_event", + employee_id, + event_id, + unique=True, + ), + {"comment": "Employee to Event Information"}, + ) + + +class Event2Employee(CrudCollection): + """ + Employee2Event class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "event2employee" + __exclude__fields__ = [] + + employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) + employee_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Employee UUID" + ) + event_service_id: Mapped[int] = mapped_column( + ForeignKey("services.id"), nullable=False + ) + event_service_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Event Cluster UUID" + ) + + __table_args__ = ( + Index( + "event2employee_employee_to_event", + employee_id, + event_service_id, + unique=True, + ), + {"comment": "Employee to Event Information"}, + ) + + @classmethod + def get_event_codes(cls, employee_id: int, db) -> dict[str:str]: + cls.set_session(db) + Service2Events.set_session(db) + Events.set_session(db) + Event2EmployeeExtra.set_session(db) + employee_events = cls.query.filter(cls.employee_id == employee_id).all() + service_ids = list(set([event.event_service_id for event in employee_events])) + active_event_ids = Service2Events.query.filter(Service2Events.service_id.in_(service_ids)).all() + active_events = Events.query.filter(Events.id.in_([event.event_id for event in active_event_ids])).all() + if extra_events := Event2EmployeeExtra.query.filter(Event2EmployeeExtra.employee_id == employee_id).all(): + events_extra = Events.query.filter(Events.id.in_([event.event_id for event in extra_events]),).all() + active_events.extend(events_extra) + events_dict = {} + for event in active_events: + if not event.endpoint_code in events_dict: + events_dict[str(event.endpoint_code)] = str(event.function_code) + else: + ValueError("Duplicate event code found for single endpoint") + return events_dict + + +class Event2Occupant(CrudCollection): + """ + Occupant2Event class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "event2occupant" + __exclude__fields__ = [] + + build_living_space_id: Mapped[str] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + build_living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Living Space UUID" + ) + event_service_id: Mapped[int] = mapped_column( + ForeignKey("services.id"), nullable=False + ) + event_service_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Event Cluster UUID" + ) + # event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), nullable=False) + # event_uu_id = mapped_column(String, nullable=False, comment="Event UUID") + + __table_args__ = ( + Index( + "event2occupant_bind_event_to_occupant", + build_living_space_id, + event_service_id, + unique=True, + ), + {"comment": "Occupant2Event Information"}, + ) + + @classmethod + def get_event_codes(cls, build_living_space_id: int, db) -> dict[str:str]: + cls.set_session(db) + Service2Events.set_session(db) + Events.set_session(db) + occupant_events = cls.query.filter(cls.build_living_space_id == build_living_space_id).all() + service_ids = list(set([event.event_service_id for event in occupant_events])) + active_event_ids = Service2Events.query.filter(Service2Events.service_id.in_(service_ids)).all() + active_events = Events.query.filter(Events.id.in_([event.event_id for event in active_event_ids])).all() + if extra_events := Event2OccupantExtra.query.filter(Event2OccupantExtra.build_living_space_id == build_living_space_id).all(): + events_extra = Events.query.filter(Events.id.in_([event.event_id for event in extra_events])).all() + active_events.extend(events_extra) + events_dict = {} + for event in active_events: + if not event.endpoint_code in events_dict: + events_dict[str(event.endpoint_code)] = str(event.function_code) + else: + ValueError("Duplicate event code found for single endpoint") + return events_dict + + +class Application2Employee(CrudCollection): + """ + Application2Employee class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "application2employee" + __exclude__fields__ = [] + + employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) + employee_uu_id = mapped_column(String, nullable=False, comment="Employee UUID") + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id = mapped_column(String, nullable=False, comment="Service UUID") + + @classmethod + def get_application_codes(cls, employee_id: int, db) -> list[int]: + cls.set_session(db) + Service2Application.set_session(db) + Applications.set_session(db) + Application2EmployeeExtra.set_session(db) + employee_services = cls.query.filter(cls.employee_id == employee_id).all() + service_ids = [service.service_id for service in employee_services] + active_applications = Service2Application.query.filter(Service2Application.service_id.in_(service_ids)).all() + applications = Applications.query.filter(Applications.id.in_([application.application_id for application in active_applications])).all() + if extra_applications := Application2EmployeeExtra.query.filter(Application2EmployeeExtra.employee_id == employee_id).all(): + applications_extra = Applications.query.filter(Applications.id.in_([application.application_id for application in extra_applications])).all() + applications.extend(applications_extra) + applications_dict = {} + for application in applications: + if not application.site_url in applications_dict: + applications_dict[str(application.site_url)] = str(application.application_code) + else: + ValueError("Duplicate application code found for single endpoint") + return applications_dict + + __table_args__ = ( + Index( + "application2employee_employee_to_service", + employee_uu_id, + service_uu_id, + unique=True, + ), + {"comment": "Application to Employee Information"}, + ) + + +class Application2Occupant(CrudCollection): + """ + Application2Occupant class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "application2occupant" + __exclude__fields__ = [] + + build_living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + build_living_space_uu_id = mapped_column( + String, nullable=False, comment="Build Living Space UUID" + ) + service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False) + service_uu_id = mapped_column(String, nullable=False, comment="Service UUID") + + @classmethod + def get_application_codes(cls, build_living_space_id: int, db) -> list[int]: + cls.set_session(db) + Service2Application.set_session(db) + Applications.set_session(db) + Application2OccupantExtra.set_session(db) + occupant_services = cls.query.filter(cls.build_living_space_id == build_living_space_id).all() + service_ids = [service.service_id for service in occupant_services] + active_applications = Service2Application.query.filter(Service2Application.service_id.in_(service_ids)).all() + applications = Applications.query.filter(Applications.id.in_([application.application_id for application in active_applications])).all() + if extra_applications := Application2OccupantExtra.query.filter(Application2OccupantExtra.build_living_space_id == build_living_space_id).all(): + applications_extra = Applications.query.filter(Applications.id.in_([application.application_id for application in extra_applications])).all() + applications.extend(applications_extra) + applications_dict = {} + for application in applications: + if not application.site_url in applications_dict: + applications_dict[str(application.site_url)] = str(application.application_code) + else: + ValueError("Duplicate application code found for single endpoint") + applications.extend(applications_extra) + applications_dict = {} + for application in applications: + if not application.site_url in applications_dict: + applications_dict[str(application.site_url)] = str(application.application_code) + else: + ValueError("Duplicate application code found for single endpoint") + return applications_dict + + __table_args__ = ( + Index( + "application2occupant_occupant_to_service", + build_living_space_uu_id, + service_uu_id, + unique=True, + ), + {"comment": "Application to Occupant Information"}, + ) + + +class Application2EmployeeExtra(CrudCollection): + """ + Application2EmployeeExtra class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "application2employee_extra" + __exclude__fields__ = [] + + employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) + employee_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Employee UUID" + ) + application_id: Mapped[int] = mapped_column(ForeignKey("applications.id")) + application_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Application UUID" + ) + site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") + application_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Code" + ) + + __table_args__ = ( + Index( + "application_to_employee", + employee_id, + site_url, + application_id, + unique=True, + ), + {"comment": "Application2Employee Information"}, + ) + + +class Application2OccupantExtra(CrudCollection): + """ + Application2OccupantExtra class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "application2occupant_extra" + __exclude__fields__ = [] + + build_living_space_id: Mapped[int] = mapped_column( + ForeignKey("build_living_space.id"), nullable=False + ) + build_living_space_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Build Living Space UUID" + ) + application_id: Mapped[int] = mapped_column(ForeignKey("applications.id")) + application_uu_id: Mapped[str] = mapped_column( + String, nullable=False, comment="Application UUID" + ) + site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") + application_code: Mapped[str] = mapped_column( + String, nullable=False, comment="Application Code" + ) + + __table_args__ = ( + Index( + "application_to_occupant", + build_living_space_id, + site_url, + application_id, + unique=True, + ), + {"comment": "Application2Occupant Information"}, + ) diff --git a/ServicesApi/Schemas/identity/identity.py b/ServicesApi/Schemas/identity/identity.py new file mode 100644 index 0000000..f78075e --- /dev/null +++ b/ServicesApi/Schemas/identity/identity.py @@ -0,0 +1,488 @@ +import arrow +from schemas.base_imports import ( + CrudCollection, + String, + Integer, + Boolean, + ForeignKey, + Index, + TIMESTAMP, + Text, + func, + BigInteger, + Numeric, + or_, + and_, + mapped_column, + Mapped, + relationship, +) + + +class UsersTokens(CrudCollection): + + __tablename__ = "users_tokens" + __exclude__fields__ = [] + + user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) + + token_type: Mapped[str] = mapped_column(String(16), server_default="RememberMe") + token: Mapped[str] = mapped_column(String, server_default="") + domain: Mapped[str] = mapped_column(String, server_default="") + expires_at: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), + default=str(arrow.now().shift(days=3)), + ) + + # users = relationship("Users", back_populates="tokens", foreign_keys=[user_id]) + + +class Credentials(CrudCollection): + """ + Credentials class to store user credentials + """ + + __tablename__ = "credentials" + __exclude__fields__ = [] + + credential_token: Mapped[str] = mapped_column( + String, server_default="", comment="Credential token for authentication" + ) + user_id: Mapped[int] = mapped_column( + ForeignKey("users.id"), nullable=False, comment="Foreign key to users table" + ) + user_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="User UUID", index=True + ) + person_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=False, comment="Foreign key to person table" + ) + person_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Person UUID", index=True + ) + name: Mapped[str] = mapped_column( + String, server_default="", comment="Name of the user", index=True + ) + surname: Mapped[str] = mapped_column( + String, server_default="", comment="Surname of the user", index=True + ) + email: Mapped[str] = mapped_column( + String, server_default="", comment="Email address of the user", index=True + ) + phone: Mapped[str] = mapped_column( + String, server_default="", comment="Phone number of the user", index=True + ) + is_verified: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Flag to check if user is verified" + ) + + def generate_token(self) -> str: + """ + Generate a unique token for the user + """ + name_token, rest_of_token = "", "" + if self.name and self.surname: + name_token = f"{self.name[0].upper()}{self.surname[0].upper()}" + return "" + + +class Users(CrudCollection): + """ + Application User frame to connect to API with assigned token-based HTTP connection + """ + + __tablename__ = "users" + __exclude__fields__ = [ + "hash_password", + "password_token", + "expiry_begins", + "related_company", + ] + + user_tag: Mapped[str] = mapped_column( + String(64), server_default="", comment="Unique tag for the user", index=True + ) + email: Mapped[str] = mapped_column( + String(128), server_default="", comment="Email address of the user", index=True + ) + phone_number: Mapped[str] = mapped_column( + String, server_default="", comment="Phone number of the user", index=True + ) + via: Mapped[str] = mapped_column( + String, + server_default="111", + comment="Email 1/ Phone 2/ User Tag 3 All 111 Only 100", + ) + + avatar: Mapped[str] = mapped_column( + String, server_default="", comment="Avatar URL for the user" + ) + hash_password: Mapped[str] = mapped_column( + String(256), server_default="", comment="Hashed password for security" + ) + password_token: Mapped[str] = mapped_column( + String(256), server_default="", comment="Token for password reset" + ) + remember_me: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Flag to remember user login" + ) + + password_expires_day: Mapped[int] = mapped_column( + Integer, + server_default=str(30), + comment="Password expires in days", + ) + password_expiry_begins: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), + server_default=func.now(), + comment="Timestamp when password expiry begins", + ) + related_company: Mapped[str] = mapped_column(String, comment="Related Company UUID") + + person_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=False, comment="Foreign key to person table" + ) + person_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Person UUID", index=True + ) + local_timezone = mapped_column( + String, server_default="GMT+3", comment="Local timezone of user" + ) + person = relationship("People", back_populates="user", foreign_keys=[person_id]) + default_language: Mapped[str] = mapped_column( + String, server_default="tr", comment="Default language of user" + ) + + +class RelationshipDutyPeople(CrudCollection): + + __tablename__ = "relationship_duty_people" + __exclude__fields__ = [] + + company_id: Mapped[int] = mapped_column( + ForeignKey("companies.id"), nullable=False + ) # 1, 2, 3 + duties_id: Mapped[int] = mapped_column( + ForeignKey("duties.id"), nullable=False + ) # duty -> (n)person Evyos LTD + member_id: Mapped[int] = mapped_column( + ForeignKey("people.id"), nullable=False + ) # 2, 3, 4 + + relationship_type: Mapped[str] = mapped_column( + String, nullable=True, server_default="Employee" + ) # Commercial + show_only: Mapped[bool] = mapped_column(Boolean, server_default="0") + + # related_company: Mapped[List["Company"]] = relationship( + # "Company", + # back_populates="related_companies", + # foreign_keys=[related_company_id], + # ) + + __table_args__ = ( + Index( + "person_relationship_ndx_01", + company_id, + duties_id, + member_id, + relationship_type, + unique=True, + ), + {"comment": "Person Relationship Information"}, + ) + + +class People(CrudCollection): + """ + People that are related to users in the application + """ + + __tablename__ = "people" + __exclude__fields__ = [] + __many__table__ = RelationshipDutyPeople + __encrypt_list__ = [ + "father_name", + "mother_name", + "country_code", + "national_identity_id", + "birth_place", + "birth_date", + "tax_no", + ] + + firstname: Mapped[str] = mapped_column( + String, nullable=False, comment="First name of the person" + ) + surname: Mapped[str] = mapped_column( + String(24), nullable=False, comment="Surname of the person" + ) + middle_name: Mapped[str] = mapped_column( + String, server_default="", comment="Middle name of the person" + ) + sex_code: Mapped[str] = mapped_column( + String(1), nullable=False, comment="Sex code of the person (e.g., M/F)" + ) + person_ref: Mapped[str] = mapped_column( + String, server_default="", comment="Reference ID for the person" + ) + person_tag: Mapped[str] = mapped_column( + String, server_default="", comment="Unique tag for the person" + ) + + # ENCRYPT DATA + father_name: Mapped[str] = mapped_column( + String, server_default="", comment="Father's name of the person" + ) + mother_name: Mapped[str] = mapped_column( + String, server_default="", comment="Mother's name of the person" + ) + country_code: Mapped[str] = mapped_column( + String(4), server_default="TR", comment="Country code of the person" + ) + national_identity_id: Mapped[str] = mapped_column( + String, server_default="", comment="National identity ID of the person" + ) + birth_place: Mapped[str] = mapped_column( + String, server_default="", comment="Birth place of the person" + ) + birth_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), + server_default="1900-01-01", + comment="Birth date of the person", + ) + tax_no: Mapped[str] = mapped_column( + String, server_default="", comment="Tax number of the person" + ) + # Receive at Create person + # language = mapped_column( + # String, comment="Language code of the person" + # ) + # currency = mapped_column( + # String, comment="Currency code of the person" + # ) + + # ENCRYPT DATA + user = relationship( + "Users", back_populates="person", foreign_keys="Users.person_id" + ) + + __table_args__ = ( + Index( + "person_ndx_001", + national_identity_id, + unique=True, + ), + {"comment": "Person Information"}, + ) + + @property + def full_name(self): + if self.middle_name: + return f"{self.firstname} {self.middle_name} {self.surname}" + return f"{self.firstname} {self.surname}" + + +class OccupantTypes(CrudCollection): + """ + Occupant Types class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "occupant_types" + __exclude__fields__ = [] + + occupant_type: Mapped[str] = mapped_column( + String, nullable=False, comment="Occupant Type" + ) + occupant_description: Mapped[str] = mapped_column(String, server_default="") + occupant_code: Mapped[str] = mapped_column(String, server_default="") + occupant_category: Mapped[str] = mapped_column(String, server_default="") + occupant_category_type: Mapped[str] = mapped_column(String, server_default="") + occupant_is_unique: Mapped[bool] = mapped_column(Boolean, server_default="0") + + __table_args__ = ({"comment": "Occupant Types Information"},) + + +class Contracts(CrudCollection): + """ + Contract class based on declarative_base and BaseMixin via session + """ + + __tablename__ = "contracts" + __exclude__fields__ = [] + + contract_type: Mapped[str] = mapped_column( + String(5), + nullable=False, + comment="The code for personnel is P and the code for companies is C.", + ) + contract_title: Mapped[str] = mapped_column(String(255)) + contract_details: Mapped[str] = mapped_column(Text) + contract_terms: Mapped[str] = mapped_column(Text) + + contract_code: Mapped[str] = mapped_column( + String(100), + nullable=False, + comment="contract_code is the unique code given by the system.", + ) + contract_date: Mapped[TIMESTAMP] = mapped_column( + TIMESTAMP(timezone=True), + server_default="2099-12-31 23:59:59", + comment="contract date is the date the contract is made. " + "expire start is the start date of the contract, expire en is the end date of the contract.", + ) + + company_id: Mapped[int] = mapped_column( + Integer, ForeignKey("companies.id"), nullable=True + ) + company_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Company UUID" + ) + + person_id: Mapped[int] = mapped_column( + Integer, ForeignKey("people.id"), nullable=True + ) + person_uu_id: Mapped[str] = mapped_column( + String, server_default="", comment="Person UUID" + ) + + @classmethod + def retrieve_contact_no(cls): + # todo When create record contract_code == below string + related_date, counter = Contracts.client_arrow.now(), 1 + return ( + f"{related_date.date().year}{str(cls.contract_type)}{str(counter).zfill(6)}" + ) + + __table_args__ = ( + Index("_contract_ndx_01", contract_code, unique=True), + {"comment": "Contract Information"}, + ) + + + # @property + # def is_occupant(self): + # return not str(self.email).split("@")[1] == Auth.ACCESS_EMAIL_EXT + # + # @property + # def is_employee(self): + # return str(self.email).split("@")[1] == Auth.ACCESS_EMAIL_EXT + # + # @property + # def user_type(self): + # return "Occupant" if self.is_occupant else "Employee" + # + # @classmethod + # def credentials(cls): + # db_session = cls.new_session() + # person_object: People = People.filter_by_one( + # db=db_session, system=True, id=cls.person_id + # ).data + # if person_object: + # return { + # "person_id": person_object.id, + # "person_uu_id": str(person_object.uu_id), + # } + # return { + # "person_id": None, + # "person_uu_id": None, + # } + # + # @property + # def password_expiry_ends(self): + # """Calculates the expiry end date based on expiry begins and expires day""" + # return self.password_expiry_begins + timedelta( + # days=int( + # "".join( + # [ + # _ + # for _ in str(self.password_expires_day).split(",")[0] + # if _.isdigit() + # ] + # ) + # ) + # ) + # + # @classmethod + # def create_action(cls, create_user: InsertUsers, token_dict): + # db_session = cls.new_session() + # found_person = People.filter_one( + # People.uu_id == create_user.people_uu_id, + # db=db_session, + # ).data + # + # if not found_person: + # raise HTTPException(status_code=400, detail="Person not found.") + # if ( + # not any(i in str(create_user.email) for i in ["@", "."]) + # and not len(str(create_user.phone_number)) >= 10 + # ): + # raise HTTPException( + # status_code=400, + # detail="Please enter at least one valid email or phone number.", + # ) + # if not create_user.avatar: + # create_user.avatar = ApiStatic.PLACEHOLDER + # create_dict = create_user.model_dump() + # del create_dict["people_uu_id"] + # create_dict["person_id"] = found_person.id + # create_dict["person_uu_id"] = str(found_person.uu_id) + # create_dict["related_company"] = token_dict.selected_company.company_uu_id + # created_user = cls.find_or_create(**create_dict) + # created_user.reset_password_token(found_user=created_user) + # return created_user + # + # def get_employee_and_duty_details(self): + # from ApiLayers.Schemas import Employees, Duties + # + # db_session = self.new_session() + # found_person = People.filter_one( + # People.id == self.person_id, + # db=db_session, + # ) + # found_employees = Employees.filter_by_active( + # people_id=found_person.id, is_confirmed=True, db=db_session + # ) + # found_duties = Duties.filter_all( + # Duties.is_confirmed == True, + # Duties.id.in_( + # list(found_employee.duty_id for found_employee in found_employees.data) + # ), + # db=db_session, + # ) + # if not found_employees.count: + # raise HTTPException( + # status_code=401, + # detail={ + # "message": "Person has no confirmed duty. No employee match please register " + # "your super admin", + # "completed": False, + # }, + # ) + # return { + # "duty_list": [ + # { + # "duty_id": duty.id, + # "duty_uu_id": duty.uu_id.__str__(), + # "duty_code": duty.duty_code, + # "duty_name": duty.duty_name, + # "duty_description": duty.duty_description, + # } + # for duty in found_duties.data + # ], + # } + # + # def get_main_domain_and_other_domains(self, get_main_domain: bool = True): + # from ApiLayers.Schemas import MongoQueryIdentity + # + # query_engine = MongoQueryIdentity(company_uuid=self.related_company) + # domain_via_user = query_engine.get_domain_via_user(user_uu_id=str(self.uu_id)) + # if not domain_via_user: + # raise HTTPException( + # status_code=401, + # detail="Domain not found. Please contact the admin.", + # ) + # domain_via_user = domain_via_user[0] + # if get_main_domain: + # return domain_via_user.get("main_domain", None) + # return domain_via_user.get("other_domains_list", None) \ No newline at end of file diff --git a/ServicesApi/Schemas/others/enums.py b/ServicesApi/Schemas/others/enums.py new file mode 100644 index 0000000..8ff5294 --- /dev/null +++ b/ServicesApi/Schemas/others/enums.py @@ -0,0 +1,110 @@ +from schemas.base_imports import ( + CrudCollection, + UUID, + String, + text, + mapped_column, + Mapped, +) + + +class ApiEnumDropdown(CrudCollection): + __tablename__ = "api_enum_dropdown" + __exclude__fields__ = ["enum_class"] + __language_model__ = None + + id: Mapped[int] = mapped_column(primary_key=True) + uu_id: Mapped[str] = mapped_column( + UUID, server_default=text("gen_random_uuid()"), index=True, unique=True + ) + enum_class: Mapped[str] = mapped_column( + String, nullable=False, comment="Enum Constant Name" + ) + key: Mapped[str] = mapped_column(String, nullable=False, comment="Enum Key") + value: Mapped[str] = mapped_column(String, nullable=False, comment="Enum Value") + description: Mapped[str] = mapped_column(String, nullable=True) + + __table_args__ = ({"comment": "Enum objets that are linked to tables"},) + + @classmethod + def get_by_uuid(cls, uuid: str): + with cls.new_session() as db_session: + return cls.filter_by_one(uu_id=str(uuid), db=db_session).data + + @classmethod + def get_debit_search(cls, search_debit: str = None, search_uu_id: str = None): + with cls.new_session() as db_session: + if search_uu_id: + if search := cls.filter_one_system( + cls.enum_class.in_(["DebitTypes"]), + cls.uu_id == search_uu_id, + db=db_session, + ).data: + return search + elif search_debit: + if search := cls.filter_one( + cls.enum_class.in_(["DebitTypes"]), + cls.key == search_debit, + db=db_session, + ).data: + return search + return cls.filter_all_system( + cls.enum_class.in_(["DebitTypes"]), db=db_session + ).data + + @classmethod + def get_due_types(cls): + with cls.new_session() as db_session: + if due_list := cls.filter_all_system( + cls.enum_class == "BuildDuesTypes", + cls.key.in_(["BDT-A", "BDT-D"]), + db=db_session, + ).data: + return [due.uu_id.__str__() for due in due_list] + # raise HTTPException( + # status_code=404, + # detail="No dues types found", + # ) + + @classmethod + def due_type_search(cls, search_management: str = None, search_uu_id: str = None): + with cls.new_session() as db_session: + if search_uu_id: + if search := cls.filter_one_system( + cls.enum_class.in_(["BuildDuesTypes"]), + cls.uu_id == search_uu_id, + db=db_session, + ).data: + return search + elif search_management: + if search := cls.filter_one_system( + cls.enum_class.in_(["BuildDuesTypes"]), + cls.key == search_management, + db=db_session, + ).data: + return search + return cls.filter_all_system( + cls.enum_class.in_(["BuildDuesTypes"]), db=db_session + ).data + + def get_enum_dict(self): + return { + "uu_id": str(self.uu_id), + "enum_class": self.enum_class, + "key": self.key, + "value": self.value, + "description": self.description, + } + + @classmethod + def uuid_of_enum(cls, enum_class: str, key: str): + with cls.new_session() as db_session: + return str( + getattr( + cls.filter_one_system( + cls.enum_class == enum_class, cls.key == key, db=db_session + ).data, + "uu_id", + None, + ) + ) diff --git a/ServicesApi/Schemas/rules/rules.py b/ServicesApi/Schemas/rules/rules.py new file mode 100644 index 0000000..f1cf8b1 --- /dev/null +++ b/ServicesApi/Schemas/rules/rules.py @@ -0,0 +1,37 @@ +from schemas.base_imports import ( + CrudCollection, + UUID, + String, + mapped_column, + Mapped, + Index, +) + + +class EndpointRestriction(CrudCollection): + """ + Initialize Endpoint Restriction with default values + """ + + __tablename__ = "endpoint_restriction" + __exclude__fields__ = [] + + operation_uu_id: Mapped[UUID] = mapped_column( + String, comment="UUID of the operation", nullable=False, unique=True + ) + endpoint_function: Mapped[str] = mapped_column( + String, comment="Function name of the API endpoint" + ) + endpoint_name: Mapped[str] = mapped_column( + String, comment="Name of the API endpoint" + ) + endpoint_method: Mapped[str] = mapped_column( + String, comment="HTTP method used by the endpoint" + ) + endpoint_desc: Mapped[str] = mapped_column( + String, server_default="", comment="Description of the endpoint" + ) + + __table_args__ = ( + Index("idx_endpoint_restriction_operation_uu_id", operation_uu_id, endpoint_method, endpoint_name, unique=True), + ) diff --git a/ServicesApi/api_env.env b/ServicesApi/api_env.env new file mode 100644 index 0000000..c1cddc1 --- /dev/null +++ b/ServicesApi/api_env.env @@ -0,0 +1,41 @@ +MONGO_ENGINE=mongodb +MONGO_DB=appdb +MONGO_HOST=10.10.2.13 +MONGO_PORT=27017 +MONGO_USER=appuser +MONGO_AUTH_DB=appdb +MONGO_PASSWORD=apppassword + +POSTGRES_USER=postgres +POSTGRES_PASSWORD=password +POSTGRES_DB=postgres +POSTGRES_HOST=10.10.2.14 +POSTGRES_PORT=5432 +POSTGRES_ENGINE=postgresql+psycopg2 +POSTGRES_POOL_PRE_PING=True +POSTGRES_POOL_SIZE=20 +POSTGRES_MAX_OVERFLOW=10 +POSTGRES_POOL_RECYCLE=600 +POSTGRES_POOL_TIMEOUT=30 +POSTGRES_ECHO=True + +REDIS_HOST=10.10.2.15 +REDIS_PASSWORD=your_strong_password_here +REDIS_PORT=6379 +REDIS_DB=0 + +API_ACCESS_EMAIL_EXT=evyos.com.tr +API_ALGORITHM=HS256 +API_ACCESS_TOKEN_LENGTH=90 +API_REFRESHER_TOKEN_LENGTH=144 +API_EMAIL_HOST=10.10.2.36 +API_DATETIME_FORMAT=YYYY-MM-DD HH:mm:ss Z +API_FORGOT_LINK=https://www.evyos.com.tr/password/create?tokenUrl= +API_VERSION=0.1.001 +API_ACCESS_TOKEN_TAG=eys-acs-tkn + +EMAIL_HOST=10.10.2.34 +EMAIL_USERNAME=karatay@mehmetkaratay.com.tr +EMAIL_PASSWORD=system +EMAIL_PORT=587 +EMAIL_SEND=0 diff --git a/ServicesApi/pyproject.toml b/ServicesApi/pyproject.toml new file mode 100644 index 0000000..28e084c --- /dev/null +++ b/ServicesApi/pyproject.toml @@ -0,0 +1,27 @@ +[project] +name = "evyos-services-api" +version = "0.1.0" +description = "Evyos services api" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "alembic>=1.15.2", + "arrow>=1.3.0", + "cryptography>=44.0.2", + "faker>=37.1.0", + "fastapi>=0.115.12", + "pandas>=2.2.3", + "prometheus-fastapi-instrumentator>=7.1.0", + "psycopg2-binary>=2.9.10", + "pydantic-settings>=2.8.1", + "pymongo>=4.11.3", + "pytest>=8.3.5", + "redbox>=0.2.1", + "redis>=5.2.1", + "redmail>=0.6.0", + "requests>=2.32.3", + "sqlalchemy-mixins>=2.0.5", + "textdistance>=4.6.3", + "unidecode>=1.3.8", + "uvicorn>=0.34.0", +] diff --git a/ServicesBank/Templates/template_accounts.html b/ServicesBank/Templates/template_accounts.html new file mode 100644 index 0000000..df06ed6 --- /dev/null +++ b/ServicesBank/Templates/template_accounts.html @@ -0,0 +1,62 @@ + + +
+ + +Banka Kayıtları : {{today}}
+Son Bakiye : {{bank_balance}}
++ {{"Status : İkinci Bakiye Hatalı" if balance_error else "Status + :OK"}} +
+| {{ header }} | + {% endfor %} +
|---|
| {{ cell }} | + {% endfor %} +
Teşekkür ederiz,
Evyos Yönetim
Saygılarımızla
+ src/app/page.tsx
+
+ .
+ + {body} +
+ ) +} + +export { + useFormField, + Form, + FormItem, + FormLabel, + FormControl, + FormDescription, + FormMessage, + FormField, +} diff --git a/ServicesWeb/customer/src/components/ui/hover-card.tsx b/ServicesWeb/customer/src/components/ui/hover-card.tsx new file mode 100644 index 0000000..e754186 --- /dev/null +++ b/ServicesWeb/customer/src/components/ui/hover-card.tsx @@ -0,0 +1,44 @@ +"use client" + +import * as React from "react" +import * as HoverCardPrimitive from "@radix-ui/react-hover-card" + +import { cn } from "@/lib/utils" + +function HoverCard({ + ...props +}: React.ComponentProps
+ src/app/page.tsx
+
+ .
+ + {body} +
+ ) +} + +export { + useFormField, + Form, + FormItem, + FormLabel, + FormControl, + FormDescription, + FormMessage, + FormField, +} diff --git a/ServicesWeb/management/src/components/ui/hover-card.tsx b/ServicesWeb/management/src/components/ui/hover-card.tsx new file mode 100644 index 0000000..e754186 --- /dev/null +++ b/ServicesWeb/management/src/components/ui/hover-card.tsx @@ -0,0 +1,44 @@ +"use client" + +import * as React from "react" +import * as HoverCardPrimitive from "@radix-ui/react-hover-card" + +import { cn } from "@/lib/utils" + +function HoverCard({ + ...props +}: React.ComponentProps