first commit
This commit is contained in:
93
.dockerignore
Normal file
93
.dockerignore
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.gitattributes
|
||||||
|
|
||||||
|
|
||||||
|
# CI
|
||||||
|
.codeclimate.yml
|
||||||
|
.travis.yml
|
||||||
|
.taskcluster.yml
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
docker-compose.yml
|
||||||
|
service_app/Dockerfile
|
||||||
|
.docker
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
**/__pycache__/
|
||||||
|
**/*.py[cod]
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
service_app/env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Virtual environment
|
||||||
|
service_app/.env
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Python mode for VIM
|
||||||
|
.ropeproject
|
||||||
|
**/.ropeproject
|
||||||
|
|
||||||
|
# Vim swap files
|
||||||
|
**/*.swp
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
test_application/
|
||||||
|
|
||||||
|
|
||||||
162
.gitignore
vendored
Normal file
162
.gitignore
vendored
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
# ---> Python
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.idea/
|
||||||
|
.Python
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.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
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
service_app/.env
|
||||||
|
.venv
|
||||||
|
service_app/env/
|
||||||
|
venv/
|
||||||
|
service_app/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/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.12
|
||||||
88
README.md
Normal file
88
README.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
|
||||||
|
uv add arrow alembic fastapi uvicorn sqlalchemy-mixins redis psycopg2-binary pymongo rsa redmail unidecode textdistance pandas faker requests cryptography
|
||||||
|
|
||||||
|
user_creds_create
|
||||||
|
user_creds_update
|
||||||
|
|
||||||
|
timezone Comparator must be used as GMT+0 and users GMT+X
|
||||||
|
[Base Collection don't have find_one / find_all bla bla]ApiEnumDropdown: functions [
|
||||||
|
enum_class = mapped_column(String, nullable=False, comment="Enum Constant Name")
|
||||||
|
key = mapped_column(String, nullable=False, comment="Enum Key")
|
||||||
|
value = mapped_column(String, nullable=False, comment="Enum Value")
|
||||||
|
description = mapped_column(String, nullable=True)
|
||||||
|
]
|
||||||
|
BuildType: functions [
|
||||||
|
build_type = mapped_column(String, nullable=False, comment="Build Type")
|
||||||
|
description = mapped_column(String, nullable=True)
|
||||||
|
]
|
||||||
|
OccupantType: functions [
|
||||||
|
occupant_type = mapped_column(String, nullable=False, comment="Occupant Type")
|
||||||
|
description = mapped_column(String, nullable=True)
|
||||||
|
]
|
||||||
|
|
||||||
|
create & update & select
|
||||||
|
is_confirmed = True
|
||||||
|
|
||||||
|
find_one / find_all is found @Database
|
||||||
|
is_confirmed = False raise Exception Record is in database but not confirmed by supervisor
|
||||||
|
|
||||||
|
find_or_create -> If record is not found create it
|
||||||
|
if found.is_deleted = True: return "Record is found but deleted. Please contact your supervisor"
|
||||||
|
if found.is_confirmed = False: return "Record is found but not confirmed by supervisor"
|
||||||
|
|
||||||
|
|
||||||
|
update Which fields are possible to update
|
||||||
|
except
|
||||||
|
- is_confirmed
|
||||||
|
|
||||||
|
delete -> Update is_deleted = True
|
||||||
|
except
|
||||||
|
- id
|
||||||
|
|
||||||
|
destroy -> Only available for system
|
||||||
|
|
||||||
|
patch -> Only available for system [event] Retrieve available events for token user
|
||||||
|
|
||||||
|
+ Occupant Information +
|
||||||
|
Occupant [Settings] -> Event Group [Settings]
|
||||||
|
Occupant [Accounts] -> Event Group [Accounts]
|
||||||
|
Occupant [Decision Book] -> Event Group [Decision Book]
|
||||||
|
Occupant [Projects] -> Event Group [Projects]
|
||||||
|
Occupant [Events] -> Event Group [Events]
|
||||||
|
Occupant [Company] -> Event Group [Company]
|
||||||
|
Occupant [People] -> Event Group [People]
|
||||||
|
Occupant [Build] -> Event Group [Build]
|
||||||
|
Occupant [Address] -> Event Group [Address]
|
||||||
|
|
||||||
|
|
||||||
|
ApiActions:
|
||||||
|
insert_
|
||||||
|
insert_bulk
|
||||||
|
update_
|
||||||
|
update_bulk
|
||||||
|
delete_
|
||||||
|
delete_bulk
|
||||||
|
patch_
|
||||||
|
patch_bulk
|
||||||
|
|
||||||
|
InnerJoin:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class FilterFromUser:
|
||||||
|
raise_exception = FilterModelofEvent(**filter_records)
|
||||||
|
|
||||||
|
HTTP_404_NOT_FOUND make available for Next.js
|
||||||
|
HTTP_401_UNAUTHORIZED make available for Next.js
|
||||||
|
HTTP_403_FORBIDDEN make available for Next.js
|
||||||
|
HTTP_400_BAD_REQUEST make available for Next.js
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list",
|
||||||
|
}
|
||||||
|
event_description = "List Decision Book Items"
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
BuildDecisionBook:
|
||||||
|
|
||||||
|
|occupant_type |occupant_description |occupant_code|occupant_category|occupant_category_type|
|
||||||
|
|------------------------|---------------------------------|-------------|-----------------|----------------------|
|
||||||
|
|Toplantı Başkanı |Toplantı Başkanı |MT-PRS |Toplantı |MT |
|
||||||
|
|Toplantı Katip |Toplantıda tutanak tutan kişi |MT-WRT |Toplantı |MT |
|
||||||
|
|Toplantı Katılımcısı |Toplantıda sadece katılan kişi |MT-ATT |Toplantı |MT |
|
||||||
|
|Toplantı Danışman |Toplantıda danışmanlık yapan kişi|MT-ADV |Toplantı |MT |
|
||||||
|
|Daire Sahibi |Daire Sahibi |FL-OWN |Daire |FL |
|
||||||
|
|Daire Kiracısı |Daire Kiracısı |FL-TEN |Daire |FL |
|
||||||
|
|Daire Sakini |Daire Sakini |FL-RES |Daire |FL |
|
||||||
|
|Daire Sakini Vekili |Daire Sakini Vekili |FL-REP |Daire |FL |
|
||||||
|
|Bina Avukatı |Bina Avukatı |BU-ATT |Bina |BU |
|
||||||
|
|Bina Avukatı Yardımcısı |Bina Avukatı Yardımcısı |BU-ATA |Bina |BU |
|
||||||
|
|Bina Denetmen Yardımcısı|Bina Denetmen Yardımcısı |BU-SPA |Bina |BU |
|
||||||
|
|Bina Denetmeni |Bina Denetmeni |BU-SPV |Bina |BU |
|
||||||
|
|Bina Yönetici Yardımcısı|Bina Yönetici Yardımcısı |BU-MNA |Bina |BU |
|
||||||
|
|Bina Yöneticisi |Bina Yöneticisi |BU-MNG |Bina |BU |
|
||||||
|
|Bina Muhasabecisi |Bina Muhasabecisi |BU-ACC |Bina |BU |
|
||||||
|
|
||||||
|
|
||||||
|
1. Events[]
|
||||||
|
2. Events[]
|
||||||
|
|
||||||
|
|
||||||
|
Occupant:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Category:
|
||||||
|
::Category + CategoryType
|
||||||
|
- Bina (BU) -> Build
|
||||||
|
- Daire (FL) -> BuildPart
|
||||||
|
- Toplantı (MT) -> Decision Book
|
||||||
|
|
||||||
|
|
||||||
|
Service:
|
||||||
|
MT-PRS -> [Toplantı] Başkanı
|
||||||
|
MT-WRT -> [Toplantı] Katip
|
||||||
|
MT-ATT -> [Toplantı] Katılımcısı
|
||||||
|
MT-ADV -> [Toplantı] Danışman
|
||||||
|
|
||||||
|
1. Action Endpoint: /build/decision_book/items/create
|
||||||
|
2. Action Endpoint: /build/decision_book/person/create
|
||||||
|
3. Action Endpoint: /build/decision_book/invitation/send
|
||||||
|
|
||||||
|
occupant_type & employee
|
||||||
|
|
||||||
|
occupant X -> Restriction Optimum How to map =>
|
||||||
|
Build Need -> 1 yr annual meeting
|
||||||
|
|
||||||
|
API -> REQ[Toplantı] -> Client[Occ, Emp] -> Select[Com, Bul] -> Event -> Service
|
||||||
|
|
||||||
|
Module: Build Management
|
||||||
|
|
||||||
|
1. Service [Toplantı] Olagan - OPTIONAL
|
||||||
|
|
||||||
|
2. Service [Toplantı] Olağanüstü + OPTIONAL
|
||||||
|
3. Service [Toplantı] Ihtiyaç + OPTIONAL
|
||||||
|
4. Service [Toplantı] Karar + OPTIONAL
|
||||||
|
|
||||||
|
4. Service [Bina] Yönetim - OPTIONAL
|
||||||
|
5. Service [Bina] Yasal İşler - OPTIONAL
|
||||||
|
6. Service [Bina] Temizlik - OPTIONAL
|
||||||
|
7. Service [Bina] Isınma Sistemi - OPTIONAL
|
||||||
|
|
||||||
|
8. Service [Bina] Güvenlik Sistemi + OPTIONAL
|
||||||
|
9. Service [Bina] Bakım + OPTIONAL
|
||||||
|
10. Service [Bina] Onarım + OPTIONAL
|
||||||
|
|
||||||
|
11. Service [Daire] Kiralama + OPTIONAL
|
||||||
|
12. Service [Daire] Satış + OPTIONAL
|
||||||
|
13. Service [Daire] Tadiilat + OPTIONAL
|
||||||
|
14. Service [Daire] Temizlik + OPTIONAL
|
||||||
|
|
||||||
|
|
||||||
|
Pazarlama:
|
||||||
|
P1. Build Management Module (1, 4, 5, 6, 7)
|
||||||
|
P2. Build Management Gold Module (P1 + 8, 14)
|
||||||
|
P3. Build Management Platinum Module (P2 + 9, 10, 11, 12, 13)
|
||||||
|
P4. Build Management Custom Module (X, X, X ...)
|
||||||
|
|
||||||
|
|
||||||
|
1 Module -> n Service -> n Event(Unique 4 each establishment) -> n Action(Unique 4 each establishment)
|
||||||
|
|
||||||
|
Occupant Client:
|
||||||
|
- Services with same name and @DataBase Addresses can not be clarified due to event -> service relation
|
||||||
|
|
||||||
|
Schema:
|
||||||
|
|
||||||
|
Toplantı Karar Mapping:
|
||||||
|
- A Create Meeting Invitation [MT-PRS] +BookInvatationTable ->
|
||||||
|
- B Create Decision Book Attendance [MT-PRS] +BookPersonTable ->
|
||||||
|
- C Create Decision Book
|
||||||
|
- D Create Decision Book Items
|
||||||
|
- E Verify Decision Book [MT-PRS]
|
||||||
|
- F Announce Decision Book is verified
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Buy -> Service[Toplantı Karar] Database Address: id[1]
|
||||||
|
- A Create Meeting Invitation Action: 3
|
||||||
|
:: [Event:1]Send invitation to all occupants via EMAIL
|
||||||
|
- B Create Decision Book Attendance Action: 2
|
||||||
|
:: [Event:2]Create attendance for all occupants from EMAIL
|
||||||
|
- C Create Decision Book Items Action: 1
|
||||||
|
:: [Event:3]Create items for all occupants from OCCUPANT_TYPE[MT-WRT] individual is responsible for Note TAKING
|
||||||
|
|
||||||
|
Buy -> Service[Toplantı Karar AI] Database Address: id[2]
|
||||||
|
- A Create Meeting Invitation Action: 3
|
||||||
|
:: [Event:1]Send invitation to all occupants via EMAIL
|
||||||
|
- B Create Decision Book Attendance Action: 2
|
||||||
|
:: [Event:2]Create attendance for all occupants from EMAIL
|
||||||
|
- D Create Decision Book Items AI Action: 1
|
||||||
|
:: [Event:4] [Event:3] + individual takes note via different [Service] fee : 0.20Cent
|
||||||
|
|
||||||
|
Buy -> Service[Toplantı Karar AI + Storage] Database Address: id[3]
|
||||||
|
- A Create Meeting Invitation Action: 3
|
||||||
|
:: [Event:1]Send invitation to all occupants via EMAIL
|
||||||
|
- B Create Decision Book Attendance Action: 2
|
||||||
|
:: [Event:2]Create attendance for all occupants from EMAIL and store @Data fees : 0.50Cent
|
||||||
|
- D Create Decision Book Items AI Action: 7
|
||||||
|
:: [Event:4] [Event:3] + individual takes note via different [Service] fee : 0.20Cent
|
||||||
|
|
||||||
|
Employee Client:
|
||||||
|
- Services with same name and @DataBase Addresses can not be clarified due to event -> service relation
|
||||||
|
|
||||||
|
Buy -> Service[Toplantı 15] Database Address: id[3]
|
||||||
|
-> Clearance of Event Bulk
|
||||||
|
Note-taking via AI implementation Action: 1
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
BuildDecisionBook:
|
||||||
|
|
||||||
|
|occupant_type |occupant_description |occupant_code|occupant_category|occupant_category_type|
|
||||||
|
|------------------------|---------------------------------|-------------|-----------------|----------------------|
|
||||||
|
|Toplantı Başkanı |Toplantı Başkanı |MT-PRS |Toplantı |MT |
|
||||||
|
|Toplantı Katip |Toplantıda tutanak tutan kişi |MT-WRT |Toplantı |MT |
|
||||||
|
|Toplantı Katılımcısı |Toplantıda sadece katılan kişi |MT-ATT |Toplantı |MT |
|
||||||
|
|Toplantı Danışman |Toplantıda danışmanlık yapan kişi|MT-ADV |Toplantı |MT |
|
||||||
|
|Daire Sahibi |Daire Sahibi |FL-OWN |Daire |FL |
|
||||||
|
|Daire Kiracısı |Daire Kiracısı |FL-TEN |Daire |FL |
|
||||||
|
|Daire Sakini |Daire Sakini |FL-RES |Daire |FL |
|
||||||
|
|Daire Sakini Vekili |Daire Sakini Vekili |FL-REP |Daire |FL |
|
||||||
|
|Bina Avukatı |Bina Avukatı |BU-ATT |Bina |BU |
|
||||||
|
|Bina Avukatı Yardımcısı |Bina Avukatı Yardımcısı |BU-ATA |Bina |BU |
|
||||||
|
|Bina Denetmen Yardımcısı|Bina Denetmen Yardımcısı |BU-SPA |Bina |BU |
|
||||||
|
|Bina Denetmeni |Bina Denetmeni |BU-SPV |Bina |BU |
|
||||||
|
|Bina Yönetici Yardımcısı|Bina Yönetici Yardımcısı |BU-MNA |Bina |BU |
|
||||||
|
|Bina Yöneticisi |Bina Yöneticisi |BU-MNG |Bina |BU |
|
||||||
|
|Bina Muhasabecisi |Bina Muhasabecisi |BU-ACC |Bina |BU |
|
||||||
|
|
||||||
|
Occupant Objesi Toplantı:
|
||||||
|
------------------------------------------------------------------------------------------------------------------------
|
||||||
|
MT-PRS:
|
||||||
|
1. Toplantıdan Sorumludur. Toplantıyı yönetir.
|
||||||
|
2. Kararlar alınırken toplantıyı yönetir.
|
||||||
|
3 Alınan kararları katılımcılara onaylatır
|
||||||
|
4. Alınan kararları bir metne dönüştürür.
|
||||||
|
5. Katibe yazdırır.
|
||||||
|
6. Yazılan metini kontrol eder ve onaylar.
|
||||||
|
7. Metne itiraz edenler olursa, her itirazı kayıt ettirir.
|
||||||
|
8. Eğer toplantı olağan toplantı ise ve aidatı ilgilendirioyorsa
|
||||||
|
9. Aidat kararlarını katip tarafından rakamsal değerler ile yazdırır.
|
||||||
|
10. Aidat kararlarını onaylar.
|
||||||
|
11. Alınan karar bir tadilat ise, açıklamalarını yazdırır.
|
||||||
|
12. Projeyi açtırır.
|
||||||
|
13. Alınan kararları yasal bir sureç takip ediyor ise yasal takip sürecini açar ve hukuki süreci başlatır/takip eder.
|
||||||
|
|
||||||
|
MT-WRT:
|
||||||
|
1. Toplantıda başkanın aldığı kararları metne çevirmek ile görevlidir.
|
||||||
|
2. Borçlandırma, Proje, Yasal süreçlerinin tanımlanmasını sağlar.
|
||||||
|
|
||||||
|
MT-ATT:
|
||||||
|
1. Toplantıda alınana kararlara tanıklık eder.
|
||||||
|
2. Itirazı var ise itiraz eder.
|
||||||
|
3. Itirazı yok ise kararları onaylar.
|
||||||
|
|
||||||
|
MT-ADV:
|
||||||
|
1. Toplantıda alınan kararlarlara onay veremez veya itiraz edemez.
|
||||||
|
2. Toplantıda karar alınırken danışmanlık yapar.
|
||||||
|
|
||||||
|
BU-MNG:
|
||||||
|
1 Toplantı tarihi belirliyor. +
|
||||||
|
2. Toplantı davetini ilgili tarihi ile duyunur. -
|
||||||
|
3. Toplantı günü yeterli kriterler oluşmuş ise toplantıyı başlatır. -
|
||||||
|
4. Divan Kurulunu kurar. -
|
||||||
|
5. Toplantı başkanını ve katibi deneteledikten sonra başkana toplantıyı devreder.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------------------------------
|
||||||
|
{"enum_class": "MeetingTypes", "type_code": "RBM", "type_name": "Regular Building Meeting"},
|
||||||
|
{"enum_class": "MeetingTypes", "type_code": "DBM", "type_name": "Disaster Building Meeting"},
|
||||||
|
{"enum_class": "MeetingTypes", "type_code": "EBM", "type_name": "Emergency Building Meeting"},
|
||||||
|
|
||||||
|
|
||||||
|
Düzenli Bina Toplantısı (RBM) Servisi:
|
||||||
|
2. Tarihinin belirlenirmesi.
|
||||||
|
3. Tarihinin duyurulması.
|
||||||
|
4. %51 kişinin toplantıya katılması zorunludur.
|
||||||
|
5. %51 sağlanmadıysa bir sonraki tarihe ertelenir.
|
||||||
|
6. 2 tarihte kritere bakılmaksızın toplantı başlatılır. (Kaç kişinin katılacağına bakılmaz)
|
||||||
|
7. Divan Kurulu kurulur.
|
||||||
|
8. Toplantı başkanı ve katibi belirlenir.
|
||||||
|
9. Toplantı toplantı başkanına devredilir.
|
||||||
|
10. Toplantı tipine göre bir karar alınır.
|
||||||
|
11. Karar kurul tarafından istişare edilir.
|
||||||
|
12. Karar kurul tarafından onaylanır.
|
||||||
|
13. Karar katip tarafından yazılır.
|
||||||
|
14. Karar başkan tarafından onaylanır. (Katibin yazdığı metin kontrol edilir)
|
||||||
|
15. Bir sonraki karara geçilir.
|
||||||
|
16. Karar defterine katılımcılar tarafından imza atılır.
|
||||||
|
17. Karar defteri yeni Bina Yöneticisine teslim edilir.
|
||||||
|
|
||||||
|
Olaganüstü Bina Toplantısı (DBM) Servisi:
|
||||||
|
2. Tarihinin belirlenirmesi.
|
||||||
|
3. Tarihinin duyurulması.
|
||||||
|
7. Divan Kurulu kurulur.
|
||||||
|
|
||||||
|
8. Toplantı başkanı ve katibi belirlenir.
|
||||||
|
9. Toplantı toplantı başkanına devredilir.
|
||||||
|
10. Toplantı tipine göre bir karar alınır.
|
||||||
|
11. Karar kurul tarafından istişare edilir.
|
||||||
|
12. Karar kurul tarafından onaylanır.
|
||||||
|
|
||||||
|
13. Karar katip tarafından yazılır.
|
||||||
|
14. Karar başkan tarafından onaylanır. (Katibin yazdığı metin kontrol edilir)
|
||||||
|
15. Bir sonraki karara geçilir.
|
||||||
|
16. Karar defterine katılımcılar tarafından imza atılır.
|
||||||
|
|
||||||
|
Acil Bina Toplantısı (EBM) Servisi:
|
||||||
|
2. Tarihinin belirlenirmesi.
|
||||||
|
3. Tarihinin duyurulması.
|
||||||
|
7. Divan Kurulu kurulur.
|
||||||
|
8. Toplantı başkanı ve katibi belirlenir.
|
||||||
|
9. Toplantı toplantı başkanına devredilir.
|
||||||
|
10. Toplantı tipine göre bir karar alınır.
|
||||||
|
11. Karar kurul tarafından istişare edilir.
|
||||||
|
12. Karar kurul tarafından onaylanır.
|
||||||
|
13. Karar katip tarafından yazılır.
|
||||||
|
14. Karar başkan tarafından onaylanır. (Katibin yazdığı metin kontrol edilir)
|
||||||
|
15. Bir sonraki karara geçilir.
|
||||||
|
16. Karar defterine katılımcılar tarafından imza atılır.
|
||||||
|
|
||||||
|
|
||||||
|
Meeting:
|
||||||
|
1. Tipini belirlenmesi.
|
||||||
|
2. Tarihinin belirlenirmesi.
|
||||||
|
3. Tarihinin duyurulması.
|
||||||
|
4. %51 kişinin toplantıya katılması zorunludur.
|
||||||
|
5. %51 sağlanmadıysa bir sonraki tarihe ertelenir.
|
||||||
|
6. 2 tarihte kritere bakılmaksızın toplantı başlatılır. (Kaç kişinin katılacağına bakılmaz)
|
||||||
|
7. Divan Kurulu kurulur.
|
||||||
|
8. Toplantı başkanı ve katibi belirlenir.
|
||||||
|
9. Toplantı toplantı başkanına devredilir.
|
||||||
|
10. Toplantı tipine göre bir karar alınır.
|
||||||
|
11. Karar kurul tarafından istişare edilir.
|
||||||
|
12. Karar kurul tarafından onaylanır.
|
||||||
|
13. Karar katip tarafından yazılır.
|
||||||
|
14. Karar başkan tarafından onaylanır. (Katibin yazdığı metin kontrol edilir)
|
||||||
|
15. Bir sonraki karara geçilir.
|
||||||
|
16. Karar defterine katılımcılar tarafından imza atılır.
|
||||||
|
17. Karar defteri yeni Bina Yöneticisine teslim edilir.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
508
a_project_files/drafts_and_notes/evyos-draft/emodeasdasdasdl.py
Normal file
508
a_project_files/drafts_and_notes/evyos-draft/emodeasdasdasdl.py
Normal file
@@ -0,0 +1,508 @@
|
|||||||
|
from sqlalchemy import (
|
||||||
|
create_engine,
|
||||||
|
UUID,
|
||||||
|
Column,
|
||||||
|
Integer,
|
||||||
|
String,
|
||||||
|
ForeignKey,
|
||||||
|
Boolean,
|
||||||
|
DateTime,
|
||||||
|
func,
|
||||||
|
text,
|
||||||
|
Index,
|
||||||
|
UniqueConstraint,
|
||||||
|
)
|
||||||
|
from sqlalchemy.orm import relationship, declarative_base
|
||||||
|
from .base import CrudMixin
|
||||||
|
from sqlalchemy_mixins.serialize import SerializeMixin
|
||||||
|
from sqlalchemy_mixins.repr import ReprMixin
|
||||||
|
from sqlalchemy_mixins.smartquery import SmartQueryMixin
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
class CrudCollection(Base, CrudMixin, ReprMixin, SmartQueryMixin, SerializeMixin):
|
||||||
|
__abstract__ = True
|
||||||
|
__repr__ = ReprMixin.__repr__
|
||||||
|
|
||||||
|
id: int = Column(Integer, primary_key=True)
|
||||||
|
uu_id: str = Column(
|
||||||
|
UUID, server_default=text("gen_random_uuid()"), index=True, unique=True
|
||||||
|
)
|
||||||
|
createdate = Column(DateTime, default=func.now())
|
||||||
|
updatedate = Column(DateTime, default=func.now(), onupdate=func.now())
|
||||||
|
createperson = Column(Integer, ForeignKey("persons.id"), nullable=True)
|
||||||
|
updateperson = Column(Integer, ForeignKey("persons.id"), nullable=True)
|
||||||
|
active = Column(Boolean, default=True)
|
||||||
|
delete = Column(Boolean, default=False)
|
||||||
|
replicationid = Column(Integer)
|
||||||
|
|
||||||
|
|
||||||
|
class Address(CrudCollection):
|
||||||
|
__tablename__ = "address"
|
||||||
|
__table_args__ = (
|
||||||
|
Index("_address_ndx_00", country_code, b_state, city, district),
|
||||||
|
{"comment": "Address Information"},
|
||||||
|
)
|
||||||
|
country_code = mapped_column(
|
||||||
|
String(9), server_default="TR", nullable=False, comment="Country Code"
|
||||||
|
)
|
||||||
|
city = mapped_column(String(24), nullable=False, comment="City")
|
||||||
|
district = mapped_column(String(24), nullable=False, comment="District")
|
||||||
|
b_state = mapped_column(String(24), server_default="")
|
||||||
|
neighborhood = mapped_column(String(24), server_default="")
|
||||||
|
street = mapped_column(String(24), server_default="")
|
||||||
|
postcode = mapped_column(String(8), server_default="")
|
||||||
|
latitude = mapped_column(Numeric(20, 12), server_default="0")
|
||||||
|
longitude = mapped_column(Numeric(20, 12), server_default="0")
|
||||||
|
|
||||||
|
official_companies: Mapped["Company"] = relationship(
|
||||||
|
"Company",
|
||||||
|
back_populates="official_address",
|
||||||
|
foreign_keys="Company.official_address_id",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Company(CrudCollection):
|
||||||
|
__tablename__ = "companies"
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint("tax_number", name="uq_companies_tax_number"),
|
||||||
|
{"comment": "İşletmelerin bilgilerini tutar"},
|
||||||
|
)
|
||||||
|
official_name = mapped_column(String, nullable=True, comment="Şirketin resmi adı")
|
||||||
|
public_name = Column(String, nullable=False, comment="Şirketin bilinen adı")
|
||||||
|
tax_number = Column(String, nullable=False, unique=True, comment="Vergi numarası")
|
||||||
|
organizations = relationship("Organization", back_populates="company")
|
||||||
|
locations = relationship("Location", back_populates="company")
|
||||||
|
|
||||||
|
default_lang_type = mapped_column(String(5), server_default="TR")
|
||||||
|
default_money_type = mapped_column(String(5), server_default="TL")
|
||||||
|
is_commercial = mapped_column(Boolean, server_default="True")
|
||||||
|
is_blacklist = mapped_column(Boolean, server_default="False")
|
||||||
|
|
||||||
|
official_address_id = mapped_column(ForeignKey("address.id"))
|
||||||
|
parent_id = mapped_column(ForeignKey("company.id"))
|
||||||
|
|
||||||
|
official_address: Mapped[List["Address"]] = relationship(
|
||||||
|
"Address",
|
||||||
|
back_populates="official_companies",
|
||||||
|
foreign_keys=[official_address_id],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Organization(CrudCollection):
|
||||||
|
__tablename__ = "organizations"
|
||||||
|
__table_args__ = {"comment": "Her şirketin organizasyon yapısını tutar"}
|
||||||
|
name = Column(String, nullable=False, comment="Organizasyonun adı")
|
||||||
|
company_id = Column(
|
||||||
|
Integer, ForeignKey("companies.id"), nullable=False, comment="Şirket ID"
|
||||||
|
)
|
||||||
|
valid_from = Column(
|
||||||
|
DateTime, default=func.now(), comment="Geçerlilik başlangıç tarihi"
|
||||||
|
)
|
||||||
|
valid_to = Column(DateTime, nullable=True, comment="Geçerlilik bitiş tarihi")
|
||||||
|
company = relationship("Company", back_populates="organizations")
|
||||||
|
employees = relationship("Employee", back_populates="organization")
|
||||||
|
locations = relationship("Location", back_populates="organization")
|
||||||
|
phones = relationship("Phone", back_populates="organization")
|
||||||
|
menus = relationship("Menu", back_populates="organization")
|
||||||
|
|
||||||
|
|
||||||
|
class Location(CrudCollection):
|
||||||
|
__tablename__ = "locations"
|
||||||
|
__table_args__ = {
|
||||||
|
"comment": "Şirketin farklı lokasyonlarını (depo, ofis, şube, büro vb.) tutar"
|
||||||
|
}
|
||||||
|
name = Column(String, nullable=False, comment="Lokasyon adı")
|
||||||
|
address = Column(String, nullable=False, comment="Lokasyon adresi")
|
||||||
|
location_type = Column(
|
||||||
|
String, nullable=False, comment="Lokasyon türü (depo, ofis, şube, büro vb.)"
|
||||||
|
)
|
||||||
|
company_id = Column(
|
||||||
|
Integer, ForeignKey("companies.id"), nullable=False, comment="Şirket ID"
|
||||||
|
)
|
||||||
|
organization_id = Column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("organizations.id"),
|
||||||
|
nullable=False,
|
||||||
|
comment="Organizasyon ID",
|
||||||
|
)
|
||||||
|
company = relationship("Company", back_populates="locations")
|
||||||
|
organization = relationship("Organization", back_populates="locations")
|
||||||
|
|
||||||
|
|
||||||
|
class Person(CrudCollection):
|
||||||
|
__tablename__ = "persons"
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint("identity_number", name="uq_persons_identity_number"),
|
||||||
|
{"comment": "Kişilerin bilgilerini tutar"},
|
||||||
|
)
|
||||||
|
first_name = Column(String, nullable=False, comment="İlk isim")
|
||||||
|
last_name = Column(String, nullable=False, comment="Soy isim")
|
||||||
|
identity_number = Column(
|
||||||
|
String, nullable=False, unique=True, comment="Kimlik numarası"
|
||||||
|
)
|
||||||
|
mother_name = Column(String, nullable=False, comment="Anne adı")
|
||||||
|
father_name = Column(String, nullable=False, comment="Baba adı")
|
||||||
|
birth_place = Column(String, nullable=False, comment="Doğum yeri")
|
||||||
|
birth_date = Column(DateTime, nullable=False, comment="Doğum tarihi")
|
||||||
|
gender = Column(String, nullable=False, comment="Cinsiyet")
|
||||||
|
nationality_code = Column(String, nullable=False, comment="Ülke kimlik kodu")
|
||||||
|
employees = relationship("Employee", back_populates="person")
|
||||||
|
users = relationship("User", back_populates="person")
|
||||||
|
|
||||||
|
|
||||||
|
class Employee(CrudCollection):
|
||||||
|
__tablename__ = "employees"
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint("person_id", name="uq_employee_person_id"),
|
||||||
|
{"comment": "Çalışanların bilgilerini tutar"},
|
||||||
|
)
|
||||||
|
person_id = Column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("persons.id"),
|
||||||
|
nullable=False,
|
||||||
|
unique=True,
|
||||||
|
comment="Kişi ID",
|
||||||
|
)
|
||||||
|
organization_id = Column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("organizations.id"),
|
||||||
|
nullable=False,
|
||||||
|
comment="Organizasyon ID",
|
||||||
|
)
|
||||||
|
person = relationship("Person", back_populates="employees")
|
||||||
|
organization = relationship("Organization", back_populates="employees")
|
||||||
|
processes = relationship("EmployeeProcess", back_populates="employee")
|
||||||
|
permissions = relationship("Permission", back_populates="employee")
|
||||||
|
salaries = relationship("Salary", back_populates="employee")
|
||||||
|
performances = relationship("Performance", back_populates="employee")
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
class User(CrudCollection):
|
||||||
|
__tablename__ = 'users'
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint('email', name='uq_users_email'),
|
||||||
|
UniqueConstraint('phone_number', name='uq_users_phone_number'),
|
||||||
|
{'comment': 'Kullanıcıların giriş bilgilerini tutar'}
|
||||||
|
)
|
||||||
|
person_id = Column(Integer, ForeignKey('persons.id'), nullable=False, comment='Kişi ID')
|
||||||
|
email = Column(String, nullable=True, unique=True, comment='E-posta adresi')
|
||||||
|
phone_number = Column(String, nullable=True, unique=True, comment='Telefon numarası')
|
||||||
|
password_hash = Column(String, nullable=False, comment='Parola hash değeri')
|
||||||
|
person = relationship('Person', back_populates='users')
|
||||||
|
login_attempts = relationship('LoginAttempt', back_populates='user')
|
||||||
|
|
||||||
|
class LoginAttempt(CrudCollection):
|
||||||
|
__tablename__ = 'login_attempts'
|
||||||
|
__table_args__ = {'comment': 'Kullanıcıların giriş denemelerini tutar'}
|
||||||
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=False, comment='Kullanıcı ID')
|
||||||
|
timestamp = Column(DateTime, default=func.now(), nullable=False, comment='Giriş deneme zamanı')
|
||||||
|
success = Column(Boolean, default=False, nullable=False, comment='Giriş başarılı mı')
|
||||||
|
user = relationship('User', back_populates='login_attempts')
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Process(CrudCollection):
|
||||||
|
__tablename__ = "processes"
|
||||||
|
__table_args__ = {"comment": "İş süreçlerinin tanımlamalarını tutar"}
|
||||||
|
name = Column(String, nullable=False, comment="Süreç adı")
|
||||||
|
employee_processes = relationship("EmployeeProcess", back_populates="process")
|
||||||
|
emails = relationship("Email", back_populates="process")
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeeProcess(CrudCollection):
|
||||||
|
__tablename__ = "employee_processes"
|
||||||
|
__table_args__ = {
|
||||||
|
"comment": "Çalışan ile iş süreçleri arasındaki ilişkileri ve yetkileri tutar"
|
||||||
|
}
|
||||||
|
employee_id = Column(
|
||||||
|
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
|
||||||
|
)
|
||||||
|
process_id = Column(
|
||||||
|
Integer, ForeignKey("processes.id"), nullable=False, comment="Süreç ID"
|
||||||
|
)
|
||||||
|
can_add = Column(Boolean, default=False, comment="Ekleme yetkisi")
|
||||||
|
can_update = Column(Boolean, default=False, comment="Güncelleme yetkisi")
|
||||||
|
can_delete = Column(Boolean, default=False, comment="Silme yetkisi")
|
||||||
|
employee = relationship("Employee", back_populates="processes")
|
||||||
|
process = relationship("Process", back_populates="employee_processes")
|
||||||
|
|
||||||
|
|
||||||
|
class Permission(CrudCollection):
|
||||||
|
__tablename__ = "permissions"
|
||||||
|
__table_args__ = {"comment": "Yetkileri tanımlar ve çalışanlara devredilebilir"}
|
||||||
|
employee_id = Column(
|
||||||
|
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
|
||||||
|
)
|
||||||
|
granted_to = Column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("employees.id"),
|
||||||
|
nullable=True,
|
||||||
|
comment="Yetki verilen çalışan ID",
|
||||||
|
) # Temporary delegation
|
||||||
|
permission_type = Column(
|
||||||
|
String, nullable=False, comment="Yetki türü (add, update, delete)"
|
||||||
|
)
|
||||||
|
valid_until = Column(DateTime, nullable=True, comment="Geçerlilik bitiş tarihi")
|
||||||
|
employee = relationship(
|
||||||
|
"Employee", foreign_keys=[employee_id], back_populates="permissions"
|
||||||
|
)
|
||||||
|
granted_employee = relationship("Employee", foreign_keys=[granted_to])
|
||||||
|
|
||||||
|
|
||||||
|
class Performance(CrudCollection):
|
||||||
|
__tablename__ = "performances"
|
||||||
|
__table_args__ = {"comment": "Çalışanların performanslarını tutar"}
|
||||||
|
employee_id = Column(
|
||||||
|
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
|
||||||
|
)
|
||||||
|
review_date = Column(DateTime, nullable=False, comment="Değerlendirme tarihi")
|
||||||
|
score = Column(Float, nullable=False, comment="Performans puanı")
|
||||||
|
notes = Column(String, nullable=True, comment="Notlar")
|
||||||
|
employee = relationship("Employee", back_populates="performances")
|
||||||
|
|
||||||
|
|
||||||
|
class Salary(CrudCollection):
|
||||||
|
__tablename__ = "salaries"
|
||||||
|
__table_args__ = {"comment": "Çalışanların maaş bilgilerini tutar"}
|
||||||
|
employee_id = Column(
|
||||||
|
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
|
||||||
|
)
|
||||||
|
salary_amount = Column(Float, nullable=False, comment="Maaş miktarı")
|
||||||
|
effective_date = Column(DateTime, nullable=False, comment="Geçerlilik tarihi")
|
||||||
|
employee = relationship("Employee", back_populates="salaries")
|
||||||
|
|
||||||
|
|
||||||
|
class Email(CrudCollection):
|
||||||
|
__tablename__ = "emails"
|
||||||
|
__table_args__ = {
|
||||||
|
"comment": "İş süreçlerine ve çalışanlara e-posta gönderimlerini takip eder"
|
||||||
|
}
|
||||||
|
process_id = Column(
|
||||||
|
Integer, ForeignKey("processes.id"), nullable=False, comment="Süreç ID"
|
||||||
|
)
|
||||||
|
recipient = Column(String, nullable=False, comment="Alıcı e-posta adresi")
|
||||||
|
subject = Column(String, nullable=False, comment="E-posta konusu")
|
||||||
|
body = Column(String, nullable=False, comment="E-posta içeriği")
|
||||||
|
sent_date = Column(
|
||||||
|
DateTime, default=func.now(), nullable=False, comment="Gönderim tarihi"
|
||||||
|
)
|
||||||
|
process = relationship("Process", back_populates="emails")
|
||||||
|
|
||||||
|
|
||||||
|
class Phone(CrudCollection):
|
||||||
|
__tablename__ = "phones"
|
||||||
|
__table_args__ = {"comment": "Organizasyonlara ait telefon bilgilerini tutar"}
|
||||||
|
organization_id = Column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("organizations.id"),
|
||||||
|
nullable=False,
|
||||||
|
comment="Organizasyon ID",
|
||||||
|
)
|
||||||
|
phone_number = Column(String, nullable=False, comment="Telefon numarası")
|
||||||
|
phone_type = Column(
|
||||||
|
String, nullable=False, comment="Telefon türü (Sabit, Mobil vb.)"
|
||||||
|
)
|
||||||
|
organization = relationship("Organization", back_populates="phones")
|
||||||
|
|
||||||
|
|
||||||
|
class Menu(CrudCollection):
|
||||||
|
__tablename__ = "menus"
|
||||||
|
__table_args__ = (
|
||||||
|
Index("ix_menus_title", "title"),
|
||||||
|
{"comment": "Menü öğelerini tutar"},
|
||||||
|
)
|
||||||
|
title = Column(String, nullable=False, comment="Menü başlığı")
|
||||||
|
link = Column(String, nullable=False, comment="Menü bağlantısı")
|
||||||
|
icon = Column(String, nullable=True, comment="Menü simgesi")
|
||||||
|
order = Column(Integer, nullable=False, default=0, comment="Menü sıralaması")
|
||||||
|
organization_id = Column(
|
||||||
|
Integer,
|
||||||
|
ForeignKey("organizations.id"),
|
||||||
|
nullable=False,
|
||||||
|
comment="Organizasyon ID",
|
||||||
|
)
|
||||||
|
page_id = Column(Integer, ForeignKey("pages.id"), nullable=True, comment="Sayfa ID")
|
||||||
|
sub_menus = relationship(
|
||||||
|
"SubMenu", back_populates="menu", cascade="all, delete-orphan"
|
||||||
|
)
|
||||||
|
organization = relationship("Organization", back_populates="menus")
|
||||||
|
page = relationship("Page", back_populates="menus")
|
||||||
|
|
||||||
|
|
||||||
|
class SubMenu(CrudCollection):
|
||||||
|
__tablename__ = "sub_menus"
|
||||||
|
__table_args__ = (
|
||||||
|
Index("ix_sub_menus_title", "title"),
|
||||||
|
{"comment": "Alt menü öğelerini tutar"},
|
||||||
|
)
|
||||||
|
menu_id = Column(
|
||||||
|
Integer, ForeignKey("menus.id"), nullable=False, comment="Ana Menü ID"
|
||||||
|
)
|
||||||
|
title = Column(String, nullable=False, comment="Alt Menü başlığı")
|
||||||
|
link = Column(String, nullable=False, comment="Alt Menü bağlantısı")
|
||||||
|
icon = Column(String, nullable=True, comment="Alt Menü simgesi")
|
||||||
|
order = Column(Integer, nullable=False, default=0, comment="Alt Menü sıralaması")
|
||||||
|
layer = Column(Integer, nullable=False, default=0, comment="Alt Menü seviyesi")
|
||||||
|
page_id = Column(Integer, ForeignKey("pages.id"), nullable=True, comment="Sayfa ID")
|
||||||
|
menu = relationship("Menu", back_populates="sub_menus")
|
||||||
|
page = relationship("Page", back_populates="sub_menus")
|
||||||
|
|
||||||
|
|
||||||
|
class Page(CrudCollection):
|
||||||
|
__tablename__ = "pages"
|
||||||
|
__table_args__ = {"comment": "Uygulamada kullanılacak sayfaları tutar"}
|
||||||
|
title = Column(String, nullable=False, comment="Sayfa başlığı")
|
||||||
|
path = Column(String, nullable=False, comment="Sayfa yolu")
|
||||||
|
menus = relationship("Menu", back_populates="page")
|
||||||
|
sub_menus = relationship("SubMenu", back_populates="page")
|
||||||
|
functions = relationship("Function", back_populates="page")
|
||||||
|
|
||||||
|
|
||||||
|
class Function(CrudCollection):
|
||||||
|
__tablename__ = "functions"
|
||||||
|
__table_args__ = {
|
||||||
|
"comment": "Uygulamada kullanılacak fonksiyon parçacıklarını tutar"
|
||||||
|
}
|
||||||
|
name = Column(String, nullable=False, comment="Fonksiyon adı")
|
||||||
|
description = Column(String, nullable=True, comment="Fonksiyon açıklaması")
|
||||||
|
code = Column(String, nullable=False, comment="Fonksiyon kodu")
|
||||||
|
page_id = Column(
|
||||||
|
Integer, ForeignKey("pages.id"), nullable=False, comment="Sayfa ID"
|
||||||
|
)
|
||||||
|
page = relationship("Page", back_populates="functions")
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy.exc import NoResultFound
|
||||||
|
|
||||||
|
|
||||||
|
def authenticate(email=None, phone_number=None, password=None):
|
||||||
|
try:
|
||||||
|
if email:
|
||||||
|
user = session.query(User).filter(User.email == email).one()
|
||||||
|
elif phone_number:
|
||||||
|
user = session.query(User).filter(User.phone_number == phone_number).one()
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Şifre doğrulama (gerçek şifre doğrulama fonksiyonu kullanılmalıdır)
|
||||||
|
if user.password_hash == password:
|
||||||
|
login_attempt = LoginAttempt(user_id=user.id, success=True)
|
||||||
|
session.add(login_attempt)
|
||||||
|
session.commit()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
login_attempt = LoginAttempt(user_id=user.id, success=False)
|
||||||
|
session.add(login_attempt)
|
||||||
|
session.commit()
|
||||||
|
return False
|
||||||
|
except NoResultFound:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# PostgreSQL veritabanına bağlan
|
||||||
|
engine = create_engine("postgresql://username:password@localhost/mydatabase")
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
|
||||||
|
# Oturum oluştur
|
||||||
|
Session = sessionmaker(bind=engine)
|
||||||
|
session = Session()
|
||||||
|
|
||||||
|
# Örnek veriler ekle
|
||||||
|
company = Company(name="My Company", tax_number="1234567890")
|
||||||
|
session.add(company)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
organization = Organization(name="IT Department", company_id=company.id)
|
||||||
|
session.add(organization)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
location = Location(
|
||||||
|
name="Main Office",
|
||||||
|
address="123 Main St",
|
||||||
|
location_type="Office",
|
||||||
|
company_id=company.id,
|
||||||
|
organization_id=organization.id,
|
||||||
|
)
|
||||||
|
session.add(location)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
person = Person(
|
||||||
|
first_name="John",
|
||||||
|
last_name="Doe",
|
||||||
|
identity_number="9876543210",
|
||||||
|
mother_name="Jane Doe",
|
||||||
|
father_name="Joe Doe",
|
||||||
|
birth_place="New York",
|
||||||
|
birth_date="1980-01-01",
|
||||||
|
gender="Male",
|
||||||
|
nationality_code="US",
|
||||||
|
)
|
||||||
|
session.add(person)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
employee = Employee(person_id=person.id, organization_id=organization.id)
|
||||||
|
session.add(employee)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user = User(
|
||||||
|
person_id=person.id,
|
||||||
|
email="john.doe@example.com",
|
||||||
|
phone_number="555-1234",
|
||||||
|
password_hash="hashed_password",
|
||||||
|
)
|
||||||
|
session.add(user)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
login_attempt = LoginAttempt(user_id=user.id, success=True)
|
||||||
|
session.add(login_attempt)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
process = Process(name="Code Review")
|
||||||
|
session.add(process)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
employee_process = EmployeeProcess(
|
||||||
|
employee_id=employee.id,
|
||||||
|
process_id=process.id,
|
||||||
|
can_add=True,
|
||||||
|
can_update=True,
|
||||||
|
can_delete=False,
|
||||||
|
)
|
||||||
|
session.add(employee_process)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
permission = Permission(
|
||||||
|
employee_id=employee.id, permission_type="add", valid_until=None
|
||||||
|
)
|
||||||
|
session.add(permission)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
performance = Performance(employee_id=employee.id, review_date="2023-01-01", score=4.5)
|
||||||
|
session.add(performance)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
salary = Salary(
|
||||||
|
employee_id=employee.id,
|
||||||
|
amount=5000.0,
|
||||||
|
effective_from="2023-01-01",
|
||||||
|
effective_to="2024-01-01",
|
||||||
|
)
|
||||||
|
session.add(salary)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
phone1 = Phone(
|
||||||
|
organization_id=organization.id, phone_number="555-1234", phone_type="mobil"
|
||||||
|
)
|
||||||
|
session.add(phone1)
|
||||||
|
phone2 = Phone(
|
||||||
|
organization_id=organization.id, phone_number="555-5678", phone_type="sabit"
|
||||||
|
)
|
||||||
|
session.add(phone2)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
email = Email(process_id=process.id, email_address="codereview@example.com")
|
||||||
|
session.add(email)
|
||||||
|
session.commit()
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
Event.Controller
|
||||||
|
class Person:
|
||||||
|
1. Berkay Karatay
|
||||||
|
2. Melih Asd
|
||||||
|
...
|
||||||
|
|
||||||
|
class User:
|
||||||
|
Berkay User
|
||||||
|
Melih User
|
||||||
|
...
|
||||||
|
|
||||||
|
class Company:
|
||||||
|
Evyos
|
||||||
|
...
|
||||||
|
|
||||||
|
class Departments:
|
||||||
|
General Managment
|
||||||
|
Information Tech. Dep.
|
||||||
|
Sales
|
||||||
|
...
|
||||||
|
|
||||||
|
class Duties:
|
||||||
|
General Manager
|
||||||
|
Backend Developer
|
||||||
|
Area Manager
|
||||||
|
...
|
||||||
|
|
||||||
|
class Occupant:
|
||||||
|
job_resp: Boolean true | false true
|
||||||
|
resp_empp_id Employees[1]
|
||||||
|
Bina Sakini
|
||||||
|
...
|
||||||
|
|
||||||
|
class Employees:
|
||||||
|
1. st - en - Person 1
|
||||||
|
...
|
||||||
|
|
||||||
|
class Events:
|
||||||
|
1. Cari Hesap kontrol
|
||||||
|
2. Cari Hesap Gözlem
|
||||||
|
3. Cari Hesap Oluştur
|
||||||
|
|
||||||
|
Cari Hesap [WAG]
|
||||||
|
Kazan Dairesi İşleri
|
||||||
|
Daire Bilgileri [HAG]
|
||||||
|
Sorumlu Kişiye Mail [WAG]
|
||||||
|
Bina Bilgileri [HAG]
|
||||||
|
|
||||||
|
Wag APi Service Build
|
||||||
|
Hag APi Service Build
|
||||||
|
...
|
||||||
|
|
||||||
|
class BudgetRecords:
|
||||||
|
|
||||||
|
|
||||||
|
CRUD Row(s)
|
||||||
|
CompanyBudgetRecords:
|
||||||
|
/list
|
||||||
|
/create
|
||||||
|
/update
|
||||||
|
/delete
|
||||||
|
/destroy
|
||||||
|
|
||||||
|
CompanyEmployees:
|
||||||
|
1 insan(class Person) + 1 görev(class CompanyDuty)
|
||||||
|
|
||||||
|
CompanyDuty:
|
||||||
|
n(görev) kümesi
|
||||||
|
|
||||||
|
CompanyDepartments:
|
||||||
|
n(duty) kümesi
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
OccupantTypes
|
||||||
|
|
||||||
|
Token (Save AS) => User => Employee => Menu
|
||||||
|
|
||||||
|
+ User ID && User UUID
|
||||||
|
+ People ID && People UUID
|
||||||
|
+ User Info
|
||||||
|
+ Employee ID && Employee UUID
|
||||||
|
+ CompanyId + CompanyUUID
|
||||||
|
+ DutyId + Duty UUID [duty_id]
|
||||||
|
|
||||||
|
+ OccupantTypesId + OccupantTypesUUID + OccupantTypes [String]
|
||||||
|
+ Priority ID, Priority Code [priority_id ,priority_code]
|
||||||
|
|
||||||
|
+ Request [IP + header]
|
||||||
|
+ Reachable Module List[id]
|
||||||
|
+ List of reachable Endpoint Codes [Array] ???
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
class User:
|
||||||
|
email = karatay.berkay@gmail.com
|
||||||
|
via: email | phone | user_tag
|
||||||
|
phone: tanımlı
|
||||||
|
is_occupant True
|
||||||
|
...
|
||||||
|
|
||||||
|
class User:
|
||||||
|
email = karatay.berkay@evyos.com.tr
|
||||||
|
via: email X | phone | user_tag
|
||||||
|
phone: +90 111 11 11
|
||||||
|
is_occupant False
|
||||||
|
...
|
||||||
|
|
||||||
|
class Person:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Person -> User -> Email | Phone
|
||||||
|
|
||||||
|
@gmail
|
||||||
|
@evyos.com.tr
|
||||||
|
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
class Person:
|
||||||
|
1. Berkay Karatay
|
||||||
|
2. Melih Asd
|
||||||
|
3. Osman
|
||||||
|
...
|
||||||
|
|
||||||
|
class User:
|
||||||
|
Berkay User
|
||||||
|
Melih User
|
||||||
|
...
|
||||||
|
|
||||||
|
class Company:
|
||||||
|
Evyos
|
||||||
|
...
|
||||||
|
|
||||||
|
class Departments:
|
||||||
|
General Managment
|
||||||
|
Information Tech. Dep.
|
||||||
|
Sales
|
||||||
|
...
|
||||||
|
|
||||||
|
class Duties:
|
||||||
|
General Manager
|
||||||
|
Backend Developer
|
||||||
|
Area Manager
|
||||||
|
Kazan Manager
|
||||||
|
...
|
||||||
|
|
||||||
|
class Occupant:
|
||||||
|
job_resp: Boolean true | false true
|
||||||
|
resp_empp_id Employees[1]
|
||||||
|
Bina Sakini
|
||||||
|
...
|
||||||
|
|
||||||
|
class Employees:
|
||||||
|
1. st - en - Person 1
|
||||||
|
3. st - en - Person 3
|
||||||
|
...
|
||||||
|
|
||||||
|
class Events2Employees:
|
||||||
|
|
||||||
|
class Events2Occupants:
|
||||||
|
|
||||||
|
class Events:
|
||||||
|
1. Cari Hesap kontrol
|
||||||
|
2. Cari Hesap Gözlem
|
||||||
|
3. Cari Hesap Oluştur
|
||||||
|
|
||||||
|
Cari Hesap [WAG]
|
||||||
|
Kazan Dairesi İşleri
|
||||||
|
Daire Bilgileri [HAG]
|
||||||
|
Sorumlu Kişiye Mail [WAG]
|
||||||
|
Bina Bilgileri [HAG]
|
||||||
|
|
||||||
|
Wag APi Service Build
|
||||||
|
Hag APi Service Build
|
||||||
|
...
|
||||||
|
|
||||||
|
class BudgetRecords:
|
||||||
|
|
||||||
|
|
||||||
|
CRUD Row(s)
|
||||||
|
CompanyBudgetRecords:
|
||||||
|
/list
|
||||||
|
/create
|
||||||
|
/update
|
||||||
|
/delete
|
||||||
|
/destroy
|
||||||
|
|
||||||
|
CompanyEmployees:
|
||||||
|
1 insan(class Person) + 1 görev(class CompanyDuty)
|
||||||
|
|
||||||
|
CompanyDuty:
|
||||||
|
n(görev) kümesi
|
||||||
|
|
||||||
|
CompanyDepartments:
|
||||||
|
n(duty) kümesi
|
||||||
|
|
||||||
|
[Login Action]
|
||||||
|
|
||||||
|
Person -> User
|
||||||
|
Query: Event
|
||||||
|
Company -> Department -> Duty -> Employee -> Person | (n) Occupant -> Person
|
||||||
|
|
||||||
|
|
||||||
|
Company : evyos.com
|
||||||
|
Department : Satış Dep.
|
||||||
|
Duty : Temsilci
|
||||||
|
Employee: Berkay Karatay[Person]
|
||||||
|
(n) Occupant
|
||||||
|
Occupant: Melih[Person]
|
||||||
|
Occupant: Songül[Person]
|
||||||
|
Occupant: Günay[Person]
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
Building.Controller
|
||||||
|
|
||||||
|
class Person:
|
||||||
|
1. Berkay Karatay
|
||||||
|
...
|
||||||
|
|
||||||
|
class User:
|
||||||
|
Berkay User
|
||||||
|
...
|
||||||
|
|
||||||
|
class Build:
|
||||||
|
response_company_id:
|
||||||
|
X resp_employee: (person_id old version)
|
||||||
|
|
||||||
|
class Employee2Parts:
|
||||||
|
|
||||||
|
build_id:
|
||||||
|
part_id:
|
||||||
|
resp_employee: Person + Duty
|
||||||
|
...
|
||||||
|
|
||||||
|
class LivingSpace:
|
||||||
|
|
||||||
|
is_tenant_live:
|
||||||
|
build_parts_id:
|
||||||
|
owner_person_id:
|
||||||
|
life_person_id:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
[Login Action]
|
||||||
|
|
||||||
|
Person -> User
|
||||||
|
|
||||||
|
Build -> Parts -> Employee -> Person
|
||||||
|
|
||||||
|
! Check is_occupant is true or false
|
||||||
|
|
||||||
|
Query: LivingSpace
|
||||||
|
Person -> Occupant -> LivingSpace -> (n)Part -> (n)Build
|
||||||
|
|
||||||
|
Query: Employee2Parts
|
||||||
|
Person -> Employee -> (n)Build [Employee2Parts]
|
||||||
|
|
||||||
|
Occupant & Employee[]
|
||||||
|
|
||||||
|
Occupant: Tenant | Owner n(Record)
|
||||||
|
LivingSpace[Info] && Event[]
|
||||||
|
|
||||||
|
Employee:
|
||||||
|
Build[Info] && Event[]
|
||||||
|
|
||||||
@@ -0,0 +1,408 @@
|
|||||||
|
#### Application Draft ####
|
||||||
|
|
||||||
|
Token (Save AS) => User => Employee => Menu
|
||||||
|
+ User ID
|
||||||
|
+ People ID
|
||||||
|
+ User Info
|
||||||
|
+ Employee ID
|
||||||
|
+ Request [IP + header]
|
||||||
|
+ List of reachable Endpoint Codes [Array]
|
||||||
|
+ CompanyId + CompanyUUID
|
||||||
|
+ DutyId + DutyUUID [duty_id]
|
||||||
|
+ Priority ID, Priority Code [priority_id ,priority_code]
|
||||||
|
|
||||||
|
Company & Customer [Common Attributes]
|
||||||
|
o User
|
||||||
|
o People
|
||||||
|
|
||||||
|
--- Customer [Structure]
|
||||||
|
|
||||||
|
Build +
|
||||||
|
BuildPart +
|
||||||
|
is_rentable = True (Life Space)
|
||||||
|
is_rentable = False (Non-life Space)
|
||||||
|
LivingSpace [Property] + // a human living in BuildPart in a given timeline
|
||||||
|
|
||||||
|
LivingSpace Branches
|
||||||
|
Property[Owner] +
|
||||||
|
Property[Tenant] +
|
||||||
|
|
||||||
|
Financial Assets +
|
||||||
|
|
||||||
|
--- Company [Gives Service]
|
||||||
|
|
||||||
|
Company +
|
||||||
|
Employee +
|
||||||
|
|
||||||
|
Company Responsiablity = Company[Employee] => Group[Customer]
|
||||||
|
|
||||||
|
--- Services [Receives Services]
|
||||||
|
|
||||||
|
+ Property Renovation Dues [Customer Financial Assets ]
|
||||||
|
+ Property Goverment Tax Dues [Customer Financial Assets ]
|
||||||
|
+ Property Building Dues [Customer Financial Assets ]
|
||||||
|
+ Heating Systems [HAG]
|
||||||
|
|
||||||
|
Optional Extra tutu
|
||||||
|
+ Cooling Systems [HAG]
|
||||||
|
+ Landscape Systems [HAG]
|
||||||
|
|
||||||
|
|
||||||
|
User Logins:
|
||||||
|
|
||||||
|
1. Company[Employee]
|
||||||
|
2. Property[Tenant]
|
||||||
|
3. Property[Owner]
|
||||||
|
|
||||||
|
|
||||||
|
- Primary Company Schema -
|
||||||
|
# Primary Company Roles #
|
||||||
|
|
||||||
|
SystemAdmin [Static] [Root Manager] [Application's Primary Management Office Employee]
|
||||||
|
+ Accesses all role and priviliges maintains management
|
||||||
|
Example: Groot => User can manage all access and permissions, access rules can not be manupilated or deleted
|
||||||
|
|
||||||
|
SystemUser [Static] < SystemAdmin
|
||||||
|
+ System storage and services are maintained by this role
|
||||||
|
- Can not reach any personel data in any case
|
||||||
|
|
||||||
|
I. Database [Database Manager]
|
||||||
|
II. Network [Network Manager]
|
||||||
|
III. Application Services [Application Manager]
|
||||||
|
Example: => IT Department of manager [Primary Company]
|
||||||
|
|
||||||
|
[System Admin] => SystemAdmin99 [People]
|
||||||
|
[Database Manager] => SystemUser96 [People]
|
||||||
|
[Network Manager] => SystemUser97 [People]
|
||||||
|
|
||||||
|
[Application Manager] => SystemUser98 [People]
|
||||||
|
for each company:
|
||||||
|
* Creates Company: [Company] = ABC Company
|
||||||
|
* Creates Employee: [Owner] & [SuperUser] = Owner & SuperUser
|
||||||
|
* Assigns Employee to Company: ABC Company Owner & ABC Company SuperUser
|
||||||
|
* Creates People: [People] = Jonathan
|
||||||
|
* Assigns People to Employee: [People] Jonathan -> [Employee] Owner = ABC Company Owner Jonathan
|
||||||
|
// if Owner==None: ilk atanan superuser=Owner
|
||||||
|
[Application Manager] => Company => Employee => People
|
||||||
|
|
||||||
|
|
||||||
|
- API -
|
||||||
|
// APi has primary company in its default settings
|
||||||
|
# Company Employee #
|
||||||
|
|
||||||
|
[Application Manager] Actions
|
||||||
|
|
||||||
|
Employee > Owner > People 1
|
||||||
|
Employee > SuperUser > People 1
|
||||||
|
|
||||||
|
Owner [Static] < [Application Manager] Johantan
|
||||||
|
* Can receive Access Token[Login]
|
||||||
|
* [Application Manager] => with SystemAdmin approval
|
||||||
|
|
||||||
|
- [Data] Can NOT manupilate data 4ex Change company info
|
||||||
|
- [Employee] Can create any role or permissions without any approval in its [Company]
|
||||||
|
|
||||||
|
SuperUser [Static] < [Application Manager] Johantan
|
||||||
|
* Can receive Access Token[Login]
|
||||||
|
* [Application Manager] => SystemAdmin approval
|
||||||
|
|
||||||
|
+ [Employee] Can create any role or permissions without any approval in its [Company]
|
||||||
|
+ [Data] Can manupilate data 4ex Change company info
|
||||||
|
- [Company] Can only receive [Data] to its own company [ReadOnly]
|
||||||
|
- SuperUser -> can grant User SuperUser => SystemAdmin approval
|
||||||
|
|
||||||
|
[SuperUser] => Employee => Rules&Restrictions
|
||||||
|
|
||||||
|
User:
|
||||||
|
[Dynamic] < [Application Manager]
|
||||||
|
// Defined Role 4ex [SuperUser] => access right [Login] = Access Token API connect
|
||||||
|
|
||||||
|
|
||||||
|
Annotations:
|
||||||
|
- When [SuperUser] creates a [Employee] approval=False until [Owner] approval & [Application Manager] sets approval=True
|
||||||
|
- Simult Test Algorith Codelanacak !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
- Crud Collection'da mutlaka expire ile ilgili bi function olacak
|
||||||
|
- filter listlerin active, delete, regular(active==True and delete==False) function ayrı olacak
|
||||||
|
- create action lar BaseModellerin içinde olacak ya da (Optional) create, update rule based Inhert kulllan
|
||||||
|
- Pydanticler model_dump ve excluded_dump olarak inhr.
|
||||||
|
- Responselar herbiri Response status code, message, completed, data şeklinde olacak
|
||||||
|
- Create a initilizer with compose yaml.
|
||||||
|
- Cache ip address to avoid unnecessary request to Api[IP]
|
||||||
|
|
||||||
|
Build -> Data
|
||||||
|
Financial Assets -> Data
|
||||||
|
Personal Info -> People
|
||||||
|
|
||||||
|
|
||||||
|
Company A -> Company B -> Company C
|
||||||
|
Company B -> Company D
|
||||||
|
Company B -> Company E
|
||||||
|
Company B -> Company Z
|
||||||
|
|
||||||
|
score A > B > C
|
||||||
|
evyos A ankara A ayranci C
|
||||||
|
|
||||||
|
Company
|
||||||
|
1.Company A
|
||||||
|
2.Company B
|
||||||
|
3.Company C
|
||||||
|
4.Company D
|
||||||
|
5.Company E
|
||||||
|
6.Company F
|
||||||
|
|
||||||
|
|
||||||
|
Organization Cluster
|
||||||
|
1. Evyos Evyos Organizasyonu 385 0
|
||||||
|
2. Ankara Evyos Organizasyonu 385 1
|
||||||
|
3. Ayrancı Evyos Organizasyonu 385 2
|
||||||
|
4. BEsat Evyos Organizasyonu 385 2
|
||||||
|
5. KEsat Evyos Organizasyonu 385 2
|
||||||
|
6. Keklik Evyos Organizasyonu 385 3
|
||||||
|
7. İlker Evyos Organizasyonu 385 3
|
||||||
|
8. İstanbul Evyos Organizasyonu 385 1
|
||||||
|
9. Kayseri Evyos Organizasyonu 385 2
|
||||||
|
|
||||||
|
|
||||||
|
READ => company_id IN (2, 3, 4, 5, 6, 7)
|
||||||
|
WRITE => company_id IN (2)
|
||||||
|
|
||||||
|
|
||||||
|
READ => build_id IN (22, 333, 4444, 555, 6, 7)
|
||||||
|
WRITE => company_id IN (2)
|
||||||
|
|
||||||
|
Employee
|
||||||
|
id company_id employee
|
||||||
|
1 1 Genel Mudur Company A
|
||||||
|
2 1 Bekçi Company A
|
||||||
|
3 2 Genel Mudur Company B
|
||||||
|
4 2 Bekçi Company B
|
||||||
|
|
||||||
|
|
||||||
|
##### Access to data #####
|
||||||
|
Role based data access->
|
||||||
|
# Information Data Block #
|
||||||
|
|
||||||
|
Building Information Data -> Service Taker
|
||||||
|
Company Information Data -> Service Giver
|
||||||
|
|
||||||
|
# Offical Data Block #
|
||||||
|
|
||||||
|
Building Financial Data -> Service Taker
|
||||||
|
Company Financial Data -> Service Giver
|
||||||
|
|
||||||
|
#### Summary ####
|
||||||
|
Maximum amount of building a employee can be responsiable of? 50
|
||||||
|
|
||||||
|
Alg: Duty(Person) ->
|
||||||
|
Person = User
|
||||||
|
Access Token
|
||||||
|
|
||||||
|
(Service Giver)
|
||||||
|
Company R-> Department R-> Duty R-> Employee R-> Person
|
||||||
|
|
||||||
|
(Service Taker)
|
||||||
|
Company R-> Building R-> Person
|
||||||
|
|
||||||
|
|
||||||
|
Service Giver:
|
||||||
|
Company (related to) Job (related to) Employee (related to) Person
|
||||||
|
This flow indicates a hierarchical relationship where each entity is related to the next.
|
||||||
|
Company: The organization providing the service.
|
||||||
|
Duty: Specific roles or tasks within the company that are related to providing the service.
|
||||||
|
Employee: The individual performing the job-related tasks within the company.
|
||||||
|
Person: The individual as a person, highlighting the human element of the employee.
|
||||||
|
|
||||||
|
Service Taker:
|
||||||
|
Company (related to) Job (related to) Employee (related to) Building
|
||||||
|
This flow indicates a hierarchical relationship where each entity is related to the next, but with a different end point.
|
||||||
|
Company: The organization receiving the service.
|
||||||
|
Duty: Specific roles or tasks within the company that are related to managing or utilizing the service.
|
||||||
|
Employee: The individual performing the job-related tasks within the company.
|
||||||
|
Building: The physical location or facility where the service is utilized or managed.
|
||||||
|
|
||||||
|
duty_id = mapped_column(ForeignKey("duty.id"), nullable=False)
|
||||||
|
owner_id = mapped_column(ForeignKey("company.id"), nullable=False) X
|
||||||
|
member_id = mapped_column(ForeignKey("company.id"), nullable=False)
|
||||||
|
parent_id = mapped_column(ForeignKey("company.id"), nullable=False)
|
||||||
|
relationship_type = mapped_column(String, nullable=False)
|
||||||
|
child_count = mapped_column(Integer)
|
||||||
|
|
||||||
|
X company
|
||||||
|
duty_id ? Evyos GM -< Ankara GM Ayrancı GM
|
||||||
|
select query=
|
||||||
|
|
||||||
|
|
||||||
|
Company Sub
|
||||||
|
#### Filters ####
|
||||||
|
Add extra query to Crud:
|
||||||
|
{
|
||||||
|
"company_id_in": @Redis[Array],
|
||||||
|
"build_id_in": @Redis[Array],
|
||||||
|
"employee_id": @Redis[Array],
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
# Query Pos.
|
||||||
|
|
||||||
|
o What are the employee branch? T
|
||||||
|
- Company filtereleyerek X
|
||||||
|
+ Mongo Db den brach ı cekerek
|
||||||
|
o What are sub companies under certain company_id? X
|
||||||
|
- CompanyRelationship Table like
|
||||||
|
+ Mongo Db den brach ı cekerek
|
||||||
|
|
||||||
|
o Who are my employess [Personel Info]?
|
||||||
|
EmployeeRelationship Table
|
||||||
|
Department -> Duty -> Employee
|
||||||
|
|
||||||
|
o What buildings are in my responsibilty?
|
||||||
|
BuildingRelationship Table
|
||||||
|
|
||||||
|
o What are certain debts of Build Parts?
|
||||||
|
CompanyRelationship Table ilke
|
||||||
|
|
||||||
|
o Iban and financial informations of Buildings?
|
||||||
|
AccountingRelationship Table ilke
|
||||||
|
|
||||||
|
o Salaries of a group of Employees?
|
||||||
|
X
|
||||||
|
|
||||||
|
o Duty information of a group of Employees?
|
||||||
|
X
|
||||||
|
|
||||||
|
o List Decision Book Items of a build part?
|
||||||
|
Build R-> Decision Book
|
||||||
|
Responsiable of related Building
|
||||||
|
Employee Query if Build view yetkisi varsa -> Decision Book
|
||||||
|
|
||||||
|
o Living Space info of a certian person?
|
||||||
|
Responsiable of related Building
|
||||||
|
Living Space -> Person Detail Infop
|
||||||
|
|
||||||
|
o Which build parts I am responsiable of?
|
||||||
|
Person -> Build Parts
|
||||||
|
Query employee -> Building
|
||||||
|
|
||||||
|
o Address of a person?
|
||||||
|
Query employee -> Building
|
||||||
|
|
||||||
|
o Email, phone personal info of a employee?
|
||||||
|
Brach Company
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
User[Person] -> Employee Salaries Table data
|
||||||
|
User Company[Employee]
|
||||||
|
|
||||||
|
|
||||||
|
[Table]Company2BuildingRelationship
|
||||||
|
company_id build_id responsiable
|
||||||
|
1 3 True
|
||||||
|
2 3 False
|
||||||
|
|
||||||
|
Company2BuildingRelationship: Are these users of this company are responsiable from this building.
|
||||||
|
|
||||||
|
|
||||||
|
[Table]Company2EmployeeRelationship:
|
||||||
|
company_id employee_id
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
|
||||||
|
[Table]Company2CompanyRelationship:
|
||||||
|
1EVYOS 2Ankara 3Besat 4Ayrancı 5Dikmen 6Çayyolu 7Beysukent 8OsmanMah 9NecatiMah
|
||||||
|
2Ankara -> 3Besat 4Ayrancı 5Dikmen 6Çayyolu 7Beysukent -> 8OsmanMah 9NecatiMah
|
||||||
|
|
||||||
|
|
||||||
|
Top Hiercacy:
|
||||||
|
|
||||||
|
ADD field:
|
||||||
|
top_hiercacy_companies: id: 1, uuid: 1a1a51bd-67f5-4f85-bd7c-1edb6afdaa7e Evyos
|
||||||
|
|
||||||
|
Ask for branch ???
|
||||||
|
Update a branch ???
|
||||||
|
Delete a branch ???
|
||||||
|
Carry branch ???
|
||||||
|
Get "18aa001a-6878-4d39-bc21-0e63ba33beff" -> carry to "1a1a51bd-67f5-4f85-bd7c-1edb6afdaa7e"
|
||||||
|
DELETE -> INSERT
|
||||||
|
Go to mongo collection of top_hiercacy_company
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
[Table]Company2CompanyRelationship: ??? Branch
|
||||||
|
owner_company_id member_company_id
|
||||||
|
1 2
|
||||||
|
2 3
|
||||||
|
3 4
|
||||||
|
1 5
|
||||||
|
1 6
|
||||||
|
|
||||||
|
class CompanyRelationship(CrudCollection):
|
||||||
|
"""
|
||||||
|
CompanyRelationship class based on declarative_base and CrudCollection via session
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = "company_relationship"
|
||||||
|
__exclude__fields__ = []
|
||||||
|
|
||||||
|
duty_id = mapped_column(ForeignKey("duty.id"), nullable=False)
|
||||||
|
owner_id = mapped_column(ForeignKey("company.id"), nullable=False)
|
||||||
|
member_id = mapped_column(ForeignKey("company.id"), nullable=False)
|
||||||
|
parent_id = mapped_column(ForeignKey("company.id"), nullable=False)
|
||||||
|
child_count = mapped_column(Integer)
|
||||||
|
json_text = mapped_column(String)
|
||||||
|
|
||||||
|
relationship_type = mapped_column(String, nullable=False)
|
||||||
|
|
||||||
|
Mehmet Karatay > Javascript
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
EmployeeRelationship Table
|
||||||
|
|
||||||
|
|
||||||
|
X and Y Employee
|
||||||
|
Employee ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Relationship
|
||||||
|
|
||||||
|
# Bindings of Queries #
|
||||||
|
Buildings [Decision Books, Project Books] 2 Resp.
|
||||||
|
Companies [Duty, Departments] 2 Resp.
|
||||||
|
Employees [Salaries, People] 2 Resp.
|
||||||
|
Accounts [Iban, Debits] 2 Resp.
|
||||||
|
People [LivingSpace, Users, Addresses] 2 Resp.
|
||||||
|
|
||||||
|
Role = Company + Job
|
||||||
|
Employee = Role + People
|
||||||
|
Employee R-> Employee
|
||||||
|
Employee R-> AccessRule ???
|
||||||
|
|
||||||
|
# Bindings of Actions #
|
||||||
|
|
||||||
|
INSERT -> Res? X
|
||||||
|
UPDATE -> Res? X
|
||||||
|
SELECT -> Res? |
|
||||||
|
DELETE -> Res?
|
||||||
|
ACTIVATE -> Res?
|
||||||
|
DESTROY -> Res?
|
||||||
|
|
||||||
|
|
||||||
|
id employee_id restrict_id by_who
|
||||||
|
1 2 3 2
|
||||||
|
2 2 4 2
|
||||||
|
3 2 5 2
|
||||||
|
1 -7 Genel Mudur
|
||||||
|
|
||||||
|
|
||||||
|
Permissions
|
||||||
|
|
||||||
|
A | 1 SuperUser
|
||||||
|
B | 2 Sub SuperUser
|
||||||
|
C | 3 Sub Sub SuperUser
|
||||||
|
|
||||||
|
|
||||||
|
A1 -> B2 -> C3
|
||||||
|
Many to Many
|
||||||
|
1 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
|
||||||
|
Employees[TOKEN]
|
||||||
|
User -> Person -> Employees -> Duty -> Department -> Company
|
||||||
|
Duty -> Occupant -> Department -> Company
|
||||||
|
|
||||||
|
Occupant[TOKEN]
|
||||||
|
User -> People -> LivingSpace -> Building(n) -> BuildPart(n) -> Company
|
||||||
|
|
||||||
|
User
|
||||||
|
?Occupant @User mail = personal mail google.com.tr OR personal domains included
|
||||||
|
?Employee @User mail = evyos.com.tr OR company domains included
|
||||||
|
|
||||||
|
Evyos Free id1 + Evyos [] id2 + Evyos [] id3
|
||||||
|
0TL + 100TL + 1000TL
|
||||||
|
|
||||||
|
Mail Service +
|
||||||
|
|
||||||
|
Occupant Types:
|
||||||
|
Bina Yönetici : 1 tip kullanıcı
|
||||||
|
Daire Sakini : 2 tip kullanıcı
|
||||||
|
|
||||||
|
Daire Sahibi : 3 tip kullanıcı
|
||||||
|
Bina Görevlisi : 4 tip kullanıcı
|
||||||
|
Bina Denetcisi : 5 tip kullanıcı
|
||||||
|
Bina Muhasebecisi : 6 tip kullanıcı
|
||||||
|
Bina Teknisyeni : 7 tip kullanıcı
|
||||||
|
Bina Güvenlik Görevlisi : 8 tip kullanıcı
|
||||||
|
Bina Temizlik Görevlisi : 9 tip kullanıcı
|
||||||
|
Bina Bahçıvanı : 10 tip kullanıcı
|
||||||
|
|
||||||
|
Plan:
|
||||||
|
evyos_free 1
|
||||||
|
evyos_basic 2
|
||||||
|
evyos_premium 3
|
||||||
|
evyos_enterprise 4
|
||||||
|
|
||||||
|
Service:
|
||||||
|
occupant_id: 1,
|
||||||
|
plan: 1,
|
||||||
|
|
||||||
|
|
||||||
|
event_id: 1,
|
||||||
|
service_id: 1,
|
||||||
|
|
||||||
|
Company Occupant
|
||||||
|
|
||||||
|
User -> Person
|
||||||
|
|
||||||
|
o Employee -> Duty -> Department -> Company -> Building -> Person ->
|
||||||
|
o Building -> Decision Book -> Person ->
|
||||||
|
|
||||||
|
CompanyPerson R-> User
|
||||||
|
CustomerPerson R-> User
|
||||||
|
|
||||||
|
class Person:
|
||||||
|
|
||||||
|
+ is_employee_related True Company User
|
||||||
|
+ is_living_space_related True LivingSpace User
|
||||||
|
|
||||||
|
is_employee_related:
|
||||||
|
Cahce company details
|
||||||
|
Cahce Menu Reach points
|
||||||
|
Cahce Employee Endpoint Access Rules
|
||||||
|
Cahce Responsiable Buildings and connect to WAG Services
|
||||||
|
|
||||||
|
is_living_space_related:
|
||||||
|
Cahce BuildPart Details and connect to HAG Services
|
||||||
|
No need to cache any company details
|
||||||
|
|
||||||
|
building_decision_book_responsaible:
|
||||||
|
Manager:
|
||||||
|
Supervisor:
|
||||||
|
|
||||||
|
|
||||||
|
##### Step by step Test Guide #####
|
||||||
|
----- INIT -----
|
||||||
|
1. department_name: Manager
|
||||||
|
2. department_name: IT Department
|
||||||
|
|
||||||
|
Duty
|
||||||
|
Company[Managment] (GROOT)
|
||||||
|
|
||||||
|
department_name: Manager 1
|
||||||
|
duty_name: General Manager User(1)
|
||||||
|
|
||||||
|
department_name: IT Department 2
|
||||||
|
|
||||||
|
duty_name: Application Manager User(2) + Login
|
||||||
|
duty_name: Database Manager
|
||||||
|
duty_name: Network Manager
|
||||||
|
|
||||||
|
Rule: 78 can create company / employee / duty / department / person
|
||||||
|
duty_name: Super User User(3) + Login
|
||||||
|
|
||||||
|
----- INIT -----
|
||||||
|
|
||||||
|
----- API -----
|
||||||
|
|
||||||
|
When User(2) creates any row in database it must be confirmed by User(3)[Notification]
|
||||||
|
User(2) => Login and confirm below...
|
||||||
|
User(3) => Login and create below...
|
||||||
|
|
||||||
|
### Company ###
|
||||||
|
|
||||||
|
[GROOT]
|
||||||
|
|
||||||
|
Person X 5
|
||||||
|
Email X 5
|
||||||
|
Phone X 5
|
||||||
|
User X 3
|
||||||
|
|
||||||
|
Sub Company X 5 [GROOT] && GROOT connect => Sub Company X 5
|
||||||
|
Sub Sub Company X 5 [Sub Company] && Each Sub Company connect => Sub SUb Company X 2
|
||||||
|
|
||||||
|
Sub Company 2 X 5 = 10 User
|
||||||
|
Sub Sub Company 2 x 25 = 50 User
|
||||||
|
60 User
|
||||||
|
|
||||||
|
10
|
||||||
|
Person X 2
|
||||||
|
Email X 2
|
||||||
|
Phone X 2
|
||||||
|
User X 2
|
||||||
|
|
||||||
|
1. department_name: Manager
|
||||||
|
1. duty_name: General Manager
|
||||||
|
1. employee_name: 1
|
||||||
|
|
||||||
|
2. department_name: IT Department
|
||||||
|
2. duty_name: Super User
|
||||||
|
2. employee_name: 1
|
||||||
|
|
||||||
|
### Company ###
|
||||||
|
|
||||||
|
### Build ###
|
||||||
|
|
||||||
|
### Build ###
|
||||||
|
|
||||||
|
### Book ###
|
||||||
|
|
||||||
|
### Book ###
|
||||||
|
|
||||||
|
### Account ###
|
||||||
|
|
||||||
|
### Account ###
|
||||||
|
|
||||||
|
----- API -----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class User(Person):
|
||||||
|
...
|
||||||
|
|
||||||
|
class Company:
|
||||||
|
...
|
||||||
|
|
||||||
|
class LivingSpaces:
|
||||||
|
|
||||||
|
tenant_person: True
|
||||||
|
owner_person: True
|
||||||
|
...
|
||||||
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
Company
|
||||||
|
o1 Evyos LTD - System
|
||||||
|
|
||||||
|
2 Evyos Istanbul BD
|
||||||
|
3 Evyos Ankara BD
|
||||||
|
Evyos Izmir BD
|
||||||
|
|
||||||
|
o Evyos Ankara BD
|
||||||
|
|
||||||
|
Çankaya YS
|
||||||
|
YeniMahalle YS
|
||||||
|
Sincan YS
|
||||||
|
|
||||||
|
o Evyos Istanbul BD
|
||||||
|
|
||||||
|
Bakırköy YS
|
||||||
|
Kadıköy YS
|
||||||
|
Pendik YS
|
||||||
|
|
||||||
|
o Evyos Izmir BD
|
||||||
|
|
||||||
|
Karşıyaka YS
|
||||||
|
|
||||||
|
duty_id
|
||||||
|
1 GM Evyos
|
||||||
|
2 GM Evyos Ankara BD
|
||||||
|
|
||||||
|
RelationshipDutyCompany
|
||||||
|
|
||||||
|
Berkay duty_id SU = id = 5 -> [TOKEN] -< Company_id = 1 Evyos LTD
|
||||||
|
Koray duty_id SU = id = 7 -> [TOKEN] -< Company_id = 3 Evyos Ankara BD
|
||||||
|
|
||||||
|
owner_id member_id parent_id active type duties_id Auto
|
||||||
|
1 2 1 False Organization 2 @/create
|
||||||
|
1 3 1 False Organization 2 @/create
|
||||||
|
1 4 1 False Organization 2 @/create
|
||||||
|
|
||||||
|
1 5 3 False Organization 5
|
||||||
|
1 6 3 False Organization 5
|
||||||
|
1 7 3 False Organization 5
|
||||||
|
|
||||||
|
1 8 2 False Organization
|
||||||
|
1 9 2 False Organization
|
||||||
|
1 10 2 False Organization
|
||||||
|
1 88 3 False Commercial
|
||||||
|
|
||||||
|
1 11 4 False Organization
|
||||||
|
|
||||||
|
3 5 3 False Organization 3
|
||||||
|
3 88 3 False Commercial 3
|
||||||
|
3 6 3 False Organization 3
|
||||||
|
3 7 3 False Organization 3
|
||||||
|
|
||||||
|
|
||||||
|
Evyos LTD SuperUser (company_id=1)
|
||||||
|
Login...
|
||||||
|
|
||||||
|
2Evyos Istanbul BD Evyos LTD SuperUser + 1
|
||||||
|
3Evyos Ankara BD Evyos LTD SuperUser + 1
|
||||||
|
4Evyos Izmir BD Evyos LTD SuperUser + 1
|
||||||
|
5VevYos Trabzon
|
||||||
|
|
||||||
|
1 Evyos LTD Evyos Verimlilik Sistemleri Evyos LTD SuperUser + 1
|
||||||
|
|
||||||
|
|
||||||
|
2Evyos Istanbul BD Istanbul SuperUser Evyos LTD SuperUser + 1
|
||||||
|
3Evyos Ankara BD Ankara SuperUser Evyos LTD SuperUser + 1
|
||||||
|
4Evyos Izmir BD Izmır SuperUser Evyos LTD SuperUser + 1
|
||||||
|
|
||||||
|
5VevYos Trabzon
|
||||||
|
|
||||||
|
|
||||||
|
CREATE => 1-> company_id:[2,3,4]
|
||||||
|
VIEW => 1 company_id:[2,3,4,5,6,7...11]
|
||||||
|
{
|
||||||
|
"company_id":
|
||||||
|
}
|
||||||
|
5Çankaya YS Çankaya YS Evyos Ankara BD SuperUser +
|
||||||
|
6YeniMahalle YS YeniMahalle YS Evyos Ankara BD SuperUser +
|
||||||
|
7Sincan YS Sincan YS Evyos Ankara BD SuperUser +
|
||||||
|
|
||||||
|
8Bakırköy YS Bakırköy YS
|
||||||
|
9Kadıköy YS Kadıköy YS
|
||||||
|
10Pendik YS Pendik YS
|
||||||
|
|
||||||
|
11Karşıyaka YS Karşıyaka YS
|
||||||
|
|
||||||
|
|
||||||
|
select * from build a
|
||||||
|
inner join buid_re b on a.=b.id
|
||||||
|
where (id = 5)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
+ Application Defaults
|
||||||
|
o Duty form .init
|
||||||
|
o Department form .init
|
||||||
|
o RelationshipDutyCompany -> Evyos Ltd -> 78 Super User .init
|
||||||
|
O Evyos için duty = bulk duty on every company creation -> 78 Super User can access his companies bulk duties
|
||||||
|
|
||||||
|
relationship = company_id filter -> Action filter(company_id) relationship_type = Organization
|
||||||
|
relationship = company_id filter -> Action filter(company_id) relationship_type = Commercial
|
||||||
|
|
||||||
|
For every company creation, the following action: Only Create [Organization]
|
||||||
|
- Create a (Department) Execution Office & Create a (Duty) General Manager
|
||||||
|
- Create a (Department) IT Department & Create a (Duty) Super User & Create a Bulk Duty for Super User
|
||||||
|
|
||||||
|
EndpointRestrictions:
|
||||||
|
Duty: R-> Endpoint: /company/create" name: "Create Company" code: "AR001" method: "POST"
|
||||||
|
|
||||||
|
Abstract Class:
|
||||||
|
o Get class to inherit from it and check which fields are available for each duty given in table
|
||||||
|
o Explain the fields ,their usage, and examples
|
||||||
|
- PATCH /company/create with [TOKEN] -> BaseModel for this duty and ApiEnumDropdowns [RESPONSE]
|
||||||
|
- PATCH /company/update with [TOKEN] -> BaseModel for this duty and ApiEnumDropdowns [RESPONSE]
|
||||||
|
|
||||||
|
Re arrange TOKEN
|
||||||
|
Token (Save AS) => User => Employee => Menu
|
||||||
|
+ User ID
|
||||||
|
+ People ID
|
||||||
|
+ User Info
|
||||||
|
+ Employee ID
|
||||||
|
+ Request [IP + header]
|
||||||
|
+ List of reachable Endpoint Codes [Array]
|
||||||
|
+ CompanyId + CompanyUUID
|
||||||
|
+ DutyId + DutyUUID [duty_id]
|
||||||
|
+ Priority ID, Priority Code [priority_id ,priority_code]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Event:
|
||||||
|
mail_gönderme: 1
|
||||||
|
mail_alma: 2
|
||||||
|
mail_analiz: 3
|
||||||
|
xl_import_export: 4
|
||||||
|
xl_takibi: 5
|
||||||
|
|
||||||
|
|
||||||
|
OccType:
|
||||||
|
Daire Sakini 1,
|
||||||
|
|
||||||
|
EmpType:
|
||||||
|
Muhasebeci 1,
|
||||||
|
|
||||||
|
|
||||||
|
Plan:
|
||||||
|
evyos_free 1,
|
||||||
|
evyos_basic 2,
|
||||||
|
evyos_premium 3,
|
||||||
|
evyos_enterprise 4
|
||||||
|
|
||||||
|
|
||||||
|
ApplicationServices:
|
||||||
|
id: 1
|
||||||
|
occupant_id: 1,
|
||||||
|
plan: 1,
|
||||||
|
|
||||||
|
id: 2
|
||||||
|
occupant_id: 1,
|
||||||
|
plan: 2,
|
||||||
|
|
||||||
|
id: 3
|
||||||
|
occupant_id: 1,
|
||||||
|
plan: 3,
|
||||||
|
|
||||||
|
|
||||||
|
Events2Services:
|
||||||
|
event_id: 1,
|
||||||
|
service_id: 1,
|
||||||
|
|
||||||
|
event_id: 1,
|
||||||
|
service_id: 2,
|
||||||
|
event_id: 2,
|
||||||
|
service_id: 2,
|
||||||
|
|
||||||
|
event_id: 1,
|
||||||
|
service_id: 3,
|
||||||
|
event_id: 2,
|
||||||
|
service_id: 3,
|
||||||
|
event_id: 3,
|
||||||
|
service_id: 3,
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
- Do the endpoints -
|
||||||
|
|
||||||
|
RelationshipDutyCompany org*perm
|
||||||
|
|
||||||
|
Select -> Inner Join with duty_id
|
||||||
|
Create -> Redis cache pre-determined value = company_id
|
||||||
|
Update -> Redis cache pre-determined with duty_id
|
||||||
|
|
||||||
|
|
||||||
|
Select -> Inner Join with duty_id
|
||||||
|
Create -> Redis cache pre-determined value = company_id
|
||||||
|
Update -> Redis cache pre-determined with duty_id
|
||||||
|
|
||||||
|
Redis Cache material
|
||||||
|
- duty_id
|
||||||
|
- duty_uu_id
|
||||||
|
- duty_code: 96
|
||||||
|
|
||||||
|
- company_id
|
||||||
|
- company_uu_id
|
||||||
|
|
||||||
|
- uu_id
|
||||||
|
- get_available_patch_methods(['confirm', 'delete', 'active'])
|
||||||
|
|
||||||
|
|
||||||
|
Endpoint Acccess List
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
list endpoint + confirm-delete-active
|
||||||
|
{
|
||||||
|
confirm True, delete=True, active=True,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
POST
|
||||||
|
update endpoint +
|
||||||
|
create endpoint +
|
||||||
|
|
||||||
|
PATCH endpoint && update endpoint +
|
||||||
|
duty_code ??? if 96 =>
|
||||||
|
{
|
||||||
|
"patch_type": [
|
||||||
|
"confirm", Application Manager [OK] : Restrict
|
||||||
|
"delete", SuperUser
|
||||||
|
"active", SuperUser
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Notlar
|
||||||
|
|
||||||
|
ApiEnum Dropdown her seferinde load üretiyor onun yerine obje attribute olarak ekle
|
||||||
|
__enums__ = {
|
||||||
|
"abc": [],
|
||||||
|
"abcd": []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
|
||||||
|
Department:
|
||||||
|
Bağımsız bir işi yapan kadrolar tümüne
|
||||||
|
|
||||||
|
Staff:
|
||||||
|
Duty yapacak kadro
|
||||||
|
|
||||||
|
Employee:
|
||||||
|
Staffdaki çalışanlar
|
||||||
|
|
||||||
|
İnsan Kaynakları
|
||||||
|
Department
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleSection:
|
||||||
|
module_section = ["Department", "OccupantTypes"]
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
Module -> Service -> Event -> 500MB default 0.00TL core, def
|
||||||
|
Module -> Service -> Event -> 1GB price 10.00TL add-on
|
||||||
|
Module -> Service -> Event -> 2GB price 20.00TL add-on
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
İç Hizmetler Müdürlüğü
|
||||||
|
|
||||||
|
|
||||||
|
Module: Satış Departmanı Modülü Base 0.00TL
|
||||||
|
Cari Servisi (Service)
|
||||||
|
+ Cari Hesap Okuma Event 0.00TL
|
||||||
|
+ Cari Hesap Uyarma Event 0.00TL
|
||||||
|
+ Cari Hesap Analiz Event 0.00TL
|
||||||
|
Toplam: 0.00TL
|
||||||
|
|
||||||
|
Module: Satış Departmanı Modülü Permium 30 TL
|
||||||
|
Cari Servisi Premium (Service)
|
||||||
|
+ Cari Hesap Okuma Event 0.00TL
|
||||||
|
+ Cari Hesap Uyarma Event 0.00TL
|
||||||
|
+ Cari Hesap Analiz Event 0.00TL
|
||||||
|
+ Cari Hesap Mail Event 10.00TL
|
||||||
|
+ Cari Hesap SMS Event 20.00TL
|
||||||
|
Toplam: 30.00TL
|
||||||
|
|
||||||
|
|
||||||
|
Dış Hiztmetler Müdürlüğü
|
||||||
|
|
||||||
|
Module (Department) | Service | -> (n) Duty -> Staff -> Employee -> Event
|
||||||
|
Module (OccupantTypes) | Service | -> -> (n) Duty -> Staff -> Employee -> LivingSpace -> Event
|
||||||
|
|
||||||
|
Service:
|
||||||
|
OccupantType + Module
|
||||||
|
|
||||||
|
OccupantType -> User -> People
|
||||||
|
|
||||||
|
Event -> Service
|
||||||
|
|
||||||
|
Department -> (n) Module -> Duty -> Staff -> Employee
|
||||||
|
|
||||||
|
Mali İşler -> A Muhasabe B Finans ->
|
||||||
|
|
||||||
|
user -> people.id + occupant_type.id -> BuildLivingSpace -> Module -> Modules2Occupant -> Event
|
||||||
|
user -> employee.id -> Duty -> Staff -> Employee -> Event -> Module -> Modules2Employee -> Event
|
||||||
|
|
||||||
|
Employee
|
||||||
|
X Occupant
|
||||||
|
|
||||||
|
User:
|
||||||
|
1. Employee
|
||||||
|
employee.id () => Module
|
||||||
|
|
||||||
|
2. (n) Occupant Types
|
||||||
|
|
||||||
|
-> Daire Sakini () => Module
|
||||||
|
-> Daire Sahibi people.id () => Module
|
||||||
|
|
||||||
|
-> Staff () people.id X buildmanagment_staff.id => Module
|
||||||
|
|
||||||
|
Duty : Employee
|
||||||
|
User ->
|
||||||
|
|
||||||
|
is_occupant: False
|
||||||
|
Employee
|
||||||
|
Staff
|
||||||
|
|
||||||
|
is_occupant: True
|
||||||
|
LivingSpace
|
||||||
|
Occupant_Type
|
||||||
|
|
||||||
|
class LivingSpace:
|
||||||
|
People people.id false
|
||||||
|
BuildPart build.id
|
||||||
|
Occupant_type Daire Sakini
|
||||||
|
start_date =
|
||||||
|
stop_date =
|
||||||
|
agremeent_no =
|
||||||
|
|
||||||
|
|
||||||
|
LivingSpace:
|
||||||
|
Occupant occupant.id
|
||||||
|
LivingSpaceType living_space_type
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
|
||||||
|
postgres EndpointRestriction(CrudCollection):
|
||||||
|
"""
|
||||||
|
Initiliaze Endpoint Restriction on default
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = "endpoint_restriction"
|
||||||
|
__exclude__fields__ = []
|
||||||
|
|
||||||
|
endpoint_name = mapped_column(String, server_default="")
|
||||||
|
endpoint_method = mapped_column(String, server_default="")
|
||||||
|
endpoint_desc = mapped_column(String, server_default="")
|
||||||
|
endpoint_code = mapped_column(String, server_default="", unique=True)
|
||||||
|
endpoint_priority = mapped_column(SmallInteger, server_default="0")
|
||||||
|
|
||||||
|
|
||||||
|
postgres Priority(CrudCollection):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Initiliaze at api roles on default
|
||||||
|
4ex.
|
||||||
|
{
|
||||||
|
"0": "User",
|
||||||
|
"4": "Owner",
|
||||||
|
"8": "Tenant",
|
||||||
|
"12": "Freelancer",
|
||||||
|
"16": "Tech",
|
||||||
|
"78": "Super User",
|
||||||
|
"96": "Database Manager",
|
||||||
|
"97": "Network Manager",
|
||||||
|
"98": "Application Manager",
|
||||||
|
"99": "System Admin",
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = "priority"
|
||||||
|
__exclude__fields__ = []
|
||||||
|
|
||||||
|
priority_code = mapped_column(SmallInteger, server_default="0")
|
||||||
|
priority_desc = mapped_column(String, server_default="")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
postgres User(CrudCollection):
|
||||||
|
"""
|
||||||
|
Application User frame to connect to api with assigned token based HTTP connection
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = "user"
|
||||||
|
__exclude__fields__ = [
|
||||||
|
"hash_password",
|
||||||
|
"password_token",
|
||||||
|
"expiry_begins"
|
||||||
|
]
|
||||||
|
|
||||||
|
user_tag = mapped_column(String(64), server_default="", comment="User Tag")
|
||||||
|
|
||||||
|
email = mapped_column(String(128), server_default="")
|
||||||
|
phone_number = mapped_column(String, server_default="")
|
||||||
|
avatar = mapped_column(String, server_default="")
|
||||||
|
|
||||||
|
hash_password = mapped_column(String(256), server_default="")
|
||||||
|
password_token = mapped_column(String(256), server_default="")
|
||||||
|
remember_me = mapped_column(Boolean, server_default="0")
|
||||||
|
|
||||||
|
expires_day = mapped_column(Integer, server_default=env.PASSWORD_EXPIRE_DAY, comment="Password Expires in Days") // Password must be changed by user in [expires_day] days
|
||||||
|
expiry_begins = mapped_column(TIMESTAMP, server_default=func.now())
|
||||||
|
|
||||||
|
priority_id = mapped_column(ForeignKey("priority.id"), nullable=False)
|
||||||
|
person_id = mapped_column(ForeignKey("people.id"), nullable=False)
|
||||||
|
|
||||||
|
priority: Mapped["Priority"] = relationship("Priority", back_populates="user", foreign_keys=[priority_id])
|
||||||
|
|
||||||
|
@property def expiry_ends():
|
||||||
|
return expiry_begins + expires_day
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_super_user():
|
||||||
|
return bool(self.priority.priority_code == 78)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_user():
|
||||||
|
return bool(self.priority.priority_code == 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
postgres Person(CrudCollection):
|
||||||
|
"""
|
||||||
|
People that are related to users in application
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = "person"
|
||||||
|
__exclude__fields__ = []
|
||||||
|
|
||||||
|
firstname = mapped_column(String(24), nullable=False, comment="First Name")
|
||||||
|
surname = mapped_column(String(24), nullable=False, comment="Surname")
|
||||||
|
middle_name = mapped_column(String(16), server_default="")
|
||||||
|
sex_code = mapped_column(String(1), nullable=False, comment="Sex Code")
|
||||||
|
person_ref = Mapped[str] = mapped_column(String(24), server_default="")
|
||||||
|
person_tag = mapped_column(String(64), server_default="")
|
||||||
|
|
||||||
|
// ENCRYPT DATA
|
||||||
|
father_name = mapped_column(String(24), server_default="")
|
||||||
|
mother_name = mapped_column(String(24), server_default="")
|
||||||
|
country_code = mapped_column(String(4), server_default="TR")
|
||||||
|
national_identity_id = mapped_column(String(48), server_default="")
|
||||||
|
birth_place = mapped_column(String(24), server_default="")
|
||||||
|
birth_date = mapped_column(TIMESTAMP, server_default="1900-01-01")
|
||||||
|
tax_no = mapped_column(String(48), server_default="")
|
||||||
|
// ENCRYPT DATA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Company(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__ = "company"
|
||||||
|
__exclude__fields__ = ["is_blacklist", "is_commercial"]
|
||||||
|
|
||||||
|
formal_name = mapped_column(String(64), nullable=False, comment="Formal Name")
|
||||||
|
company_type = mapped_column(String(1), nullable=False, comment="Company Type")
|
||||||
|
commercial_type = mapped_column(
|
||||||
|
String(5), nullable=False, comment="Commercial Type"
|
||||||
|
)
|
||||||
|
tax_no = mapped_column(
|
||||||
|
String(48), index=True, unique=True, nullable=False, comment="Tax No"
|
||||||
|
)
|
||||||
|
|
||||||
|
public_name = mapped_column(String(64))
|
||||||
|
nick_name = mapped_column(String(64))
|
||||||
|
default_lang_type = mapped_column(String(5), server_default="TR")
|
||||||
|
default_money_type = mapped_column(String(5), server_default="TL")
|
||||||
|
is_commercial = mapped_column(Boolean, server_default="False")
|
||||||
|
is_blacklist = mapped_column(Boolean, server_default="False")
|
||||||
|
|
||||||
|
official_address_id = mapped_column(ForeignKey("address.id"))
|
||||||
|
parent_id = mapped_column(ForeignKey("company.id"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Rule of Mongo Collection Creation #
|
||||||
|
|
||||||
|
// To avoid data load for no-sql storage all collection must be created in a pattern of
|
||||||
|
// mongo_collection_name = str(Company.uu_id()) + str(storage_reasoning) 4ex. : mongo_collection_name = str(Company.uu_id()) + str('UserPasswordHistory')
|
||||||
|
// MongoCollectionBase = str(Company.uu_id())
|
||||||
|
|
||||||
|
[Company][info] -> [Company][info] -> [Company][info] -> [Company][info]
|
||||||
|
|
||||||
|
Mongo MongoCollectionBase + Access:
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mongo MongoCollectionBase + Domain:
|
||||||
|
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"domain_tag": {
|
||||||
|
...
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
!! ADD domain_tag for user to name this domain -> so user can use domain with device that is saved
|
||||||
|
|
||||||
|
|
||||||
|
Mongo MongoCollectionBase + PasswordHistory:
|
||||||
|
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"password_history":
|
||||||
|
[
|
||||||
|
...{
|
||||||
|
"password_hashed": "", // String
|
||||||
|
"tmstp": "" // TMSTP,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"access_history_detail": device_single_history
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mongo MongoCollectionBase + AccessHistory:
|
||||||
|
// Last 60 History of a user login to application
|
||||||
|
// ! add function retrieve_last()
|
||||||
|
{
|
||||||
|
"access_history":
|
||||||
|
[
|
||||||
|
...{
|
||||||
|
"platform": "", // String
|
||||||
|
"agent": "", // String
|
||||||
|
"last_seen": "", // TMSTP
|
||||||
|
"remote_addr": "", // String
|
||||||
|
"geo_location": "", // String
|
||||||
|
"detail": {} // From ip retrieve api data
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/event/create
|
||||||
|
/authentication/select
|
||||||
|
/authentication/valid
|
||||||
|
/Duty/list
|
||||||
|
/Duty/create
|
||||||
|
/Duty/update/{company_uu_id}
|
||||||
|
/Duty/patch/{company_uu_id}
|
||||||
|
/duties/list
|
||||||
|
/duties/create
|
||||||
|
/People/list/
|
||||||
|
/People/create
|
||||||
|
/People/update/{user_uu_id}
|
||||||
|
/People/patch/{user_uu_id}
|
||||||
|
/event/list
|
||||||
|
/event/register/employee
|
||||||
|
/event/register/occupant
|
||||||
|
/User/list
|
||||||
|
/User/create
|
||||||
|
/User/update/{user_uu_id}
|
||||||
|
/User/patch/{user_uu_id}
|
||||||
|
/Company/list
|
||||||
|
/Company/create
|
||||||
|
/Company/update/{company_uu_id}
|
||||||
|
/Company/patch/{company_uu_id}
|
||||||
|
/Department/list
|
||||||
|
/Department/create
|
||||||
|
/Department/update/{company_uu_id}
|
||||||
|
/Department/patch/{company_uu_id}
|
||||||
|
/building/build/list
|
||||||
|
/building/build/create
|
||||||
|
/building/build/update/{build_uu_id}
|
||||||
|
/building/build/patch/{build_uu_id}
|
||||||
|
/Building/Parts/list
|
||||||
|
/Building/Parts/create
|
||||||
|
/Building/Parts/update/{build_uu_id}
|
||||||
|
/Building/Parts/patch/{build_uu_id}
|
||||||
|
/Building/Sites/patch/{build_uu_id}
|
||||||
|
/Building/Area/patch/{build_uu_id}
|
||||||
|
/Building/LivingSpace/list
|
||||||
|
/Building/LivingSpace/create
|
||||||
|
/Building/LivingSpace/update/{build_uu_id}
|
||||||
|
/Building/LivingSpace/patch/{build_uu_id}
|
||||||
|
/Build/DecisionBook/list
|
||||||
|
/Build/DecisionBook/create
|
||||||
|
/Build/DecisionBook/update/{book_uu_id}
|
||||||
|
/Build/DecisionBook/patch/{book_uu_id}
|
||||||
|
/Build/DecisionBook/Person/list
|
||||||
|
/Build/DecisionBook/Person/create
|
||||||
|
/Build/DecisionBook/Person/update/{book_uu_id}
|
||||||
|
/event/list
|
||||||
|
/Build/DecisionBook/Person/patch/{book_uu_id}
|
||||||
|
/Build/DecisionBook/Items/list
|
||||||
|
/Build/DecisionBook/Items/create
|
||||||
|
/Build/DecisionBook/Items/update/{book_uu_id}
|
||||||
|
/Build/DecisionBook/Items/patch/{book_uu_id}
|
||||||
|
/Build/DecisionBook/Items/Debits/list
|
||||||
|
/Build/DecisionBook/Items/Debits/create
|
||||||
|
/Build/DecisionBook/Items/Debits/update/{book_uu_id}
|
||||||
|
/Build/DecisionBook/Items/Debits/patch/{book_uu_id}
|
||||||
|
/Build/ProjectDecisionBook/list
|
||||||
|
/Build/ProjectDecisionBook/create
|
||||||
|
/Build/ProjectDecisionBook/update/{book_uu_id}
|
||||||
|
/Build/ProjectDecisionBook/patch/{book_uu_id}
|
||||||
|
/Build/ProjectDecisionBook/Items/list
|
||||||
|
/Build/ProjectDecisionBook/Items/create
|
||||||
|
/Build/ProjectDecisionBook/Items/update/{book_uu_id}
|
||||||
|
/Build/ProjectDecisionBook/Items/patch/{book_uu_id}
|
||||||
|
/Build/ProjectDecisionBook/Items/Debits/list
|
||||||
|
/Build/ProjectDecisionBook/Items/Debits/create
|
||||||
|
/Build/ProjectDecisionBook/Items/Debits/update/{book_uu_id}
|
||||||
|
/Build/ProjectDecisionBook/Items/Debits/patch/{book_uu_id}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/Duty/list
|
||||||
|
/Duty/create
|
||||||
|
/duties/list
|
||||||
|
/duties/create
|
||||||
|
/People/list
|
||||||
|
/People/create
|
||||||
|
/event/register/employee
|
||||||
|
/event/register/occupant
|
||||||
|
/User/list
|
||||||
|
/User/create
|
||||||
|
/Company/list
|
||||||
|
/Company/create
|
||||||
|
/Department/list
|
||||||
|
/Department/create
|
||||||
|
/building/build/list
|
||||||
|
/Building/Parts/list
|
||||||
|
/Building/LivingSpace/list
|
||||||
|
/Build/DecisionBook/list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Company[Evyos]
|
||||||
|
|
||||||
|
Create Department[Department]
|
||||||
|
- Genel Müdürlük GM
|
||||||
|
- Mali İşler Departmanı MD
|
||||||
|
- İnsan Kaynakları Departmanı İKD
|
||||||
|
- Satış Departmanı SD
|
||||||
|
- Bilgi Teknolojileri Departmanı BTD
|
||||||
|
|
||||||
|
Create Duty[Duty]
|
||||||
|
- Genel Müdür GM 1
|
||||||
|
- Mali İşler Direktörlüğü MD
|
||||||
|
- İnsan Kaynakları Direktörlüğü İKD
|
||||||
|
- Satış Direktörlüğü SD
|
||||||
|
- Bilgi Teknolojileri Direktörlüğü BTD
|
||||||
|
|
||||||
|
- Muhasebe Müdürlüğü MM
|
||||||
|
- Finans Müdürlüğü FM
|
||||||
|
|
||||||
|
- Muhasabe Şefliği MS
|
||||||
|
- Muhasebe Uzmanı MU
|
||||||
|
- Muhasebe Elemanı ME
|
||||||
|
|
||||||
|
- Finans Şefliği FS
|
||||||
|
- Finans Uzmanı FU
|
||||||
|
- Finans Elemanı FE
|
||||||
|
|
||||||
|
- İnsan Kaynakları Müdürlüğü İKM
|
||||||
|
- İnsan Kaynakları Şefliği İKS
|
||||||
|
- İnsan Kaynakları Uzmanı İKU
|
||||||
|
- İnsan Kaynakları Elemanı İKE
|
||||||
|
|
||||||
|
- Satış Müdürlüğü SM
|
||||||
|
- Satış Bölge Şefliği SS
|
||||||
|
- Satış Temsilcisi ST
|
||||||
|
|
||||||
|
- Veri Tabanı Yöneticisi VTY
|
||||||
|
- Aplikasyon Sorumlusu AS
|
||||||
|
- Ağ Yöneticisi AY
|
||||||
|
|
||||||
|
Create Staff[Staff]
|
||||||
|
- Genel Müdür GM 1 | Duty: Genel Müdür
|
||||||
|
- Mali İşler Direktörü MD 1 | Duty: Mali İşler Direktörlüğü
|
||||||
|
- İnsan Kaynakları Direktörü İKD 2 | Duty: İnsan Kaynakları Direktörlüğü
|
||||||
|
- Satış Direktörü SD 3 | Duty: Satış Direktörlüğü
|
||||||
|
- Bilgi Teknolojileri Direktörü BTD 6 | Duty: Bilgi Teknolojileri Direktörlüğü
|
||||||
|
|
||||||
|
- Muhasabe Müdürü MM | Duty: Muhasebe Müdürlüğü
|
||||||
|
- Finans Müdürü FM | Duty: Finans Müdürlüğü
|
||||||
|
|
||||||
|
- Muhasabe Şefi MS | Duty: Muhasabe Şefliği
|
||||||
|
- Muhasabe Uzmanı MU | Duty: Muhasebe Uzmanı
|
||||||
|
- Digital Muhasabe Elemanı | Duty: Muhasebe Elemanı
|
||||||
|
- Muhasabe Elemanı | Duty: Muhasebe Elemanı
|
||||||
|
|
||||||
|
- Finans Şefi FS | Duty: Finans Şefliği
|
||||||
|
- Finans Uzmanı FU | Duty: Finans Uzmanı
|
||||||
|
- Finans Elemanı FE | Duty: Finans Elemanı
|
||||||
|
|
||||||
|
- İnsan Kaynakları Müdürü İKM | Duty: İnsan Kaynakları Müdürlüğü
|
||||||
|
- İnsan Kaynakları Şefi İKS | Duty: İnsan Kaynakları Şefliği
|
||||||
|
- İnsan Kaynakları Uzmanı İKU | Duty: İnsan Kaynakları Uzmanı
|
||||||
|
- İnsan Kaynakları Elemanı İKE | Duty: İnsan Kaynakları Elemanı
|
||||||
|
|
||||||
|
- Satış Müdürü SM | Duty: Satış Müdürlüğü
|
||||||
|
- Satış Ankara Bölge Şefi SS | Duty: Satış Bölge Şefliği
|
||||||
|
- Satış İstanbul Bölge Şefi SS | Duty: Satış Bölge Şefliği
|
||||||
|
- Satış İzmir Bölge Şefi SS | Duty: Satış Bölge Şefliği
|
||||||
|
- Satış Ankara Çankaya Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
- Satış Ankara Keçiören Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
- Satış Ankara Yenimahalle Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
- Satış İstanbul Beylikdüzü Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
- Satış İstanbul Kadıköy Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
- Satış İstanbul Üsküdar Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
- Satış İzmir Bornova Temsilcisi ST | Duty: Satış Temsilcisi
|
||||||
|
|
||||||
|
- Veri Tabanı Yöneticisi VTY | Duty: Veri Tabanı Yöneticisi
|
||||||
|
- Aplikasyon Sorumlusu AS | Duty: Aplikasyon Sorumlusu
|
||||||
|
- Super User AS | Duty: Aplikasyon Sorumlusu
|
||||||
|
- Ağ Yöneticisi AY | Duty: Ağ Yöneticisi
|
||||||
|
|
||||||
|
|
||||||
|
o Department - İcra Kurulu İCK
|
||||||
|
Duty[İCK]
|
||||||
|
- [Duty]Genel Müdür GM 1 --> Staff[GM] - Genel Müdür GM 1
|
||||||
|
- [Duty]Mali İşler Direktörlüğü MD --> Staff[MD] - Mali İşler Direktörü MD 1
|
||||||
|
- [Duty]İnsan Kaynakları Direktörlüğü İKD --> Staff[İKD] - İnsan Kaynakları Direktörü İKD 2
|
||||||
|
- [Duty]Satış Direktörlüğü SD --> Staff[SD] - Satış Direktörü SD 3
|
||||||
|
- [Duty]Bilgi Teknolojileri Direktörlüğü BTD --> Staff[BTD] - Bilgi Teknolojileri Direktörü BTD 6
|
||||||
|
|
||||||
|
- [Duty]Pazarlama Direktörlüğü PD --> Staff[PD] - Pazarlama Direktörü PD 4
|
||||||
|
- [Duty]Operasyon Direktörlüğü OD --> Staff[OD] - Operasyon Direktörü OD 5
|
||||||
|
|
||||||
|
o Department - Mali İşler Departmanı MD
|
||||||
|
Duty[Mİ]
|
||||||
|
|
||||||
|
- [Duty]Muhasebe Müdürlüğü MM --> Staff[MD] Muhasabe Müdürü MM
|
||||||
|
- [Duty]Finans Müdürlüğü FM --> Staff[MD] Finans Müdürü FM
|
||||||
|
|
||||||
|
- [Duty]Muhasabe Şefliği MS 4 --> Staff[MM] Muhasabe Şefi MS
|
||||||
|
- [Duty]Muhasebe Uzmanı MU 5 --> Staff[MM] Muhasabe Uzmanı MU
|
||||||
|
- [Duty]Muhasebe Elemanı ME 6 --> Staff[MM] Digital Muhasabe Elemanı
|
||||||
|
--> Staff[MM] Muhasabe Elemanı
|
||||||
|
|
||||||
|
- [Duty]Finans Şefliği FS 7 --> Staff[FM] Finans Şefi FS
|
||||||
|
- [Duty]Finans Uzmanı FU 8 --> Staff[FM] Finans Uzmanı FU
|
||||||
|
- [Duty]Finans Elemanı FE 9 --> Staff[FM] Finans Elemanı FE
|
||||||
|
|
||||||
|
|
||||||
|
o Department - İnsan Kaynakları Departmanı İKD
|
||||||
|
Duty[İKD]
|
||||||
|
- [Duty]İnsan Kaynakları Müdürlüğü İKM --> Staff[İKD] İnsan Kaynakları Müdürü İKM
|
||||||
|
- [Duty]İnsan Kaynakları Şefliği İKS --> Staff[İKM] İnsan Kaynakları Şefi İKS
|
||||||
|
- [Duty]İnsan Kaynakları Uzmanı İKU --> Staff[İKS] İnsan Kaynakları Uzmanı İKU
|
||||||
|
- [Duty]İnsan Kaynakları Elemanı İKE --> Staff[İKS] İnsan Kaynakları Elemanı İKE
|
||||||
|
|
||||||
|
o Department - Satış Departmanı SD
|
||||||
|
- [Duty]Satış Müdürlüğü SM --> Staff[SD] Satış Müdürü SM
|
||||||
|
- [Duty]Satış Bölge Şefliği SS --> Staff[SM] Satış Ankara Bölge Şefi SS
|
||||||
|
--> Staff[SM] Satış İstanbul Bölge Şefi SS
|
||||||
|
--> Staff[SM] Satış İzmir Bölge Şefi SS
|
||||||
|
- [Duty]Satış Temsilcisi ST --> Staff[SS] Satış Ankara Çankaya Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış Ankara Keçiören Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış Ankara Yenimahalle Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış İstanbul Beylikdüzü Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış İstanbul Kadıköy Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış İstanbul Üsküdar Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış İzmir Bornova Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış İzmir Karşıyaka Temsilcisi ST
|
||||||
|
--> Staff[SS] Satış İzmir Konak Temsilcisi ST
|
||||||
|
|
||||||
|
o Department - Bilgi Teknolojileri Departmanı BTD
|
||||||
|
- [Duty]Veri Tabanı Yöneticisi VTY --> Staff[BTD] Veri Tabanı Yöneticisi VTY
|
||||||
|
- [Duty]Aplikasyon Sorumlusu AS --> Staff[BTD] Aplikasyon Sorumlusu AS
|
||||||
|
--> Staff[BTD] Super User AS
|
||||||
|
- [Duty]Ağ Yöneticisi AY --> Staff[BTD] Ağ Yöneticisi AY
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
--- Event Architecture ---
|
||||||
|
|
||||||
|
Module:
|
||||||
|
Şirkete yada kavramsal gruba devrideleden süreçler bütünü. Farklı departmanlara verilen eylemler bütünü.
|
||||||
|
|
||||||
|
Servis:
|
||||||
|
Bir modülün içerisindeki eylemler bütünü. Farklı görevleri yerine getirmek için kullanılan hizmetler.
|
||||||
|
|
||||||
|
Eylem:
|
||||||
|
Bir servisin işini farklı parametrelerle yapmasını sağlayan işlemler.
|
||||||
|
|
||||||
|
Olay:
|
||||||
|
Bir görevi yerine getirken oluşan temel fonksiyonlar. Bir eylemin gerçekleşmesi için gerekli olan temel işlemler.
|
||||||
|
|
||||||
|
|
||||||
|
example event endpoint: "https://app.evyos.com.tr/events/[module]/[service]/[action]/[event-uu-id]"
|
||||||
|
example event endpoint: "https://[IP]:port/[event-uu-id]"
|
||||||
|
Which events I can reach?
|
||||||
|
TOKEN
|
||||||
|
|
||||||
|
Module -> Service -> Action -> Events
|
||||||
|
|
||||||
|
https://[IP]:port/8oYt-lkashdıayusd-qjkywuıyh
|
||||||
|
|
||||||
|
|
||||||
|
Module: Sales Module
|
||||||
|
Service: Company
|
||||||
|
Action: Create
|
||||||
|
Event: 1
|
||||||
|
|
||||||
|
{
|
||||||
|
"event_entity_id": 1,
|
||||||
|
"name": "Create Company",
|
||||||
|
"description": "Create a new company",
|
||||||
|
"property_description": "Create a new company with all the necessary information",
|
||||||
|
"marketing_layer": 3,
|
||||||
|
"cost": 0.00,
|
||||||
|
"unit_price": 0.00,
|
||||||
|
"endpoint_id": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SuperUser:
|
||||||
|
Module: Core
|
||||||
|
Service: It Department
|
||||||
|
Action: Company Create
|
||||||
|
Event: 1
|
||||||
|
|
||||||
|
employee_id: 1
|
||||||
|
|
||||||
|
Module: Sales
|
||||||
|
|
||||||
|
Service: Company
|
||||||
|
Action: Create
|
||||||
|
Event: 1
|
||||||
|
|
||||||
|
Service: Company
|
||||||
|
Action: Update
|
||||||
|
Event: 2
|
||||||
|
|
||||||
|
Module: Marketing
|
||||||
|
|
||||||
|
Service: Company
|
||||||
|
Action: Create
|
||||||
|
Event-uu-id: 9uyt-8u7y-8u7y-8u7y
|
||||||
|
Event-uu-id: 10yt-9u7y-8u7y-8u7y
|
||||||
|
|
||||||
|
request: POST /events/sales/company/
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
|
||||||
|
App initialisation
|
||||||
|
------------------
|
||||||
|
1. Run app to deploy init data via app.py/create_app/create_application_defaults function
|
||||||
|
2. Login with super user which is defined in app.py/create_app/create_application_defaults function
|
||||||
|
3. Create a sub company @evyos.com/company/add
|
||||||
|
4. Connect Main Company[Evyos] 2-> Sub Company[New Company] evyos.com/company/available/organization
|
||||||
|
5. Add new people @evyos.com/people/add
|
||||||
|
6. Add new user @evyos.com/user/add [LATER]
|
||||||
|
7. Make new added people available for a certain duty or create new super user for new company @evyos.com/people/available/employee
|
||||||
|
|
||||||
|
Super User Actions with no event declared on system
|
||||||
|
---------------------------------------------------
|
||||||
|
@evyos.com/departments/add => Add new department
|
||||||
|
@evyos.com/duty/add => Attach new duty to new department
|
||||||
|
@evyos.com/staff/add => Add new staff to new department
|
||||||
|
Connect people to staff @evyos.com/employee/match
|
||||||
|
|
||||||
|
-> Logout with super user
|
||||||
|
-> Login with Sales Employee
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
1. Create a new building @evyos.com/building/build/add
|
||||||
|
2. Create a new build area @evyos.com/building/area/add
|
||||||
|
3. Create a new build part @evyos.com/building/part/add
|
||||||
|
4.
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Modules:
|
||||||
|
[Super User Module]
|
||||||
|
|
||||||
|
|
||||||
|
Services -> Action:
|
||||||
|
[Account]
|
||||||
|
-> Create Account
|
||||||
|
-> Update Account
|
||||||
|
-> Delete Account
|
||||||
|
-> List Account
|
||||||
|
[Address]
|
||||||
|
-> Create Address
|
||||||
|
-> Update Address
|
||||||
|
-> Delete Address
|
||||||
|
-> List Address
|
||||||
|
|
||||||
|
[Api]
|
||||||
|
[Application]
|
||||||
|
[Authentication]
|
||||||
|
[Build]
|
||||||
|
[Buildparts]
|
||||||
|
[Buildsection]
|
||||||
|
[Livingspaces]
|
||||||
|
[Company]
|
||||||
|
[Department]
|
||||||
|
[Duties]
|
||||||
|
[Duty]
|
||||||
|
[Employee]
|
||||||
|
[Staff]
|
||||||
|
[DecisionBook]
|
||||||
|
[DecisionBookItems]
|
||||||
|
[DecisionBookItemsDebits]
|
||||||
|
[DecisionBookPerson]
|
||||||
|
[Events]
|
||||||
|
[People]
|
||||||
|
[ProjectDecisionBook]
|
||||||
|
[Rules]
|
||||||
|
[Users]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
User Types
|
||||||
|
|
||||||
|
1. Employee
|
||||||
|
2. Occupant
|
||||||
|
|
||||||
|
[Login Action]
|
||||||
|
|
||||||
|
------Occupant------
|
||||||
|
Person -> User:
|
||||||
|
Company -> Department -> Duty -> Staff -> Employee -> Person | (n) Occupant -> Person
|
||||||
|
People[people_id] -> User[Login Intersect] -> BuildLivingSpace -> BuildPart -> Build -> Responsible Employee -> Company
|
||||||
|
Person [people_id]
|
||||||
|
- Occupant Type [occupant_id] + Build Part [build_parts_id]
|
||||||
|
|
||||||
|
------Employee------
|
||||||
|
Person -> User:
|
||||||
|
Company -> Department -> Duty -> Employee -> Person | (n) Employee
|
||||||
|
People[people_id] -> User[Login Intersect] -> Employee[staff_id] -> Staff -> Duty -> Department -> Company
|
||||||
|
1. Person [people_id]
|
||||||
|
2. Staff [staff_id]
|
||||||
|
|
||||||
|
Employee login TOKEN requires:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Company : evyos.com
|
||||||
|
Department : Satış Dep.
|
||||||
|
Duty : Temsilci
|
||||||
|
Employee: Berkay Karatay[Person]
|
||||||
|
(n) Occupant
|
||||||
|
Occupant: Melih[Person]
|
||||||
|
Occupant: Songül[Person]
|
||||||
|
Occupant: Günay[Person]
|
||||||
|
|
||||||
|
::Add middleware endpoint control
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
10
a_project_files/drafts_and_notes/evyos-draft/kararlar.txt
Normal file
10
a_project_files/drafts_and_notes/evyos-draft/kararlar.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
1- Geçen yıla ait toplantıda 2’nolu gündemde bahsedilen kanalizasyon için her bir kanalizasyon çıkışı için fiyat alınarak proje açılacaktır. Arka alana yağmur suyu drenajın yaptırılması.
|
||||||
|
2- Aidat gündemi içim 1-2-3’nolu daireler için 1.400 TL. diğer daireler için 1.500 TL. olarak apartman hesabına ödeme yapılmasına.
|
||||||
|
3- Hali hazırda yöneticilik görevini ifa eden Mehmet Karatay’ın görevine devam etmesine.
|
||||||
|
4- Kirişin içinden geçen kalorifer borusunun çıkarılmadan kesilmesine ve gerekli tadilatın yapılıp problemin çözülmesine ve bu arada ayrıca her dairenin kalorifer borularında su olmadığı için gerekli her radyatörlerinin temizliğini kendisinin yaptırmasına.
|
||||||
|
5- Doğalgaz tadilatından çıkan hurda boruların hurdacı tarafından gelip alınarak satışının yapılmasına.
|
||||||
|
6- Apartman içinin tadilatının yapılmasın, ışıkların ve elektrik sisteminin elden geçirilmesi ve elektrik sayaçlarının panolara konulmasına ve yeni yapılan doğalgaz boruların pasa karşı astar boya ile ve sarı renkle boyanmasına.
|
||||||
|
7- İç kapı teklifi alınarak gerekli tadilatın gerçekleştirilmesi için çalışma yapılması, ek kapı veya tek kapı seçenekleri değerlendirilerek fiyat alınmasına,
|
||||||
|
8- Binanın su depo temizliğinin yapılmasına.
|
||||||
|
9- Çatı havalandırma camlarından çatlamış olanların değiştirilmesine.
|
||||||
|
10- Arka zemin dairenin yoğun yağışlarda evini su basmasından korunmak amacı ile saçak yapılmasına karar verilmiştir.
|
||||||
140
a_project_files/drafts_and_notes/evyos-draft/menu_items
Normal file
140
a_project_files/drafts_and_notes/evyos-draft/menu_items
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
{
|
||||||
|
"_id": {
|
||||||
|
"$oid": "662a85f05b8acaaa3b37238c"
|
||||||
|
},
|
||||||
|
"user_id": 7,
|
||||||
|
"menu": {
|
||||||
|
"only_menu_item": false,
|
||||||
|
"item_order": 0,
|
||||||
|
"layer": 0,
|
||||||
|
"app_name": "Tanımlama Menüsü",
|
||||||
|
"app_description": "Tanımlama Menüsü",
|
||||||
|
"app_path": "",
|
||||||
|
"uu_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
|
||||||
|
"app_parent_items_id": null,
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APP166d9a3f495e4261baabdd456e9d294b",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"only_menu_item": false,
|
||||||
|
"item_order": 10,
|
||||||
|
"layer": 1,
|
||||||
|
"app_name": "Firma İşlemleri",
|
||||||
|
"app_description": "Firma İşlemleri",
|
||||||
|
"app_path": "",
|
||||||
|
"uu_id": "d1aa4365-b1ef-4c91-ac8e-e3289f7eb075",
|
||||||
|
"app_parent_items_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APPd1aa4365b1ef4c91ac8ee3289f7eb075",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"only_menu_item": true,
|
||||||
|
"item_order": 20,
|
||||||
|
"layer": 2,
|
||||||
|
"app_name": "Firma Tanımlama",
|
||||||
|
"app_description": "Firma Tanımlama",
|
||||||
|
"app_path": "create_company",
|
||||||
|
"uu_id": "a3c60a25-ff46-4872-b209-9e501dde7b73",
|
||||||
|
"app_parent_items_id": "d1aa4365-b1ef-4c91-ac8e-e3289f7eb075",
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APPa3c60a25ff464872b2099e501dde7b73"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"only_menu_item": false,
|
||||||
|
"item_order": 30,
|
||||||
|
"layer": 1,
|
||||||
|
"app_name": "Personel İşlemleri",
|
||||||
|
"app_description": "Personel İşlemleri",
|
||||||
|
"app_path": "",
|
||||||
|
"uu_id": "eebb591d-842b-4495-8721-e09552665a06",
|
||||||
|
"app_parent_items_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APPeebb591d842b44958721e09552665a06",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"only_menu_item": true,
|
||||||
|
"item_order": 40,
|
||||||
|
"layer": 2,
|
||||||
|
"app_name": "Kişi Tanımlama",
|
||||||
|
"app_description": "Kişi Tanımlama",
|
||||||
|
"app_path": "create_person",
|
||||||
|
"uu_id": "0c6c8cd2-f6b7-471f-9671-5cc1ac9f502e",
|
||||||
|
"app_parent_items_id": "eebb591d-842b-4495-8721-e09552665a06",
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APP0c6c8cd2f6b7471f96715cc1ac9f502e"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"only_menu_item": false,
|
||||||
|
"item_order": 50,
|
||||||
|
"layer": 1,
|
||||||
|
"app_name": "Bina İşlemleri",
|
||||||
|
"app_description": "Bina İşlemleri",
|
||||||
|
"app_path": "",
|
||||||
|
"uu_id": "66627ebb-0425-425f-bc0f-8a943eb0a3ca",
|
||||||
|
"app_parent_items_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APP66627ebb0425425fbc0f8a943eb0a3ca",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"only_menu_item": true,
|
||||||
|
"item_order": 60,
|
||||||
|
"layer": 2,
|
||||||
|
"app_name": "Bina ve bölüm tanımlama",
|
||||||
|
"app_description": "Bina ve bölüm tanımlama",
|
||||||
|
"app_path": "create_build",
|
||||||
|
"uu_id": "173c4d8e-5577-4d4d-8712-f6fa2fbc8019",
|
||||||
|
"app_parent_items_id": "66627ebb-0425-425f-bc0f-8a943eb0a3ca",
|
||||||
|
"after_separator": false,
|
||||||
|
"row_limit": 100,
|
||||||
|
"read": true,
|
||||||
|
"write": false,
|
||||||
|
"delete": false,
|
||||||
|
"report_print": false,
|
||||||
|
"report_export": false,
|
||||||
|
"program_name": "APP173c4d8e55774d4d8712f6fa2fbc8019"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
229
a_project_files/drafts_and_notes/evyos-draft/recursive_menu.py
Normal file
229
a_project_files/drafts_and_notes/evyos-draft/recursive_menu.py
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
data = '{"menu":[{"only_menu_item":false,"item_order":0,"layer":0,"app_name":"Tanımlama Menüsü","app_description":"Tanımlama Menüsü","app_path":"","uu_id":"166d9a3f-495e-4261-baab-dd456e9d294b","app_parent_items_id":null,"after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP166d9a3f495e4261baabdd456e9d294b"},{"only_menu_item":false,"item_order":10,"layer":1,"app_name":"Firma İşlemleri","app_description":"Firma İşlemleri","app_path":"","uu_id":"d1aa4365-b1ef-4c91-ac8e-e3289f7eb075","app_parent_items_id":"166d9a3f-495e-4261-baab-dd456e9d294b","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APPd1aa4365b1ef4c91ac8ee3289f7eb075"},{"only_menu_item":true,"item_order":20,"layer":2,"app_name":"Firma Tanımlama","app_description":"Firma Tanımlama","app_path":"create_company","uu_id":"a3c60a25-ff46-4872-b209-9e501dde7b73","app_parent_items_id":"d1aa4365-b1ef-4c91-ac8e-e3289f7eb075","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APPa3c60a25ff464872b2099e501dde7b73"},{"only_menu_item":false,"item_order":30,"layer":1,"app_name":"Personel İşlemleri","app_description":"Personel İşlemleri","app_path":"","uu_id":"eebb591d-842b-4495-8721-e09552665a06","app_parent_items_id":"166d9a3f-495e-4261-baab-dd456e9d294b","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APPeebb591d842b44958721e09552665a06"},{"only_menu_item":true,"item_order":40,"layer":2,"app_name":"Kişi Tanımlama","app_description":"Kişi Tanımlama","app_path":"create_person","uu_id":"0c6c8cd2-f6b7-471f-9671-5cc1ac9f502e","app_parent_items_id":"eebb591d-842b-4495-8721-e09552665a06","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP0c6c8cd2f6b7471f96715cc1ac9f502e"},{"only_menu_item":false,"item_order":50,"layer":1,"app_name":"Bina İşlemleri","app_description":"Bina İşlemleri","app_path":"","uu_id":"66627ebb-0425-425f-bc0f-8a943eb0a3ca","app_parent_items_id":"166d9a3f-495e-4261-baab-dd456e9d294b","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP66627ebb0425425fbc0f8a943eb0a3ca"},{"only_menu_item":true,"item_order":60,"layer":2,"app_name":"Bina ve bölüm tanımlama","app_description":"Bina ve bölüm tanımlama","app_path":"create_build","uu_id":"173c4d8e-5577-4d4d-8712-f6fa2fbc8019","app_parent_items_id":"66627ebb-0425-425f-bc0f-8a943eb0a3ca","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP173c4d8e55774d4d8712f6fa2fbc8019"}]}'
|
||||||
|
|
||||||
|
|
||||||
|
class Menu:
|
||||||
|
def __init__(self, json_data):
|
||||||
|
self.data = {}
|
||||||
|
self.json = json_data
|
||||||
|
self.app_name = None
|
||||||
|
self.app_description = None
|
||||||
|
self.app_path = None
|
||||||
|
self.uu_id = None
|
||||||
|
self.app_parent_items_id = None
|
||||||
|
self.children = {}
|
||||||
|
self.only_menu_item = None
|
||||||
|
self.item_order = None
|
||||||
|
self.layer = None
|
||||||
|
self.before_separator = None
|
||||||
|
self.row_limit = None
|
||||||
|
self.read = None
|
||||||
|
self.write = None
|
||||||
|
self.delete = None
|
||||||
|
self.report_print = None
|
||||||
|
self.report_export = None
|
||||||
|
self.program_name = None
|
||||||
|
self.dct = {}
|
||||||
|
self.import_data()
|
||||||
|
|
||||||
|
def add_item(
|
||||||
|
self,
|
||||||
|
only_menu_item,
|
||||||
|
item_order,
|
||||||
|
layer,
|
||||||
|
app_name,
|
||||||
|
app_description,
|
||||||
|
app_path,
|
||||||
|
uu_id,
|
||||||
|
app_parent_items_id,
|
||||||
|
before_separator,
|
||||||
|
row_limit,
|
||||||
|
read,
|
||||||
|
write,
|
||||||
|
delete,
|
||||||
|
report_print,
|
||||||
|
report_export,
|
||||||
|
program_name,
|
||||||
|
):
|
||||||
|
self.app_name = app_name
|
||||||
|
self.app_description = app_description
|
||||||
|
self.app_path = app_path
|
||||||
|
self.uu_id = uu_id
|
||||||
|
self.app_parent_items_id = app_parent_items_id
|
||||||
|
self.children = {}
|
||||||
|
self.only_menu_item = only_menu_item
|
||||||
|
self.item_order = item_order
|
||||||
|
self.layer = layer
|
||||||
|
self.before_separator = before_separator
|
||||||
|
self.row_limit = row_limit
|
||||||
|
self.read = read
|
||||||
|
self.write = write
|
||||||
|
self.delete = delete
|
||||||
|
self.report_print = report_print
|
||||||
|
self.report_export = report_export
|
||||||
|
self.program_name = program_name
|
||||||
|
self.dct = dict(
|
||||||
|
app_parent_items_id=app_parent_items_id,
|
||||||
|
uu_id=uu_id,
|
||||||
|
app_name=app_name,
|
||||||
|
children={},
|
||||||
|
app_path=app_path,
|
||||||
|
app_description=app_description,
|
||||||
|
only_menu_item=self.only_menu_item,
|
||||||
|
item_order=self.item_order,
|
||||||
|
layer=self.layer,
|
||||||
|
before_separator=self.before_separator,
|
||||||
|
row_limit=self.row_limit,
|
||||||
|
read=self.read,
|
||||||
|
write=self.write,
|
||||||
|
delete=self.delete,
|
||||||
|
report_print=self.report_print,
|
||||||
|
report_export=self.report_export,
|
||||||
|
program_name=self.program_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
xx = self.find_data(self.data, str(app_parent_items_id))
|
||||||
|
if not xx:
|
||||||
|
self.data[self.uu_id] = self.dct
|
||||||
|
else:
|
||||||
|
xx["children"][self.uu_id] = self.dct
|
||||||
|
# xx.self.children[self.uu_id] = self.dct
|
||||||
|
# self.add_data(self.data, None)
|
||||||
|
|
||||||
|
def find_data(self, search_data, find_text):
|
||||||
|
if find_text is None:
|
||||||
|
return None
|
||||||
|
for x, y in search_data.items():
|
||||||
|
if x == find_text:
|
||||||
|
print(find_text, " bulundu")
|
||||||
|
# y["children"].append(self.dct)
|
||||||
|
return y
|
||||||
|
if "children" in y and len(y["children"]) > 0:
|
||||||
|
ret = self.find_data(y["children"], find_text)
|
||||||
|
if ret is not None:
|
||||||
|
return ret
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def show_col(i, y):
|
||||||
|
print(
|
||||||
|
"layer :",
|
||||||
|
i,
|
||||||
|
" app_parent_items_id",
|
||||||
|
y["app_parent_items_id"],
|
||||||
|
"uu_id",
|
||||||
|
y["uu_id"],
|
||||||
|
"app_name",
|
||||||
|
y["app_name"],
|
||||||
|
"app_path",
|
||||||
|
y["app_path"],
|
||||||
|
"app_description",
|
||||||
|
y["app_description"],
|
||||||
|
"only_menu_item",
|
||||||
|
y["only_menu_item"],
|
||||||
|
"item_order",
|
||||||
|
y["item_order"],
|
||||||
|
"layer",
|
||||||
|
y["layer"],
|
||||||
|
"before_separator",
|
||||||
|
y["before_separator"],
|
||||||
|
"row_limit",
|
||||||
|
y["row_limit"],
|
||||||
|
"read",
|
||||||
|
y["read"],
|
||||||
|
"write",
|
||||||
|
y["write"],
|
||||||
|
"delete",
|
||||||
|
y["delete"],
|
||||||
|
"report_print",
|
||||||
|
y["report_print"],
|
||||||
|
"report_export",
|
||||||
|
y["report_export"],
|
||||||
|
"program_name",
|
||||||
|
y["program_name"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def show_data(self):
|
||||||
|
# print(self.data)
|
||||||
|
for x, y in self.data.items():
|
||||||
|
self.show_col(0, y)
|
||||||
|
if type(y) is dict:
|
||||||
|
for a, b in y["children"].items():
|
||||||
|
self.show_col(1, b)
|
||||||
|
if type(y) is dict:
|
||||||
|
for c, d in b["children"].items():
|
||||||
|
self.show_col(2, d)
|
||||||
|
if type(y) is dict:
|
||||||
|
for e, f in d["children"].items():
|
||||||
|
self.show_col(3, f)
|
||||||
|
|
||||||
|
# print("show Dat :", x, y)
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
def import_data(self):
|
||||||
|
if type(self.json) is str:
|
||||||
|
print("string miş")
|
||||||
|
self.json = json.loads(self.json)
|
||||||
|
for item, value in self.json.items():
|
||||||
|
if type(value) is list:
|
||||||
|
for x in range(len(value)):
|
||||||
|
print(f"t:{type(value[x])} : {value[x]}")
|
||||||
|
if type(value[x]) is list:
|
||||||
|
print("list", x)
|
||||||
|
if type(value[x]) is dict:
|
||||||
|
print(
|
||||||
|
value[x]["app_name"],
|
||||||
|
value[x]["app_description"],
|
||||||
|
value[x]["app_path"],
|
||||||
|
value[x]["uu_id"],
|
||||||
|
value[x]["app_parent_items_id"],
|
||||||
|
[],
|
||||||
|
value[x]["only_menu_item"],
|
||||||
|
value[x]["item_order"],
|
||||||
|
value[x]["layer"],
|
||||||
|
value[x]["after_separator"],
|
||||||
|
value[x]["row_limit"],
|
||||||
|
value[x]["read"],
|
||||||
|
value[x]["write"],
|
||||||
|
value[x]["delete"],
|
||||||
|
value[x]["report_print"],
|
||||||
|
value[x]["report_export"],
|
||||||
|
value[x]["program_name"],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add_item(
|
||||||
|
value[x]["only_menu_item"],
|
||||||
|
value[x]["item_order"],
|
||||||
|
value[x]["layer"],
|
||||||
|
value[x]["app_name"],
|
||||||
|
value[x]["app_description"],
|
||||||
|
value[x]["app_path"],
|
||||||
|
value[x]["uu_id"],
|
||||||
|
value[x]["app_parent_items_id"],
|
||||||
|
value[x]["after_separator"],
|
||||||
|
value[x]["row_limit"],
|
||||||
|
value[x]["read"],
|
||||||
|
value[x]["write"],
|
||||||
|
value[x]["delete"],
|
||||||
|
value[x]["report_print"],
|
||||||
|
value[x]["report_export"],
|
||||||
|
value[x]["program_name"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# self.add_item(value[x]["app_name"], app_description, app_path, uu_id, app_parent_items_id):
|
||||||
|
# self.app_name = app_name
|
||||||
|
# for child in item.children:
|
||||||
|
# print(f" - {child.app_name}")
|
||||||
|
|
||||||
|
|
||||||
|
(0, [1, 3, 5])
|
||||||
|
(1, [2])
|
||||||
|
(3, [4])
|
||||||
|
(5, [6])
|
||||||
|
(4, [7])
|
||||||
|
|
||||||
|
menu = Menu(json.loads(data))
|
||||||
|
print("*" * 100)
|
||||||
|
menu.show_data()
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import time
|
||||||
|
|
||||||
|
import pandas
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from services.email.service import send_email
|
||||||
|
from logging import getLogger, basicConfig, INFO
|
||||||
|
|
||||||
|
# from company_budget_records import insert_budget_record
|
||||||
|
|
||||||
|
logger = getLogger(__name__)
|
||||||
|
basicConfig(filename=__name__, level=INFO)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_xl_files_and_copy_to_database():
|
||||||
|
completed = "bank_excels/completed"
|
||||||
|
incoming = "bank_excels/incoming"
|
||||||
|
pandas.set_option("display.max_columns", None)
|
||||||
|
pandas.set_option("display.width", 1200)
|
||||||
|
|
||||||
|
current_directory = os.getcwd()
|
||||||
|
# current_directory = "/home/berkay/git-evyos/wag-management-api"
|
||||||
|
absolute_path = os.path.join(current_directory, incoming)
|
||||||
|
|
||||||
|
excel_files = glob.glob(os.path.join(absolute_path, "*.xls*"))
|
||||||
|
for file_path in excel_files:
|
||||||
|
xl_file = pandas.read_excel(file_path)
|
||||||
|
xl_frame = pandas.DataFrame(xl_file)
|
||||||
|
iban = ""
|
||||||
|
for row in xl_frame.itertuples():
|
||||||
|
if "IBAN" in str(row[3]).upper():
|
||||||
|
iban = str(row[5]).replace(" ", "")
|
||||||
|
if not str(row[1]) == "nan" and not str(row[2]) == "nan":
|
||||||
|
if len(str(row[1]).split("/")) > 2:
|
||||||
|
insert_dict = dict(
|
||||||
|
iban=str(iban),
|
||||||
|
bank_date=datetime.datetime.strptime(
|
||||||
|
str(row[1]), "%d/%m/%Y-%H:%M:%S"
|
||||||
|
).__str__(),
|
||||||
|
channel_branch=str(row[3]),
|
||||||
|
currency_value=(
|
||||||
|
float(str(row[4]).replace(",", "")) if row[4] else 0
|
||||||
|
),
|
||||||
|
balance=float(str(row[5]).replace(",", "")) if row[5] else 0,
|
||||||
|
additional_balance=(
|
||||||
|
float(str(row[6]).replace(",", "")) if row[6] else 0
|
||||||
|
),
|
||||||
|
process_name=str(row[7]),
|
||||||
|
process_type=str(row[8]),
|
||||||
|
process_comment=str(row[9]),
|
||||||
|
bank_reference_code=str(row[15]),
|
||||||
|
)
|
||||||
|
logger.info(f"Insert Dict: {insert_dict}")
|
||||||
|
print(f"Insert Dict: {insert_dict}")
|
||||||
|
# find_or_create, found = EdmBudgetRecords.find_or_create(**insert_dict)
|
||||||
|
# find_or_create, found = insert_budget_record(insert_dict)
|
||||||
|
find_or_create, found = None, None
|
||||||
|
if found:
|
||||||
|
send_html = f"""
|
||||||
|
<br/>
|
||||||
|
<h1>Bank Excel File</h1>
|
||||||
|
<p>Bank Excel File is processed</p>
|
||||||
|
<br/>
|
||||||
|
<h3>{str(find_or_create.bank_date)}</h3>
|
||||||
|
<h3>{str(find_or_create.process_comment)}</h3>
|
||||||
|
<h3>{str(find_or_create.currency_value)}</h3>
|
||||||
|
<p>Thank you</p>
|
||||||
|
<p>Wag Management</p>
|
||||||
|
<p>Sincere Regards</p>
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
send_email(
|
||||||
|
subject="Bank Excel File",
|
||||||
|
receivers=["mehmet.karatay@hotmail.com"],
|
||||||
|
html=send_html,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
finally:
|
||||||
|
print("Email is sent")
|
||||||
|
shutil.move(
|
||||||
|
file_path,
|
||||||
|
os.path.join(current_directory, completed, os.path.basename(file_path)),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
while True:
|
||||||
|
parse_xl_files_and_copy_to_database()
|
||||||
|
time.sleep(int(os.getenv("PARSER_SEQUENCE", 60)))
|
||||||
27
a_project_files/drafts_and_notes/evyos-draft/todos/todos.txt
Normal file
27
a_project_files/drafts_and_notes/evyos-draft/todos/todos.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Add via[Field] to @ login_via_credentials
|
||||||
|
Check is_occupant is True or False @ login_via_credentials
|
||||||
|
Add middleware @endpoint-controller to @ Event.Controller
|
||||||
|
If Events2Occupants and Events2Employees are not found for user request, response 401 Unauthorized
|
||||||
|
Also check user priority before Events2Occupants and Events2Employees
|
||||||
|
/home/berkay/evyos-apis/wag_api_service/shared_functions
|
||||||
|
|
||||||
|
Add default http errors status and message over Config Class
|
||||||
|
Change login and token object with occupant and employee
|
||||||
|
Add middleware to check user priority
|
||||||
|
Event rendering function must check with
|
||||||
|
Module -> Event
|
||||||
|
|
||||||
|
For each event add step and required previous step
|
||||||
|
|
||||||
|
Redis Cache TOKEN(encrypted) + UUID(encrypted) = Object (encrypted)
|
||||||
|
|
||||||
|
Occupant {
|
||||||
|
people_id,
|
||||||
|
occupant_id
|
||||||
|
}
|
||||||
|
|
||||||
|
Employee {
|
||||||
|
priority_id (Nullable | User),
|
||||||
|
*duty_id
|
||||||
|
}
|
||||||
|
|
||||||
23
a_project_files/http_json_examples/auth.json
Normal file
23
a_project_files/http_json_examples/auth.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"login_sup":
|
||||||
|
{
|
||||||
|
"domain": "evyos.com.tr",
|
||||||
|
"access_key": "karatay.berkay.sup@evyos.com.tr",
|
||||||
|
"password": "string",
|
||||||
|
"remember_me": false
|
||||||
|
},
|
||||||
|
"login_occupant":
|
||||||
|
{
|
||||||
|
"domain": "evyos.com.tr",
|
||||||
|
"access_key": "gdemirel@example.com",
|
||||||
|
"password": "string",
|
||||||
|
"remember_me": false
|
||||||
|
},
|
||||||
|
"select_sup": {
|
||||||
|
"company_uu_id": "0c8b808c-0f3b-4030-a2e7-681ed4478b97"
|
||||||
|
},
|
||||||
|
"select_occupant": {
|
||||||
|
"occupant_uu_id": "16dc4457-4c71-4a87-bd7a-53e87f6657d5",
|
||||||
|
"build_part_uu_id": "295de6a4-e5ba-4f3a-b5c0-02dff0578dc2"
|
||||||
|
}
|
||||||
|
}
|
||||||
34
a_project_files/http_json_examples/buildings.json
Normal file
34
a_project_files/http_json_examples/buildings.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"build":
|
||||||
|
{
|
||||||
|
"gov_address_code": "123456",
|
||||||
|
"build_name": "Beaver Build",
|
||||||
|
"build_no": "56",
|
||||||
|
"build_types": "A",
|
||||||
|
"max_floor": 12,
|
||||||
|
"underground_floor": 1,
|
||||||
|
"build_date": "01.01.2021",
|
||||||
|
"tax_no": "1234567890",
|
||||||
|
"lift_count": 0,
|
||||||
|
"heating_system": true,
|
||||||
|
"cooling_system": false,
|
||||||
|
"hot_water_system": false,
|
||||||
|
"block_service_man_count": 0,
|
||||||
|
"security_service_man_count": 0,
|
||||||
|
"garage_count": 2
|
||||||
|
},
|
||||||
|
"build_part":
|
||||||
|
{
|
||||||
|
"build_uu_id": "19d53a0c-1fa8-4011-8c91-75c05d357838",
|
||||||
|
"address_gov_code": "132456789101112",
|
||||||
|
"part_no": 1,
|
||||||
|
"part_level": 0,
|
||||||
|
"build_part_type_uu_id": "8eeeedd2-82b2-46d2-8611-4ea3d31dc122",
|
||||||
|
"part_code": 1,
|
||||||
|
"part_gross_size": 90,
|
||||||
|
"part_net_size": 90,
|
||||||
|
"human_livable": true,
|
||||||
|
"part_direction": "9fcbc4fa-245e-42a4-b4e2-6e2eb3222d3d",
|
||||||
|
"current_owner_person_uu_id": "bd96727c-2732-4432-98f3-516c403b0f6d"
|
||||||
|
}
|
||||||
|
}
|
||||||
31
a_project_files/http_json_examples/company.json
Normal file
31
a_project_files/http_json_examples/company.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"create_companies" :[
|
||||||
|
{
|
||||||
|
"formal_name": "Evyos Ankara Bölge Müdürlüğü",
|
||||||
|
"company_type": "Commercial",
|
||||||
|
"commercial_type": "Branch",
|
||||||
|
"public_name": "Evyos Ankara Bölge Müdürlüğü",
|
||||||
|
"company_tag": "Ankara Bölge Müdürlüğü",
|
||||||
|
"default_lang_type": "TR",
|
||||||
|
"default_money_type": "TL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"formal_name": "Evyos İzmir Bölge Müdürlüğü",
|
||||||
|
"company_type": "Commercial",
|
||||||
|
"commercial_type": "Branch",
|
||||||
|
"public_name": "Evyos İzmir Bölge Müdürlüğü",
|
||||||
|
"company_tag": "İzmir Bölge Müdürlüğü",
|
||||||
|
"default_lang_type": "TR",
|
||||||
|
"default_money_type": "TL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"formal_name": "Evyos İstanbul Bölge Müdürlüğü",
|
||||||
|
"company_type": "Commercial",
|
||||||
|
"commercial_type": "Branch",
|
||||||
|
"public_name": "Evyos İstanbul Bölge Müdürlüğü",
|
||||||
|
"company_tag": "İstanbul Bölge Müdürlüğü",
|
||||||
|
"default_lang_type": "TR",
|
||||||
|
"default_money_type": "TL"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
63
a_project_files/http_json_examples/decision_books.json
Normal file
63
a_project_files/http_json_examples/decision_books.json
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"decision_book":
|
||||||
|
{
|
||||||
|
"build_uu_id": "19d53a0c-1fa8-4011-8c91-75c05d357838",
|
||||||
|
"period_start_date": "2024-07-01",
|
||||||
|
"period_stop_date": "2025-06-30",
|
||||||
|
"decision_type": "DMB",
|
||||||
|
"meeting_date": "2024-06-26 21:44:20.749 +0300",
|
||||||
|
"is_out_sourced": false
|
||||||
|
},
|
||||||
|
"decision_book_item":[
|
||||||
|
{
|
||||||
|
"item_order": 1,
|
||||||
|
"item_comment": "Geçen yıla ait toplantıda 2’nolu gündemde bahsedilen kanalizasyon için her bir kanalizasyon çıkışı için fiyat alınarak proje açılacaktır. Arka alana yağmur suyu drenajın yaptırılması.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 2,
|
||||||
|
"item_comment": "Aidat gündemi içim 1-2-3’nolu daireler için 1.400 TL. diğer daireler için 1.500 TL. olarak apartman hesabına ödeme yapılmasına.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 3,
|
||||||
|
"item_comment": "Hali hazırda yöneticilik görevini ifa eden Mehmet Karatay’ın görevine devam etmesine.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 4,
|
||||||
|
"item_comment": "Kirişin içinden geçen kalorifer borusunun çıkarılmadan kesilmesine ve gerekli tadilatın yapılıp problemin çözülmesine ve bu arada ayrıca her dairenin kalorifer borularında su olmadığı için gerekli her radyatörlerinin temizliğini kendisinin yaptırmasına.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 5,
|
||||||
|
"item_comment": "Doğalgaz tadilatından çıkan hurda boruların hurdacı tarafından gelip alınarak satışının yapılmasına.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 6,
|
||||||
|
"item_comment": "Apartman içinin tadilatının yapılmasın, ışıkların ve elektrik sisteminin elden geçirilmesi ve elektrik sayaçlarının panolara konulmasına ve yeni yapılan doğalgaz boruların pasa karşı astar boya ile ve sarı renkle boyanmasına.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 7,
|
||||||
|
"item_comment": "İç kapı teklifi alınarak gerekli tadilatın gerçekleştirilmesi için çalışma yapılması, ek kapı veya tek kapı seçenekleri değerlendirilerek fiyat alınmasına,",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 8,
|
||||||
|
"item_comment": "Binanın su depo temizliğinin yapılmasına.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 9,
|
||||||
|
"item_comment": "Çatı havalandırma camlarından çatlamış olanların değiştirilmesine.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_order": 10,
|
||||||
|
"item_comment": "Arka zemin dairenin yoğun yağışlarda evini su basmasından korunmak amacı ile saçak yapılmasına karar verilmiştir.",
|
||||||
|
"build_decision_book_uu_id": "6a8e5ac9-97ea-43c8-8f7a-d6dffde551e6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"decision_book_item_debit":
|
||||||
|
{
|
||||||
|
"build_decision_book_item_uu_id": "855c1b77-f00e-4bc2-b3d1-42fc28ea2cb8",
|
||||||
|
"dues_values": {"NET_80": 1400, "NET_88": 1500}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"decision_books_project":
|
||||||
|
{
|
||||||
|
"build_decision_book_item_uu_id": "11b9dafa-8d7f-4b8f-8dad-3f8dbecaab98",
|
||||||
|
"project_response_person_uu_id": "7be73c91-ec57-46e0-99fa-95fa038c5f8d",
|
||||||
|
"project_name": "Depo Temizliği",
|
||||||
|
"project_start_date": "2024-06-01",
|
||||||
|
"project_stop_date": "2024-08-01",
|
||||||
|
"project_type": "TDL",
|
||||||
|
"is_out_sourced": false,
|
||||||
|
"project_note": "Sertifika alınacak",
|
||||||
|
"meeting_date": "2024-06-10"
|
||||||
|
},
|
||||||
|
"decision_book_item":
|
||||||
|
{
|
||||||
|
"item_order": 1,
|
||||||
|
"item_comment": "2,5 saat sürecek iş için 1000 TL fiyat istendi. 2 taksit ile ödenecek",
|
||||||
|
"build_decision_book_project_uu_id": "4a6bfdac-57d0-4876-8344-ae3f56c3b6d6"
|
||||||
|
},
|
||||||
|
"decision_book_item_debit" :
|
||||||
|
{
|
||||||
|
"build_decision_book_project_item_uu_id": "b862122a-2ef7-4a0d-b2e9-e2242b228b1f",
|
||||||
|
"payment_date": "2024-06-04",
|
||||||
|
"dues_values": {"NET_80": 1400, "NET_88": 1500}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
111
a_project_files/later_use_codes/joined_selection.py
Normal file
111
a_project_files/later_use_codes/joined_selection.py
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
@classmethod
|
||||||
|
def select_action(cls, duty_id, filter_expr: list = None):
|
||||||
|
from application.base import AlchemyResponse
|
||||||
|
|
||||||
|
keys_list = list(cls.__table__.columns) + list(
|
||||||
|
RelationshipDutyUser.__table__.columns
|
||||||
|
)
|
||||||
|
keys = [str(_.table) + "*" + str(_.name) for _ in keys_list]
|
||||||
|
data_list = []
|
||||||
|
if filter_expr is not None:
|
||||||
|
filter_expr = (RelationshipDutyUser.duty_id == duty_id, *filter_expr)
|
||||||
|
data = (
|
||||||
|
cls.session.query(
|
||||||
|
*cls.__table__.columns, *RelationshipDutyUser.__table__.columns
|
||||||
|
)
|
||||||
|
.select_from(cls)
|
||||||
|
.join(RelationshipDutyUser, RelationshipDutyUser.member_id == cls.id)
|
||||||
|
.filter(*filter_expr)
|
||||||
|
)
|
||||||
|
|
||||||
|
return AlchemyResponse(
|
||||||
|
query=data, data=data_list if data_list else data.all(), count=data.count()
|
||||||
|
)
|
||||||
|
data = (
|
||||||
|
cls.session.query(
|
||||||
|
*cls.__table__.columns, *RelationshipDutyUser.__table__.columns
|
||||||
|
)
|
||||||
|
.select_from(cls)
|
||||||
|
.join(RelationshipDutyUser, RelationshipDutyUser.member_id == cls.id)
|
||||||
|
.filter(RelationshipDutyUser.duty_id == duty_id)
|
||||||
|
)
|
||||||
|
for _ in data.all():
|
||||||
|
temp_dict = {}
|
||||||
|
for ix, item in enumerate(_):
|
||||||
|
table, key = str(keys[ix]).split("*")[0], str(keys[ix]).split("*")[1]
|
||||||
|
if table in temp_dict:
|
||||||
|
temp_dict[table][key] = item
|
||||||
|
else:
|
||||||
|
temp_dict[table] = {}
|
||||||
|
temp_dict[table][key] = item
|
||||||
|
data_list.append(temp_dict)
|
||||||
|
return AlchemyResponse(
|
||||||
|
query=data, data=data_list if data_list else data.all(), count=data.count()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_filter_with_options(model, options: ListOptions, duty_id):
|
||||||
|
from application.base import AlchemyResponse
|
||||||
|
|
||||||
|
if options.query:
|
||||||
|
model.query_filter = options.query
|
||||||
|
model.filter_attr = options
|
||||||
|
if hasattr(model, "select_action"):
|
||||||
|
list_of_model_records = model.select_action(duty_id=duty_id)
|
||||||
|
else:
|
||||||
|
list_of_model_records = model.filter_by_non_deleted()
|
||||||
|
|
||||||
|
if hasattr(list_of_model_records.data, "get_dict"):
|
||||||
|
if not list_of_model_records.count:
|
||||||
|
return AlchemyResponse(
|
||||||
|
query=list_of_model_records.query,
|
||||||
|
count=list_of_model_records.count,
|
||||||
|
data=[],
|
||||||
|
)
|
||||||
|
return AlchemyResponse(
|
||||||
|
query=list_of_model_records.query,
|
||||||
|
count=list_of_model_records.count,
|
||||||
|
data=[_.get_dict() for _ in list_of_model_records.data],
|
||||||
|
)
|
||||||
|
if not list_of_model_records.count:
|
||||||
|
return AlchemyResponse(
|
||||||
|
query=list_of_model_records.query,
|
||||||
|
count=list_of_model_records.count,
|
||||||
|
data=[],
|
||||||
|
)
|
||||||
|
return AlchemyResponse(
|
||||||
|
query=list_of_model_records.query,
|
||||||
|
count=list_of_model_records.count,
|
||||||
|
data=model.joined_to_dict(list_of_model_records.data),
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def joined_to_dict(cls, joined_list: list):
|
||||||
|
exclude = list(cls.__exclude__fields__) + [
|
||||||
|
"is_confirmed",
|
||||||
|
"deleted",
|
||||||
|
"replication_id",
|
||||||
|
"id",
|
||||||
|
]
|
||||||
|
serialized_list = []
|
||||||
|
new_dict = {}
|
||||||
|
for joined_dict_list in joined_list:
|
||||||
|
for joined_dict in joined_dict_list:
|
||||||
|
return_dict = {}
|
||||||
|
for key, val in joined_dict_list[joined_dict].items():
|
||||||
|
if key not in exclude and "_id" not in key:
|
||||||
|
if val is None:
|
||||||
|
return_dict[key] = None
|
||||||
|
elif key == "active":
|
||||||
|
return_dict[key] = bool(val)
|
||||||
|
elif isinstance(val, int) or isinstance(val, float):
|
||||||
|
return_dict[key] = float(val)
|
||||||
|
elif isinstance(val, bool):
|
||||||
|
return_dict[key] = bool(val)
|
||||||
|
else:
|
||||||
|
return_dict[key] = str(val)
|
||||||
|
if key == "uu_id":
|
||||||
|
return_dict["uu_id"] = str(val)
|
||||||
|
new_dict[joined_dict] = return_dict
|
||||||
|
serialized_list.append(new_dict)
|
||||||
|
return serialized_list
|
||||||
27
api_configs/__init__.py
Normal file
27
api_configs/__init__.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from api_configs.configs import (
|
||||||
|
Config,
|
||||||
|
ApiStatic,
|
||||||
|
Auth,
|
||||||
|
WagDatabase,
|
||||||
|
WagRedis,
|
||||||
|
TestRedis,
|
||||||
|
HagRedis,
|
||||||
|
MongoConfig,
|
||||||
|
TestMongo,
|
||||||
|
RelationAccess,
|
||||||
|
EmailConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Config",
|
||||||
|
"ApiStatic",
|
||||||
|
"Auth",
|
||||||
|
"WagDatabase",
|
||||||
|
"WagRedis",
|
||||||
|
"TestRedis",
|
||||||
|
"HagRedis",
|
||||||
|
"MongoConfig",
|
||||||
|
"TestMongo",
|
||||||
|
"RelationAccess",
|
||||||
|
"EmailConfig",
|
||||||
|
]
|
||||||
154
api_configs/configs.py
Normal file
154
api_configs/configs.py
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
INSECURE_PATHS = [
|
||||||
|
"/",
|
||||||
|
"/metrics",
|
||||||
|
"/openapi.json",
|
||||||
|
"/openapi.json_files",
|
||||||
|
"/docs",
|
||||||
|
"/redoc",
|
||||||
|
"/auth/login",
|
||||||
|
"/favicon.ico",
|
||||||
|
"/internal/isbank/retreive",
|
||||||
|
"/docs/oauth2-redirect",
|
||||||
|
"/hardware/auth/receive/hardware/token",
|
||||||
|
"/hardware/auth/hardware/greetings",
|
||||||
|
"/test/create/test/staff",
|
||||||
|
"/test/create/test/gateway",
|
||||||
|
"/test/create/test/company",
|
||||||
|
"/infos/current_date",
|
||||||
|
"/authentication/login",
|
||||||
|
"/authentication/logout",
|
||||||
|
"/authentication/refresher",
|
||||||
|
"/authentication/refresh",
|
||||||
|
"/authentication/disconnect",
|
||||||
|
"/authentication/create_password",
|
||||||
|
"/authentication/change_password",
|
||||||
|
"/authentication/forgot",
|
||||||
|
"/authentication/avatar",
|
||||||
|
"/api/Contact/Us/current_date",
|
||||||
|
]
|
||||||
|
|
||||||
|
APP_NAME = "evyos-web-api-gateway"
|
||||||
|
TITLE = "WAG API Web Api Gateway"
|
||||||
|
DESCRIPTION = "This api is serves as web api gateway only to evyos web services."
|
||||||
|
APP_URL = "https://www.wag.eys.gen.tr"
|
||||||
|
|
||||||
|
|
||||||
|
class ApiStatic:
|
||||||
|
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
|
||||||
|
FORGOT_LINK = "https://www.evyos.com.tr/auth/create-password/"
|
||||||
|
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
|
||||||
|
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def forgot_link(cls, forgot_key):
|
||||||
|
return cls.FORGOT_LINK + forgot_key
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def blacklist_login(cls, record_id):
|
||||||
|
return cls.BLACKLIST_LINK + record_id
|
||||||
|
|
||||||
|
|
||||||
|
class Auth:
|
||||||
|
ACCESS_EMAIL_EXT = "evyos.com.tr"
|
||||||
|
ACCESS_TOKEN_TAG = "evyos-session-key"
|
||||||
|
REFRESHER_TOKEN_TAG = "eys_token_refresher"
|
||||||
|
SECRET_KEY_72 = (
|
||||||
|
"t3sUAmjTGeTgDc6dAUrB41u2SNg0ZHzj4HTjem95y3fRH1nZXOHIBj163kib6iLybT0gLaxq"
|
||||||
|
)
|
||||||
|
SECRET_KEY_96 = "7ct8VpiwaP1hR2bVSet4dEEAgepuTZUOnO1QxOgKyDqBR2PkqNhcubSrbUUigQKoQA1PBoeeQn5ZCo24pESmVtKs76nA4EKq"
|
||||||
|
SECRET_KEY_144 = (
|
||||||
|
"R2p5Rq6KCr6PCfjFYUeH1keF2VWHFEuqINVjBGGnvRA2m10pYUKqfOtIGBcaj2v5wZmElDndzSHGOS7roQsoTelPSok0"
|
||||||
|
+ "qqMucurMWE0FGexGpFuJkfPEm9tH2OjMOqegvEetpSVywH0W4Kh4"
|
||||||
|
)
|
||||||
|
|
||||||
|
ALGORITHM = "HS256"
|
||||||
|
ACCESS_TOKEN_LENGTH: int = 90
|
||||||
|
REFRESHER_TOKEN_LENGTH: int = 144
|
||||||
|
PASSWORD_EXPIRE_DAY = datetime.timedelta(days=30)
|
||||||
|
TOKEN_EXPIRE_MINUTES_1 = datetime.timedelta(minutes=1)
|
||||||
|
TOKEN_EXPIRE_MINUTES_15 = datetime.timedelta(minutes=15)
|
||||||
|
TOKEN_EXPIRE_MINUTES_30 = datetime.timedelta(minutes=30)
|
||||||
|
TOKEN_EXPIRE_DAY_1 = datetime.timedelta(days=1)
|
||||||
|
TOKEN_EXPIRE_DAY_5 = datetime.timedelta(days=5)
|
||||||
|
TOKEN_EXPIRE_DAY_15 = datetime.timedelta(days=15)
|
||||||
|
TOKEN_EXPIRE_DAY_30 = datetime.timedelta(days=30)
|
||||||
|
|
||||||
|
|
||||||
|
class WagDatabase:
|
||||||
|
SQL: str = "postgresql+psycopg2"
|
||||||
|
USERNAME: str = "berkay_wag_user"
|
||||||
|
PASSWORD: str = "berkay_wag_user_password"
|
||||||
|
HOST: str = "postgres_commercial"
|
||||||
|
PORT = "5432"
|
||||||
|
# HOST: str = "127.0.0.1"
|
||||||
|
# PORT: str = "5434"
|
||||||
|
DATABASE_NAME: str = "wag_database"
|
||||||
|
DATABASE_URL = f"{SQL}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE_NAME}"
|
||||||
|
|
||||||
|
|
||||||
|
class HagRedis:
|
||||||
|
REDIS_HOST: str = "hardware_token_service"
|
||||||
|
REDIS_PASSWORD: str = "hardware_redis_password"
|
||||||
|
REDIS_PORT: int = 6379
|
||||||
|
REDIS_DB: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
class WagRedis:
|
||||||
|
# REDIS_HOST: str = "10.10.2.44"
|
||||||
|
# REDIS_PORT: int = 11112
|
||||||
|
REDIS_HOST = "commercial_memory_service"
|
||||||
|
REDIS_PASSWORD: str = "commercial_redis_password"
|
||||||
|
REDIS_PORT: int = 6379
|
||||||
|
REDIS_DB: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestRedis:
|
||||||
|
REDIS_HOST: str = "localhost"
|
||||||
|
REDIS_PASSWORD: str = "commercial_redis_password"
|
||||||
|
REDIS_PORT: int = 11112
|
||||||
|
REDIS_DB: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestDatabase:
|
||||||
|
SQL: str = "postgresql+psycopg2"
|
||||||
|
USERNAME: str = "berkay_wag_user"
|
||||||
|
PASSWORD: str = "berkay_wag_user_password"
|
||||||
|
HOST: str = "10.10.2.44"
|
||||||
|
PORT: str = "5434"
|
||||||
|
DATABASE_NAME: str = "wag_database"
|
||||||
|
DATABASE_URL = f"{SQL}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DATABASE_NAME}"
|
||||||
|
|
||||||
|
|
||||||
|
class MongoConfig:
|
||||||
|
password = "mongo_password"
|
||||||
|
username = "mongo_user"
|
||||||
|
database_name = "mongo_database"
|
||||||
|
# host = "10.10.2.44"
|
||||||
|
# port = 11122
|
||||||
|
host = "commercial_mongo_service"
|
||||||
|
port = 27017
|
||||||
|
url = f"mongodb://{username}:{password}@{host}:{port}/{database_name}?retryWrites=true&w=majority"
|
||||||
|
|
||||||
|
|
||||||
|
class TestMongo:
|
||||||
|
password = "mongo_password"
|
||||||
|
username = "mongo_user"
|
||||||
|
database_name = "mongo_database"
|
||||||
|
host = "localhost"
|
||||||
|
port = 11110
|
||||||
|
url = f"mongodb://{username}:{password}@{host}:{port}/{database_name}?retryWrites=true&w=majority"
|
||||||
|
|
||||||
|
|
||||||
|
class EmailConfig:
|
||||||
|
EMAIL_HOST: str = "10.10.2.34"
|
||||||
|
EMAIL_USERNAME: str = "karatay@mehmetkaratay.com.tr"
|
||||||
|
EMAIL_PASSWORD: str = "system"
|
||||||
|
|
||||||
|
class RelationAccess:
|
||||||
|
# 77 Evyos superuser of Superuser - 78 all company superuser - 98 Manager of 77 & 78
|
||||||
|
SuperAccessList = ["77", "78", "98"]
|
||||||
|
|
||||||
0
api_events/__init__.py
Normal file
0
api_events/__init__.py
Normal file
218
api_events/events/__init__.py
Normal file
218
api_events/events/__init__.py
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
from api_events.events.identity.people import (
|
||||||
|
PeopleListEventMethod,
|
||||||
|
PeopleCreateEventMethod,
|
||||||
|
PeopleDeleteEventMethod,
|
||||||
|
PeopleUpdateEventMethod,
|
||||||
|
PeoplePatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.address.address import (
|
||||||
|
AddressListEventMethod,
|
||||||
|
AddressCreateEventMethod,
|
||||||
|
AddressUpdateEventMethod,
|
||||||
|
AddressPatchEventMethod,
|
||||||
|
AddressSearchEventMethod,
|
||||||
|
AddressPostCodeCreateEventMethod,
|
||||||
|
AddressPostCodeUpdateEventMethod,
|
||||||
|
AddressPostCodeListEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.authentication import (
|
||||||
|
AuthenticationLoginEventMethod,
|
||||||
|
AuthenticationSelectEventMethod,
|
||||||
|
AuthenticationCheckTokenEventMethod,
|
||||||
|
AuthenticationRefreshEventMethod,
|
||||||
|
AuthenticationChangePasswordEventMethod,
|
||||||
|
AuthenticationCreatePasswordEventMethod,
|
||||||
|
AuthenticationDisconnectUserEventMethod,
|
||||||
|
AuthenticationLogoutEventMethod,
|
||||||
|
AuthenticationRefreshTokenEventMethod,
|
||||||
|
AuthenticationForgotPasswordEventMethod,
|
||||||
|
AuthenticationDownloadAvatarEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.identity.users import (
|
||||||
|
UserListEventMethod,
|
||||||
|
UserCreateEventMethod,
|
||||||
|
UserUpdateEventMethod,
|
||||||
|
UserPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.building.building_build import (
|
||||||
|
BuildListEventMethod,
|
||||||
|
BuildCreateEventMethod,
|
||||||
|
BuildUpdateEventMethod,
|
||||||
|
BuildPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.building.building_build_parts import (
|
||||||
|
BuildingBuildPartsListEventMethod,
|
||||||
|
BuildingBuildPartsCreateEventMethod,
|
||||||
|
BuildingBuildPartsUpdateEventMethod,
|
||||||
|
BuildingBuildPartsPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.company.company_company import (
|
||||||
|
CompanyListEventMethod,
|
||||||
|
CompanyCreateEventMethod,
|
||||||
|
CompanyUpdateEventMethod,
|
||||||
|
CompanyPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.company.company_department import (
|
||||||
|
DepartmentListEventMethod,
|
||||||
|
DepartmentCreateEventMethod,
|
||||||
|
DepartmentUpdateEventMethod,
|
||||||
|
DepartmentPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.company.company_duties import (
|
||||||
|
DutiesListEventMethod,
|
||||||
|
DutiesGetByUUIDEventMethod,
|
||||||
|
DutiesCreateEventMethod,
|
||||||
|
DutiesUpdateEventMethod,
|
||||||
|
DutiesPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.company.company_duty import (
|
||||||
|
DutyListEventMethod,
|
||||||
|
DutyCreateEventMethod,
|
||||||
|
DutyUpdateEventMethod,
|
||||||
|
DutyPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.company.company_employee import (
|
||||||
|
EmployeeListEventMethod,
|
||||||
|
EmployeeCreateEventMethod,
|
||||||
|
EmployeeUpdateEventMethod,
|
||||||
|
EmployeePatchEventMethod,
|
||||||
|
Employee2PeopleEmployEventMethod,
|
||||||
|
Employee2PeopleFireEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.company.company_staff import (
|
||||||
|
StaffListEventMethod,
|
||||||
|
StaffCreateEventMethod,
|
||||||
|
StaffGetByUUIDEventMethod,
|
||||||
|
StaffUpdateEventMethod,
|
||||||
|
StaffPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.building.building_living_spaces import (
|
||||||
|
BuildingLivingSpacesPartsListEventMethod,
|
||||||
|
BuildingLivingSpacesPartsCreateEventMethod,
|
||||||
|
BuildingLivingSpacesPartsUpdateEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.decision_book.decision_book_decision_book import (
|
||||||
|
DecisionBookListEventMethod,
|
||||||
|
DecisionBookCreateEventMethod,
|
||||||
|
DecisionBookUpdateEventMethod,
|
||||||
|
DecisionBookPatchEventMethod,
|
||||||
|
DecisionBookApprovalEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.decision_book.decision_book_decision_book_items import (
|
||||||
|
DecisionBookDecisionBookItemsListEventMethod,
|
||||||
|
DecisionBookDecisionBookItemsCreateEventMethod,
|
||||||
|
DecisionBookDecisionBookItemsUpdateEventMethod,
|
||||||
|
DecisionBookDecisionBookItemsPatchEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.events.events_bind_events import (
|
||||||
|
EventBindOccupantEventMethod,
|
||||||
|
EventBindEmployeeEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.events.events_bind_services import (
|
||||||
|
ServiceBindOccupantEventMethod,
|
||||||
|
ServiceBindEmployeeEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.decision_book.decision_book_decision_book_person import (
|
||||||
|
DecisionBookPersonListEventMethod,
|
||||||
|
DecisionBookPersonAddEventMethod,
|
||||||
|
DecisionBookPersonRemoveEventMethod,
|
||||||
|
DecisionBookPersonAttendEventMethod,
|
||||||
|
DecisionBookPersonAssignOccupantEventMethod,
|
||||||
|
)
|
||||||
|
from api_events.events.decision_book.decision_book_invitations import (
|
||||||
|
BuildDecisionBookInvitationsListEventMethod,
|
||||||
|
BuildDecisionBookInvitationsCreateEventMethod,
|
||||||
|
BuildDecisionBookInvitationsUpdateEventMethod,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"AddressListEventMethod",
|
||||||
|
"AddressCreateEventMethod",
|
||||||
|
"AddressUpdateEventMethod",
|
||||||
|
"AddressPatchEventMethod",
|
||||||
|
"AddressSearchEventMethod",
|
||||||
|
"AddressPostCodeCreateEventMethod",
|
||||||
|
"AddressPostCodeUpdateEventMethod",
|
||||||
|
"AddressPostCodeListEventMethod",
|
||||||
|
"PeopleListEventMethod",
|
||||||
|
"PeopleDeleteEventMethod",
|
||||||
|
"PeopleUpdateEventMethod",
|
||||||
|
"PeoplePatchEventMethod",
|
||||||
|
"PeopleCreateEventMethod",
|
||||||
|
"AuthenticationLoginEventMethod",
|
||||||
|
"AuthenticationSelectEventMethod",
|
||||||
|
"AuthenticationCheckTokenEventMethod",
|
||||||
|
"AuthenticationRefreshEventMethod",
|
||||||
|
"AuthenticationChangePasswordEventMethod",
|
||||||
|
"AuthenticationCreatePasswordEventMethod",
|
||||||
|
"AuthenticationDisconnectUserEventMethod",
|
||||||
|
"AuthenticationLogoutEventMethod",
|
||||||
|
"AuthenticationRefreshTokenEventMethod",
|
||||||
|
"AuthenticationForgotPasswordEventMethod",
|
||||||
|
"AuthenticationDownloadAvatarEventMethod",
|
||||||
|
"UserListEventMethod",
|
||||||
|
"UserCreateEventMethod",
|
||||||
|
"UserUpdateEventMethod",
|
||||||
|
"UserPatchEventMethod",
|
||||||
|
"BuildListEventMethod",
|
||||||
|
"BuildCreateEventMethod",
|
||||||
|
"BuildUpdateEventMethod",
|
||||||
|
"BuildPatchEventMethod",
|
||||||
|
"BuildingBuildPartsListEventMethod",
|
||||||
|
"BuildingBuildPartsCreateEventMethod",
|
||||||
|
"BuildingBuildPartsUpdateEventMethod",
|
||||||
|
"BuildingBuildPartsPatchEventMethod",
|
||||||
|
"BuildingLivingSpacesPartsListEventMethod",
|
||||||
|
"BuildingLivingSpacesPartsCreateEventMethod",
|
||||||
|
"BuildingLivingSpacesPartsUpdateEventMethod",
|
||||||
|
"DecisionBookListEventMethod",
|
||||||
|
"DecisionBookCreateEventMethod",
|
||||||
|
"DecisionBookUpdateEventMethod",
|
||||||
|
"DecisionBookPatchEventMethod",
|
||||||
|
"DecisionBookApprovalEventMethod",
|
||||||
|
"DecisionBookPersonListEventMethod",
|
||||||
|
"DecisionBookPersonAddEventMethod",
|
||||||
|
"DecisionBookPersonRemoveEventMethod",
|
||||||
|
"DecisionBookDecisionBookItemsListEventMethod",
|
||||||
|
"DecisionBookDecisionBookItemsCreateEventMethod",
|
||||||
|
"DecisionBookDecisionBookItemsUpdateEventMethod",
|
||||||
|
"DecisionBookDecisionBookItemsPatchEventMethod",
|
||||||
|
"CompanyPatchEventMethod",
|
||||||
|
"CompanyCreateEventMethod",
|
||||||
|
"CompanyUpdateEventMethod",
|
||||||
|
"CompanyListEventMethod",
|
||||||
|
"DepartmentListEventMethod",
|
||||||
|
"DepartmentCreateEventMethod",
|
||||||
|
"DepartmentUpdateEventMethod",
|
||||||
|
"DepartmentPatchEventMethod",
|
||||||
|
"DutiesListEventMethod",
|
||||||
|
"DutiesGetByUUIDEventMethod",
|
||||||
|
"DutiesCreateEventMethod",
|
||||||
|
"DutiesUpdateEventMethod",
|
||||||
|
"DutiesPatchEventMethod",
|
||||||
|
"DutyListEventMethod",
|
||||||
|
"DutyCreateEventMethod",
|
||||||
|
"DutyUpdateEventMethod",
|
||||||
|
"DutyPatchEventMethod",
|
||||||
|
"EmployeeListEventMethod",
|
||||||
|
"EmployeeCreateEventMethod",
|
||||||
|
"EmployeeUpdateEventMethod",
|
||||||
|
"EmployeePatchEventMethod",
|
||||||
|
"Employee2PeopleEmployEventMethod",
|
||||||
|
"Employee2PeopleFireEventMethod",
|
||||||
|
"StaffListEventMethod",
|
||||||
|
"StaffCreateEventMethod",
|
||||||
|
"StaffGetByUUIDEventMethod",
|
||||||
|
"StaffUpdateEventMethod",
|
||||||
|
"StaffPatchEventMethod",
|
||||||
|
"EventBindOccupantEventMethod",
|
||||||
|
"EventBindEmployeeEventMethod",
|
||||||
|
"ServiceBindOccupantEventMethod",
|
||||||
|
"ServiceBindEmployeeEventMethod",
|
||||||
|
"BuildDecisionBookInvitationsListEventMethod",
|
||||||
|
"BuildDecisionBookInvitationsCreateEventMethod",
|
||||||
|
"BuildDecisionBookInvitationsUpdateEventMethod",
|
||||||
|
"DecisionBookPersonAttendEventMethod",
|
||||||
|
"DecisionBookPersonAssignOccupantEventMethod",
|
||||||
|
]
|
||||||
70
api_events/events/abstract_class.py
Normal file
70
api_events/events/abstract_class.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import typing
|
||||||
|
from abc import ABC
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class ActionsSchema(ABC):
|
||||||
|
|
||||||
|
def __init__(self, endpoint: str = None):
|
||||||
|
self.endpoint = endpoint
|
||||||
|
|
||||||
|
def retrieve_action_from_endpoint(self):
|
||||||
|
from databases import EndpointRestriction
|
||||||
|
|
||||||
|
endpoint_restriction = EndpointRestriction.filter_all(
|
||||||
|
EndpointRestriction.endpoint_name.ilike(f"%{self.endpoint}%")
|
||||||
|
).get(1)
|
||||||
|
if not endpoint_restriction:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"Endpoint {self.endpoint} not found in the database",
|
||||||
|
)
|
||||||
|
return endpoint_restriction
|
||||||
|
|
||||||
|
|
||||||
|
class ActionsSchemaFactory:
|
||||||
|
|
||||||
|
def __init__(self, action: ActionsSchema):
|
||||||
|
self.action = action
|
||||||
|
try:
|
||||||
|
self.action_match = self.action.retrieve_action_from_endpoint()
|
||||||
|
except Exception as e:
|
||||||
|
err = e
|
||||||
|
self.action_match = None
|
||||||
|
|
||||||
|
|
||||||
|
class MethodToEvent(ABC, ActionsSchemaFactory):
|
||||||
|
|
||||||
|
event_type: str = None
|
||||||
|
event_description: str = ""
|
||||||
|
event_category: str = ""
|
||||||
|
|
||||||
|
__event_keys__: dict = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def call_event_method(cls, method_uu_id: str, *args, **kwargs):
|
||||||
|
function_name = cls.__event_keys__.get(method_uu_id)
|
||||||
|
return getattr(cls, function_name)(*args, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def ban_token_objects(
|
||||||
|
cls,
|
||||||
|
token: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
ban_list: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
|
||||||
|
if token.user_type == ban_list.user_type:
|
||||||
|
if isinstance(token, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
detail="No employee can reach this event. An notification is send to admin about event registration",
|
||||||
|
)
|
||||||
|
if isinstance(token, OccupantTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
detail="No occupant can reach this event. An notification is send to admin about event registration",
|
||||||
|
)
|
||||||
0
api_events/events/account/__init__.py
Normal file
0
api_events/events/account/__init__.py
Normal file
4
api_events/events/account/account.py
Normal file
4
api_events/events/account/account.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
class ApiEvents(MethodToEvent): ...
|
||||||
0
api_events/events/address/__init__.py
Normal file
0
api_events/events/address/__init__.py
Normal file
372
api_events/events/address/address.py
Normal file
372
api_events/events/address/address.py
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
AddressPostcode,
|
||||||
|
Addresses,
|
||||||
|
RelationshipEmployee2PostCode,
|
||||||
|
AddressStreet,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from api_validations.validations_request import (
|
||||||
|
ListOptions,
|
||||||
|
InsertAddress,
|
||||||
|
InsertPostCode,
|
||||||
|
SearchAddress
|
||||||
|
)
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class AddressListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"9c251d7d-da70-4d63-a72c-e69c26270442": "address_list_super_user", # 1
|
||||||
|
"52afe375-dd95-4f4b-aaa2-4ec61bc6de52": "address_list_employee",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def address_list_super_user(cls, list_options: ListOptions, token_dict):
|
||||||
|
from sqlalchemy import select
|
||||||
|
|
||||||
|
post_code_list = RelationshipEmployee2PostCode.filter_active(
|
||||||
|
RelationshipEmployee2PostCode.company_id
|
||||||
|
== token_dict.selected_company.company_id,
|
||||||
|
).data
|
||||||
|
post_code_id_list = [post_code.member_id for post_code in post_code_list]
|
||||||
|
if not post_code_id_list:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="User has no post code registered. User can not list addresses.",
|
||||||
|
)
|
||||||
|
|
||||||
|
get_street_ids = AddressPostcode.session.execute(
|
||||||
|
select(AddressPostcode.street_id).where(
|
||||||
|
AddressPostcode.id.in_(post_code_id_list)
|
||||||
|
)
|
||||||
|
).all()
|
||||||
|
Addresses.pre_query = Addresses.filter_active(
|
||||||
|
Addresses.street_id.in_(*get_street_ids) if get_street_ids else None
|
||||||
|
).query
|
||||||
|
Addresses.filter_attr = list_options
|
||||||
|
records = Addresses.filter_active(
|
||||||
|
*Addresses.get_smart_query(list_options.query)
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def address_list_employee(cls, list_options: ListOptions, token_dict):
|
||||||
|
Addresses.filter_attr = list_options
|
||||||
|
records = Addresses.list_via_employee(
|
||||||
|
token_dict=token_dict,
|
||||||
|
filter_expr=Addresses.get_smart_query(list_options.query),
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"ffdc445f-da10-4ce4-9531-d2bdb9a198ae": "create_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_address(cls, data: InsertAddress, token_dict):
|
||||||
|
post_code = AddressPostcode.find_one(uu_id=data.post_code_uu_id)
|
||||||
|
if not post_code:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="Post code not found. User can not create address without post code.",
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
data_dict["street_id"] = post_code.street_id
|
||||||
|
del data_dict["post_code_uu_id"]
|
||||||
|
|
||||||
|
address = Addresses.find_or_create(**data_dict)
|
||||||
|
if not address.is_found:
|
||||||
|
RelationshipEmployee2PostCode.find_or_create(
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
member_id=post_code.id,
|
||||||
|
company_id=token_dict.selected_company.company_id,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Address record",
|
||||||
|
"data": address.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressSearchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SEARCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e0ac1269-e9a7-4806-9962-219ac224b0d0": "search_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def search_address(cls, data: SearchAddress, token_dict):
|
||||||
|
import database_sql_models
|
||||||
|
from time import perf_counter
|
||||||
|
|
||||||
|
st = perf_counter()
|
||||||
|
|
||||||
|
pre_query_first = AddressStreet.search_address_text(search_text=data.search)
|
||||||
|
query, schemas, new_data_list = (
|
||||||
|
pre_query_first.get("query"),
|
||||||
|
pre_query_first.get("schema"),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
filter_list = data.list_options.dump()
|
||||||
|
filter_table = AddressStreet
|
||||||
|
if filter_list.get("order_field") not in schemas:
|
||||||
|
filter_list["order_field"] = "uu_id"
|
||||||
|
else:
|
||||||
|
filter_table = getattr(
|
||||||
|
database_sql_models, str(filter_list.get("order_field")).split(".")[0]
|
||||||
|
)
|
||||||
|
filter_list["order_field"] = str(filter_list.get("order_field")).split(".")[
|
||||||
|
1
|
||||||
|
]
|
||||||
|
|
||||||
|
order = (
|
||||||
|
getattr(filter_table, filter_list.get("order_field")).desc()
|
||||||
|
if str(filter_list.get("order_type"))[0] == "d"
|
||||||
|
else getattr(filter_table, filter_list.get("order_field")).asc()
|
||||||
|
)
|
||||||
|
|
||||||
|
query = (
|
||||||
|
query.order_by(order)
|
||||||
|
.limit(int(filter_list.get("size")))
|
||||||
|
.offset(int((filter_list.get("page")) - 1) * int(filter_list.get("size")))
|
||||||
|
.populate_existing()
|
||||||
|
)
|
||||||
|
|
||||||
|
records = list(query.all())
|
||||||
|
print(perf_counter() - st)
|
||||||
|
|
||||||
|
for item in records:
|
||||||
|
new_data_dict = {}
|
||||||
|
for index, schema in enumerate(schemas):
|
||||||
|
new_data_dict[schema] = str(item[index])
|
||||||
|
if "uu_id" in str(item[index]):
|
||||||
|
new_data_dict[schema] = str(new_data_dict.get(schema))
|
||||||
|
new_data_list.append(new_data_dict)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"pagination": filter_list,
|
||||||
|
"count": len(new_data_list),
|
||||||
|
"data": new_data_list,
|
||||||
|
"message": "Search Address records",
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27": "update_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_address(cls, address_uu_id: str, data: InsertAddress, token_dict):
|
||||||
|
address = Addresses.find_one_or_abort(uu_id=address_uu_id)
|
||||||
|
post_code = RelationshipEmployee2PostCode.postcode.find_one(
|
||||||
|
member_id=address.post_code_id
|
||||||
|
)
|
||||||
|
if not post_code:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="Post code not found. User can not update address without post code.",
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
data_dict["post_code_id"] = post_code.id
|
||||||
|
del data_dict["post_code_uu_id"]
|
||||||
|
|
||||||
|
updated_address = address.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Address record",
|
||||||
|
"data": updated_address.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"b0e55a7e-af81-468c-b46c-a6b3a6b68d5d": "patch_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def patch_address(cls, address_uu_id: str, data: InsertAddress, token_dict):
|
||||||
|
address = Addresses.find_one_or_abort(uu_id=address_uu_id)
|
||||||
|
post_code = RelationshipEmployee2PostCode.postcode.find_one(
|
||||||
|
member_id=address.post_code_id
|
||||||
|
)
|
||||||
|
if not post_code:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="Post code not found. User can not patch address without post code.",
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
data_dict["post_code_id"] = post_code.id
|
||||||
|
del data_dict["post_code_uu_id"]
|
||||||
|
|
||||||
|
patched_address = address.patch(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Address record",
|
||||||
|
"data": patched_address.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressPostCodeCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"6f1406ac-577d-4f2c-8077-71fff2252c5f": "create_post_code_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_post_code_address(cls, data: InsertPostCode, token_dict):
|
||||||
|
data_dump = data.excluded_dump()
|
||||||
|
street = AddressStreet.find_one(uu_id=data.street_uu_id)
|
||||||
|
if not street:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="Street not found. User can not create post code without street.",
|
||||||
|
)
|
||||||
|
data_dump["street_id"] = street.id
|
||||||
|
data_dump["postcode"] = data.post_code
|
||||||
|
del data_dump["street_uu_id"], data_dump["post_code"]
|
||||||
|
|
||||||
|
post_code = AddressPostcode.find_or_create(**data_dump)
|
||||||
|
if not post_code.is_found:
|
||||||
|
AddressPostcode.__many__table__.find_or_create(
|
||||||
|
member_id=post_code.id,
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
company_id=token_dict.selected_company.company_id,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Post Code record",
|
||||||
|
"data": post_code.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressPostCodeUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"df18e489-a63c-477f-984c-aa52d30640ad": "update_post_code_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_post_code_address(
|
||||||
|
cls, post_code_uu_id: str, data: InsertPostCode, token_dict
|
||||||
|
):
|
||||||
|
post_code = AddressPostcode.find_one_or_abort(uu_id=post_code_uu_id)
|
||||||
|
street = AddressStreet.find_one(uu_id=data.street_uu_id)
|
||||||
|
if not street:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="Street not found. User can not update post code without street.",
|
||||||
|
)
|
||||||
|
|
||||||
|
updated_post_code = post_code.update(**data.excluded_dump())
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Post Code record",
|
||||||
|
"data": updated_post_code.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressPostCodeListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"88d37b78-1ac4-4513-9d25-090ac3a24f31": "list_post_code_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def list_post_code_address(cls, list_options: ListOptions, token_dict):
|
||||||
|
post_code_list = AddressPostcode.__many__table__.filter_active(
|
||||||
|
AddressPostcode.__many__table__.company_id
|
||||||
|
== token_dict.selected_company.company_id
|
||||||
|
).data
|
||||||
|
if not post_code_list:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="User has no post code registered or not yet any post code created.",
|
||||||
|
)
|
||||||
|
|
||||||
|
AddressPostcode.pre_query = AddressPostcode.filter_active(
|
||||||
|
AddressPostcode.id.in_(
|
||||||
|
[post_code.member_id for post_code in post_code_list]
|
||||||
|
)
|
||||||
|
).query
|
||||||
|
AddressPostcode.filter_attr = list_options
|
||||||
|
records = AddressPostcode.filter_active(
|
||||||
|
*Addresses.get_smart_query(list_options.query)
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AddressListEventMethod = AddressListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/address/list")
|
||||||
|
)
|
||||||
|
AddressCreateEventMethod = AddressCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/address/create")
|
||||||
|
)
|
||||||
|
AddressUpdateEventMethod = AddressUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/address/update")
|
||||||
|
)
|
||||||
|
AddressPatchEventMethod = AddressPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/address/patch")
|
||||||
|
)
|
||||||
|
AddressPostCodeCreateEventMethod = AddressPostCodeCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/postcode/create")
|
||||||
|
)
|
||||||
|
AddressPostCodeUpdateEventMethod = AddressPostCodeUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/postcode/update")
|
||||||
|
)
|
||||||
|
AddressPostCodeListEventMethod = AddressPostCodeListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/postcode/list")
|
||||||
|
)
|
||||||
|
AddressSearchEventMethod = AddressSearchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/address/search")
|
||||||
|
)
|
||||||
0
api_events/events/application/__init__.py
Normal file
0
api_events/events/application/__init__.py
Normal file
5
api_events/events/application/api.py
Normal file
5
api_events/events/application/api.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookEvents(MethodToEvent): ...
|
||||||
5
api_events/events/application/application.py
Normal file
5
api_events/events/application/application.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationEvents(MethodToEvent): ...
|
||||||
682
api_events/events/application/authentication.py
Normal file
682
api_events/events/application/authentication.py
Normal file
@@ -0,0 +1,682 @@
|
|||||||
|
import json
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.requests import Request
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Companies,
|
||||||
|
Staff,
|
||||||
|
Duties,
|
||||||
|
Departments,
|
||||||
|
Employees,
|
||||||
|
BuildLivingSpace,
|
||||||
|
BuildParts,
|
||||||
|
Build,
|
||||||
|
RelationshipEmployee2PostCode,
|
||||||
|
Duty,
|
||||||
|
Event2Occupant,
|
||||||
|
Event2Employee,
|
||||||
|
Users,
|
||||||
|
UsersTokens,
|
||||||
|
OccupantTypes,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_services import (
|
||||||
|
redis_cli,
|
||||||
|
send_email,
|
||||||
|
get_object_via_access_key,
|
||||||
|
get_object_via_user_uu_id,
|
||||||
|
save_access_token_to_redis,
|
||||||
|
update_selected_to_redis,
|
||||||
|
password_is_changed_template,
|
||||||
|
change_your_password_template,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_library.date_time_actions.date_functions import DateTimeLocal
|
||||||
|
from api_configs import ApiStatic, Auth
|
||||||
|
from databases.no_sql_models.login_handlers import load_user_with_erp_details
|
||||||
|
|
||||||
|
from api_validations.validations_request import (
|
||||||
|
Login,
|
||||||
|
Logout,
|
||||||
|
ChangePassword,
|
||||||
|
Remember,
|
||||||
|
Forgot,
|
||||||
|
CreatePassword,
|
||||||
|
OccupantSelection,
|
||||||
|
EmployeeSelection,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationLoginEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "LOGIN"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_login_with_domain_and_creds(
|
||||||
|
cls,
|
||||||
|
data: Login,
|
||||||
|
request,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
access_dict = Users.login_user_with_credentials(data=data, request=request)
|
||||||
|
found_user = access_dict.get("user", None)
|
||||||
|
if not found_user:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "User is logged in successfully",
|
||||||
|
"access_token": access_dict.get("access_token"),
|
||||||
|
"refresh_token": access_dict.get("refresher_token"),
|
||||||
|
"access_object": access_dict.get("access_object"),
|
||||||
|
"user": found_user.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationSelectEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_select_company_or_occupant_type(
|
||||||
|
cls,
|
||||||
|
request: Request,
|
||||||
|
data: typing.Union[EmployeeSelection, OccupantSelection],
|
||||||
|
token_dict: dict = None,
|
||||||
|
):
|
||||||
|
from api_objects import OccupantToken, CompanyToken
|
||||||
|
|
||||||
|
token_user = get_object_via_access_key(request=request)
|
||||||
|
if token_user.user_type == 1:
|
||||||
|
if data.company_uu_id not in token_user.companies_uu_id_list:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Company is not found in users company list",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
if selected_company := Companies.find_one(uu_id=data.company_uu_id):
|
||||||
|
department_ids = [
|
||||||
|
department.id
|
||||||
|
for department in Departments.filter_by_active(
|
||||||
|
company_id=selected_company.id
|
||||||
|
).data
|
||||||
|
]
|
||||||
|
duties_ids = [
|
||||||
|
duties.id
|
||||||
|
for duties in Duties.filter_active(
|
||||||
|
Duties.company_id == selected_company.id,
|
||||||
|
Duties.department_id.in_(department_ids),
|
||||||
|
).data
|
||||||
|
]
|
||||||
|
staff_ids = [
|
||||||
|
staff.id
|
||||||
|
for staff in Staff.filter_active(
|
||||||
|
Staff.duties_id.in_(duties_ids)
|
||||||
|
).data
|
||||||
|
]
|
||||||
|
employee = Employees.filter_active(
|
||||||
|
Employees.people_id == token_user.person_id,
|
||||||
|
Employees.staff_id.in_(staff_ids),
|
||||||
|
).data[0]
|
||||||
|
|
||||||
|
reachable_event_list_id, reachable_event_list_uu_id = (
|
||||||
|
Event2Employee.get_event_id_by_employee_id(employee_id=employee.id)
|
||||||
|
)
|
||||||
|
staff = Staff.find_one(id=employee.staff_id)
|
||||||
|
duties = Duties.find_one(id=staff.duties_id)
|
||||||
|
department = Departments.find_one(id=duties.department_id)
|
||||||
|
bulk_id = Duty.find_one(duty_code="BULK")
|
||||||
|
bulk_duty_id = Duties.find_one(
|
||||||
|
company_id=selected_company.id, duties_id=bulk_id.id
|
||||||
|
)
|
||||||
|
update_selected_to_redis(
|
||||||
|
request=request,
|
||||||
|
add_payload=CompanyToken(
|
||||||
|
company_uu_id=selected_company.uu_id.__str__(),
|
||||||
|
company_id=selected_company.id,
|
||||||
|
department_id=department.id,
|
||||||
|
department_uu_id=department.uu_id.__str__(),
|
||||||
|
duty_id=duties.id,
|
||||||
|
duty_uu_id=duties.uu_id.__str__(),
|
||||||
|
bulk_duties_id=bulk_duty_id.id,
|
||||||
|
staff_id=staff.id,
|
||||||
|
staff_uu_id=staff.uu_id.__str__(),
|
||||||
|
employee_id=employee.id,
|
||||||
|
employee_uu_id=employee.uu_id.__str__(),
|
||||||
|
reachable_event_list_id=reachable_event_list_id,
|
||||||
|
reachable_event_list_uu_id=reachable_event_list_uu_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Company is selected successfully",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
elif token_user.user_type == 2:
|
||||||
|
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
|
||||||
|
if not occupant_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Occupant Type is not found",
|
||||||
|
)
|
||||||
|
build_part = BuildParts.find_one(uu_id=data.build_part_uu_id)
|
||||||
|
if not build_part:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Build Part is not found",
|
||||||
|
)
|
||||||
|
build = Build.find_one(id=build_part.build_id)
|
||||||
|
related_company = RelationshipEmployee2Build.find_one(member_id=build.id)
|
||||||
|
company_related = Companies.find_one(id=related_company.company_id)
|
||||||
|
responsible_employee = Employees.find_one(id=related_company.employee_id)
|
||||||
|
if selected_occupant_type := BuildLivingSpace.find_one(
|
||||||
|
occupant_type=occupant_type.id,
|
||||||
|
person_id=token_user.person_id,
|
||||||
|
build_parts_id=build_part.id,
|
||||||
|
):
|
||||||
|
reachable_event_list_id, reachable_event_list_uu_id = (
|
||||||
|
Event2Occupant.get_event_id_by_build_living_space_id(
|
||||||
|
build_living_space_id=selected_occupant_type.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
update_selected_to_redis(
|
||||||
|
request=request,
|
||||||
|
add_payload=OccupantToken(
|
||||||
|
living_space_id=selected_occupant_type.id,
|
||||||
|
living_space_uu_id=selected_occupant_type.uu_id.__str__(),
|
||||||
|
occupant_type_id=occupant_type.id,
|
||||||
|
occupant_type_uu_id=occupant_type.uu_id.__str__(),
|
||||||
|
occupant_type=occupant_type.occupant_type,
|
||||||
|
build_id=build.id,
|
||||||
|
build_uuid=build.uu_id.__str__(),
|
||||||
|
build_part_id=build_part.id,
|
||||||
|
build_part_uuid=build_part.uu_id.__str__(),
|
||||||
|
responsible_employee_id=responsible_employee.id,
|
||||||
|
responsible_employee_uuid=responsible_employee.uu_id.__str__(),
|
||||||
|
responsible_company_id=company_related.id,
|
||||||
|
responsible_company_uuid=company_related.uu_id.__str__(),
|
||||||
|
reachable_event_list_id=reachable_event_list_id,
|
||||||
|
reachable_event_list_uu_id=reachable_event_list_uu_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Occupant is selected successfully",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data provided"},
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationCheckTokenEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CHECK"
|
||||||
|
__event_keys__ = {
|
||||||
|
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_login_with_domain_and_creds(
|
||||||
|
cls, request, token_dict: dict = None
|
||||||
|
):
|
||||||
|
if get_object_via_access_key(request=request):
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Access Token is valid"},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Access Token is NOT valid"},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationRefreshEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "REFRESH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_refresh_user_info(cls, request, token_dict: dict = None):
|
||||||
|
access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
|
||||||
|
if token_user := get_object_via_access_key(request=request):
|
||||||
|
if found_user := Users.find_one(uu_id=token_user.get("uu_id")):
|
||||||
|
user_token = UsersTokens.find_one(
|
||||||
|
domain=found_user.domain_name,
|
||||||
|
user_id=found_user.id,
|
||||||
|
token_type="RememberMe",
|
||||||
|
)
|
||||||
|
access_dict = {
|
||||||
|
"access_token": access_token,
|
||||||
|
"refresh_token": getattr(user_token, "token", None),
|
||||||
|
}
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "User is logged in successfully via refresh token",
|
||||||
|
"data": load_user_with_erp_details(found_user, access_dict),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": {}},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationChangePasswordEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_change_password(
|
||||||
|
cls, request, data: ChangePassword, token_dict: dict = None
|
||||||
|
):
|
||||||
|
token_user = get_object_via_access_key(request=request)
|
||||||
|
if token_user.user_type == 1:
|
||||||
|
if found_user := Users.find_one(uu_id=token_user.uu_id):
|
||||||
|
if found_user.check_password(data.old_password):
|
||||||
|
found_user.set_password(data.new_password)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Password is changed successfully",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Old password is not correct",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data"},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationCreatePasswordEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_create_password(
|
||||||
|
cls, request, data: CreatePassword, token_dict: dict = None
|
||||||
|
):
|
||||||
|
|
||||||
|
if not data.re_password == data.password:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
|
||||||
|
)
|
||||||
|
if found_user := Users.find_one(password_token=data.password_token):
|
||||||
|
found_user.create_password(password=data.password)
|
||||||
|
found_user.password_token = None
|
||||||
|
found_user.save()
|
||||||
|
send_email_completed = send_email(
|
||||||
|
subject=f"Dear {found_user.user_tag}, your password has been changed.",
|
||||||
|
receivers=[str(found_user.email)],
|
||||||
|
html=password_is_changed_template(user_name=found_user.user_tag),
|
||||||
|
)
|
||||||
|
if not send_email_completed:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="Email can not be sent. Try again later"
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Password is created successfully",
|
||||||
|
"data": found_user.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Record not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationDisconnectUserEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_disconnect_user(
|
||||||
|
cls, request: Request, data: Logout, token_dict: dict = None
|
||||||
|
):
|
||||||
|
|
||||||
|
if token_user := get_object_via_access_key(request=request):
|
||||||
|
found_user = Users.find_one(uu_id=token_user.get("uu_id"))
|
||||||
|
if not found_user:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Invalid data",
|
||||||
|
"data": None,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id):
|
||||||
|
for key in already_tokens:
|
||||||
|
token_user = json.loads(redis_cli.get(key) or {})
|
||||||
|
redis_cli.delete(key)
|
||||||
|
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
|
||||||
|
selected_user.remove_refresher_token(
|
||||||
|
domain=data.domain, disconnect=True
|
||||||
|
)
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=found_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key=token_user.get("access_input"),
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=datetime.datetime.utcnow().__str__(),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "All sessions are disconnected",
|
||||||
|
"data": token_user,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": None},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationLogoutEventMethods(MethodToEvent):
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_logout_user(
|
||||||
|
cls, request: Request, data: Logout, token_dict: dict = None
|
||||||
|
):
|
||||||
|
token_user = None
|
||||||
|
if already_tokens := get_object_via_access_key(request=request):
|
||||||
|
for key in already_tokens:
|
||||||
|
token_user = json.loads(redis_cli.get(key) or {})
|
||||||
|
if token_user.get("domain") == data.domain:
|
||||||
|
redis_cli.delete(key)
|
||||||
|
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
|
||||||
|
selected_user.remove_refresher_token(domain=data.domain)
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=selected_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key=token_user.get("access_input"),
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=datetime.datetime.utcnow().__str__(),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Session is logged out",
|
||||||
|
"data": token_user,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Logout is not successfully completed",
|
||||||
|
"data": None,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationRefreshTokenEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_refresher_token(
|
||||||
|
cls, request: Request, data: Remember, token_dict: dict = None
|
||||||
|
):
|
||||||
|
token_refresher = UsersTokens.find_one(
|
||||||
|
token=data.refresh_token, domain=data.domain
|
||||||
|
)
|
||||||
|
if not token_refresher:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": {}},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
if found_user := Users.find_one(id=token_refresher.user_id):
|
||||||
|
found_user: Users = found_user
|
||||||
|
access_key = save_access_token_to_redis(
|
||||||
|
request=request, found_user=found_user, domain=data.domain
|
||||||
|
)
|
||||||
|
found_user.last_agent = request.headers.get("User-Agent", None)
|
||||||
|
found_user.last_platform = request.headers.get("Origin", None)
|
||||||
|
found_user.last_remote_addr = getattr(
|
||||||
|
request, "remote_addr", None
|
||||||
|
) or request.headers.get("X-Forwarded-For", None)
|
||||||
|
found_user.last_seen = str(DateTimeLocal.now())
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=found_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key="via_refresher",
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=datetime.datetime.utcnow().__str__(),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "User is logged in successfully via refresher token",
|
||||||
|
"data": load_user_with_erp_details(
|
||||||
|
found_user,
|
||||||
|
{
|
||||||
|
"access_token": access_key,
|
||||||
|
"refresh_token": data.refresh_token,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": {}},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationForgotPasswordEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_forgot_password(
|
||||||
|
cls, request: Request, data: Forgot, token_dict: dict = None
|
||||||
|
):
|
||||||
|
found_user: Users = Users.check_user_exits(
|
||||||
|
access_key=data.access_key, domain=data.domain
|
||||||
|
)
|
||||||
|
forgot_key = save_access_token_to_redis(
|
||||||
|
request=request, found_user=found_user, domain=data.domain
|
||||||
|
)
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=found_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key=data.access_key,
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=str(DateTimeLocal.now()),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
|
||||||
|
send_email_completed = send_email(
|
||||||
|
subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.",
|
||||||
|
receivers=[str(found_user.email)],
|
||||||
|
html=change_your_password_template(
|
||||||
|
user_name=found_user.user_tag, forgot_link=forgot_link
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if not send_email_completed:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="Email can not be sent. Try again later"
|
||||||
|
)
|
||||||
|
|
||||||
|
found_user.password_token = forgot_key
|
||||||
|
found_user.password_token_is_valid = str(DateTimeLocal.shift(days=1))
|
||||||
|
found_user.save()
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Password is change link is sent to your email or phone",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_download_avatar(
|
||||||
|
cls, request: Request, data: Forgot, token_dict: dict = None
|
||||||
|
):
|
||||||
|
found_user = Users.check_user_exits(
|
||||||
|
access_key=data.access_key, domain=data.domain
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Avatar and profile is shared via user credentials",
|
||||||
|
"data": {
|
||||||
|
"last_seen": str(found_user.last_seen),
|
||||||
|
"avatar": found_user.avatar,
|
||||||
|
"remember_me": found_user.remember_me,
|
||||||
|
"expiry_ends": str(found_user.expiry_ends),
|
||||||
|
"expired_str": str(
|
||||||
|
DateTimeLocal.now()
|
||||||
|
- DateTimeLocal.get(str(found_user.expiry_ends))
|
||||||
|
),
|
||||||
|
"expired_int": int(
|
||||||
|
(
|
||||||
|
DateTimeLocal.now()
|
||||||
|
- DateTimeLocal.get(str(found_user.expiry_ends))
|
||||||
|
).days
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AuthenticationLoginEventMethod = AuthenticationLoginEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/login")
|
||||||
|
)
|
||||||
|
AuthenticationSelectEventMethod = AuthenticationSelectEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/select")
|
||||||
|
)
|
||||||
|
AuthenticationCheckTokenEventMethod = AuthenticationCheckTokenEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/valid")
|
||||||
|
)
|
||||||
|
AuthenticationRefreshEventMethod = AuthenticationRefreshEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/refresh")
|
||||||
|
)
|
||||||
|
AuthenticationChangePasswordEventMethod = AuthenticationChangePasswordEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/change_password")
|
||||||
|
)
|
||||||
|
AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/create_password")
|
||||||
|
)
|
||||||
|
AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/disconnect")
|
||||||
|
)
|
||||||
|
AuthenticationLogoutEventMethod = AuthenticationLogoutEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/logout")
|
||||||
|
)
|
||||||
|
AuthenticationRefreshTokenEventMethod = AuthenticationRefreshTokenEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/refresher")
|
||||||
|
)
|
||||||
|
AuthenticationForgotPasswordEventMethod = AuthenticationForgotPasswordEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/forgot")
|
||||||
|
)
|
||||||
|
AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/avatar")
|
||||||
|
)
|
||||||
5
api_events/events/application/rules.py
Normal file
5
api_events/events/application/rules.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class RulesEvents(MethodToEvent): ...
|
||||||
680
api_events/events/authentication.py
Normal file
680
api_events/events/authentication.py
Normal file
@@ -0,0 +1,680 @@
|
|||||||
|
import json
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.requests import Request
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from databases import (
|
||||||
|
Companies,
|
||||||
|
Staff,
|
||||||
|
Duties,
|
||||||
|
Departments,
|
||||||
|
Employees,
|
||||||
|
BuildLivingSpace,
|
||||||
|
BuildParts,
|
||||||
|
Build,
|
||||||
|
RelationshipEmployee2Build,
|
||||||
|
Event2Occupant,
|
||||||
|
Event2Employee,
|
||||||
|
Users,
|
||||||
|
UsersTokens,
|
||||||
|
OccupantTypes,
|
||||||
|
Duty,
|
||||||
|
)
|
||||||
|
from databases.no_sql_models.login_handlers import load_user_with_erp_details
|
||||||
|
|
||||||
|
from api_validations.validations_request import (
|
||||||
|
Login,
|
||||||
|
Logout,
|
||||||
|
ChangePassword,
|
||||||
|
Remember,
|
||||||
|
Forgot,
|
||||||
|
CreatePassword,
|
||||||
|
OccupantSelection,
|
||||||
|
EmployeeSelection,
|
||||||
|
)
|
||||||
|
from api_services import (
|
||||||
|
password_is_changed_template,
|
||||||
|
change_your_password_template,
|
||||||
|
save_access_token_to_redis,
|
||||||
|
update_selected_to_redis,
|
||||||
|
get_object_via_access_key,
|
||||||
|
get_object_via_user_uu_id,
|
||||||
|
redis_cli,
|
||||||
|
send_email,
|
||||||
|
)
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
from api_configs import ApiStatic, Auth
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_library.date_time_actions.date_functions import DateTimeLocal
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationLoginEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "LOGIN"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e672846d-cc45-4d97-85d5-6f96747fac67": "authentication_login_with_domain_and_creds",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_login_with_domain_and_creds(
|
||||||
|
cls,
|
||||||
|
data: Login,
|
||||||
|
request,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
access_dict = Users.login_user_with_credentials(data=data, request=request)
|
||||||
|
found_user = access_dict.get("user", None)
|
||||||
|
if not found_user:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "User is logged in successfully",
|
||||||
|
"access_token": access_dict.get("access_token"),
|
||||||
|
"refresh_token": access_dict.get("refresher_token"),
|
||||||
|
"access_object": access_dict.get("access_object"),
|
||||||
|
"user": found_user.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationSelectEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"cee96b9b-8487-4e9f-aaed-2e8c79687bf9": "authentication_select_company_or_occupant_type",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_select_company_or_occupant_type(
|
||||||
|
cls,
|
||||||
|
request: Request,
|
||||||
|
data: typing.Union[EmployeeSelection, OccupantSelection],
|
||||||
|
token_dict: dict = None,
|
||||||
|
):
|
||||||
|
from api_objects.auth.token_objects import OccupantToken, CompanyToken
|
||||||
|
|
||||||
|
token_user = get_object_via_access_key(request=request)
|
||||||
|
if token_user.user_type == 1:
|
||||||
|
if data.company_uu_id not in token_user.companies_uu_id_list:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Company is not found in users company list",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
if selected_company := Companies.find_one(uu_id=data.company_uu_id):
|
||||||
|
department_ids = [
|
||||||
|
department.id
|
||||||
|
for department in Departments.filter_by_active(
|
||||||
|
company_id=selected_company.id
|
||||||
|
).data
|
||||||
|
]
|
||||||
|
duties_ids = [
|
||||||
|
duties.id
|
||||||
|
for duties in Duties.filter_active(
|
||||||
|
Duties.company_id == selected_company.id,
|
||||||
|
Duties.department_id.in_(department_ids),
|
||||||
|
).data
|
||||||
|
]
|
||||||
|
staff_ids = [
|
||||||
|
staff.id
|
||||||
|
for staff in Staff.filter_active(
|
||||||
|
Staff.duties_id.in_(duties_ids)
|
||||||
|
).data
|
||||||
|
]
|
||||||
|
employee = Employees.filter_active(
|
||||||
|
Employees.people_id == token_user.person_id,
|
||||||
|
Employees.staff_id.in_(staff_ids),
|
||||||
|
).data[0]
|
||||||
|
|
||||||
|
reachable_event_list_id, reachable_event_list_uu_id = (
|
||||||
|
Event2Employee.get_event_id_by_employee_id(employee_id=employee.id)
|
||||||
|
)
|
||||||
|
staff = Staff.find_one(id=employee.staff_id)
|
||||||
|
duties = Duties.find_one(id=staff.duties_id)
|
||||||
|
department = Departments.find_one(id=duties.department_id)
|
||||||
|
bulk_id = Duty.find_one(duty_code="BULK")
|
||||||
|
bulk_duty_id = Duties.find_one(
|
||||||
|
company_id=selected_company.id, duties_id=bulk_id.id
|
||||||
|
)
|
||||||
|
update_selected_to_redis(
|
||||||
|
request=request,
|
||||||
|
add_payload=CompanyToken(
|
||||||
|
company_uu_id=selected_company.uu_id.__str__(),
|
||||||
|
company_id=selected_company.id,
|
||||||
|
department_id=department.id,
|
||||||
|
department_uu_id=department.uu_id.__str__(),
|
||||||
|
duty_id=duties.id,
|
||||||
|
duty_uu_id=duties.uu_id.__str__(),
|
||||||
|
bulk_duties_id=bulk_duty_id.id,
|
||||||
|
staff_id=staff.id,
|
||||||
|
staff_uu_id=staff.uu_id.__str__(),
|
||||||
|
employee_id=employee.id,
|
||||||
|
employee_uu_id=employee.uu_id.__str__(),
|
||||||
|
reachable_event_list_id=reachable_event_list_id,
|
||||||
|
reachable_event_list_uu_id=reachable_event_list_uu_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Company is selected successfully",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
elif token_user.user_type == 2:
|
||||||
|
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
|
||||||
|
if not occupant_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Occupant Type is not found",
|
||||||
|
)
|
||||||
|
build_part = BuildParts.find_one(uu_id=data.build_part_uu_id)
|
||||||
|
if not build_part:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Build Part is not found",
|
||||||
|
)
|
||||||
|
build = Build.find_one(id=build_part.build_id)
|
||||||
|
related_company = RelationshipEmployee2Build.find_one(member_id=build.id)
|
||||||
|
company_related = Companies.find_one(id=related_company.company_id)
|
||||||
|
responsible_employee = Employees.find_one(id=related_company.employee_id)
|
||||||
|
if selected_occupant_type := BuildLivingSpace.find_one(
|
||||||
|
occupant_type=occupant_type.id,
|
||||||
|
person_id=token_user.person_id,
|
||||||
|
build_parts_id=build_part.id,
|
||||||
|
):
|
||||||
|
reachable_event_list_id, reachable_event_list_uu_id = (
|
||||||
|
Event2Occupant.get_event_id_by_build_living_space_id(
|
||||||
|
build_living_space_id=selected_occupant_type.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
update_selected_to_redis(
|
||||||
|
request=request,
|
||||||
|
add_payload=OccupantToken(
|
||||||
|
living_space_id=selected_occupant_type.id,
|
||||||
|
living_space_uu_id=selected_occupant_type.uu_id.__str__(),
|
||||||
|
occupant_type_id=occupant_type.id,
|
||||||
|
occupant_type_uu_id=occupant_type.uu_id.__str__(),
|
||||||
|
occupant_type=occupant_type.occupant_type,
|
||||||
|
build_id=build.id,
|
||||||
|
build_uuid=build.uu_id.__str__(),
|
||||||
|
build_part_id=build_part.id,
|
||||||
|
build_part_uuid=build_part.uu_id.__str__(),
|
||||||
|
responsible_employee_id=responsible_employee.id,
|
||||||
|
responsible_employee_uuid=responsible_employee.uu_id.__str__(),
|
||||||
|
responsible_company_id=company_related.id,
|
||||||
|
responsible_company_uuid=company_related.uu_id.__str__(),
|
||||||
|
reachable_event_list_id=reachable_event_list_id,
|
||||||
|
reachable_event_list_uu_id=reachable_event_list_uu_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Occupant is selected successfully",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data provided"},
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationCheckTokenEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CHECK"
|
||||||
|
__event_keys__ = {
|
||||||
|
"73d77e45-a33f-4f12-909e-3b56f00d8a12": "authentication_check_token_is_valid",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_login_with_domain_and_creds(
|
||||||
|
cls, request, token_dict: dict = None
|
||||||
|
):
|
||||||
|
if get_object_via_access_key(request=request):
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Access Token is valid"},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Access Token is NOT valid"},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationRefreshEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "REFRESH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"48379bb2-ba81-4d8e-a9dd-58837cfcbf67": "authentication_refresh_user_info",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_refresh_user_info(cls, request, token_dict: dict = None):
|
||||||
|
|
||||||
|
|
||||||
|
access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
|
||||||
|
if token_user := get_object_via_access_key(request=request):
|
||||||
|
if found_user := Users.find_one(uu_id=token_user.get("uu_id")):
|
||||||
|
user_token = UsersTokens.find_one(
|
||||||
|
domain=found_user.domain_name,
|
||||||
|
user_id=found_user.id,
|
||||||
|
token_type="RememberMe",
|
||||||
|
)
|
||||||
|
access_dict = {
|
||||||
|
"access_token": access_token,
|
||||||
|
"refresh_token": getattr(user_token, "token", None),
|
||||||
|
}
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "User is logged in successfully via refresh token",
|
||||||
|
"data": load_user_with_erp_details(found_user, access_dict),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": {}},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationChangePasswordEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"f09f7c1a-bee6-4e32-8444-962ec8f39091": "authentication_change_password",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_change_password(
|
||||||
|
cls, request, data: ChangePassword, token_dict: dict = None
|
||||||
|
):
|
||||||
|
token_user = get_object_via_access_key(request=request)
|
||||||
|
if token_user.user_type == 1:
|
||||||
|
if found_user := Users.find_one(uu_id=token_user.uu_id):
|
||||||
|
if found_user.check_password(data.old_password):
|
||||||
|
found_user.set_password(data.new_password)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Password is changed successfully",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Old password is not correct",
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data"},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationCreatePasswordEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c519f9af-92e1-47b2-abf7-5a3316d075f7": "authentication_create_password",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_create_password(
|
||||||
|
cls, request, data: CreatePassword, token_dict: dict = None
|
||||||
|
):
|
||||||
|
if not data.re_password == data.password:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
|
||||||
|
)
|
||||||
|
if found_user := Users.find_one(password_token=data.password_token):
|
||||||
|
found_user.create_password(password=data.password)
|
||||||
|
found_user.password_token = None
|
||||||
|
found_user.save()
|
||||||
|
send_email_completed = send_email(
|
||||||
|
subject=f"Dear {found_user.user_tag}, your password has been changed.",
|
||||||
|
receivers=[str(found_user.email)],
|
||||||
|
html=password_is_changed_template(user_name=found_user.user_tag),
|
||||||
|
)
|
||||||
|
if not send_email_completed:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="Email can not be sent. Try again later"
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Password is created successfully",
|
||||||
|
"data": found_user.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Record not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationDisconnectUserEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8b586848-2fb3-4161-abbe-642157eec7ce": "authentication_disconnect_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_disconnect_user(
|
||||||
|
cls, request: Request, data: Logout, token_dict: dict = None
|
||||||
|
):
|
||||||
|
if token_user := get_object_via_access_key(request=request):
|
||||||
|
found_user = Users.find_one(uu_id=token_user.get("uu_id"))
|
||||||
|
if not found_user:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Invalid data",
|
||||||
|
"data": None,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
if already_tokens := get_object_via_user_uu_id(user_id=found_user.uu_id):
|
||||||
|
for key in already_tokens:
|
||||||
|
token_user = json.loads(redis_cli.get(key) or {})
|
||||||
|
redis_cli.delete(key)
|
||||||
|
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
|
||||||
|
selected_user.remove_refresher_token(
|
||||||
|
domain=data.domain, disconnect=True
|
||||||
|
)
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=found_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key=token_user.get("access_input"),
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=datetime.datetime.utcnow().__str__(),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "All sessions are disconnected",
|
||||||
|
"data": token_user,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": None},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationLogoutEventMethods(MethodToEvent):
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5cc22e4e-a0f7-4077-be41-1871feb3dfd1": "authentication_logout_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_logout_user(
|
||||||
|
cls, request: Request, data: Logout, token_dict: dict = None
|
||||||
|
):
|
||||||
|
token_user = None
|
||||||
|
if already_tokens := get_object_via_access_key(request=request):
|
||||||
|
for key in already_tokens:
|
||||||
|
token_user = json.loads(redis_cli.get(key) or {})
|
||||||
|
if token_user.get("domain") == data.domain:
|
||||||
|
redis_cli.delete(key)
|
||||||
|
selected_user = Users.find_one(uu_id=token_user.get("uu_id"))
|
||||||
|
selected_user.remove_refresher_token(domain=data.domain)
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=selected_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key=token_user.get("access_input"),
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=datetime.datetime.utcnow().__str__(),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Session is logged out",
|
||||||
|
"data": token_user,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Logout is not successfully completed",
|
||||||
|
"data": None,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationRefreshTokenEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c90f3334-10c9-4181-b5ff-90d98a0287b2": "authentication_refresher_token",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_refresher_token(
|
||||||
|
cls, request: Request, data: Remember, token_dict: dict = None
|
||||||
|
):
|
||||||
|
token_refresher = UsersTokens.find_one(
|
||||||
|
token=data.refresh_token, domain=data.domain
|
||||||
|
)
|
||||||
|
if not token_refresher:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": {}},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
if found_user := Users.find_one(id=token_refresher.user_id):
|
||||||
|
found_user: Users = found_user
|
||||||
|
access_key = save_access_token_to_redis(
|
||||||
|
request=request, found_user=found_user, domain=data.domain
|
||||||
|
)
|
||||||
|
found_user.last_agent = request.headers.get("User-Agent", None)
|
||||||
|
found_user.last_platform = request.headers.get("Origin", None)
|
||||||
|
found_user.last_remote_addr = getattr(
|
||||||
|
request, "remote_addr", None
|
||||||
|
) or request.headers.get("X-Forwarded-For", None)
|
||||||
|
found_user.last_seen = str(DateTimeLocal.now())
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=found_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key="via_refresher",
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=datetime.datetime.utcnow().__str__(),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "User is logged in successfully via refresher token",
|
||||||
|
"data": load_user_with_erp_details(
|
||||||
|
found_user,
|
||||||
|
{
|
||||||
|
"access_token": access_key,
|
||||||
|
"refresh_token": data.refresh_token,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": False, "message": "Invalid data", "data": {}},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationForgotPasswordEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e3ca6e24-b9f8-4127-949c-3bfa364e3513": "authentication_forgot_password",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_forgot_password(
|
||||||
|
cls, request: Request, data: Forgot, token_dict: dict = None
|
||||||
|
):
|
||||||
|
found_user: Users = Users.check_user_exits(
|
||||||
|
access_key=data.access_key, domain=data.domain
|
||||||
|
)
|
||||||
|
forgot_key = save_access_token_to_redis(
|
||||||
|
request=request, found_user=found_user, domain=data.domain
|
||||||
|
)
|
||||||
|
# UserLogger.log_error(
|
||||||
|
# str(
|
||||||
|
# dict(
|
||||||
|
# user_id=found_user.id,
|
||||||
|
# domain=data.domain,
|
||||||
|
# access_key=data.access_key,
|
||||||
|
# agent=request.headers.get("User-Agent", None),
|
||||||
|
# ip=getattr(request, "remote_addr", None)
|
||||||
|
# or request.headers.get("X-Forwarded-For", None),
|
||||||
|
# platform=request.headers.get("Origin", None),
|
||||||
|
# login_date=str(DateTimeLocal.now()),
|
||||||
|
# is_login=False,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
forgot_link = ApiStatic.forgot_link(forgot_key=forgot_key)
|
||||||
|
send_email_completed = send_email(
|
||||||
|
subject=f"Dear {found_user.user_tag}, your forgot password link has been sent.",
|
||||||
|
receivers=[str(found_user.email)],
|
||||||
|
html=change_your_password_template(
|
||||||
|
user_name=found_user.user_tag, forgot_link=forgot_link
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if not send_email_completed:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="Email can not be sent. Try again later"
|
||||||
|
)
|
||||||
|
|
||||||
|
found_user.password_token = forgot_key
|
||||||
|
found_user.password_token_is_valid = str(DateTimeLocal.shift(days=1))
|
||||||
|
found_user.save()
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Password is change link is sent to your email or phone",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationDownloadAvatarEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c140cd5f-307f-4046-a93e-3ade032a57a7": "authentication_download_avatar",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def authentication_download_avatar(
|
||||||
|
cls, request: Request, data: Forgot, token_dict: dict = None
|
||||||
|
):
|
||||||
|
found_user = Users.check_user_exits(
|
||||||
|
access_key=data.access_key, domain=data.domain
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Avatar and profile is shared via user credentials",
|
||||||
|
"data": {
|
||||||
|
"last_seen": str(found_user.last_seen),
|
||||||
|
"avatar": found_user.avatar,
|
||||||
|
"remember_me": found_user.remember_me,
|
||||||
|
"expiry_ends": str(found_user.expiry_ends),
|
||||||
|
"expired_str": str(
|
||||||
|
DateTimeLocal.now()
|
||||||
|
- DateTimeLocal.get(str(found_user.expiry_ends))
|
||||||
|
),
|
||||||
|
"expired_int": int(
|
||||||
|
(
|
||||||
|
DateTimeLocal.now()
|
||||||
|
- DateTimeLocal.get(str(found_user.expiry_ends))
|
||||||
|
).days
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AuthenticationLoginEventMethod = AuthenticationLoginEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/login")
|
||||||
|
)
|
||||||
|
AuthenticationSelectEventMethod = AuthenticationSelectEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/select")
|
||||||
|
)
|
||||||
|
AuthenticationCheckTokenEventMethod = AuthenticationCheckTokenEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/valid")
|
||||||
|
)
|
||||||
|
AuthenticationRefreshEventMethod = AuthenticationRefreshEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/refresh")
|
||||||
|
)
|
||||||
|
AuthenticationChangePasswordEventMethod = AuthenticationChangePasswordEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/change_password")
|
||||||
|
)
|
||||||
|
AuthenticationCreatePasswordEventMethod = AuthenticationCreatePasswordEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/create_password")
|
||||||
|
)
|
||||||
|
AuthenticationDisconnectUserEventMethod = AuthenticationDisconnectUserEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/disconnect")
|
||||||
|
)
|
||||||
|
AuthenticationLogoutEventMethod = AuthenticationLogoutEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/logout")
|
||||||
|
)
|
||||||
|
AuthenticationRefreshTokenEventMethod = AuthenticationRefreshTokenEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/refresher")
|
||||||
|
)
|
||||||
|
AuthenticationForgotPasswordEventMethod = AuthenticationForgotPasswordEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/forgot")
|
||||||
|
)
|
||||||
|
AuthenticationDownloadAvatarEventMethod = AuthenticationDownloadAvatarEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/authentication/avatar")
|
||||||
|
)
|
||||||
0
api_events/events/building/__init__.py
Normal file
0
api_events/events/building/__init__.py
Normal file
252
api_events/events/building/building_build.py
Normal file
252
api_events/events/building/building_build.py
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Build,
|
||||||
|
# RelationshipEmployee2Build,
|
||||||
|
Addresses,
|
||||||
|
BuildParts,
|
||||||
|
BuildTypes,
|
||||||
|
ApiEnumDropdown,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_validations import (
|
||||||
|
InsertBuild,
|
||||||
|
UpdateBuild,
|
||||||
|
PatchRecord,
|
||||||
|
ListOptions,
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class BuildListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"68b3b5ed-b74c-4a27-820f-3959214e94e9": "build_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build_list(
|
||||||
|
cls,
|
||||||
|
list_options: ListOptions,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
if isinstance(token_dict, OccupantTokenObject):
|
||||||
|
Build.pre_query = Build.filter_active(
|
||||||
|
Build.id == token_dict.selected_occupant.build_id
|
||||||
|
).query
|
||||||
|
elif isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
Build.pre_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
Build.filter_attr = list_options
|
||||||
|
records = Build.filter_active(
|
||||||
|
*Build.get_smart_query(smart_query=list_options.query)
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"a2271854-6b90-43da-a440-a62b70d90528": "build_create",
|
||||||
|
"b67ee709-0992-4604-9f90-fb1da10d5cf9": "create_building_employee",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build_create(cls, data: InsertBuild, token_dict: EmployeeTokenObject):
|
||||||
|
if not token_dict.selected_company.employee_id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Employee id is not found for {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not token_dict.selected_company.company_id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Company id is not found for {token_dict.selected_company.company_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
created_build = Build.create_action(data=data, token=token_dict)
|
||||||
|
if not created_build.is_found:
|
||||||
|
build_type = BuildTypes.find_one(type_code="APT_YNT")
|
||||||
|
if not build_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Build type APT_YNT is not found. Please contact with your system administrator.",
|
||||||
|
)
|
||||||
|
api_enum = ApiEnumDropdown.find_one(enum_class="Directions", key="NN")
|
||||||
|
if not api_enum:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Api Enum NN is not found. Please contact with your system administrator.",
|
||||||
|
)
|
||||||
|
build_parts = dict(
|
||||||
|
address_gov_code=f"{data.gov_address_code}-M",
|
||||||
|
build_id=int(created_build.id),
|
||||||
|
build_uu_id=str(created_build.uu_id),
|
||||||
|
part_no="0",
|
||||||
|
part_type_id=int(build_type.id),
|
||||||
|
part_type_uu_id=str(build_type.uu_id),
|
||||||
|
part_direction_id=int(api_enum.id),
|
||||||
|
part_direction_uu_id=str(api_enum.uu_id),
|
||||||
|
part_code="MAN-ROOM",
|
||||||
|
human_livable=False,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
man_build_part = BuildParts.find_or_create(**build_parts)
|
||||||
|
if not man_build_part.is_found:
|
||||||
|
created_build.update(management_room_id=man_build_part.id)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Build record completed. This build is assigned to you.",
|
||||||
|
"data": created_build.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
detail=f"Build record create not successful for Employee UUID : {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_building_employee(
|
||||||
|
cls, data: InsertBuild, token_dict: EmployeeTokenObject
|
||||||
|
):
|
||||||
|
records = Addresses.list_via_employee(
|
||||||
|
token_dict=token_dict, filter_expr=[Addresses.uu_id == data.address_uu_id]
|
||||||
|
)
|
||||||
|
if not records.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"This address {data.address_uu_id} is not found in the user's address list.",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not token_dict.selected_company.employee_id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Employee id is not found for {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not token_dict.selected_company.company_id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Company id is not found for {token_dict.selected_company.company_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
created_build = Build.create_action(data=data, token=token_dict)
|
||||||
|
if not created_build.is_found:
|
||||||
|
RelationshipEmployee2Build.find_or_create(
|
||||||
|
company_id=token_dict.selected_company.company_id,
|
||||||
|
member_id=created_build.id,
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Build record completed. This build is assigned to you.",
|
||||||
|
"data": created_build.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"Build record create not successful for {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5ad38a66-1189-451e-babb-77de2d63d757": "build_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build_update(cls, build_uu_id: str, data: UpdateBuild, token_dict):
|
||||||
|
Build.pre_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
if Build.filter_active(Build.person_id == token_dict.person_id):
|
||||||
|
if updated_build := Build.update_action(
|
||||||
|
data=data, token=token_dict, build_uu_id=build_uu_id
|
||||||
|
):
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Build record",
|
||||||
|
"data": updated_build,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=f"This user can not modify {build_uu_id} - building.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e3876bfe-8847-4dea-ae36-e709f7431930": "build_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def build_patch(cls, build_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_build = Build.find_one_or_abort(uu_id=build_uu_id)
|
||||||
|
access_authorized_build = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
filter_expr=[Build.id == find_one_build.id],
|
||||||
|
)
|
||||||
|
if access_authorized_build.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_build.active = bool(action.get("active", find_one_build.active))
|
||||||
|
find_one_build.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_build.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_build.deleted = bool(action.get("delete", find_one_build.deleted))
|
||||||
|
find_one_build.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Build record completed",
|
||||||
|
"data": find_one_build.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Build record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
BuildListEventMethod = BuildListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/build/list")
|
||||||
|
)
|
||||||
|
BuildCreateEventMethod = BuildCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/build/create")
|
||||||
|
)
|
||||||
|
BuildUpdateEventMethod = BuildUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/build/update")
|
||||||
|
)
|
||||||
|
BuildPatchEventMethod = BuildPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/build/patch")
|
||||||
|
)
|
||||||
5
api_events/events/building/building_build_area.py
Normal file
5
api_events/events/building/building_build_area.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildAreaEvents(MethodToEvent): ...
|
||||||
150
api_events/events/building/building_build_parts.py
Normal file
150
api_events/events/building/building_build_parts.py
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi import status
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Build,
|
||||||
|
BuildParts,
|
||||||
|
)
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
from api_validations import (
|
||||||
|
InsertBuildParts,
|
||||||
|
ListOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildPartsListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"b860e37a-e19b-4c45-9543-461241f7587c": "building_build_parts_list"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
build_list_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
)
|
||||||
|
build_list_ids = [build.id for build in build_list_query.all()]
|
||||||
|
BuildParts.pre_query = BuildParts.query.filter(
|
||||||
|
BuildParts.build_id.in_(build_list_ids)
|
||||||
|
)
|
||||||
|
records = BuildParts.filter_active(
|
||||||
|
*BuildParts.get_smart_query(list_options.query)
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildPartsCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": "building_build_parts_create"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_create(cls, data: InsertBuildParts, token_dict: dict):
|
||||||
|
created_build = BuildParts.create_action(data=data, token=token_dict)
|
||||||
|
if not created_build:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Create Build Parts is not completed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Build Parts record",
|
||||||
|
"data": created_build.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildPartsUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"58fdf95e-2110-4ed6-9c26-95f4be87eaee": "building_build_parts_update"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_update(cls, data: InsertBuildParts, token_dict: dict):
|
||||||
|
if updated_build := BuildParts.update_action(data=data, token=token_dict):
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Build Parts record",
|
||||||
|
"data": updated_build,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Build Parts record",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildPartsPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"87a15ade-3474-4206-b574-bbf8580cbb14": "building_build_parts_patch"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_patch(cls, data, token_dict):
|
||||||
|
find_one_build = BuildParts.find_one(uu_id=data.uu_id)
|
||||||
|
access_authorized_build = BuildParts.select_action(
|
||||||
|
duty_id=token_dict.selected_company.duty_id,
|
||||||
|
filter_expr=[BuildParts.id == find_one_build.id],
|
||||||
|
)
|
||||||
|
if access_authorized_build.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_build.active = bool(action.get("active", find_one_build.active))
|
||||||
|
find_one_build.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_build.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_build.deleted = bool(action.get("delete", find_one_build.deleted))
|
||||||
|
find_one_build.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Build Parts record",
|
||||||
|
"data": find_one_build.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Update Build Parts record",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
BuildingBuildPartsListEventMethod = BuildingBuildPartsListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/parts/list")
|
||||||
|
)
|
||||||
|
BuildingBuildPartsCreateEventMethod = BuildingBuildPartsCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/parts/create")
|
||||||
|
)
|
||||||
|
BuildingBuildPartsUpdateEventMethod = BuildingBuildPartsUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/parts/update")
|
||||||
|
)
|
||||||
|
BuildingBuildPartsPatchEventMethod = BuildingBuildPartsPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/parts/patch")
|
||||||
|
)
|
||||||
5
api_events/events/building/building_build_sites.py
Normal file
5
api_events/events/building/building_build_sites.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildSitesEvents(MethodToEvent): ...
|
||||||
5
api_events/events/building/building_build_types.py
Normal file
5
api_events/events/building/building_build_types.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingBuildTypesEvents(MethodToEvent): ...
|
||||||
240
api_events/events/building/building_living_spaces.py
Normal file
240
api_events/events/building/building_living_spaces.py
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
BuildParts,
|
||||||
|
Build,
|
||||||
|
BuildLivingSpace,
|
||||||
|
OccupantTypes,
|
||||||
|
|
||||||
|
)
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
from api_validations import (
|
||||||
|
InsertBuildLivingSpace,
|
||||||
|
ListOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
class BuildingLivingSpacesPartsListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8fd04d94-68fb-4a07-9549-8b47aee3a870": "building_build_parts_list",
|
||||||
|
"2f3041a9-6184-44c2-ac38-8ea934297ed1": "building_build_parts_list_with_expired",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
build_id_list_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
Build.filter_attr = list_options
|
||||||
|
build_part_id_list_query = BuildParts.filter_active(
|
||||||
|
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
|
||||||
|
)
|
||||||
|
|
||||||
|
list_options.query.pop("expiry_starts", None)
|
||||||
|
list_options.query.pop("expiry_ends", None)
|
||||||
|
|
||||||
|
records = BuildLivingSpace.filter_active(
|
||||||
|
BuildLivingSpace.build_parts_id.in_(
|
||||||
|
[build_part.id for build_part in build_part_id_list_query.data]
|
||||||
|
),
|
||||||
|
*BuildLivingSpace.get_smart_query(smart_query=list_options.query),
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_list_with_expired(
|
||||||
|
cls, list_options: ListOptions, token_dict
|
||||||
|
):
|
||||||
|
build_id_list_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
Build.filter_attr = list_options
|
||||||
|
build_part_id_list_query = BuildParts.filter_active(
|
||||||
|
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
|
||||||
|
)
|
||||||
|
|
||||||
|
records = BuildLivingSpace.filter_active(
|
||||||
|
BuildLivingSpace.build_parts_id.in_(
|
||||||
|
[build_part.id for build_part in build_part_id_list_query.data]
|
||||||
|
),
|
||||||
|
*BuildLivingSpace.get_smart_query(smart_query=list_options.query),
|
||||||
|
expired=False,
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingLivingSpacesPartsCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"b78ca45c-b9f4-41f6-9ddb-2c6f2faa2570": "building_live_space_create"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_live_space_create(
|
||||||
|
cls,
|
||||||
|
data: InsertBuildLivingSpace,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
from service_app.application import DateTimeLocal
|
||||||
|
from database_sql_models import People
|
||||||
|
from sqlalchemy.sql import select
|
||||||
|
|
||||||
|
data_dict = data.dump()
|
||||||
|
build_id_list_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
build_part = BuildParts.filter_active(
|
||||||
|
BuildParts.uu_id == data.build_parts_uu_id,
|
||||||
|
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
|
||||||
|
)
|
||||||
|
if not build_part.get(1):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
|
||||||
|
)
|
||||||
|
build_part = build_part.get(1)
|
||||||
|
|
||||||
|
life_person = People.find_one(uu_id=data.person_uu_id or "")
|
||||||
|
if not life_person:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
detail=f"{data.life_person_uu_id} - Living Person is not found in database. "
|
||||||
|
f"Check build live person uu_id",
|
||||||
|
)
|
||||||
|
|
||||||
|
occupant_type = OccupantTypes.find_one(uu_id=data.occupant_type_uu_id)
|
||||||
|
if not occupant_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
detail=f"{data.occupant_type_uu_id} - Occupant Type is not found in database. "
|
||||||
|
f"Check occupant type uu_id",
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict["occupant_type"] = occupant_type.id
|
||||||
|
data_dict["occupant_type_uu_id"] = str(occupant_type.uu_id)
|
||||||
|
data_dict["build_parts_id"] = build_part.id
|
||||||
|
data_dict["build_parts_uu_id"] = str(build_part.uu_id)
|
||||||
|
data_dict["person_id"] = life_person.id
|
||||||
|
data_dict["person_uu_id"] = str(life_person.uu_id)
|
||||||
|
|
||||||
|
living_space_id = BuildLivingSpace.session.execute(
|
||||||
|
select(BuildLivingSpace.id)
|
||||||
|
.where(
|
||||||
|
*[
|
||||||
|
BuildLivingSpace.build_parts_id == build_part.id,
|
||||||
|
BuildLivingSpace.person_id == life_person.id,
|
||||||
|
BuildLivingSpace.occupant_type == occupant_type.id,
|
||||||
|
BuildLivingSpace.active == True,
|
||||||
|
BuildLivingSpace.is_confirmed == True,
|
||||||
|
str(DateTimeLocal.now()) < BuildLivingSpace.expiry_ends,
|
||||||
|
str(DateTimeLocal.now()) >= BuildLivingSpace.expiry_starts,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
.order_by(BuildLivingSpace.expiry_starts.desc())
|
||||||
|
).first()
|
||||||
|
|
||||||
|
last_living_space = BuildLivingSpace.find_one(
|
||||||
|
id=living_space_id[0] if living_space_id else None
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict["expiry_starts"] = str(DateTimeLocal.now())
|
||||||
|
created_living_space = BuildLivingSpace.create_action(
|
||||||
|
data=data_dict, token_dict=token_dict
|
||||||
|
)
|
||||||
|
|
||||||
|
if last_living_space:
|
||||||
|
if last_living_space.expiry_ends > DateTimeLocal.now():
|
||||||
|
last_living_space.expiry_ends = str(DateTimeLocal.shift(minutes=-10))
|
||||||
|
last_living_space.save()
|
||||||
|
return created_living_space
|
||||||
|
|
||||||
|
|
||||||
|
class BuildingLivingSpacesPartsUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"70b4666f-4ceb-46ec-b89e-24be8712f0e7": "building_build_parts_update"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_build_parts_update(cls, build_uu_id: str, data, token_dict):
|
||||||
|
from service_app.application import DateTimeLocal
|
||||||
|
from database_sql_models import People
|
||||||
|
from sqlalchemy.sql import select
|
||||||
|
|
||||||
|
data_dict = data.dump()
|
||||||
|
build_id_list_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
build_part = BuildParts.filter_active(
|
||||||
|
BuildParts.uu_id == data.build_parts_uu_id,
|
||||||
|
BuildParts.build_id.in_([build.id for build in build_id_list_query.all()]),
|
||||||
|
)
|
||||||
|
if not build_part.get(1):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
detail=f"{data.build_parts_uu_id} - Build Part is not found in database. Check build part uu_id",
|
||||||
|
)
|
||||||
|
build_part = build_part.get(1)
|
||||||
|
|
||||||
|
life_person = People.find_one(uu_id=data.life_person_uu_id or "")
|
||||||
|
if not life_person:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
detail=f"{data.life_person_uu_id} - Living Person is not found in database. "
|
||||||
|
f"Check build live person uu_id",
|
||||||
|
)
|
||||||
|
|
||||||
|
living_spaces = select(BuildLivingSpace.id).order_by(
|
||||||
|
BuildLivingSpace.expiry_starts.desc()
|
||||||
|
)
|
||||||
|
living_space_id = BuildLivingSpace.session.execute(living_spaces).first()
|
||||||
|
last_living_space = BuildLivingSpace.find_one(
|
||||||
|
id=getattr(living_space_id[0], "id", None) if living_space_id else None
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict["expiry_starts"] = DateTimeLocal.now()
|
||||||
|
data_dict["is_tenant_live"] = bool(data.is_tenant_live)
|
||||||
|
data_dict["build_parts_id"] = build_part.id
|
||||||
|
if data_dict["is_tenant_live"]:
|
||||||
|
owner_person = getattr(last_living_space, "owner_person_id", None)
|
||||||
|
if not owner_person:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_418_IM_A_TEAPOT,
|
||||||
|
detail=dict(
|
||||||
|
message="Owner person of build part is not defined. Please register owner of part first.",
|
||||||
|
data=build_part.get_dict(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
data_dict["life_person_id"] = life_person.id
|
||||||
|
data_dict["owner_person_id"] = owner_person
|
||||||
|
else:
|
||||||
|
data_dict["life_person_id"] = life_person.id
|
||||||
|
data_dict["owner_person_id"] = life_person.id
|
||||||
|
del data_dict["build_parts_uu_id"], data_dict["life_person_uu_id"]
|
||||||
|
|
||||||
|
|
||||||
|
BuildingLivingSpacesPartsListEventMethod = BuildingLivingSpacesPartsListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/living_space/list")
|
||||||
|
)
|
||||||
|
BuildingLivingSpacesPartsCreateEventMethod = (
|
||||||
|
BuildingLivingSpacesPartsCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/living_space/create")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
BuildingLivingSpacesPartsUpdateEventMethod = (
|
||||||
|
BuildingLivingSpacesPartsUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/building/living_space/update")
|
||||||
|
)
|
||||||
|
)
|
||||||
0
api_events/events/company/__init__.py
Normal file
0
api_events/events/company/__init__.py
Normal file
171
api_events/events/company/company_company.py
Normal file
171
api_events/events/company/company_company.py
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import Companies
|
||||||
|
|
||||||
|
from api_validations import (
|
||||||
|
InsertCompany,
|
||||||
|
UpdateCompany,
|
||||||
|
ListOptions,
|
||||||
|
PatchRecord,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class CompanyListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": "company_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def company_list(
|
||||||
|
cls,
|
||||||
|
list_options: ListOptions,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
Companies.pre_query = Companies.select_action(
|
||||||
|
duty_id_list=[
|
||||||
|
token_dict.selected_company.duty_id,
|
||||||
|
token_dict.selected_company.bulk_duties_id,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif isinstance(token_dict, OccupantTokenObject):
|
||||||
|
Companies.pre_query = Companies.filter_active(
|
||||||
|
Companies.id == token_dict.selected_occupant.responsible_company_id
|
||||||
|
).query
|
||||||
|
Companies.filter_attr = list_options
|
||||||
|
records = Companies.filter_active(
|
||||||
|
*Companies.get_smart_query(list_options.query)
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CompanyCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"76f11a08-5f4a-4e1f-961f-aaef21699acd": "company_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def company_create(cls, data: InsertCompany, token_dict):
|
||||||
|
created_company = Companies.create_action(
|
||||||
|
data=data, token=token_dict.companies_list
|
||||||
|
)
|
||||||
|
created_company.related_company = token_dict.get("company_uu_id")
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Company record",
|
||||||
|
"data": created_company.get_dict(),
|
||||||
|
"password_token": {
|
||||||
|
"password_token": created_company.password_token,
|
||||||
|
"password_expires_day": str(created_company.password_expires_day),
|
||||||
|
"password_expiry_begins": str(
|
||||||
|
created_company.password_expiry_begins
|
||||||
|
),
|
||||||
|
"hash_password": created_company.hash_password,
|
||||||
|
"related_company": created_company.related_company,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CompanyUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"41ea7f29-006a-4310-b5c4-b2a0e1a504bd": "company_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def company_update(cls, company_uu_id: str, data: UpdateCompany, token_dict):
|
||||||
|
find_one_company = Companies.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_company = Companies.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Companies.id == token_dict.get("")],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_company = find_one_company.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Company record",
|
||||||
|
"data": updated_company,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Update Company record", "data": {}},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CompanyPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"6320d696-1fd1-49f9-860a-8f22e5b8a68d": "company_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def company_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_company = Companies.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_company = Companies.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Companies.id == find_one_company.id],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_company.active = bool(
|
||||||
|
action.get("active", find_one_company.active)
|
||||||
|
)
|
||||||
|
find_one_company.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_company.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_company.deleted = bool(
|
||||||
|
action.get("delete", find_one_company.deleted)
|
||||||
|
)
|
||||||
|
find_one_company.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Company record completed",
|
||||||
|
"data": find_one_company.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Company record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
CompanyPatchEventMethod = CompanyListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/company/list")
|
||||||
|
)
|
||||||
|
CompanyCreateEventMethod = CompanyCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/company/create")
|
||||||
|
)
|
||||||
|
CompanyUpdateEventMethod = CompanyUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/company/update")
|
||||||
|
)
|
||||||
|
CompanyListEventMethod = CompanyPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/company/patch")
|
||||||
|
)
|
||||||
167
api_events/events/company/company_department.py
Normal file
167
api_events/events/company/company_department.py
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from validations import (
|
||||||
|
DepartmentsPydantic,
|
||||||
|
PatchRecord,
|
||||||
|
ListOptions,
|
||||||
|
BaseModelRegular,
|
||||||
|
)
|
||||||
|
|
||||||
|
from databases import Departments
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"2cb90331-c1b4-4923-8314-8111326b621a": "department_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def department_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
Departments.filter_attr = list_options
|
||||||
|
records = Departments.filter_active(
|
||||||
|
*Departments.get_smart_query(smart_query=list_options.query),
|
||||||
|
Departments.company_id == token_dict.selected_company.company_id
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AdminUserInsertDepartments(BaseModelRegular):
|
||||||
|
department_code: str
|
||||||
|
department_name: str
|
||||||
|
company_uu_id: Optional[str] = None
|
||||||
|
|
||||||
|
department_description: str
|
||||||
|
parent_department_uu_id: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": "super_user_department_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def super_user_department_create(cls, data: DepartmentsPydantic, token_dict):
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
data_dict["company_id"] = token_dict.selected_company.company_id
|
||||||
|
data_dict["company_uu_id"] = token_dict.selected_company.company_uu_id
|
||||||
|
created_department = Departments.find_or_create(**data_dict)
|
||||||
|
if created_department.is_found:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Company record already exits here is the record",
|
||||||
|
"data": created_department.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Company record",
|
||||||
|
"data": created_department.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"4172706f-06c9-4c38-9ac8-59085a72f80a": "department_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def department_update(
|
||||||
|
cls, company_uu_id: str, data: DepartmentsPydantic, token_dict
|
||||||
|
):
|
||||||
|
find_one_company = Departments.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_company = Departments.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Departments.id == token_dict.get("")],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_company = find_one_company.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Company record",
|
||||||
|
"data": updated_company,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Update Company record", "data": {}},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"1e272e4f-6c1e-418b-91a7-be8b06c875da": "department_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def department_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_company = Departments.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_company = Departments.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Departments.id == find_one_company.id],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_company.active = bool(
|
||||||
|
action.get("active", find_one_company.active)
|
||||||
|
)
|
||||||
|
find_one_company.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_company.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_company.deleted = bool(
|
||||||
|
action.get("delete", find_one_company.deleted)
|
||||||
|
)
|
||||||
|
find_one_company.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Company record completed",
|
||||||
|
"data": find_one_company.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Company record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
DepartmentListEventMethod = DepartmentListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/department/list")
|
||||||
|
)
|
||||||
|
DepartmentCreateEventMethod = DepartmentCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/department/create")
|
||||||
|
)
|
||||||
|
DepartmentUpdateEventMethod = DepartmentUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/department/update")
|
||||||
|
)
|
||||||
|
DepartmentPatchEventMethod = DepartmentPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/department/patch")
|
||||||
|
)
|
||||||
199
api_events/events/company/company_duties.py
Normal file
199
api_events/events/company/company_duties.py
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from validations import InsertDuties, UpdateDuties, SelectDuties
|
||||||
|
from validations.root_validates import PatchRecord, ListOptions
|
||||||
|
|
||||||
|
from databases import Departments, Duty, Duties
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DutiesListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"44b72beb-53a8-407b-a12a-76e74b65794d": "duties_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duties_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
Duties.filter_attr = list_options
|
||||||
|
records = Duties.filter_active(
|
||||||
|
*Duties.get_smart_query(smart_query=list_options.query),
|
||||||
|
Duties.company_id == token_dict.selected_company.company_id
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"completed": True if records.count else False,
|
||||||
|
"status": "success",
|
||||||
|
"data": records.get_dict(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DutiesGetByUUIDEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "GET"
|
||||||
|
__event_keys__ = {
|
||||||
|
"30c54cce-3303-4d36-959a-b64e383ae177": "duties_get_by_uuid",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duties_get_by_uuid(cls, data: SelectDuties, token_dict):
|
||||||
|
|
||||||
|
duty = Duty.find_one(uu_id=data.duty_uu_id)
|
||||||
|
if not duty:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Duty record is not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
records = Duties.filter_active(
|
||||||
|
Duties.duties_id == duty.id,
|
||||||
|
Duties.company_id == token_dict.selected_company.company_id,
|
||||||
|
)
|
||||||
|
if not records.data:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Duties record is not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"completed": True,
|
||||||
|
"status": "success",
|
||||||
|
"data": [record.get_dict() for record in records.data],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DutiesCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"3524ae42-0825-4af7-be85-7c890a4f65d3": "duties_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duties_create(cls, data: InsertDuties, token_dict):
|
||||||
|
duty = Duty.find_one(uu_id=data.duties_uu_id)
|
||||||
|
department = Departments.find_one(uu_id=data.department_uu_id)
|
||||||
|
|
||||||
|
created_duties = Duties.find_or_create(
|
||||||
|
company_id=token_dict.selected_company.company_id,
|
||||||
|
company_uu_id=token_dict.selected_company.company_uu_id,
|
||||||
|
duties_id=duty.id,
|
||||||
|
duties_uu_id=str(duty.uu_id),
|
||||||
|
department_id=department.id,
|
||||||
|
department_uu_id=str(department.uu_id),
|
||||||
|
is_confirmed=data.is_confirmed,
|
||||||
|
)
|
||||||
|
if data.is_default_duty:
|
||||||
|
created_duties.update(users_default_duty=created_duties.id)
|
||||||
|
|
||||||
|
if not created_duties:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Failed to create Duties record",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"completed": created_duties.is_found,
|
||||||
|
"message": (
|
||||||
|
"Create Duties record"
|
||||||
|
if created_duties.is_found
|
||||||
|
else "This record is already created"
|
||||||
|
),
|
||||||
|
"data": created_duties.get_dict(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DutiesUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"3fc77829-f1ee-4511-a2ca-582daa03125b": "duties_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duties_update(cls, duties_uu_id: str, data: UpdateDuties, token_dict):
|
||||||
|
find_one_duties = Duties.find_one_or_abort(uu_id=duties_uu_id)
|
||||||
|
access_authorized_duties = Duties.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Duties.id == find_one_duties.id],
|
||||||
|
)
|
||||||
|
if access_authorized_duties.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_duties = find_one_duties.update(**data_dict)
|
||||||
|
return {
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Duties record",
|
||||||
|
"data": updated_duties,
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
"completed": False,
|
||||||
|
"message": "Update Duties record failed",
|
||||||
|
"data": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DutiesPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"ca81c6d1-975a-4288-a27b-1069aea84afe": "duties_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duties_patch(cls, duties_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_duties = Duties.find_one_or_abort(uu_id=duties_uu_id)
|
||||||
|
access_authorized_duties = Duties.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Duties.id == find_one_duties.id],
|
||||||
|
)
|
||||||
|
if access_authorized_duties.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_duties.active = bool(action.get("active", find_one_duties.active))
|
||||||
|
find_one_duties.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_duties.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_duties.deleted = bool(
|
||||||
|
action.get("delete", find_one_duties.deleted)
|
||||||
|
)
|
||||||
|
find_one_duties.save()
|
||||||
|
return {
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Duties record completed",
|
||||||
|
"data": find_one_duties.get_dict(),
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Duties record failed",
|
||||||
|
"data": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DutiesListEventMethod = DutiesListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duties/list")
|
||||||
|
)
|
||||||
|
DutiesGetByUUIDEventMethod = DutiesGetByUUIDEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duties/get_by_duty_uuid")
|
||||||
|
)
|
||||||
|
DutiesCreateEventMethod = DutiesCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duties/create")
|
||||||
|
)
|
||||||
|
DutiesUpdateEventMethod = DutiesUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duties/update")
|
||||||
|
)
|
||||||
|
DutiesPatchEventMethod = DutiesPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duties/patch")
|
||||||
|
)
|
||||||
135
api_events/events/company/company_duty.py
Normal file
135
api_events/events/company/company_duty.py
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from validations import InsertCompanyDuty
|
||||||
|
from validations.root_validates import PatchRecord, ListOptions
|
||||||
|
|
||||||
|
from databases import Duty
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class DutyListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"23231c7d-4ff2-4b39-b71b-ea350d31fadf": "duty_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duty_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
records = Duty.filter_active(
|
||||||
|
*Duty.get_smart_query(list_options.query),
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DutyCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c6ea200e-fa17-4393-b390-37f5337c9c65": "duty_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duty_create(cls, data: InsertCompanyDuty, token_dict):
|
||||||
|
created_duty = Duty.find_or_create(**data.excluded_dump())
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Company record",
|
||||||
|
"data": created_duty.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DutyUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"ad952647-bcf8-482d-9e05-b2ee8086483f": "duty_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duty_update(cls, company_uu_id: str, data, token_dict):
|
||||||
|
find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_company = Duty.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5), # ?
|
||||||
|
filter_expr=[Duty.id == token_dict.get("")],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_company = find_one_company.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Company record",
|
||||||
|
"data": updated_company,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Update Company record", "data": {}},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DutyPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b": "duty_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def duty_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_company = Duty.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_company = Duty.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Duty.id == find_one_company.id],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_company.active = bool(
|
||||||
|
action.get("active", find_one_company.active)
|
||||||
|
)
|
||||||
|
find_one_company.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_company.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_company.deleted = bool(
|
||||||
|
action.get("delete", find_one_company.deleted)
|
||||||
|
)
|
||||||
|
find_one_company.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Company record completed",
|
||||||
|
"data": find_one_company.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Company record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
DutyListEventMethod = DutyListEventMethods(action=ActionsSchema(endpoint="/duty/list"))
|
||||||
|
DutyCreateEventMethod = DutyCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duty/create")
|
||||||
|
)
|
||||||
|
DutyUpdateEventMethod = DutyUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duty/update")
|
||||||
|
)
|
||||||
|
DutyPatchEventMethod = DutyPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/duty/patch")
|
||||||
|
)
|
||||||
291
api_events/events/company/company_employee.py
Normal file
291
api_events/events/company/company_employee.py
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from validations import (
|
||||||
|
InsertEmployees,
|
||||||
|
BindEmployees2People,
|
||||||
|
PatchRecord,
|
||||||
|
ListOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
from databases import Employees, Staff, People, EmployeeHistory
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeeListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"cb677c92-6b05-4122-af5c-12766fae8095": "employee_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def employee_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
Employees.filter_attr = list_options
|
||||||
|
records = Employees.filter_active(
|
||||||
|
*Employees.get_smart_query(smart_query=list_options.query),
|
||||||
|
Employees.company_id == token_dict.selected_company.company_id,
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeeCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"1e1632c3-bb0e-46a5-8e45-da3f6d88ac43": "employee_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def employee_create(cls, data: InsertEmployees, token_dict):
|
||||||
|
person = People.find_one(uu_id=data.people_uu_id)
|
||||||
|
staff = Staff.find_one(uu_id=data.staff_uu_id)
|
||||||
|
if not staff:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Staff record not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
created_employee = Employees.create(
|
||||||
|
staff_id=staff.id,
|
||||||
|
staff_uu_id=str(staff.uu_id),
|
||||||
|
people_id=person.id if person else None,
|
||||||
|
people_uu_id=str(person.uu_id) if person else None,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True if not created_employee.is_found else False,
|
||||||
|
"message": "Create Employee record",
|
||||||
|
"data": created_employee.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeeUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"9015a076-d78c-463d-9474-ea343a125fb8": "employee_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def employee_update(cls, employee_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_employee = Employees.find_one_or_abort(uu_id=employee_uu_id)
|
||||||
|
access_authorized_employee = Employees.select_action(
|
||||||
|
employee_id=getattr(token_dict, "employee_id", 5),
|
||||||
|
filter_expr=[Employees.id == token_dict.get("")],
|
||||||
|
)
|
||||||
|
if access_authorized_employee.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_employee = find_one_employee.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Employee record",
|
||||||
|
"data": updated_employee,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Update Employee record",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeePatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8446ce0b-9310-4b9f-93e2-61f56a9dacd1": "employee_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def employee_patch(cls, employee_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
find_one_employee = Employees.find_one_or_abort(uu_id=employee_uu_id)
|
||||||
|
access_authorized_employee = Employees.select_action(
|
||||||
|
employee_id=getattr(token_dict, "employee_id", 5),
|
||||||
|
filter_expr=[Employees.id == find_one_employee.id],
|
||||||
|
)
|
||||||
|
if access_authorized_employee.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_employee.active = bool(
|
||||||
|
action.get("active", find_one_employee.active)
|
||||||
|
)
|
||||||
|
find_one_employee.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_employee.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_employee.deleted = bool(
|
||||||
|
action.get("delete", find_one_employee.deleted)
|
||||||
|
)
|
||||||
|
find_one_employee.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Employee record completed",
|
||||||
|
"data": find_one_employee.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Employee record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Employee2PeopleEmployEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5eb04057-7a74-4555-b2c6-14eda32dae89": "company_employee_employ",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def company_employee_employ(cls, data: BindEmployees2People, token_dict):
|
||||||
|
selected_staff = Staff.find_one(uu_id=data.staff_uu_id)
|
||||||
|
selected_people = People.find_one(uu_id=data.people_uu_id)
|
||||||
|
if not selected_staff:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Staff record not found",
|
||||||
|
)
|
||||||
|
if not selected_people:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="People record not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
find_one_employee = Employees.filter_active(
|
||||||
|
Employees.staff_id == selected_staff.id,
|
||||||
|
Employees.people_id == None,
|
||||||
|
).data
|
||||||
|
|
||||||
|
staff_name_upper = str(selected_staff.staff_name).upper()
|
||||||
|
if not find_one_employee:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": f"There is no space for new Employee for given staff : {staff_name_upper}",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
)
|
||||||
|
if not data.expiry_starts:
|
||||||
|
data.expiry_starts = datetime.now()
|
||||||
|
|
||||||
|
find_one_employee = find_one_employee[0].update(
|
||||||
|
people_id=selected_people.id,
|
||||||
|
expiry_starts=data.expiry_starts,
|
||||||
|
**token_dict.update_creds,
|
||||||
|
)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Get Employee to People record",
|
||||||
|
"data": find_one_employee.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Employee2PeopleFireEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"caf914fa-0899-4b0b-a85a-3d40fdaa06a5": "company_employee_fire",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def company_employee_fire(cls, data: BindEmployees2People, token_dict):
|
||||||
|
selected_people = People.find_one(uu_id=data.people_uu_id)
|
||||||
|
if not selected_people:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="People record not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
find_one_employee: Employees = Employees.find_one(people_id=selected_people.id)
|
||||||
|
if not find_one_employee:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Employee record not found for given People",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
find_one_employee = find_one_employee.update(
|
||||||
|
people_id=None, **token_dict.update_creds
|
||||||
|
)
|
||||||
|
if not find_one_employee.people_id:
|
||||||
|
employee_history = EmployeeHistory.find_or_create(
|
||||||
|
staff_id=find_one_employee.staff_id,
|
||||||
|
expiry_ends=data.expiry_ends,
|
||||||
|
people_id=selected_people.id,
|
||||||
|
created_by_id=find_one_employee.created_by_id,
|
||||||
|
updated_by_id=find_one_employee.updated_by_id,
|
||||||
|
confirmed_by_id=find_one_employee.confirmed_by_id,
|
||||||
|
replication_id=find_one_employee.replication_id,
|
||||||
|
created_by=find_one_employee.created_by,
|
||||||
|
updated_by=find_one_employee.updated_by,
|
||||||
|
confirmed_by=find_one_employee.confirmed_by,
|
||||||
|
active=find_one_employee.active,
|
||||||
|
is_confirmed=find_one_employee.is_confirmed,
|
||||||
|
deleted=find_one_employee.deleted,
|
||||||
|
expiry_starts=find_one_employee.expiry_starts,
|
||||||
|
is_notification_send=find_one_employee.is_notification_send,
|
||||||
|
cryp_uu_id=find_one_employee.cryp_uu_id,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Employee is fired from Staff",
|
||||||
|
"data": find_one_employee.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Employee record not found for given People",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
EmployeeListEventMethod = EmployeeListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/employee/list")
|
||||||
|
)
|
||||||
|
EmployeeCreateEventMethod = EmployeeCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/employee/create")
|
||||||
|
)
|
||||||
|
EmployeeUpdateEventMethod = EmployeeUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/employee/update")
|
||||||
|
)
|
||||||
|
EmployeePatchEventMethod = EmployeePatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/employee/patch")
|
||||||
|
)
|
||||||
|
Employee2PeopleEmployEventMethod = Employee2PeopleEmployEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/employee/employ")
|
||||||
|
)
|
||||||
|
Employee2PeopleFireEventMethod = Employee2PeopleFireEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/employee/fire")
|
||||||
|
)
|
||||||
148
api_events/events/company/company_staff.py
Normal file
148
api_events/events/company/company_staff.py
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
|
||||||
|
from validations import (
|
||||||
|
InsertStaff,
|
||||||
|
SelectStaff,
|
||||||
|
PatchRecord,
|
||||||
|
ListOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
from databases import Staff, Duties
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class StaffListEventMethods(MethodToEvent):
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8984a519-99bf-4f25-8f34-2e1aebba468c": "staff_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def staff_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
Staff.filter_attr = list_options
|
||||||
|
records = Staff.filter_active(
|
||||||
|
*Staff.get_smart_query(smart_query=list_options.query),
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StaffCreateEventMethods(MethodToEvent):
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8f619257-19fd-404f-b713-7392c588dc36": "staff_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def staff_create(cls, data: InsertStaff, token_dict: EmployeeTokenObject):
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
duties = Duties.find_one(uu_id=data.duties_uu_id)
|
||||||
|
if not duties:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Duties not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict["duties_id"] = duties.id
|
||||||
|
|
||||||
|
created_duty = Staff.find_or_create(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Staff record",
|
||||||
|
"data": created_duty.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StaffGetByUUIDEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "GET"
|
||||||
|
__event_keys__ = {
|
||||||
|
"7724cfbb-c0ee-4261-959b-61b84e88a34f": "staff_get_by_uu_id",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def staff_get_by_uu_id(cls, data: SelectStaff, token_dict):
|
||||||
|
if data.duties_uu_id:
|
||||||
|
duties_id = Duties.find_one(uu_id=data.duties_uu_id)
|
||||||
|
selected_staffs = Staff.filter_active(
|
||||||
|
Staff.duties_id == duties_id.id,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Staff records are listed",
|
||||||
|
"data": [
|
||||||
|
selected_staff.get_dict()
|
||||||
|
for selected_staff in selected_staffs.data
|
||||||
|
],
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Get Staff record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StaffUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5329f35d-ff9d-4656-a831-ba9c8204e483": "staff_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def staff_update(cls, staff_uu_id: str, data, token_dict):
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Update Staff record", "data": {}},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StaffPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"b1cd7c0a-1458-472b-894f-3adc857c8512": "staff_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def staff_patch(cls, staff_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch Staff record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
StaffListEventMethod = StaffListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/staff/list")
|
||||||
|
)
|
||||||
|
StaffCreateEventMethod = StaffCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/staff/create")
|
||||||
|
)
|
||||||
|
StaffGetByUUIDEventMethod = StaffGetByUUIDEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/staff/get_by_duties_uu_id")
|
||||||
|
)
|
||||||
|
StaffUpdateEventMethod = StaffUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/staff/update")
|
||||||
|
)
|
||||||
|
StaffPatchEventMethod = StaffPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/staff/patch")
|
||||||
|
)
|
||||||
0
api_events/events/decision_book/__init__.py
Normal file
0
api_events/events/decision_book/__init__.py
Normal file
220
api_events/events/decision_book/decision_book_decision_book.py
Normal file
220
api_events/events/decision_book/decision_book_decision_book.py
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Build,
|
||||||
|
BuildDecisionBook,
|
||||||
|
Companies,
|
||||||
|
OccupantTypes,
|
||||||
|
)
|
||||||
|
|
||||||
|
from validations import (
|
||||||
|
InsertDecisionBook,
|
||||||
|
ListOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
from api_library.date_time_actions.date_functions import DateTimeLocal
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5c10d6ae-2aee-4243-a7c3-94826d028d13": "building_decision_book_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_list(
|
||||||
|
cls,
|
||||||
|
list_options: ListOptions,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
records = []
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
|
||||||
|
build_id_list_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
build_id_list = build_id_list_query.all()
|
||||||
|
if not build_id_list:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
records = BuildDecisionBook.filter_active(
|
||||||
|
BuildDecisionBook.build_id.in_([build.id for build in build_id_list]),
|
||||||
|
*BuildDecisionBook.get_smart_query(list_options.query),
|
||||||
|
)
|
||||||
|
elif isinstance(token_dict, OccupantTokenObject):
|
||||||
|
records = BuildDecisionBook.filter_active(
|
||||||
|
BuildDecisionBook.build_id == token_dict.selected_occupant.build_id,
|
||||||
|
*BuildDecisionBook.get_smart_query(list_options.query),
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"0a68cb44-271a-4829-81f6-cd99a5f326b4": "building_decision_book_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_create(
|
||||||
|
cls,
|
||||||
|
data: InsertDecisionBook,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
Build.pre_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id
|
||||||
|
)
|
||||||
|
build = Build.filter_active(
|
||||||
|
Build.uu_id == data.build_uu_id,
|
||||||
|
)
|
||||||
|
if not build.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Emloyee UUID {token_dict.selected_company.employee_uu_id} has no build with given UUID {data_dict.get('build_uu_id')}",
|
||||||
|
)
|
||||||
|
data_dict["build_id"] = build.data[0].id
|
||||||
|
if data.resp_company_uu_id:
|
||||||
|
Companies.pre_query = Companies.select_action(
|
||||||
|
duty_id_list=[
|
||||||
|
token_dict.selected_company.duty_id,
|
||||||
|
token_dict.selected_company.bulk_duties_id,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
company = Companies.filter_active(
|
||||||
|
Companies.uu_id == data.resp_company_uu_id
|
||||||
|
)
|
||||||
|
if not company.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Duty UUID {token_dict.selected_company.duty_uu_id} has no company with given UUID {data_dict.get('resp_company_uu_id')}",
|
||||||
|
)
|
||||||
|
data_dict["resp_company_id"] = company.data[0].id
|
||||||
|
data_dict["resp_company_uu_id"] = str(company.data[0].uu_id)
|
||||||
|
|
||||||
|
build_object = build.data[0]
|
||||||
|
decision_period_date = DateTimeLocal.get(build_object.decision_period_date)
|
||||||
|
data_dict["expiry_starts"] = DateTimeLocal.get(
|
||||||
|
DateTimeLocal.now().date().year,
|
||||||
|
int(decision_period_date.date().month),
|
||||||
|
int(decision_period_date.date().day),
|
||||||
|
)
|
||||||
|
data_dict["expiry_ends"] = str(
|
||||||
|
data_dict["expiry_starts"].shift(years=1, days=-1)
|
||||||
|
)
|
||||||
|
data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
|
||||||
|
build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content=dict(
|
||||||
|
message="Decision Book has created",
|
||||||
|
completed=True,
|
||||||
|
data=build_decision_book.get_dict(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
elif isinstance(token_dict, OccupantTokenObject):
|
||||||
|
occupant_manager = OccupantTypes.find_one(
|
||||||
|
occupant_category_type="BU", occupant_code="BU-MNG"
|
||||||
|
)
|
||||||
|
if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail="Only Build Manager can create decision book",
|
||||||
|
)
|
||||||
|
|
||||||
|
occupant_build = Build.find_one(id=token_dict.selected_occupant.build_id)
|
||||||
|
occupant_company = Companies.find_one(
|
||||||
|
id=token_dict.selected_occupant.responsible_company_id
|
||||||
|
)
|
||||||
|
data_dict["build_id"] = occupant_build.id
|
||||||
|
data_dict["build_uu_id"] = str(occupant_build.uu_id)
|
||||||
|
data_dict["resp_company_id"] = occupant_company.id
|
||||||
|
data_dict["resp_company_uu_id"] = str(occupant_company.uu_id)
|
||||||
|
|
||||||
|
decision_period_date = DateTimeLocal.get(
|
||||||
|
occupant_build.decision_period_date
|
||||||
|
)
|
||||||
|
data_dict["expiry_starts"] = DateTimeLocal.get(
|
||||||
|
DateTimeLocal.now().date().year,
|
||||||
|
int(decision_period_date.date().month),
|
||||||
|
int(decision_period_date.date().day),
|
||||||
|
)
|
||||||
|
data_dict["expiry_ends"] = str(
|
||||||
|
data_dict["expiry_starts"].shift(years=1, days=-1)
|
||||||
|
)
|
||||||
|
data_dict["expiry_starts"] = str(data_dict["expiry_starts"])
|
||||||
|
build_decision_book = BuildDecisionBook.find_or_create(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content=dict(
|
||||||
|
message="Decision Book has created",
|
||||||
|
completed=True,
|
||||||
|
data=build_decision_book.get_dict(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29": "building_decision_book_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_update(cls, data: InsertDecisionBook, token_dict: dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"7b58ed84-9a65-4588-994d-30df8366b050": "building_decision_book_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_patch(cls, data: InsertDecisionBook, token_dict: dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookApprovalEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"fc745142-3437-4ca2-89fa-c5a3e2b5c6c2": "building_decision_book_approval",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_approval(cls, data, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
DecisionBookListEventMethod = DecisionBookListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/list")
|
||||||
|
)
|
||||||
|
DecisionBookCreateEventMethod = DecisionBookCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/create")
|
||||||
|
)
|
||||||
|
DecisionBookUpdateEventMethod = DecisionBookUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/update")
|
||||||
|
)
|
||||||
|
DecisionBookPatchEventMethod = DecisionBookPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/patch")
|
||||||
|
)
|
||||||
|
DecisionBookApprovalEventMethod = DecisionBookApprovalEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/approval")
|
||||||
|
)
|
||||||
@@ -0,0 +1,473 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Build,
|
||||||
|
BuildParts,
|
||||||
|
BuildDecisionBook,
|
||||||
|
BuildDecisionBookItems,
|
||||||
|
BuildDecisionBookPerson,
|
||||||
|
BuildDecisionBookPayments,
|
||||||
|
BuildDecisionBookProjects,
|
||||||
|
BuildDecisionBookProjectPerson,
|
||||||
|
ApiEnumDropdown,
|
||||||
|
OccupantTypes,
|
||||||
|
Companies,
|
||||||
|
BuildLivingSpace,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
from api_library.date_time_actions.date_functions import DateTimeLocal
|
||||||
|
|
||||||
|
from validations import (
|
||||||
|
InsertBuildDecisionBookItems,
|
||||||
|
ListDecisionBook,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookDecisionBookItemsListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"eb36de59-8268-4d96-80b6-5d01c12bf0b1": "building_decision_book_items_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_items_list(
|
||||||
|
cls,
|
||||||
|
data: ListDecisionBook,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
decision_book = BuildDecisionBook.find_one(uu_id=data.build_decision_book_uu_id)
|
||||||
|
if not decision_book:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
|
||||||
|
)
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
Build.pre_query = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
filter_expr=[
|
||||||
|
Build.uu_id == decision_book.build_decision_book_uu_id,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
reachable_building = Build.filter_active()
|
||||||
|
if not reachable_building.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
Companies.pre_query = Companies.select_action(
|
||||||
|
duty_id_list=[
|
||||||
|
token_dict.selected_company.duty_id,
|
||||||
|
token_dict.selected_company.bulk_duties_id,
|
||||||
|
],
|
||||||
|
filter_expr=[Companies.id == decision_book.company_id],
|
||||||
|
)
|
||||||
|
reachable_companies = Companies.filter_active()
|
||||||
|
if not reachable_companies.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
records = BuildDecisionBookItems.filter_active(
|
||||||
|
BuildDecisionBookItems.build_decision_book_id == decision_book.id
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content=dict(
|
||||||
|
total_count=records.count,
|
||||||
|
count=len(records.data),
|
||||||
|
message=f"Decision Book Items has found from given Decision Book UUID {data.build_decision_book_uu_id}",
|
||||||
|
completed=True,
|
||||||
|
data=[record.get_dict() for record in records.data],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# BuildDecisionBookItems.pre_query = BuildDecisionBookItems.select_action(
|
||||||
|
# occupant_id=token_dict.occupant_list["occupant_id"]
|
||||||
|
# )
|
||||||
|
# records = BuildDecisionBookItems.filter_active(
|
||||||
|
# *BuildDecisionBookItems.get_smart_query(list_options.query)
|
||||||
|
# )
|
||||||
|
# return return_json_response_from_alchemy(response=records, pagination=list_options)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookDecisionBookItemsCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"dce10509-0da5-46fb-af3c-a81d54d5481c": "building_decision_book_items_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def iterate_over_build_parts(
|
||||||
|
cls,
|
||||||
|
build_parts_list,
|
||||||
|
payment_types,
|
||||||
|
local_date,
|
||||||
|
end_date,
|
||||||
|
unit_price,
|
||||||
|
unit_type,
|
||||||
|
book_payment_dict,
|
||||||
|
unit_price_is_fixed
|
||||||
|
):
|
||||||
|
start_date, payment_return_dict = local_date, {}
|
||||||
|
for build_part_single in build_parts_list:
|
||||||
|
local_date = start_date
|
||||||
|
while local_date.is_between(start_date, end_date, "[]"):
|
||||||
|
local_date = DateTimeLocal.find_last_day_of_month(local_date)
|
||||||
|
payment_amount = unit_price
|
||||||
|
if not unit_price_is_fixed:
|
||||||
|
unit_amount = str(build_part_single.due_part_key).replace(" ", "")
|
||||||
|
unit_amount = unit_amount.replace(str(unit_type).upper(), "")
|
||||||
|
payment_amount = abs(unit_price * float(unit_amount)) * -1
|
||||||
|
payment_amount = -1 * (abs(payment_amount) + (50 - float(abs(payment_amount)) % 50))
|
||||||
|
BuildDecisionBookPayments.create(
|
||||||
|
build_parts_id=build_part_single.id,
|
||||||
|
build_parts_uu_id=str(build_part_single.uu_id),
|
||||||
|
payment_amount=payment_amount,
|
||||||
|
payment_types_id=payment_types.id,
|
||||||
|
payment_types_uu_id=str(payment_types.uu_id),
|
||||||
|
process_date=str(local_date),
|
||||||
|
process_date_m=int(local_date.month),
|
||||||
|
process_date_y=int(local_date.year),
|
||||||
|
period_time=f"{local_date.year}-{str(local_date.month).zfill(2)}",
|
||||||
|
**book_payment_dict
|
||||||
|
)
|
||||||
|
local_date = local_date.shift(days=2)
|
||||||
|
part_key = str(build_part_single.due_part_key).upper()
|
||||||
|
if part_key not in payment_return_dict:
|
||||||
|
payment_return_dict[part_key] = payment_amount
|
||||||
|
|
||||||
|
return payment_return_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_payment_records_for_each_build_part(
|
||||||
|
cls,
|
||||||
|
data_info_type,
|
||||||
|
build_id,
|
||||||
|
unit_price,
|
||||||
|
unit_type,
|
||||||
|
decision_book,
|
||||||
|
decision_book_item,
|
||||||
|
unit_price_is_fixed,
|
||||||
|
currency,
|
||||||
|
debit_start_date: str = None,
|
||||||
|
debit_end_date: str = None,
|
||||||
|
):
|
||||||
|
build_parts_list = BuildParts.filter_active(
|
||||||
|
BuildParts.human_livable == True,
|
||||||
|
BuildParts.build_id == build_id,
|
||||||
|
)
|
||||||
|
book_payment_dict = dict(
|
||||||
|
payment_plan_time_periods=str(data_info_type.key),
|
||||||
|
build_decision_book_item_id=decision_book_item.id,
|
||||||
|
build_decision_book_item_uu_id=str(decision_book_item.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
currency=currency,
|
||||||
|
)
|
||||||
|
payment_types = ApiEnumDropdown.get_debit_search(search_debit="DT-D")
|
||||||
|
if data_info_type.key == "BDT-D":
|
||||||
|
local_date = DateTimeLocal.get(DateTimeLocal.get(decision_book.expiry_starts).date())
|
||||||
|
end_date = DateTimeLocal.get(DateTimeLocal.get(decision_book.expiry_ends).date())
|
||||||
|
return cls.iterate_over_build_parts(
|
||||||
|
build_parts_list=build_parts_list.data,
|
||||||
|
payment_types=payment_types,
|
||||||
|
local_date=local_date,
|
||||||
|
end_date=end_date,
|
||||||
|
unit_price=unit_price,
|
||||||
|
unit_type=unit_type,
|
||||||
|
unit_price_is_fixed=unit_price_is_fixed,
|
||||||
|
book_payment_dict=book_payment_dict,
|
||||||
|
)
|
||||||
|
elif data_info_type.key == "BDT-A":
|
||||||
|
local_date = DateTimeLocal.get(DateTimeLocal.get(debit_start_date).date())
|
||||||
|
end_date = DateTimeLocal.get(DateTimeLocal.get(debit_end_date).date())
|
||||||
|
return cls.iterate_over_build_parts(
|
||||||
|
build_parts_list=build_parts_list.data,
|
||||||
|
payment_types=payment_types,
|
||||||
|
local_date=local_date,
|
||||||
|
end_date=end_date,
|
||||||
|
unit_price=unit_price,
|
||||||
|
unit_type=unit_type,
|
||||||
|
unit_price_is_fixed=unit_price_is_fixed,
|
||||||
|
book_payment_dict=book_payment_dict,
|
||||||
|
)
|
||||||
|
elif data_info_type.key == "BDT-R" or data_info_type.key == "BDT-L":
|
||||||
|
local_date = DateTimeLocal.get(DateTimeLocal.get(debit_start_date).date())
|
||||||
|
end_date = DateTimeLocal.get(DateTimeLocal.get(debit_end_date).date())
|
||||||
|
decision_date = DateTimeLocal.get(decision_book.expiry_starts).date()
|
||||||
|
meeting_date = DateTimeLocal.get(decision_book.meeting_date).date()
|
||||||
|
|
||||||
|
already_book_projects = BuildDecisionBookProjects.filter_all(
|
||||||
|
BuildDecisionBookProjects.build_decision_book_id==decision_book.id,
|
||||||
|
BuildDecisionBookProjects.project_type==f"{decision_book.decision_type}_{data_info_type.key}",
|
||||||
|
)
|
||||||
|
management_room = BuildParts.find_one(
|
||||||
|
build_id=build_id, part_no=0, active=True, is_confirmed=True
|
||||||
|
)
|
||||||
|
occupant_man = OccupantTypes.find_one(
|
||||||
|
occupant_code="MT-VPR", occupant_category_type="MT"
|
||||||
|
)
|
||||||
|
manager_living_space = BuildLivingSpace.filter_by_active(
|
||||||
|
build_parts_id=management_room.id, occupant_type=occupant_man.id,
|
||||||
|
)
|
||||||
|
if not manager_living_space.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=f"{occupant_man.occupant_description} Living Space is not found. Check manager living space and try again",
|
||||||
|
)
|
||||||
|
already_book_project_count = already_book_projects.count + 1
|
||||||
|
manager_living_space = manager_living_space.get(1)
|
||||||
|
book_project_dict = dict(
|
||||||
|
project_no=f"{data_info_type.key}_{decision_date.year}_{already_book_project_count}",
|
||||||
|
project_name=f"{str(meeting_date)}_{decision_book.decision_type} Project {already_book_projects.count + 1}",
|
||||||
|
project_start_date=str(local_date),
|
||||||
|
project_stop_date=str(end_date),
|
||||||
|
project_type=f"{decision_book.decision_type}_{data_info_type.key}",
|
||||||
|
project_note=f"Fill later",
|
||||||
|
build_decision_book_id=decision_book.id,
|
||||||
|
build_decision_book_uu_id=str(decision_book.uu_id),
|
||||||
|
build_decision_book_item_id=decision_book_item.id,
|
||||||
|
build_decision_book_item_uu_id=str(decision_book_item.uu_id),
|
||||||
|
project_response_living_space_id=manager_living_space.id,
|
||||||
|
project_response_living_space_uu_id=str(manager_living_space.uu_id),
|
||||||
|
)
|
||||||
|
book_project_created = BuildDecisionBookProjects.find_or_create(**book_project_dict)
|
||||||
|
if not book_project_created.is_found:
|
||||||
|
decision_book_item.update(
|
||||||
|
item_comment=f"{book_project_created.project_no}_{book_project_created.project_name} "
|
||||||
|
f"is assigned to {occupant_man.occupant_description}"
|
||||||
|
)
|
||||||
|
project_lead = ApiEnumDropdown.find_one(
|
||||||
|
key="PTT-LDR", enum_class="ProjectTeamTypes"
|
||||||
|
)
|
||||||
|
project_person = BuildDecisionBookProjectPerson.find_or_create(
|
||||||
|
build_decision_book_project_id=book_project_created.id,
|
||||||
|
build_decision_book_project_uu_id=str(book_project_created.uu_id),
|
||||||
|
living_space_id=manager_living_space.id,
|
||||||
|
living_space_uu_id=str(manager_living_space.uu_id),
|
||||||
|
project_team_type_id=project_lead.id,
|
||||||
|
project_team_type_uu_id=str(project_lead.uu_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
elif data_info_type.key == "BDT-SF":
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="BDT-SF is not implemented yet. Check info type and try again",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Payment Info Type is not valid. Check payment type and try again",
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_items_create(
|
||||||
|
cls,
|
||||||
|
data: InsertBuildDecisionBookItems,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
|
detail="No employee can reach this event. An notification is send to admin about event registration",
|
||||||
|
)
|
||||||
|
elif isinstance(token_dict, OccupantTokenObject):
|
||||||
|
data_dict = data.dump()
|
||||||
|
occupant_wrt = OccupantTypes.find_one(
|
||||||
|
occupant_code="MT-WRT", occupant_category_type="MT"
|
||||||
|
)
|
||||||
|
|
||||||
|
if token_dict.selected_occupant.occupant_type_id != occupant_wrt.id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Only WRITER can create decision book item. Check your occupant type and try again",
|
||||||
|
)
|
||||||
|
|
||||||
|
decision_book_person = BuildDecisionBookPerson.find_one(token=data.token)
|
||||||
|
decision_book = BuildDecisionBook.find_one(
|
||||||
|
id=decision_book_person.build_decision_book_id
|
||||||
|
)
|
||||||
|
BuildDecisionBookItems.check_meeting_is_valid_to_start_add_attendance(
|
||||||
|
decision_book=decision_book,
|
||||||
|
token_dict=token_dict,
|
||||||
|
)
|
||||||
|
book_items = BuildDecisionBookItems.filter_active(
|
||||||
|
BuildDecisionBookItems.build_decision_book_id == decision_book.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict["item_order"] = int(book_items.count) + 1
|
||||||
|
data_dict["build_decision_book_id"] = decision_book.id
|
||||||
|
data_dict["build_decision_book_uu_id"] = str(decision_book.uu_id)
|
||||||
|
data_dict["is_confirmed"] = True
|
||||||
|
|
||||||
|
data_info_types, data_info_type = ApiEnumDropdown.due_type_search(), None
|
||||||
|
for info_type in data_info_types:
|
||||||
|
if str(info_type.uu_id) == data_dict["info_type_uu_id"]:
|
||||||
|
data_info_type = info_type
|
||||||
|
break
|
||||||
|
if not data_info_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Info Type is not valid. Check info type and try again",
|
||||||
|
)
|
||||||
|
|
||||||
|
if str(data_info_type.key).upper() in ["BDT-A", "BDT-R", "BDT-L", "BDT-SF"]:
|
||||||
|
if not data_dict["debit_start_date"] or not data_dict["debit_end_date"]:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Debit Start Date and Debit End Date is required for this payment type. "
|
||||||
|
"Check debit start date and debit end date and try again",
|
||||||
|
)
|
||||||
|
|
||||||
|
data_dict["info_type_id"] = data_info_type.id
|
||||||
|
data_dict["info_type_uu_id"] = str(data_info_type.uu_id)
|
||||||
|
unit_price, unit_type = float(data_dict["unit_price"]), str(data_dict["unit_type"])
|
||||||
|
debit_start_date, debit_end_date = data_dict["debit_start_date"], data_dict["debit_end_date"]
|
||||||
|
currency = data_dict["currency"]
|
||||||
|
del (
|
||||||
|
data_dict["token"],
|
||||||
|
data_dict["unit_price"],
|
||||||
|
data_dict["unit_type"],
|
||||||
|
data_dict["unit_price_is_fixed"],
|
||||||
|
data_dict["debit_start_date"],
|
||||||
|
data_dict["debit_end_date"],
|
||||||
|
data_dict["currency"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if new_decision_book_item := BuildDecisionBookItems.find_or_create(**data_dict):
|
||||||
|
if new_decision_book_item.is_found:
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content=dict(
|
||||||
|
message=f"Decision Book Item is already exist for given Decision Book UUID {decision_book.uu_id}",
|
||||||
|
completed=True,
|
||||||
|
data=new_decision_book_item.get_dict(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if created_payment_records_dict := cls.create_payment_records_for_each_build_part(
|
||||||
|
data_info_type=data_info_type,
|
||||||
|
build_id=decision_book.build_id,
|
||||||
|
unit_price=unit_price,
|
||||||
|
unit_type=unit_type.upper(),
|
||||||
|
decision_book=decision_book,
|
||||||
|
decision_book_item=new_decision_book_item,
|
||||||
|
unit_price_is_fixed=data.unit_price_is_fixed,
|
||||||
|
debit_start_date=debit_start_date,
|
||||||
|
debit_end_date=debit_end_date,
|
||||||
|
currency=currency
|
||||||
|
):
|
||||||
|
if data_info_type.key == "BDT-A" or data_info_type.key == "BDT-D":
|
||||||
|
if data_info_type.key == "BDT-D":
|
||||||
|
item_comment = "Regular Payment Plan : "
|
||||||
|
else:
|
||||||
|
item_comment = "Additional Payment Plan : "
|
||||||
|
for key, value in dict(sorted(
|
||||||
|
created_payment_records_dict.items(),
|
||||||
|
key=lambda x: x[1],
|
||||||
|
reverse=True
|
||||||
|
)).items():
|
||||||
|
item_comment += f" {key} | {abs(float(value))} {currency}, "
|
||||||
|
item_comment = item_comment[:-2]
|
||||||
|
new_decision_book_item.update(
|
||||||
|
item_comment=item_comment
|
||||||
|
)
|
||||||
|
new_decision_book_item.update(is_payment_created=True)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content=dict(
|
||||||
|
message=f"Decision Book Item has created for given Decision Book UUID {decision_book.uu_id}",
|
||||||
|
completed=True,
|
||||||
|
data=new_decision_book_item.get_dict(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Decision Book Item is not created. Check info type and info no and try again. Unique constraint index is implemented for info type and info no",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookDecisionBookItemsUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"f0fdfe1b-806b-4175-ad50-a1a165c0dfb7": "building_decision_book_items_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_items_update(
|
||||||
|
cls,
|
||||||
|
data: InsertBuildDecisionBookItems,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookDecisionBookItemsPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"42328809-b516-477b-82cc-2d6fadf28843": "building_decision_book_items_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_items_patch(
|
||||||
|
cls,
|
||||||
|
data: InsertBuildDecisionBookItems,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
DecisionBookDecisionBookItemsListEventMethod = (
|
||||||
|
DecisionBookDecisionBookItemsListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/items/list")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
DecisionBookDecisionBookItemsCreateEventMethod = (
|
||||||
|
DecisionBookDecisionBookItemsCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/items/create")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
DecisionBookDecisionBookItemsUpdateEventMethod = (
|
||||||
|
DecisionBookDecisionBookItemsUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/items/update")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
DecisionBookDecisionBookItemsPatchEventMethod = (
|
||||||
|
DecisionBookDecisionBookItemsPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/items/patch")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# if data.info_no is None:
|
||||||
|
# data_dict["info_no"] = data_dict["item_order"]
|
||||||
|
# elif data.occupant_types_uu_id:
|
||||||
|
# data_dict["info_type"] = None
|
||||||
|
# if occupant_type := OccupantTypes.find_one(
|
||||||
|
# uu_id=data.occupant_types_uu_id
|
||||||
|
# ):
|
||||||
|
# if (
|
||||||
|
# str(data.occupant_types_uu_id)
|
||||||
|
# in OccupantTypes.get_manager_occupant_type()
|
||||||
|
# ):
|
||||||
|
# if BuildDecisionBookItems.find_one(
|
||||||
|
# build_decision_book_id=decision_book.id,
|
||||||
|
# occupant_type=occupant_type.id,
|
||||||
|
# ):
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
# detail="This Occupant Type is already exist for given Decision Book UUID. Check occupant type and try again",
|
||||||
|
# )
|
||||||
|
# data_dict["occupant_type"] = occupant_type.id
|
||||||
|
# data_dict["occupant_type_uu_id"] = str(occupant_type.uu_id)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookDecisionBookItemsDebitsEvents(MethodToEvent): ...
|
||||||
@@ -0,0 +1,443 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
BuildDecisionBook,
|
||||||
|
BuildDecisionBookPerson,
|
||||||
|
BuildDecisionBookInvitations,
|
||||||
|
Users,
|
||||||
|
BuildLivingSpace,
|
||||||
|
BuildParts,
|
||||||
|
BuildDecisionBookPersonOccupants,
|
||||||
|
People,
|
||||||
|
OccupantTypes,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_validations import (
|
||||||
|
ListOptions,
|
||||||
|
RemoveDecisionBookPerson,
|
||||||
|
DecisionBookDecisionBookInvitationsAttend,
|
||||||
|
DecisionBookDecisionBookInvitationsUpdate,
|
||||||
|
DecisionBookDecisionBookInvitationsAssign,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookPersonListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"ea324dc0-3b08-4896-9040-7fa0401a176f": "building_decision_book_person_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_person_list(
|
||||||
|
cls, data: ListOptions, token_dict: EmployeeTokenObject
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookPersonAddEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e346f720-880b-4b07-93d6-9ac76fbbaa33": "building_decision_book_person_add",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_person_add(
|
||||||
|
cls,
|
||||||
|
data: DecisionBookDecisionBookInvitationsUpdate,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Employee cannot create decision book invitations",
|
||||||
|
)
|
||||||
|
elif isinstance(token_dict, OccupantTokenObject):
|
||||||
|
decision_book = BuildDecisionBook.find_one(
|
||||||
|
uu_id=data.build_decision_book_uu_id
|
||||||
|
)
|
||||||
|
if not decision_book:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"No Decision Book is match with given UUID {data.build_decision_book_uu_id}",
|
||||||
|
)
|
||||||
|
manager_occupant_type = OccupantTypes.find_or_abort(
|
||||||
|
occupant_code="BU-MNG", occupant_category_type="BU"
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
not manager_occupant_type.uu_id
|
||||||
|
== token_dict.selected_occupant.occupant_type_uu_id
|
||||||
|
):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Only Build Manager can update the invitation",
|
||||||
|
)
|
||||||
|
|
||||||
|
assign_occupant_type = OccupantTypes.find_or_abort(
|
||||||
|
uu_id=data.occupant_type_uu_id,
|
||||||
|
occupant_category_type="MT",
|
||||||
|
)
|
||||||
|
if not assign_occupant_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
|
||||||
|
)
|
||||||
|
|
||||||
|
manger_book_person = BuildDecisionBookPerson.find_one(
|
||||||
|
token=data.token,
|
||||||
|
build_decision_book_uu_id=data.build_decision_book_uu_id,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
)
|
||||||
|
if not manger_book_person:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Manager person not found. Please check token",
|
||||||
|
)
|
||||||
|
book_invite = BuildDecisionBookInvitations.find_one(
|
||||||
|
id=manger_book_person.invite_id,
|
||||||
|
build_id=token_dict.selected_occupant.build_id,
|
||||||
|
)
|
||||||
|
if not book_invite:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Invitation not found. Please check token",
|
||||||
|
)
|
||||||
|
selected_book_person = BuildDecisionBookPerson.find_one(
|
||||||
|
invite_id=book_invite.id,
|
||||||
|
person_uu_id=data.person_uu_id,
|
||||||
|
is_confirmed=True,
|
||||||
|
active=True,
|
||||||
|
)
|
||||||
|
if not selected_book_person:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Selected person is not in the invitation list. Please check {data.person_uu_id}",
|
||||||
|
)
|
||||||
|
selected_book_person.update(
|
||||||
|
occupant_type=assign_occupant_type.id,
|
||||||
|
occupant_type_uu_id=str(assign_occupant_type.uu_id),
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Invitation is updated",
|
||||||
|
"data": selected_book_person.get_dict(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookPersonRemoveEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "DELETE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"30588869-04cd-48ea-ad00-0e4f8dd7f735": "building_decision_book_people_remove",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def building_decision_book_people_remove(
|
||||||
|
cls, data: RemoveDecisionBookPerson, token_dict: EmployeeTokenObject
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookPersonAttendEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"bdcba521-0116-441c-ace1-84c5b68c86c7": "decision_book_invitations_attend",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decision_book_invitations_attend(
|
||||||
|
cls,
|
||||||
|
data: DecisionBookDecisionBookInvitationsAttend,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Employee cannot create decision book invitations",
|
||||||
|
)
|
||||||
|
|
||||||
|
token_user = Users.find_one(id=token_dict.user_id)
|
||||||
|
invitation_person = BuildDecisionBookPerson.find_one(
|
||||||
|
token=data.token, active=True, is_confirmed=True
|
||||||
|
)
|
||||||
|
if not invitation_person:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Invitation for the this specific user is not found. Please check token",
|
||||||
|
)
|
||||||
|
|
||||||
|
# is_token_valid = token_dict.person_id == invitation_person.person_id
|
||||||
|
# if not invitation_person.vicarious_person_id:
|
||||||
|
# if not invitation_person or not is_token_valid:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
# detail=f"Invitation for the user {token_user.email} is not valid. Please check token",
|
||||||
|
# )
|
||||||
|
# todo check if vicarious person is valid
|
||||||
|
invitation = BuildDecisionBookInvitations.find_one(
|
||||||
|
id=invitation_person.invite_id,
|
||||||
|
build_id=token_dict.selected_occupant.build_id,
|
||||||
|
)
|
||||||
|
if not invitation:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Invitation not found. Please check invitation uuid : {invitation.uu_id}",
|
||||||
|
)
|
||||||
|
invitation_person.update(
|
||||||
|
is_attending=bool(data.is_attend), vicarious_person_id=None
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Attendance is updated. Thank you for your response",
|
||||||
|
"data": {
|
||||||
|
"is_attending": bool(data.is_attend),
|
||||||
|
"user_uuid": str(token_user.uu_id),
|
||||||
|
"invitation_uuid": str(invitation.uu_id),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DecisionBookPersonAssignOccupantEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c0b65098-9c79-4212-b1d0-c7e7836cf141": "decision_book_invitations_assign_occupant",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decision_book_invitations_assign_occupant(
|
||||||
|
cls,
|
||||||
|
data: DecisionBookDecisionBookInvitationsAssign,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Employee cannot create decision book invitations",
|
||||||
|
)
|
||||||
|
|
||||||
|
book_person_manager = BuildDecisionBookPerson.find_one(
|
||||||
|
token=data.token,
|
||||||
|
build_living_space_id=token_dict.selected_occupant.living_space_id,
|
||||||
|
active=True,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
manager_occupant_type = OccupantTypes.find_or_abort(
|
||||||
|
occupant_code="BU-MNG", occupant_category_type="BU"
|
||||||
|
)
|
||||||
|
book_person_manager.check_occupant_type(manager_occupant_type)
|
||||||
|
|
||||||
|
# supervisor_occupant_type = OccupantTypes.find_or_abort(occupant_code="BU-SPV", occupant_category_type="BU")
|
||||||
|
# book_person_supervisor.check_occupant_type(supervisor_occupant_type)
|
||||||
|
|
||||||
|
invitation = BuildDecisionBookInvitations.find_one(
|
||||||
|
id=book_person_manager.invite_id,
|
||||||
|
build_id=token_dict.selected_occupant.build_id,
|
||||||
|
active=True,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
if not invitation:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Invitation not found. Please check token",
|
||||||
|
)
|
||||||
|
|
||||||
|
assign_occupant_type = OccupantTypes.find_or_abort(
|
||||||
|
uu_id=data.occupant_type_uu_id, is_confirmed=True, active=True
|
||||||
|
)
|
||||||
|
if not assign_occupant_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Occupant type must be a Meeting Type {data.occupant_type_uu_id} is not a MT type occupant",
|
||||||
|
)
|
||||||
|
|
||||||
|
build_parts_of_token = BuildParts.filter_active(
|
||||||
|
BuildParts.build_id == token_dict.selected_occupant.build_id,
|
||||||
|
)
|
||||||
|
selected_living_space = BuildLivingSpace.filter_active(
|
||||||
|
BuildLivingSpace.uu_id == data.build_living_space_uu_id,
|
||||||
|
BuildLivingSpace.build_parts_id.in_(
|
||||||
|
[build.id for build in build_parts_of_token.data]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if not selected_living_space.data:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Person not found. Please check person uuid",
|
||||||
|
)
|
||||||
|
|
||||||
|
selected_living_space = selected_living_space.get(1)
|
||||||
|
book_person_to_assign: BuildDecisionBookPerson = (
|
||||||
|
BuildDecisionBookPerson.find_one(
|
||||||
|
build_living_space_id=selected_living_space.id,
|
||||||
|
invite_id=invitation.id,
|
||||||
|
active=True,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if not book_person_to_assign:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail=f"Person not found in the invitation list. Please check person uuid: {data.person_uu_id}",
|
||||||
|
)
|
||||||
|
if not book_person_to_assign.is_attending:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=f"Person is declined the invitation. This person is not attending the meeting. "
|
||||||
|
f"Please check person uuid: {data.person_uu_id}. Invite UUID: {invitation.uu_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
if assign_occupant_type.occupant_code in ("MT-PRS", "MT-WRT"):
|
||||||
|
occupant_type_unique = OccupantTypes.find_or_abort(
|
||||||
|
occupant_code=assign_occupant_type.occupant_code,
|
||||||
|
occupant_category_type="MT",
|
||||||
|
)
|
||||||
|
if assigned_book_person_occupant := BuildDecisionBookPersonOccupants.find_one(
|
||||||
|
invite_id=invitation.id,
|
||||||
|
occupant_type_id=occupant_type_unique.id,
|
||||||
|
active=True,
|
||||||
|
is_confirmed=True,
|
||||||
|
):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=f"Only one person can be assigned to {assign_occupant_type.occupant_code} type"
|
||||||
|
f" {assigned_book_person_occupant.uu_id} is already assigned",
|
||||||
|
)
|
||||||
|
|
||||||
|
if assign_occupant_type.occupant_code == "BU-MNG":
|
||||||
|
person_occupant_manager = BuildDecisionBookPersonOccupants.find_one(
|
||||||
|
invite_id=invitation.id,
|
||||||
|
occupant_type_id=manager_occupant_type.id,
|
||||||
|
active=True,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
person_occupant_manager.delete(destroy=True)
|
||||||
|
|
||||||
|
book_person_to_assign.add_occupant_type(
|
||||||
|
occupant_type=assign_occupant_type,
|
||||||
|
build_living_space_id=selected_living_space.id,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Invitation is updated",
|
||||||
|
"data": book_person_to_assign.get_dict(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
DecisionBookPersonListEventMethod = DecisionBookPersonListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/people/list")
|
||||||
|
)
|
||||||
|
DecisionBookPersonAddEventMethod = DecisionBookPersonAddEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/people/add")
|
||||||
|
)
|
||||||
|
DecisionBookPersonRemoveEventMethod = DecisionBookPersonRemoveEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/people/remove")
|
||||||
|
)
|
||||||
|
DecisionBookPersonAttendEventMethod = DecisionBookPersonAttendEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/invitations/attend")
|
||||||
|
)
|
||||||
|
DecisionBookPersonAssignOccupantEventMethod = (
|
||||||
|
DecisionBookPersonAssignOccupantEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/invitations/assign")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build.pre_query = Build.select_action(
|
||||||
|
# employee_id=token_dict.selected_company.employee_id,
|
||||||
|
# filter_expr=[
|
||||||
|
# Build.id == decision_book.build_id,
|
||||||
|
# ],
|
||||||
|
# )
|
||||||
|
# reachable_building = Build.filter_active()
|
||||||
|
# if not reachable_building.data:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
# detail=f"No building is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# Companies.pre_query = Companies.select_action(
|
||||||
|
# duty_id_list=[
|
||||||
|
# token_dict.selected_company.duty_id,
|
||||||
|
# token_dict.selected_company.bulk_duties_id,
|
||||||
|
# ],
|
||||||
|
# filter_expr=[Companies.id == decision_book.resp_company_id],
|
||||||
|
# )
|
||||||
|
# reachable_companies = Companies.filter_active()
|
||||||
|
# if not reachable_companies.data:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
# detail=f"No company is match with given Employee UUID {token_dict.selected_company.employee_uu_id}",
|
||||||
|
# )
|
||||||
|
# person_to_add = People.find_one(uu_id=data.person_uu_id)
|
||||||
|
# if not person_to_add:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
# detail=f"No person is match with given UUID {data.person_uu_id}",
|
||||||
|
# )
|
||||||
|
# management_typecode = ApiEnumDropdown.filter_active(
|
||||||
|
# ApiEnumDropdown.uu_id == data.management_typecode_uu_id,
|
||||||
|
# ApiEnumDropdown.enum_class.in_("BuildManagementType", "BuildDuesTypes"),
|
||||||
|
# )
|
||||||
|
# if not management_typecode.data:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
# detail=f"No management type is match with given UUID {data.management_typecode_uu_id}",
|
||||||
|
# )
|
||||||
|
# condition_to_met = (
|
||||||
|
# data.management_typecode_uu_id
|
||||||
|
# in ApiEnumDropdown.get_management_type_codes_list()
|
||||||
|
# )
|
||||||
|
# any_type_already = BuildDecisionBookPerson.find_one(
|
||||||
|
# build_decision_book_id=decision_book.id,
|
||||||
|
# management_typecode=data.management_typecode_uu_id,
|
||||||
|
# )
|
||||||
|
# if condition_to_met and any_type_already:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
# detail=f"Management type is already exist in given Decision Book UUID {data.build_decision_book_uu_id}.",
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# data_dict.pop("build_decision_book_uu_id", None)
|
||||||
|
# data_dict.pop("person_uu_id", None)
|
||||||
|
# data_dict["management_typecode"] = data_dict.pop(
|
||||||
|
# "management_typecode_uu_id", None
|
||||||
|
# )
|
||||||
|
# data_dict["build_decision_book_id"] = decision_book.id
|
||||||
|
# data_dict["person_id"] = person_to_add.id
|
||||||
|
#
|
||||||
|
# created = BuildDecisionBookPerson.find_or_create(**data_dict)
|
||||||
|
# if created.is_found:
|
||||||
|
# raise HTTPException(
|
||||||
|
# status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
# detail=f"Decision Book Person is already exist in given Decision Book UUID {data.build_decision_book_uu_id}.",
|
||||||
|
# )
|
||||||
|
# return JSONResponse(
|
||||||
|
# status_code=status.HTTP_200_OK,
|
||||||
|
# content=dict(
|
||||||
|
# message=f"Decision Book Person has added for given Decision Book UUID {data.build_decision_book_uu_id}",
|
||||||
|
# completed=True,
|
||||||
|
# data=created.get_dict(),
|
||||||
|
# ),
|
||||||
|
# )
|
||||||
286
api_events/events/decision_book/decision_book_invitations.py
Normal file
286
api_events/events/decision_book/decision_book_invitations.py
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Build,
|
||||||
|
BuildLivingSpace,
|
||||||
|
BuildParts,
|
||||||
|
BuildDecisionBookInvitations,
|
||||||
|
BuildDecisionBookPerson,
|
||||||
|
BuildDecisionBook,
|
||||||
|
BuildDecisionBookPersonOccupants,
|
||||||
|
OccupantTypes,
|
||||||
|
Users,
|
||||||
|
ApiEnumDropdown,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_validations import (
|
||||||
|
DecisionBookDecisionBookInvitationsUpdate,
|
||||||
|
DecisionBookDecisionBookInvitations,
|
||||||
|
)
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
from api_library.date_time_actions.date_functions import DateTimeLocal
|
||||||
|
|
||||||
|
|
||||||
|
class BuildDecisionBookInvitationsListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e2277528-8c9c-4c0c-ae64-3ce80cae664b": "decision_book_invitations_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decision_book_invitations_list(
|
||||||
|
cls,
|
||||||
|
data,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class BuildDecisionBookInvitationsCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"d0bfa20c-841d-421c-98e6-d308f938d16a": "decision_book_invitations_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decision_book_invitations_create(
|
||||||
|
cls,
|
||||||
|
data: DecisionBookDecisionBookInvitations,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Employee cannot create decision book invitations",
|
||||||
|
)
|
||||||
|
# Check token posses the occupant type of Build Manager
|
||||||
|
occupant_manager = OccupantTypes.find_one(
|
||||||
|
occupant_category_type="BU", occupant_code="BU-MNG"
|
||||||
|
)
|
||||||
|
if not token_dict.selected_occupant.occupant_type_id == occupant_manager.id:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail="Only Build Manager can create decision book",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check decision book is valid for this token and building
|
||||||
|
decision_book = BuildDecisionBook.find_one(
|
||||||
|
uu_id=data.build_decision_book_uu_id,
|
||||||
|
build_id=token_dict.selected_occupant.build_id,
|
||||||
|
)
|
||||||
|
if not decision_book:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Decision book not found. Please create decision book first",
|
||||||
|
)
|
||||||
|
occupant_building = Build.find_one(id=token_dict.selected_occupant.build_id)
|
||||||
|
|
||||||
|
# Check meeting type is valid
|
||||||
|
meeting_type = ApiEnumDropdown.find_one(
|
||||||
|
enum_class="MeetingTypes",
|
||||||
|
)
|
||||||
|
if not meeting_type:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Meeting type not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check planned decision book date is valid
|
||||||
|
if (
|
||||||
|
not DateTimeLocal.get(data.planned_date).date()
|
||||||
|
>= DateTimeLocal.shift(days=1).date()
|
||||||
|
):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Planned date must be greater than today",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create an invitation for specific invitation type to start invite sending process
|
||||||
|
book_invitation = BuildDecisionBookInvitations.find_or_create(
|
||||||
|
build_id=token_dict.selected_occupant.build_id,
|
||||||
|
build_uu_id=token_dict.selected_occupant.build_uuid,
|
||||||
|
decision_book_id=decision_book.id,
|
||||||
|
decision_book_uu_id=str(decision_book.uu_id),
|
||||||
|
invitation_type=meeting_type.key,
|
||||||
|
living_part_count=occupant_building.livable_part_count,
|
||||||
|
living_part_percentage=0.51,
|
||||||
|
message=data.message,
|
||||||
|
planned_date=data.planned_date,
|
||||||
|
planned_date_expires=str(
|
||||||
|
DateTimeLocal.get(data.planned_date).shift(days=15).date()
|
||||||
|
),
|
||||||
|
expiry_ends=str(DateTimeLocal.get(data.planned_date).shift(days=15).date()),
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
if book_invitation.is_found:
|
||||||
|
detail_message = (
|
||||||
|
f"Invitation with: {str(book_invitation.planned_date)} already exists"
|
||||||
|
f" for {book_invitation.invitation_type}"
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=detail_message,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get all the parts of the building that is occupant in token
|
||||||
|
build_parts = BuildParts.filter_active(
|
||||||
|
BuildParts.build_id == occupant_building.id
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get all build living spaces that is found in building with distinct person id
|
||||||
|
occupants = OccupantTypes.filter_all()
|
||||||
|
build_living_spaces_people = (
|
||||||
|
BuildLivingSpace.filter_active(
|
||||||
|
BuildLivingSpace.build_parts_id.in_(
|
||||||
|
[build_part.id for build_part in build_parts.data]
|
||||||
|
),
|
||||||
|
BuildLivingSpace.occupant_type.in_(
|
||||||
|
[occupant.id for occupant in occupants.data]
|
||||||
|
),
|
||||||
|
filter_records=False,
|
||||||
|
)
|
||||||
|
.query.distinct(BuildLivingSpace.person_id)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
if not build_living_spaces_people:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="No living spaces found for the building",
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f"Tnvite UUID : {book_invitation.uu_id} Message : {data.message} Planned date : {data.planned_date}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Send invitation to all the users as attend and update the manager as build manager
|
||||||
|
attendance_occupant_type = OccupantTypes.find_or_abort(
|
||||||
|
occupant_code="MT-ATT", occupant_category_type="MT"
|
||||||
|
)
|
||||||
|
manager_occupant_type = OccupantTypes.find_or_abort(
|
||||||
|
occupant_code="BU-MNG", occupant_category_type="BU"
|
||||||
|
)
|
||||||
|
|
||||||
|
build_decision_book_person_dict = dict(
|
||||||
|
build_decision_book_id=decision_book.id,
|
||||||
|
build_decision_book_uu_id=str(decision_book.uu_id),
|
||||||
|
invite_id=book_invitation.id,
|
||||||
|
invite_uu_id=str(book_invitation.uu_id),
|
||||||
|
send_date=str(DateTimeLocal.now().date()),
|
||||||
|
expiry_starts=decision_book.expiry_starts,
|
||||||
|
expiry_ends=decision_book.expiry_ends,
|
||||||
|
is_confirmed=True,
|
||||||
|
)
|
||||||
|
# Check if the invitation is already created at database
|
||||||
|
for build_living_spaces_user in build_living_spaces_people:
|
||||||
|
if invite := BuildDecisionBookPerson.find_one(
|
||||||
|
invite_id=book_invitation.id,
|
||||||
|
build_living_space_id=build_living_spaces_user.id,
|
||||||
|
):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=f"Invitation already send to {build_living_spaces_user.email} "
|
||||||
|
f"for invite {invite.uu_id} date : {str(book_invitation.planned_date)}",
|
||||||
|
)
|
||||||
|
|
||||||
|
invitations_person = BuildDecisionBookPerson.find_or_create(
|
||||||
|
**build_decision_book_person_dict,
|
||||||
|
build_living_space_id=build_living_spaces_user.id,
|
||||||
|
build_living_space_uu_id=str(build_living_spaces_user.uu_id),
|
||||||
|
person_id=build_living_spaces_user.person_id,
|
||||||
|
token=Users.generate_token(40),
|
||||||
|
)
|
||||||
|
invitations_person.add_occupant_type(occupant_type=attendance_occupant_type)
|
||||||
|
if invitations_person and not invitations_person.is_found:
|
||||||
|
print(f'"{invitations_person.token}",')
|
||||||
|
spaces_user = Users.find_one(
|
||||||
|
active=True,
|
||||||
|
is_confirmed=True,
|
||||||
|
person_id=build_living_spaces_user.person_id,
|
||||||
|
)
|
||||||
|
# print(
|
||||||
|
# f"Invitation is send : {spaces_user.email} "
|
||||||
|
# f"Token : {invitations_person.token} "
|
||||||
|
# f"Send Date : {str(invitations_person.send_date.date())}"
|
||||||
|
# )
|
||||||
|
|
||||||
|
manager_living_spaces = BuildLivingSpace.filter_active(
|
||||||
|
BuildLivingSpace.person_id == token_dict.person_id,
|
||||||
|
)
|
||||||
|
manager_people = BuildDecisionBookPerson.filter_active(
|
||||||
|
BuildDecisionBookPerson.invite_id == book_invitation.id,
|
||||||
|
BuildDecisionBookPerson.build_living_space_id.in_(
|
||||||
|
[
|
||||||
|
manager_living_space.id
|
||||||
|
for manager_living_space in manager_living_spaces.data
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
manager_people_occupants = BuildDecisionBookPersonOccupants.filter_active(
|
||||||
|
BuildDecisionBookPersonOccupants.build_decision_book_person_id
|
||||||
|
== manager_people.get(1).id
|
||||||
|
)
|
||||||
|
dlt = [
|
||||||
|
occupants.delete(destroy=True)
|
||||||
|
for occupants in manager_people_occupants.data
|
||||||
|
]
|
||||||
|
dlt = [occupants.delete(destroy=True) for occupants in manager_people.data]
|
||||||
|
|
||||||
|
if book_person_manager := BuildDecisionBookPerson.find_or_create(
|
||||||
|
**build_decision_book_person_dict,
|
||||||
|
build_living_space_id=token_dict.selected_occupant.living_space_id,
|
||||||
|
build_living_space_uu_id=str(
|
||||||
|
token_dict.selected_occupant.living_space_uu_id
|
||||||
|
),
|
||||||
|
person_id=token_dict.person_id,
|
||||||
|
token=Users.generate_token(40),
|
||||||
|
):
|
||||||
|
book_person_manager.add_occupant_type(occupant_type=manager_occupant_type)
|
||||||
|
print(f"Manager Token : {book_person_manager.token}")
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Invitation are send to people related with building",
|
||||||
|
"data": book_invitation.get_dict(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildDecisionBookInvitationsUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"92413636-53a8-4a05-842c-1485a64e00d1": "decision_book_invitations_attend",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decision_book_invitations_attend(
|
||||||
|
cls,
|
||||||
|
data: DecisionBookDecisionBookInvitationsUpdate,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
BuildDecisionBookInvitationsListEventMethod = (
|
||||||
|
BuildDecisionBookInvitationsListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/invite/list")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
BuildDecisionBookInvitationsCreateEventMethod = (
|
||||||
|
BuildDecisionBookInvitationsCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/invite/create")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
BuildDecisionBookInvitationsUpdateEventMethod = (
|
||||||
|
BuildDecisionBookInvitationsUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/build/decision_book/invite/update")
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectDecisionBookProjectDecisionBookEvents(MethodToEvent): ...
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectDecisionBookProjectDecisionBookPersonEvents(MethodToEvent): ...
|
||||||
0
api_events/events/events/__init__.py
Normal file
0
api_events/events/events/__init__.py
Normal file
146
api_events/events/events/events_bind_events.py
Normal file
146
api_events/events/events/events_bind_events.py
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
BuildLivingSpace,
|
||||||
|
BuildParts,
|
||||||
|
Build,
|
||||||
|
Events,
|
||||||
|
Event2Occupant,
|
||||||
|
OccupantTypes,
|
||||||
|
)
|
||||||
|
from api_validations import RegisterEvents2Occupant
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class EventBindOccupantEventMethods(MethodToEvent):
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": "bind_events_occupant_super_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_events_occupant_super_user(
|
||||||
|
cls, data: RegisterEvents2Occupant, token_dict: EmployeeTokenObject
|
||||||
|
):
|
||||||
|
|
||||||
|
if not str(token_dict.user_type) == "1":
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="This employee is not authorized to add event to this occupant",
|
||||||
|
)
|
||||||
|
|
||||||
|
occupants_build_part = BuildParts.find_one(uu_id=data.build_part_uu_id)
|
||||||
|
if not occupants_build_part:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "This employee is not authorized to add event to this building",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
occupant_occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
|
||||||
|
if not occupant_occupant_type:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Occupant Types is not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
events_to_add_to_occupant = Events.filter_active(
|
||||||
|
Events.uu_id.in_(list(data.event_uu_id_list))
|
||||||
|
)
|
||||||
|
if not events_to_add_to_occupant.data:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Events are not found. Please contact with your manager",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
employee_is_authorized = Build.select_action(
|
||||||
|
employee_id=token_dict.selected_company.employee_id,
|
||||||
|
filter_expr=[Build.id == occupants_build_part.build_id],
|
||||||
|
)
|
||||||
|
if not employee_is_authorized.first():
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
)
|
||||||
|
|
||||||
|
occupant_to_add_event = BuildLivingSpace.find_one(
|
||||||
|
build_parts_id=occupants_build_part.id,
|
||||||
|
occupant_type=occupant_occupant_type.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not occupant_to_add_event:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Occupant is not found or this employee is not authorized to add event to this occupant",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
events_added = []
|
||||||
|
for event in events_to_add_to_occupant.data:
|
||||||
|
if Event2Occupant.find_or_create(
|
||||||
|
event_id=event.id,
|
||||||
|
event_uu_id=str(event.uu_id),
|
||||||
|
build_living_space_id=occupant_to_add_event.id,
|
||||||
|
build_living_space_uu_id=str(occupant_to_add_event.uu_id),
|
||||||
|
is_confirmed=True,
|
||||||
|
):
|
||||||
|
events_added.append(event)
|
||||||
|
|
||||||
|
if events_added:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Event added to occupant",
|
||||||
|
"data": [event.get_dict() for event in events_added],
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Event is not added to occupant",
|
||||||
|
"data": [],
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EventBindEmployeeEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"c93a3009-65a0-498d-9191-04484d5cde81": "bind_events_employee",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_events_employee(cls, data: RegisterEvents2Occupant, token_dict):
|
||||||
|
return token_dict.available_event(data=data, token_dict=token_dict)
|
||||||
|
|
||||||
|
|
||||||
|
EventBindOccupantEventMethod = EventBindOccupantEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/bind/events/occupant")
|
||||||
|
)
|
||||||
|
EventBindEmployeeEventMethod = EventBindEmployeeEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/bind/events/employee")
|
||||||
|
)
|
||||||
337
api_events/events/events/events_bind_services.py
Normal file
337
api_events/events/events/events_bind_services.py
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Modules,
|
||||||
|
Employees,
|
||||||
|
BuildParts,
|
||||||
|
BuildLivingSpace,
|
||||||
|
Service2Events,
|
||||||
|
Services,
|
||||||
|
OccupantTypes,
|
||||||
|
Event2Employee,
|
||||||
|
Event2Occupant,
|
||||||
|
)
|
||||||
|
from api_validations import RegisterServices2Occupant, RegisterServices2Employee
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceBindOccupantEventMethods(MethodToEvent):
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"0d2bc5c9-d4b1-4951-8305-69da4a687fdc": "bind_services_occupant",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_services_occupant_system(
|
||||||
|
cls, build_living_space_id: int, service_id: int, expires_at: str = None
|
||||||
|
):
|
||||||
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
|
|
||||||
|
living_space = BuildLivingSpace.find_or_abort(
|
||||||
|
id=build_living_space_id,
|
||||||
|
)
|
||||||
|
service = Services.find_or_abort(
|
||||||
|
id=service_id,
|
||||||
|
)
|
||||||
|
default_module = Modules.find_one(module_code="USR-PUB")
|
||||||
|
add_default_service = Services.find_one(module_id=default_module.id)
|
||||||
|
service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == service.id,
|
||||||
|
)
|
||||||
|
default_service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == add_default_service.id,
|
||||||
|
)
|
||||||
|
add_events_list = service_events.data + default_service_events.data
|
||||||
|
if not add_events_list:
|
||||||
|
raise Exception(
|
||||||
|
"Service has no events registered. Please contact with your manager"
|
||||||
|
)
|
||||||
|
|
||||||
|
event_ids_list = [
|
||||||
|
{
|
||||||
|
"build_living_space_id": living_space.id,
|
||||||
|
"build_living_space_uu_id": str(living_space.uu_id),
|
||||||
|
"event_id": service_event.event_id,
|
||||||
|
"event_uu_id": str(service_event.event_uu_id),
|
||||||
|
"is_confirmed": True,
|
||||||
|
"expiry_ends": str(expires_at) if expires_at else "2099-12-31 03:00:00",
|
||||||
|
}
|
||||||
|
for service_event in add_events_list
|
||||||
|
]
|
||||||
|
|
||||||
|
session_execute = Services.session.execute(
|
||||||
|
insert(Event2Occupant)
|
||||||
|
.values(event_ids_list)
|
||||||
|
.on_conflict_do_nothing(
|
||||||
|
index_elements=["build_living_space_id", "event_id"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
count_row = session_execute.rowcount
|
||||||
|
print(f"{count_row} events are added to occupant {str(living_space.uu_id)}")
|
||||||
|
Services.session.commit()
|
||||||
|
Services.session.flush()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_services_occupant(
|
||||||
|
cls,
|
||||||
|
data: RegisterServices2Occupant,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
|
|
||||||
|
if isinstance(token_dict, EmployeeTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Employee is not authorized to add service to any occupant",
|
||||||
|
)
|
||||||
|
|
||||||
|
occupants_build_part = BuildParts.find_one(
|
||||||
|
uu_id=data.build_part_uu_id,
|
||||||
|
build_id=token_dict.selected_occupant.build_id,
|
||||||
|
)
|
||||||
|
print("occupants_build_part", occupants_build_part)
|
||||||
|
if not occupants_build_part:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "User is not authorized to add service to this occupant or flat",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
occupant_occupant_type = OccupantTypes.find_one(uu_id=data.occupant_uu_id)
|
||||||
|
if not occupant_occupant_type:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Occupant Types is not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
service = Services.find_one(uu_id=data.service_uu_id)
|
||||||
|
if not service:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Service is not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
default_module = Modules.find_one(module_code="USR-PUB")
|
||||||
|
add_default_service = Services.find_one(module_id=default_module.id)
|
||||||
|
service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == service.id,
|
||||||
|
)
|
||||||
|
default_service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == add_default_service.id,
|
||||||
|
)
|
||||||
|
add_events_list = service_events.data + default_service_events.data
|
||||||
|
if not add_events_list:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Service has no events registered. Please contact with your manager",
|
||||||
|
)
|
||||||
|
|
||||||
|
living_space = BuildLivingSpace.find_one(
|
||||||
|
build_parts_id=occupants_build_part.id,
|
||||||
|
occupant_types_id=occupant_occupant_type.id,
|
||||||
|
person_id=token_dict.person_id,
|
||||||
|
)
|
||||||
|
if not living_space:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Living Space is not found with given data. Please check flat and occupant type",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
event_ids_list = [
|
||||||
|
{
|
||||||
|
"build_living_space_id": living_space.id,
|
||||||
|
"build_living_space_uu_id": str(living_space.uu_id),
|
||||||
|
"event_id": service_event.event_id,
|
||||||
|
"event_uu_id": str(service_event.event_uu_id),
|
||||||
|
"is_confirmed": True,
|
||||||
|
}
|
||||||
|
for service_event in add_events_list
|
||||||
|
]
|
||||||
|
|
||||||
|
session_execute = Services.session.execute(
|
||||||
|
insert(Event2Occupant)
|
||||||
|
.values(event_ids_list)
|
||||||
|
.on_conflict_do_nothing(
|
||||||
|
index_elements=["employee_id", "event_id"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
count_row = session_execute.rowcount
|
||||||
|
print(f"{count_row} events are added to employee {str(living_space.uu_id)}")
|
||||||
|
Services.session.commit()
|
||||||
|
Services.session.flush()
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceBindEmployeeEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"50f84023-d8ec-4257-bfce-08ddf077c101": "bind_services_employee_super_user",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_services_employee(cls, service_id: int, employee_id: int):
|
||||||
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
|
|
||||||
|
employee = Employees.find_or_abort(
|
||||||
|
id=employee_id,
|
||||||
|
)
|
||||||
|
service = Services.find_or_abort(
|
||||||
|
id=service_id,
|
||||||
|
)
|
||||||
|
default_module = Modules.find_one(module_code="USR-PUB")
|
||||||
|
add_default_service = Services.find_one(module_id=default_module.id)
|
||||||
|
service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == service.id,
|
||||||
|
)
|
||||||
|
default_service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == add_default_service.id,
|
||||||
|
)
|
||||||
|
add_events_list = service_events.data + default_service_events.data
|
||||||
|
if not add_events_list:
|
||||||
|
raise Exception(
|
||||||
|
"Service has no events registered. Please contact with your manager"
|
||||||
|
)
|
||||||
|
|
||||||
|
event_ids_list = [
|
||||||
|
{
|
||||||
|
"employee_id": employee_id,
|
||||||
|
"employee_uu_id": str(employee.uu_id),
|
||||||
|
"event_id": service_event.event_id,
|
||||||
|
"event_uu_id": str(service_event.event_uu_id),
|
||||||
|
"is_confirmed": True,
|
||||||
|
}
|
||||||
|
for service_event in add_events_list
|
||||||
|
]
|
||||||
|
|
||||||
|
session_execute = Services.session.execute(
|
||||||
|
insert(Event2Employee)
|
||||||
|
.values(event_ids_list)
|
||||||
|
.on_conflict_do_nothing(
|
||||||
|
index_elements=["employee_id", "event_id"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
count_row = session_execute.rowcount
|
||||||
|
print(f"{count_row} events are added to employee {employee.uu_id}")
|
||||||
|
Services.session.commit()
|
||||||
|
Services.session.flush()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_services_employee_super_user(
|
||||||
|
cls,
|
||||||
|
data: RegisterServices2Employee,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
|
|
||||||
|
if isinstance(token_dict, OccupantTokenObject):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Occupant is not authorized to add service to any employee",
|
||||||
|
)
|
||||||
|
|
||||||
|
employee = Employees.find_one(uu_id=data.employee_uu_id)
|
||||||
|
if not employee:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "This employee is not authorized to add event to this employee",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
service = Services.find_one(uu_id=data.service_uu_id)
|
||||||
|
if not service:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Service is not found",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == service.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
default_module = Modules.find_one(module_code="USR-PUB")
|
||||||
|
add_default_service = Services.find_one(module_id=default_module.id)
|
||||||
|
default_service_events = Service2Events.filter_all(
|
||||||
|
Service2Events.service_id == add_default_service.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
add_events_list = service_events.data + default_service_events.data
|
||||||
|
if not add_events_list:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Service has no events registered. Please contact with your manager",
|
||||||
|
)
|
||||||
|
|
||||||
|
event_ids_list = [
|
||||||
|
{
|
||||||
|
"employee_id": employee.id,
|
||||||
|
"employee_uu_id": employee.uu_id,
|
||||||
|
"event_id": service_event.event_id,
|
||||||
|
"event_uu_id": service_event.event_uu_id,
|
||||||
|
"is_confirmed": True,
|
||||||
|
}
|
||||||
|
for service_event in add_events_list
|
||||||
|
]
|
||||||
|
|
||||||
|
session_execute = Services.session.execute(
|
||||||
|
insert(Event2Employee)
|
||||||
|
.values(event_ids_list)
|
||||||
|
.on_conflict_do_nothing(
|
||||||
|
index_elements=["employee_id", "event_id"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
count_row = session_execute.rowcount
|
||||||
|
Services.session.commit()
|
||||||
|
Services.session.flush()
|
||||||
|
if not count_row:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "No events are added to employee",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": f"{count_row} events are added to employee",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
ServiceBindOccupantEventMethod = ServiceBindOccupantEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/bind/services/occupant")
|
||||||
|
)
|
||||||
|
ServiceBindEmployeeEventMethod = ServiceBindEmployeeEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/bind/services/employee")
|
||||||
|
)
|
||||||
218
api_events/events/events/events_events.py
Normal file
218
api_events/events/events/events_events.py
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
from fastapi.exceptions import HTTPException
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
Events,
|
||||||
|
Employees,
|
||||||
|
Staff,
|
||||||
|
Duties,
|
||||||
|
Event2Occupant,
|
||||||
|
Event2Employee,
|
||||||
|
BuildLivingSpace,
|
||||||
|
)
|
||||||
|
from api_validations import (
|
||||||
|
RegisterEvents2Employee,
|
||||||
|
RegisterEvents2Occupant,
|
||||||
|
CreateEvents,
|
||||||
|
ListOptions,
|
||||||
|
)
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class EventsListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"9fa01bef-c0e8-4fe1-b9ed-2ff1c4f35faa": "events_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def events_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
records = Events.filter_active(
|
||||||
|
*Events.get_smart_query(list_options.query),
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EventsCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"514a9f8f-e5e5-4e10-9d0b-2de8f461fc1b": "events_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def events_create(cls, data: CreateEvents, token_dict):
|
||||||
|
event = Events.find_or_create(
|
||||||
|
**token_dict.user_creds,
|
||||||
|
event_name=data.event_name,
|
||||||
|
event_description=data.event_description,
|
||||||
|
event_date=data.event_date,
|
||||||
|
event_location=data.event_location,
|
||||||
|
active=True,
|
||||||
|
deleted=False,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Event created successfully.",
|
||||||
|
"event": event.uu_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EventsUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"f94e7b79-2369-4840-bf2b-244934ca3136": "events_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def events_update(cls, data: CreateEvents, token_dict):
|
||||||
|
event = Events.find_one(uu_id=data.uu_id)
|
||||||
|
if not event:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="No event found. Please contact your responsible company.",
|
||||||
|
)
|
||||||
|
event.update(
|
||||||
|
**token_dict.user_creds,
|
||||||
|
event_name=data.event_name,
|
||||||
|
event_description=data.event_description,
|
||||||
|
event_date=data.event_date,
|
||||||
|
event_location=data.event_location,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Event updated successfully.",
|
||||||
|
"event": event.uu_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EventsPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"41944c63-22d3-4866-affd-34bcd49da58b": "events_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def events_patch(cls, data: CreateEvents, token_dict):
|
||||||
|
event = Events.find_one(uu_id=data.uu_id)
|
||||||
|
if not event:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail="No event found. Please contact your responsible company.",
|
||||||
|
)
|
||||||
|
event.update(
|
||||||
|
**token_dict.user_creds,
|
||||||
|
event_name=data.event_name,
|
||||||
|
event_description=data.event_description,
|
||||||
|
event_date=data.event_date,
|
||||||
|
event_location=data.event_location,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Event patched successfully.",
|
||||||
|
"event": event.uu_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EventsBindEventToOccupantMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"d9aa58aa-37f7-4c27-861d-3105f76f5cdc": "bind_events_employee",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_events_employee(cls, data: RegisterEvents2Employee, token_dict):
|
||||||
|
events = Events.filter_active(Events.uu_id.in_(data.event_id))
|
||||||
|
if not events:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=401,
|
||||||
|
detail="No event found. Please contact your super user.",
|
||||||
|
)
|
||||||
|
|
||||||
|
employee = Employees.find_one(employee_uu_id=data.employee_uu_id)
|
||||||
|
employee_is_not_valid = False
|
||||||
|
if employee:
|
||||||
|
staff = Staff.find_one(id=employee.staff_id)
|
||||||
|
duties = Duties.find_one(id=staff.duties_id)
|
||||||
|
if duties.company_id not in token_dict.companies_id_list:
|
||||||
|
employee_is_not_valid = True
|
||||||
|
|
||||||
|
if employee_is_not_valid:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=401,
|
||||||
|
detail="This employee can not be reached by this user. Please contact your super user.",
|
||||||
|
)
|
||||||
|
|
||||||
|
for event in events.data:
|
||||||
|
employee = Event2Employee.find_or_create(
|
||||||
|
**token_dict.user_creds, employee_id=employee.id, event_id=event.id
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Events registered successfully.",
|
||||||
|
"events": [event.uu_id for event in events.data],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EventsBindEventToEmployeeMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8bb4f4fc-b474-427e-90b3-d8681f308bb5": "bind_events_occupant",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_events_occupant(cls, data: RegisterEvents2Occupant, token_dict):
|
||||||
|
events = Events.filter_active(Events.uu_id.in_(data.event_id))
|
||||||
|
if not events:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=401,
|
||||||
|
detail="No event found. Please contact your super user.",
|
||||||
|
)
|
||||||
|
occupant = BuildLivingSpace.find_one(uu_id=data.build_living_space_uu_id)
|
||||||
|
occupant_is_not_valid = False
|
||||||
|
if occupant_is_not_valid:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=401,
|
||||||
|
detail="This occupant can not be reached by this user. Please contact your super user.",
|
||||||
|
)
|
||||||
|
|
||||||
|
for event in events.data:
|
||||||
|
occupant = Event2Occupant.find_or_create(
|
||||||
|
**token_dict.user_creds,
|
||||||
|
build_living_space_id=occupant.id,
|
||||||
|
event_id=event.id,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Events registered successfully.",
|
||||||
|
"events": [event.uu_id for event in events.data],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EventsListEventMethod = EventsListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/event/list")
|
||||||
|
)
|
||||||
|
EventsCreateEventMethod = EventsCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/event/create")
|
||||||
|
)
|
||||||
|
EventsUpdateEventMethod = EventsUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/event/update")
|
||||||
|
)
|
||||||
|
EventsPatchEventMethod = EventsPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/event/patch")
|
||||||
|
)
|
||||||
|
EventsBindEventToOccupantMethod = EventsBindEventToOccupantMethods(
|
||||||
|
action=ActionsSchema(endpoint="/bind/events/occupant")
|
||||||
|
)
|
||||||
|
EventsBindEventToEmployeeMethod = EventsBindEventToEmployeeMethods(
|
||||||
|
action=ActionsSchema(endpoint="/bind/events/employee")
|
||||||
|
)
|
||||||
85
api_events/events/events/events_model_entities.py
Normal file
85
api_events/events/events/events_model_entities.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from api_validations import DepartmentsPydantic, ListOptions
|
||||||
|
|
||||||
|
from databases import Events
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ModelEntitiesEvents(MethodToEvent):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_entities_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
Events.filter_attr = list_options
|
||||||
|
records = Events.filter_active(
|
||||||
|
*Events.get_smart_query(smart_query=list_options.query),
|
||||||
|
Events.company_id == token_dict.selected_company.company_id
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_entities_create(cls, data: DepartmentsPydantic, token_dict):
|
||||||
|
created_events = Events.create_action(data=data, token=token_dict)
|
||||||
|
if created_events.is_found:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Events record already exits here is the record",
|
||||||
|
"data": created_events.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create Events record",
|
||||||
|
"data": created_events.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_entities_update(
|
||||||
|
cls, company_uu_id: str, data: DepartmentsPydantic, token_dict
|
||||||
|
):
|
||||||
|
find_one_events = Events.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_events = Events.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Events.id == token_dict.get("")],
|
||||||
|
action="update",
|
||||||
|
data=data,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update Events record",
|
||||||
|
"data": access_authorized_events.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_entities_patch(
|
||||||
|
cls, company_uu_id: str, data: DepartmentsPydantic, token_dict
|
||||||
|
):
|
||||||
|
find_one_events = Events.find_one_or_abort(uu_id=company_uu_id)
|
||||||
|
access_authorized_events = Events.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Events.id == token_dict.get("")],
|
||||||
|
action="patch",
|
||||||
|
data=data,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch Events record",
|
||||||
|
"data": access_authorized_events.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
24
api_events/events/events/events_models.py
Normal file
24
api_events/events/events/events_models.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from validations import DepartmentsPydantic, PatchRecord, ListOptions
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ModelEvents(MethodToEvent):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_list(cls, list_options: ListOptions, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_create(cls, data: DepartmentsPydantic, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_update(cls, company_uu_id: str, data: DepartmentsPydantic, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def model_patch(cls, company_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
return
|
||||||
24
api_events/events/events/events_modules.py
Normal file
24
api_events/events/events/events_modules.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from validations import DepartmentsPydantic, PatchRecord
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ModulesEvents(MethodToEvent):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def modules_list(cls, request, list_options):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def modules_create(cls, data: DepartmentsPydantic, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def modules_update(cls, module_uu_id: str, data: DepartmentsPydantic, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def modules_patch(cls, module_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
return
|
||||||
36
api_events/events/events/events_services.py
Normal file
36
api_events/events/events/events_services.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
from validations import DepartmentsPydantic, PatchRecord, ListOptions
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class ServicesEvents(MethodToEvent):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def services_list(cls, list_options: ListOptions):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def services_create(cls, data: DepartmentsPydantic, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def services_update(cls, service_uu_id: str, data: DepartmentsPydantic, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def services_patch(cls, service_uu_id: str, data: PatchRecord, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_service_to_action(cls, data, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_module_to_service(cls, data, token_dict):
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def bind_events_patch(cls, company_uu_id: str, data: PatchRecord):
|
||||||
|
return
|
||||||
0
api_events/events/identity/__init__.py
Normal file
0
api_events/events/identity/__init__.py
Normal file
140
api_events/events/identity/people.py
Normal file
140
api_events/events/identity/people.py
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from databases import (
|
||||||
|
People,
|
||||||
|
Users,
|
||||||
|
Companies,
|
||||||
|
)
|
||||||
|
|
||||||
|
from validations import InsertPerson, UpdateUsers
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
|
||||||
|
class PeopleListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"0a05f03c-6ed8-4230-a4ff-6e7cf886909b": "super_users_people_list",
|
||||||
|
"b5612538-0445-4a4a-ab13-d2a06037f7a5": "sales_users_people_list",
|
||||||
|
"c81c2cec-d32c-4cf2-9727-d4493e11ee1f": "human_resources_users_people_list",
|
||||||
|
"d1b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b": "people_list_only_occupant_tenant_or_owner",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def super_users_people_list(cls, list_options, token_dict):
|
||||||
|
|
||||||
|
|
||||||
|
records = People.filter_active(
|
||||||
|
*People.get_smart_query(smart_query=list_options.query)
|
||||||
|
)
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def sales_users_people_list(cls, data, token_dict):
|
||||||
|
|
||||||
|
records = People.filter_active(*People.get_smart_query(smart_query=data.query))
|
||||||
|
# records = [model_class(**record) for record in records.data]
|
||||||
|
return return_json_response_from_alchemy(response=records, pagination=data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def human_resources_users_people_list(cls, data, token_dict):
|
||||||
|
|
||||||
|
records = People.filter_active(*People.get_smart_query(smart_query=data.query))
|
||||||
|
# records = [model_class(**record) for record in records.data]
|
||||||
|
return return_json_response_from_alchemy(response=records, pagination=data)
|
||||||
|
|
||||||
|
|
||||||
|
class PeopleCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1": "people_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def people_create(cls, data: InsertPerson, token_dict: dict):
|
||||||
|
|
||||||
|
created_user = People.create_action(data=data, token=token_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create User record",
|
||||||
|
"data": created_user.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PeopleUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"e05cf22c-16c4-450b-86c8-417896a26afc": "people_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def people_update(cls, data: UpdateUsers, user_uu_id: str, token_dict: dict):
|
||||||
|
|
||||||
|
find_one_user = Users.find_one_or_abort(uu_id=user_uu_id)
|
||||||
|
access_authorized_company = Companies.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Companies.id == find_one_user.id],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_user = find_one_user.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update User record",
|
||||||
|
"data": updated_user,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Update User record", "data": {}},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PeoplePatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"3ae16d66-090b-4d27-b567-cce1b10a1c3b": "people_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def people_patch(cls):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class PeopleDeleteEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "DELETE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"7f84c7a2-a120-4867-90d4-6767a41320db": "people_delete",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PeopleListEventMethod = PeopleListEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/people/list")
|
||||||
|
)
|
||||||
|
PeopleCreateEventMethod = PeopleCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/people/create")
|
||||||
|
)
|
||||||
|
PeopleUpdateEventMethod = PeopleUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/people/update")
|
||||||
|
)
|
||||||
|
PeoplePatchEventMethod = PeoplePatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/people/patch")
|
||||||
|
)
|
||||||
|
PeopleDeleteEventMethod = PeopleDeleteEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/people/delete")
|
||||||
|
)
|
||||||
167
api_events/events/identity/users.py
Normal file
167
api_events/events/identity/users.py
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
from fastapi import status
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
|
||||||
|
from databases import MongoQueryIdentity, Users, Companies, People
|
||||||
|
from databases.no_sql_models.validations import DomainViaUser
|
||||||
|
|
||||||
|
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||||
|
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
|
from api_validations.core_response import return_json_response_from_alchemy
|
||||||
|
|
||||||
|
from validations import InsertUsers, UpdateUsers, PatchRecord, ListOptions
|
||||||
|
|
||||||
|
|
||||||
|
class UserListEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "SELECT"
|
||||||
|
__event_keys__ = {
|
||||||
|
"1483a8a2-d244-4593-b9f8-f1b4bcbefcd5": "user_list",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def user_list(
|
||||||
|
cls,
|
||||||
|
list_options: ListOptions,
|
||||||
|
token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
|
||||||
|
):
|
||||||
|
# Users.pre_query = Users.select_action(duty_id_list=[
|
||||||
|
# token_dict.selected_company.duty_id,
|
||||||
|
# token_dict.selected_company.bulk_duties_id
|
||||||
|
# ])
|
||||||
|
if "user_uu_id_list" in list_options.query:
|
||||||
|
people_ids = list_options.query.pop("user_uu_id_list")
|
||||||
|
people_id_list = [
|
||||||
|
user.person_id
|
||||||
|
for user in Users.filter_active(Users.uu_id.in_(people_ids)).data
|
||||||
|
]
|
||||||
|
records = People.filter_active(People.id.in_(people_id_list))
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
records = Users.filter_active(*Users.get_smart_query(list_options.query))
|
||||||
|
return return_json_response_from_alchemy(
|
||||||
|
response=records, pagination=list_options
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UserCreateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "CREATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"8eb50c24-4bdc-4309-9836-f7048daee409": "user_create",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def user_create(cls, data: InsertUsers, token_dict):
|
||||||
|
created_user = Users.create_action(create_user=data)
|
||||||
|
created_user.related_company = token_dict.selected_company.company_uu_id
|
||||||
|
domain_via_user = DomainViaUser(
|
||||||
|
**{"user_uu_id": str(created_user.uu_id), "main_domain": "evyos.com.tr"}
|
||||||
|
)
|
||||||
|
created_user.save()
|
||||||
|
mongo_query_identity = MongoQueryIdentity(
|
||||||
|
company_uuid=created_user.related_company,
|
||||||
|
)
|
||||||
|
mongo_query_identity.create_domain_via_user(payload=domain_via_user)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Create User record",
|
||||||
|
"data": created_user.get_dict(),
|
||||||
|
"password_token": {
|
||||||
|
"password_token": created_user.password_token,
|
||||||
|
"password_expires_day": str(created_user.password_expires_day),
|
||||||
|
"password_expiry_begins": str(created_user.password_expiry_begins),
|
||||||
|
"hash_password": created_user.hash_password,
|
||||||
|
"related_company": created_user.related_company,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UserUpdateEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "UPDATE"
|
||||||
|
__event_keys__ = {
|
||||||
|
"d08a9470-1eb0-4890-a9e8-b6686239d7e9": "user_update",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def user_update(cls, data: UpdateUsers, user_uu_id: str, token_dict):
|
||||||
|
find_one_user = Users.find_one_or_abort(uu_id=user_uu_id)
|
||||||
|
access_authorized_company = Companies.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Companies.id == token_dict.get("")],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
data_dict = data.excluded_dump()
|
||||||
|
updated_user = find_one_user.update(**data_dict)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Update User record",
|
||||||
|
"data": updated_user,
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={"completed": True, "message": "Update User record", "data": {}},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UserPatchEventMethods(MethodToEvent):
|
||||||
|
|
||||||
|
event_type = "PATCH"
|
||||||
|
__event_keys__ = {
|
||||||
|
"d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0": "user_patch",
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def user_patch(cls, data: PatchRecord, user_uu_id: str, token_dict):
|
||||||
|
find_one_user = Users.find_one_or_abort(uu_id=user_uu_id)
|
||||||
|
access_authorized_company = Companies.select_action(
|
||||||
|
duty_id=getattr(token_dict, "duty_id", 5),
|
||||||
|
filter_expr=[Companies.id == find_one_user.id],
|
||||||
|
)
|
||||||
|
if access_authorized_company.count:
|
||||||
|
action = data.excluded_dump()
|
||||||
|
find_one_user.active = bool(action.get("active", find_one_user.active))
|
||||||
|
find_one_user.is_confirmed = bool(
|
||||||
|
action.get("confirm", find_one_user.is_confirmed)
|
||||||
|
)
|
||||||
|
find_one_user.deleted = bool(action.get("delete", find_one_user.deleted))
|
||||||
|
find_one_user.save()
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": True,
|
||||||
|
"message": "Patch User record completed",
|
||||||
|
"data": find_one_user.get_dict(),
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"completed": False,
|
||||||
|
"message": "Patch User record failed",
|
||||||
|
"data": {},
|
||||||
|
},
|
||||||
|
status_code=status.HTTP_200_OK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
UserListEventMethod = UserListEventMethods(action=ActionsSchema(endpoint="/user/list"))
|
||||||
|
UserCreateEventMethod = UserCreateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/user/create")
|
||||||
|
)
|
||||||
|
UserUpdateEventMethod = UserUpdateEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/user/update")
|
||||||
|
)
|
||||||
|
UserPatchEventMethod = UserPatchEventMethods(
|
||||||
|
action=ActionsSchema(endpoint="/user/patch")
|
||||||
|
)
|
||||||
31
api_events/tasks2events/__init__.py
Normal file
31
api_events/tasks2events/__init__.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from tasks2events.common_tasks.default_user import AuthDefaultEventBlock
|
||||||
|
from tasks2events.employee_tasks.super_user import SuperUserEventBlock
|
||||||
|
|
||||||
|
from tasks2events.occupant_tasks.build_manager import BuildManager
|
||||||
|
from tasks2events.occupant_tasks.build_owner import BuildOwner
|
||||||
|
from tasks2events.occupant_tasks.build_resident import BuildResident
|
||||||
|
from tasks2events.occupant_tasks.build_tenant import BuildTenant
|
||||||
|
from tasks2events.occupant_tasks.build_represent import BuildRepresent
|
||||||
|
from tasks2events.occupant_tasks.meeting_writer import BuildMeetingWriter
|
||||||
|
from tasks2events.occupant_tasks.meeting_advisor import BuildMeetingAdvisor
|
||||||
|
from tasks2events.occupant_tasks.meeting_attendance import BuildMeetingAttendance
|
||||||
|
from tasks2events.occupant_tasks.meeting_president import BuildMeetingPresident
|
||||||
|
from tasks2events.occupant_tasks.meeting_voted_president import (
|
||||||
|
BuildMeetingVotedPresident,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"AuthDefaultEventBlock",
|
||||||
|
"SuperUserEventBlock",
|
||||||
|
"BuildManager",
|
||||||
|
"BuildOwner",
|
||||||
|
"BuildResident",
|
||||||
|
"BuildTenant",
|
||||||
|
"BuildRepresent",
|
||||||
|
"BuildMeetingWriter",
|
||||||
|
"BuildMeetingPresident",
|
||||||
|
"BuildMeetingAdvisor",
|
||||||
|
"BuildMeetingAttendance",
|
||||||
|
"BuildMeetingVotedPresident",
|
||||||
|
]
|
||||||
0
api_events/tasks2events/common_tasks/__init__.py
Normal file
0
api_events/tasks2events/common_tasks/__init__.py
Normal file
22
api_events/tasks2events/common_tasks/default_user.py
Normal file
22
api_events/tasks2events/common_tasks/default_user.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from api_events.tasks2events.default_abstract import AddEventFunctionality
|
||||||
|
|
||||||
|
|
||||||
|
class AuthDefaultEventBlock(AddEventFunctionality):
|
||||||
|
service_code = "AUTH"
|
||||||
|
related_code = "DF-USER"
|
||||||
|
events = [
|
||||||
|
{"function_code": "e672846d-cc45-4d97-85d5-6f96747fac67"},
|
||||||
|
{"function_code": "cee96b9b-8487-4e9f-aaed-2e8c79687bf9"},
|
||||||
|
{"function_code": "48379bb2-ba81-4d8e-a9dd-58837cfcbf67"},
|
||||||
|
{"function_code": "f09f7c1a-bee6-4e32-8444-962ec8f39091"},
|
||||||
|
{"function_code": "87a15ade-3474-4206-b574-bbf8580cbb14"},
|
||||||
|
{"function_code": "c519f9af-92e1-47b2-abf7-5a3316d075f7"},
|
||||||
|
{"function_code": "8b586848-2fb3-4161-abbe-642157eec7ce"},
|
||||||
|
{"function_code": "5cc22e4e-a0f7-4077-be41-1871feb3dfd1"},
|
||||||
|
{"function_code": "c90f3334-10c9-4181-b5ff-90d98a0287b2"},
|
||||||
|
{"function_code": "e3ca6e24-b9f8-4127-949c-3bfa364e3513"},
|
||||||
|
{"function_code": "c140cd5f-307f-4046-a93e-3ade032a57a7"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
return super().retrieve_events(cls.events)
|
||||||
16
api_events/tasks2events/default_abstract.py
Normal file
16
api_events/tasks2events/default_abstract.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
class AddEventFunctionality:
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def retrieve_events(cls, events) -> list[tuple[int, str]]:
|
||||||
|
from database_sql_models import Events
|
||||||
|
from sqlalchemy import select
|
||||||
|
|
||||||
|
get_event_ids = Events.session.execute(
|
||||||
|
select(Events.id, Events.uu_id).where(
|
||||||
|
Events.function_code.in_([event["function_code"] for event in events])
|
||||||
|
)
|
||||||
|
).all()
|
||||||
|
if get_event_ids:
|
||||||
|
return [(get_event[0], str(get_event[1])) for get_event in get_event_ids]
|
||||||
|
else:
|
||||||
|
raise Exception("No event found")
|
||||||
0
api_events/tasks2events/employee_tasks/__init__.py
Normal file
0
api_events/tasks2events/employee_tasks/__init__.py
Normal file
83
api_events/tasks2events/employee_tasks/super_user.py
Normal file
83
api_events/tasks2events/employee_tasks/super_user.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
from api_events.tasks2events.default_abstract import AddEventFunctionality
|
||||||
|
|
||||||
|
|
||||||
|
class SuperUserEventBlock(AddEventFunctionality):
|
||||||
|
service_code = "SRE-SUE"
|
||||||
|
related_code = "SUE"
|
||||||
|
events = [
|
||||||
|
{"function_code": "2d1513f4-44ed-4fa3-84d1-dfbd0eadf9a1"},
|
||||||
|
{"function_code": "0a05f03c-6ed8-4230-a4ff-6e7cf886909b"},
|
||||||
|
{"function_code": "e05cf22c-16c4-450b-86c8-417896a26afc"},
|
||||||
|
{"function_code": "3ae16d66-090b-4d27-b567-cce1b10a1c3b"},
|
||||||
|
{"function_code": "1483a8a2-d244-4593-b9f8-f1b4bcbefcd5"},
|
||||||
|
{"function_code": "8eb50c24-4bdc-4309-9836-f7048daee409"},
|
||||||
|
{"function_code": "d08a9470-1eb0-4890-a9e8-b6686239d7e9"},
|
||||||
|
{"function_code": "d26a1a3c-eaeb-4d01-b35b-a5ed714e29c0"},
|
||||||
|
{"function_code": "68b3b5ed-b74c-4a27-820f-3959214e94e9"},
|
||||||
|
{"function_code": "a2271854-6b90-43da-a440-a62b70d90528"},
|
||||||
|
{"function_code": "5ad38a66-1189-451e-babb-77de2d63d757"},
|
||||||
|
{"function_code": "e3876bfe-8847-4dea-ae36-e709f7431930"},
|
||||||
|
{"function_code": "6320d696-1fd1-49f9-860a-8f22e5b8a68d"},
|
||||||
|
{"function_code": "76f11a08-5f4a-4e1f-961f-aaef21699acd"},
|
||||||
|
{"function_code": "41ea7f29-006a-4310-b5c4-b2a0e1a504bd"},
|
||||||
|
{"function_code": "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5"},
|
||||||
|
{"function_code": "2cb90331-c1b4-4923-8314-8111326b621a"},
|
||||||
|
{"function_code": "d8bd3985-7f3b-4267-a74e-d5017e4ea9f8"},
|
||||||
|
{"function_code": "4172706f-06c9-4c38-9ac8-59085a72f80a"},
|
||||||
|
{"function_code": "1e272e4f-6c1e-418b-91a7-be8b06c875da"},
|
||||||
|
{"function_code": "44b72beb-53a8-407b-a12a-76e74b65794d"},
|
||||||
|
{"function_code": "30c54cce-3303-4d36-959a-b64e383ae177"},
|
||||||
|
{"function_code": "3524ae42-0825-4af7-be85-7c890a4f65d3"},
|
||||||
|
{"function_code": "3fc77829-f1ee-4511-a2ca-582daa03125b"},
|
||||||
|
{"function_code": "ca81c6d1-975a-4288-a27b-1069aea84afe"},
|
||||||
|
{"function_code": "23231c7d-4ff2-4b39-b71b-ea350d31fadf"},
|
||||||
|
{"function_code": "c6ea200e-fa17-4393-b390-37f5337c9c65"},
|
||||||
|
{"function_code": "ad952647-bcf8-482d-9e05-b2ee8086483f"},
|
||||||
|
{"function_code": "d5c7b5c4-7b4e-4d5b-8e3b-2b9c5f5d0c0b"},
|
||||||
|
{"function_code": "cb677c92-6b05-4122-af5c-12766fae8095"},
|
||||||
|
{"function_code": "1e1632c3-bb0e-46a5-8e45-da3f6d88ac43"},
|
||||||
|
{"function_code": "9015a076-d78c-463d-9474-ea343a125fb8"},
|
||||||
|
{"function_code": "8446ce0b-9310-4b9f-93e2-61f56a9dacd1"},
|
||||||
|
{"function_code": "8984a519-99bf-4f25-8f34-2e1aebba468c"},
|
||||||
|
{"function_code": "8f619257-19fd-404f-b713-7392c588dc36"},
|
||||||
|
{"function_code": "7724cfbb-c0ee-4261-959b-61b84e88a34f"},
|
||||||
|
{"function_code": "5329f35d-ff9d-4656-a831-ba9c8204e483"},
|
||||||
|
{"function_code": "b1cd7c0a-1458-472b-894f-3adc857c8512"},
|
||||||
|
{"function_code": "5eb04057-7a74-4555-b2c6-14eda32dae89"},
|
||||||
|
{"function_code": "caf914fa-0899-4b0b-a85a-3d40fdaa06a5"},
|
||||||
|
{"function_code": "ffdc445f-da10-4ce4-9531-d2bdb9a198ae"},
|
||||||
|
{"function_code": "b0e55a7e-af81-468c-b46c-a6b3a6b68d5d"},
|
||||||
|
{"function_code": "1f9c3a9c-e5bd-4dcd-9b9a-3742d7e03a27"},
|
||||||
|
{"function_code": "68b3b5ed-b74c-4a27-820f-3959214e94e9"},
|
||||||
|
{"function_code": "a2271854-6b90-43da-a440-a62b70d90528"},
|
||||||
|
{"function_code": "5ad38a66-1189-451e-babb-77de2d63d757"},
|
||||||
|
{"function_code": "e3876bfe-8847-4dea-ae36-e709f7431930"},
|
||||||
|
{"function_code": "9c251d7d-da70-4d63-a72c-e69c26270442"},
|
||||||
|
{"function_code": "6f1406ac-577d-4f2c-8077-71fff2252c5f"},
|
||||||
|
{"function_code": "88d37b78-1ac4-4513-9d25-090ac3a24f31"},
|
||||||
|
{"function_code": "df18e489-a63c-477f-984c-aa52d30640ad"},
|
||||||
|
{"function_code": "e0ac1269-e9a7-4806-9962-219ac224b0d0"},
|
||||||
|
{"function_code": "b860e37a-e19b-4c45-9543-461241f7587c"},
|
||||||
|
{"function_code": "fb403f69-11ed-4f4f-ad71-5e6fb4a793d2"},
|
||||||
|
{"function_code": "58fdf95e-2110-4ed6-9c26-95f4be87eaee"},
|
||||||
|
{"function_code": "70b4666f-4ceb-46ec-b89e-24be8712f0e7"},
|
||||||
|
{"function_code": "8fd04d94-68fb-4a07-9549-8b47aee3a870"},
|
||||||
|
{"function_code": "b78ca45c-b9f4-41f6-9ddb-2c6f2faa2570"},
|
||||||
|
{"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
|
||||||
|
{"function_code": "0a68cb44-271a-4829-81f6-cd99a5f326b4"},
|
||||||
|
{"function_code": "6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29"},
|
||||||
|
{"function_code": "7b58ed84-9a65-4588-994d-30df8366b050"},
|
||||||
|
{"function_code": "eb36de59-8268-4d96-80b6-5d01c12bf0b1"},
|
||||||
|
{"function_code": "dce10509-0da5-46fb-af3c-a81d54d5481c"},
|
||||||
|
{"function_code": "f0fdfe1b-806b-4175-ad50-a1a165c0dfb7"},
|
||||||
|
{"function_code": "42328809-b516-477b-82cc-2d6fadf28843"},
|
||||||
|
{"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
|
||||||
|
{"function_code": "0a68cb44-271a-4829-81f6-cd99a5f326b4"},
|
||||||
|
{"function_code": "6bc7035c-3b53-4c0a-8cc9-1ec9c6af1e29"},
|
||||||
|
{"function_code": "7b58ed84-9a65-4588-994d-30df8366b050"},
|
||||||
|
{"function_code": "5702f0a9-fe8f-4aae-922e-6e04b497ef6a"},
|
||||||
|
{"function_code": "c93a3009-65a0-498d-9191-04484d5cde81"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
return super().retrieve_events(cls.events)
|
||||||
0
api_events/tasks2events/occupant_tasks/__init__.py
Normal file
0
api_events/tasks2events/occupant_tasks/__init__.py
Normal file
37
api_events/tasks2events/occupant_tasks/asd.py
Normal file
37
api_events/tasks2events/occupant_tasks/asd.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"""
|
||||||
|
|
||||||
|
Toplantı Başkanı Toplantı Başkanı MT-PRS Toplantı
|
||||||
|
Toplantı Katip Toplantıda tutanak tutan kişi MT-WRT Toplantı
|
||||||
|
Toplantı Katılımcısı Toplantıda sadece katılan kişi MT-ATT Toplantı
|
||||||
|
Toplantı Danışman Toplantıda danışmanlık yapan kişi MT-ADV Toplantı
|
||||||
|
Daire Sahibi Daire Sahibi FL-OWN Daire
|
||||||
|
Daire Kiracısı Daire Kiracısı FL-TEN Daire
|
||||||
|
Daire Sakini Daire Sakini FL-RES Daire
|
||||||
|
Daire Sakini Vekili Daire Sakini Vekili FL-REP Daire
|
||||||
|
Bina Avukatı Bina Avukatı BU-ATT Bina
|
||||||
|
Bina Avukatı Yardımcısı Bina Avukatı Yardımcısı BU-ATA Bina
|
||||||
|
Bina Denetmen Yardımcısı Bina Denetmen Yardımcısı BU-SPA Bina
|
||||||
|
Bina Denetmeni Bina Denetmeni BU-SPV Bina
|
||||||
|
Bina Yönetici Yardımcısı Bina Yönetici Yardımcısı BU-MNA Bina
|
||||||
|
Bina Yöneticisi Bina Yöneticisi BU-MNG Bina
|
||||||
|
Bina Muhasabecisi Bina Muhasabecisi BU-ACC Bina
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
MT_PRS = []
|
||||||
|
MT_WRT = []
|
||||||
|
MT_ATT = []
|
||||||
|
MT_ADV = []
|
||||||
|
FL_OWN = []
|
||||||
|
FL_TEN = []
|
||||||
|
FL_RES = []
|
||||||
|
FL_REP = []
|
||||||
|
BU_ATT = []
|
||||||
|
BU_ATA = []
|
||||||
|
BU_SPA = []
|
||||||
|
BU_SPV = []
|
||||||
|
BU_MNA = []
|
||||||
|
|
||||||
|
|
||||||
|
BU_ACC = []
|
||||||
21
api_events/tasks2events/occupant_tasks/build_manager.py
Normal file
21
api_events/tasks2events/occupant_tasks/build_manager.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from api_events.tasks2events.default_abstract import AddEventFunctionality
|
||||||
|
|
||||||
|
|
||||||
|
class BuildManager(AddEventFunctionality):
|
||||||
|
service_code = "SRO-BU-MNG"
|
||||||
|
related_code = "BU-MNG"
|
||||||
|
events = [
|
||||||
|
{"function_code": "dce10509-0da5-46fb-af3c-a81d54d5481c"},
|
||||||
|
{"function_code": "0d2bc5c9-d4b1-4951-8305-69da4a687fdc"},
|
||||||
|
{"function_code": "0a68cb44-271a-4829-81f6-cd99a5f326b4"},
|
||||||
|
{"function_code": "5c10d6ae-2aee-4243-a7c3-94826d028d13"},
|
||||||
|
{"function_code": "d0bfa20c-841d-421c-98e6-d308f938d16a"},
|
||||||
|
{"function_code": "68b3b5ed-b74c-4a27-820f-3959214e94e9"},
|
||||||
|
{"function_code": "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5"},
|
||||||
|
{"function_code": "92413636-53a8-4a05-842c-1485a64e00d1"},
|
||||||
|
{"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
|
||||||
|
{"function_code": "c0b65098-9c79-4212-b1d0-c7e7836cf141"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
return super().retrieve_events(cls.events)
|
||||||
13
api_events/tasks2events/occupant_tasks/build_owner.py
Normal file
13
api_events/tasks2events/occupant_tasks/build_owner.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from api_events.tasks2events.default_abstract import AddEventFunctionality
|
||||||
|
|
||||||
|
|
||||||
|
class BuildOwner(AddEventFunctionality):
|
||||||
|
|
||||||
|
service_code = "SRO-FL-OWN"
|
||||||
|
related_code = "FL-OWN"
|
||||||
|
events = [
|
||||||
|
{"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
return super().retrieve_events(cls.events)
|
||||||
13
api_events/tasks2events/occupant_tasks/build_represent.py
Normal file
13
api_events/tasks2events/occupant_tasks/build_represent.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from api_events.tasks2events.default_abstract import AddEventFunctionality
|
||||||
|
|
||||||
|
|
||||||
|
class BuildRepresent(AddEventFunctionality):
|
||||||
|
|
||||||
|
service_code = "SRO-FL-REP"
|
||||||
|
related_code = "FL-REP"
|
||||||
|
events = [
|
||||||
|
{"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
return super().retrieve_events(cls.events)
|
||||||
12
api_events/tasks2events/occupant_tasks/build_resident.py
Normal file
12
api_events/tasks2events/occupant_tasks/build_resident.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from api_events.tasks2events.default_abstract import AddEventFunctionality
|
||||||
|
|
||||||
|
|
||||||
|
class BuildResident(AddEventFunctionality):
|
||||||
|
service_code = "SRO-FL-RES"
|
||||||
|
related_code = "FL-RES"
|
||||||
|
events = [
|
||||||
|
{"function_code": "bdcba521-0116-441c-ace1-84c5b68c86c7"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
return super().retrieve_events(cls.events)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user