first commit
This commit is contained in:
commit
643d6d8f65
|
|
@ -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/
|
||||
|
||||
|
||||
|
|
@ -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/
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
3.12
|
||||
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -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)))
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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",
|
||||
]
|
||||
|
|
@ -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,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",
|
||||
]
|
||||
|
|
@ -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,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,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,0 +1,5 @@
|
|||
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
|
||||
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||
|
||||
|
||||
class DecisionBookEvents(MethodToEvent): ...
|
||||
|
|
@ -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): ...
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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): ...
|
||||
|
|
@ -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,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")
|
||||
)
|
||||
|
|
@ -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): ...
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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): ...
|
||||
|
|
@ -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): ...
|
||||
|
|
@ -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,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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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,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(),
|
||||
# ),
|
||||
# )
|
||||
|
|
@ -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,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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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,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")
|
||||
)
|
||||
|
|
@ -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")
|
||||
)
|
||||
|
|
@ -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,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)
|
||||
|
|
@ -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,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,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 = []
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
Loading…
Reference in New Issue