updated modules

This commit is contained in:
berkay 2025-01-08 15:25:05 +03:00
parent e0ea21e469
commit 57df5104b8
58 changed files with 276509 additions and 2 deletions

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,34 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="21">
<item index="0" class="java.lang.String" itemvalue="rsa" />
<item index="1" class="java.lang.String" itemvalue="pydantic" />
<item index="2" class="java.lang.String" itemvalue="alembic" />
<item index="3" class="java.lang.String" itemvalue="starlette-context" />
<item index="4" class="java.lang.String" itemvalue="pymongo" />
<item index="5" class="java.lang.String" itemvalue="arrow" />
<item index="6" class="java.lang.String" itemvalue="unidecode" />
<item index="7" class="java.lang.String" itemvalue="python-dotenv" />
<item index="8" class="java.lang.String" itemvalue="psycopg2-binary" />
<item index="9" class="java.lang.String" itemvalue="cryptography" />
<item index="10" class="java.lang.String" itemvalue="requests" />
<item index="11" class="java.lang.String" itemvalue="redis" />
<item index="12" class="java.lang.String" itemvalue="sqlalchemy" />
<item index="13" class="java.lang.String" itemvalue="pandas" />
<item index="14" class="java.lang.String" itemvalue="fastapi" />
<item index="15" class="java.lang.String" itemvalue="Deprecated" />
<item index="16" class="java.lang.String" itemvalue="faker" />
<item index="17" class="java.lang.String" itemvalue="textdistance" />
<item index="18" class="java.lang.String" itemvalue="uvicorn" />
<item index="19" class="java.lang.String" itemvalue="redmail" />
<item index="20" class="java.lang.String" itemvalue="sqlalchemy-mixins" />
</list>
</value>
</option>
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.10 (api_backend_hag)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (api_backend_hag)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/wag-managment-api-service-version-3.iml" filepath="$PROJECT_DIR$/.idea/wag-managment-api-service-version-3.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.10 (api_backend_hag)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,3 +1,17 @@
# wag-managment-api-service-version-3
- Run Store Services
On debian
> docker-compose -f ./StoreServices/debian-docker-compose.yml up --build -d
On Linux
> docker-compose -f ./StoreServices/local-docker-compose.yml up --build -d
Connectors:
commercial_main_mongo_service:
http://localhost:11777
commercial_main_memory_service:
http://localhost:11222
postgres_main_commercial:
http://localhost:5444
wag-managment-api-service-version-3

View File

@ -0,0 +1,4 @@
REDIS_HOST=commercial_redis_service
REDIS_PASSWORD=commercial_redis_password
REDIS_PORT=6379
REDIS_DB=0

View File

@ -0,0 +1,8 @@
MONGODB_DISABLE_ENFORCE_AUTH=true
MONGODB_ROOT_PASSWORD=root
MONGODB_DATABASE=mongo_database
MONGODB_USERNAME=mongo_user
MONGODB_PASSWORD=mongo_password
MONGO_INITDB_ROOT_USERNAME=mongo_user
MONGO_INITDB_ROOT_PASSWORD=mongo_password
MONGO_INITDB_DATABASE=mongo_database

View File

@ -0,0 +1,48 @@
services:
commercial_main_mongo_service:
container_name: commercial_main_mongo_service
# image: "bitnami/mongodb:latest"
image: "bitnami/mongodb:4.4.1-debian-10-r3"
networks:
- network_store_services
restart: on-failure
env_file:
- commercial_main_mongo_service.env
volumes:
- wag_commercial_mongodb_main_data:/bitnami/mongodb
ports:
- "11777:27017"
commercial_main_memory_service:
container_name: commercial_main_memory_service
image: 'bitnami/redis:latest'
networks:
- network_store_services
restart: on-failure
env_file:
- commercial_main_memory_service.env
ports:
- "11222:6379"
postgres_main_commercial:
image: 'bitnami/postgresql:latest'
container_name: postgres_main_commercial
networks:
- network_store_services
restart: on-failure
env_file:
- postgres_main_commercial.env
depends_on:
- commercial_mongo_service
ports:
- "5444:5432"
volumes:
- wag_postgres_main_commercial_data:/bitnami/postgresql
networks:
network_store_services:
volumes:
wag_postgres_main_commercial_data:
wag_commercial_mongodb_main_data:

View File

@ -0,0 +1,48 @@
services:
commercial_main_mongo_service:
container_name: commercial_main_mongo_service
image: "bitnami/mongodb:latest"
# image: "bitnami/mongodb:4.4.1-debian-10-r3"
networks:
- network_store_services
restart: on-failure
env_file:
- commercial_main_mongo_service.env
volumes:
- wag_commercial_mongodb_main_data:/bitnami/mongodb
ports:
- "11777:27017"
commercial_main_memory_service:
container_name: commercial_main_memory_service
image: 'bitnami/redis:latest'
networks:
- network_store_services
restart: on-failure
env_file:
- commercial_main_memory_service.env
ports:
- "11222:6379"
postgres_main_commercial:
image: 'bitnami/postgresql:latest'
container_name: postgres_main_commercial
networks:
- network_store_services
restart: on-failure
env_file:
- postgres_main_commercial.env
depends_on:
- commercial_mongo_service
ports:
- "5444:5432"
volumes:
- wag_postgres_main_commercial_data:/bitnami/postgresql
networks:
network_store_services:
volumes:
wag_postgres_main_commercial_data:
wag_commercial_mongodb_main_data:

View File

@ -0,0 +1,3 @@
POSTGRES_DB=wag_database
POSTGRES_USER=berkay_wag_user
POSTGRES_PASSWORD=berkay_wag_user_password

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,508 @@
from sqlalchemy import (
create_engine,
UUID,
Column,
Integer,
String,
ForeignKey,
Boolean,
DateTime,
func,
text,
Index,
UniqueConstraint,
)
from sqlalchemy.orm import relationship, declarative_base
from .base import CrudMixin
from sqlalchemy_mixins.serialize import SerializeMixin
from sqlalchemy_mixins.repr import ReprMixin
from sqlalchemy_mixins.smartquery import SmartQueryMixin
Base = declarative_base()
class CrudCollection(Base, CrudMixin, ReprMixin, SmartQueryMixin, SerializeMixin):
__abstract__ = True
__repr__ = ReprMixin.__repr__
id: int = Column(Integer, primary_key=True)
uu_id: str = Column(
UUID, server_default=text("gen_random_uuid()"), index=True, unique=True
)
createdate = Column(DateTime, default=func.now())
updatedate = Column(DateTime, default=func.now(), onupdate=func.now())
createperson = Column(Integer, ForeignKey("persons.id"), nullable=True)
updateperson = Column(Integer, ForeignKey("persons.id"), nullable=True)
active = Column(Boolean, default=True)
delete = Column(Boolean, default=False)
replicationid = Column(Integer)
class Address(CrudCollection):
__tablename__ = "address"
__table_args__ = (
Index("_address_ndx_00", country_code, b_state, city, district),
{"comment": "Address Information"},
)
country_code = mapped_column(
String(9), server_default="TR", nullable=False, comment="Country Code"
)
city = mapped_column(String(24), nullable=False, comment="City")
district = mapped_column(String(24), nullable=False, comment="District")
b_state = mapped_column(String(24), server_default="")
neighborhood = mapped_column(String(24), server_default="")
street = mapped_column(String(24), server_default="")
postcode = mapped_column(String(8), server_default="")
latitude = mapped_column(Numeric(20, 12), server_default="0")
longitude = mapped_column(Numeric(20, 12), server_default="0")
official_companies: Mapped["Company"] = relationship(
"Company",
back_populates="official_address",
foreign_keys="Company.official_address_id",
)
class Company(CrudCollection):
__tablename__ = "companies"
__table_args__ = (
UniqueConstraint("tax_number", name="uq_companies_tax_number"),
{"comment": "İşletmelerin bilgilerini tutar"},
)
official_name = mapped_column(String, nullable=True, comment="Şirketin resmi adı")
public_name = Column(String, nullable=False, comment="Şirketin bilinen adı")
tax_number = Column(String, nullable=False, unique=True, comment="Vergi numarası")
organizations = relationship("Organization", back_populates="company")
locations = relationship("Location", back_populates="company")
default_lang_type = mapped_column(String(5), server_default="TR")
default_money_type = mapped_column(String(5), server_default="TL")
is_commercial = mapped_column(Boolean, server_default="True")
is_blacklist = mapped_column(Boolean, server_default="False")
official_address_id = mapped_column(ForeignKey("address.id"))
parent_id = mapped_column(ForeignKey("company.id"))
official_address: Mapped[List["Address"]] = relationship(
"Address",
back_populates="official_companies",
foreign_keys=[official_address_id],
)
class Organization(CrudCollection):
__tablename__ = "organizations"
__table_args__ = {"comment": "Her şirketin organizasyon yapısını tutar"}
name = Column(String, nullable=False, comment="Organizasyonun adı")
company_id = Column(
Integer, ForeignKey("companies.id"), nullable=False, comment="Şirket ID"
)
valid_from = Column(
DateTime, default=func.now(), comment="Geçerlilik başlangıç tarihi"
)
valid_to = Column(DateTime, nullable=True, comment="Geçerlilik bitiş tarihi")
company = relationship("Company", back_populates="organizations")
employees = relationship("Employee", back_populates="organization")
locations = relationship("Location", back_populates="organization")
phones = relationship("Phone", back_populates="organization")
menus = relationship("Menu", back_populates="organization")
class Location(CrudCollection):
__tablename__ = "locations"
__table_args__ = {
"comment": "Şirketin farklı lokasyonlarını (depo, ofis, şube, büro vb.) tutar"
}
name = Column(String, nullable=False, comment="Lokasyon adı")
address = Column(String, nullable=False, comment="Lokasyon adresi")
location_type = Column(
String, nullable=False, comment="Lokasyon türü (depo, ofis, şube, büro vb.)"
)
company_id = Column(
Integer, ForeignKey("companies.id"), nullable=False, comment="Şirket ID"
)
organization_id = Column(
Integer,
ForeignKey("organizations.id"),
nullable=False,
comment="Organizasyon ID",
)
company = relationship("Company", back_populates="locations")
organization = relationship("Organization", back_populates="locations")
class Person(CrudCollection):
__tablename__ = "persons"
__table_args__ = (
UniqueConstraint("identity_number", name="uq_persons_identity_number"),
{"comment": "Kişilerin bilgilerini tutar"},
)
first_name = Column(String, nullable=False, comment="İlk isim")
last_name = Column(String, nullable=False, comment="Soy isim")
identity_number = Column(
String, nullable=False, unique=True, comment="Kimlik numarası"
)
mother_name = Column(String, nullable=False, comment="Anne adı")
father_name = Column(String, nullable=False, comment="Baba adı")
birth_place = Column(String, nullable=False, comment="Doğum yeri")
birth_date = Column(DateTime, nullable=False, comment="Doğum tarihi")
gender = Column(String, nullable=False, comment="Cinsiyet")
nationality_code = Column(String, nullable=False, comment="Ülke kimlik kodu")
employees = relationship("Employee", back_populates="person")
users = relationship("User", back_populates="person")
class Employee(CrudCollection):
__tablename__ = "employees"
__table_args__ = (
UniqueConstraint("person_id", name="uq_employee_person_id"),
{"comment": "Çalışanların bilgilerini tutar"},
)
person_id = Column(
Integer,
ForeignKey("persons.id"),
nullable=False,
unique=True,
comment="Kişi ID",
)
organization_id = Column(
Integer,
ForeignKey("organizations.id"),
nullable=False,
comment="Organizasyon ID",
)
person = relationship("Person", back_populates="employees")
organization = relationship("Organization", back_populates="employees")
processes = relationship("EmployeeProcess", back_populates="employee")
permissions = relationship("Permission", back_populates="employee")
salaries = relationship("Salary", back_populates="employee")
performances = relationship("Performance", back_populates="employee")
"""
class User(CrudCollection):
__tablename__ = 'users'
__table_args__ = (
UniqueConstraint('email', name='uq_users_email'),
UniqueConstraint('phone_number', name='uq_users_phone_number'),
{'comment': 'Kullanıcıların giriş bilgilerini tutar'}
)
person_id = Column(Integer, ForeignKey('persons.id'), nullable=False, comment='Kişi ID')
email = Column(String, nullable=True, unique=True, comment='E-posta adresi')
phone_number = Column(String, nullable=True, unique=True, comment='Telefon numarası')
password_hash = Column(String, nullable=False, comment='Parola hash değeri')
person = relationship('Person', back_populates='users')
login_attempts = relationship('LoginAttempt', back_populates='user')
class LoginAttempt(CrudCollection):
__tablename__ = 'login_attempts'
__table_args__ = {'comment': 'Kullanıcıların giriş denemelerini tutar'}
user_id = Column(Integer, ForeignKey('users.id'), nullable=False, comment='Kullanıcı ID')
timestamp = Column(DateTime, default=func.now(), nullable=False, comment='Giriş deneme zamanı')
success = Column(Boolean, default=False, nullable=False, comment='Giriş başarılı mı')
user = relationship('User', back_populates='login_attempts')
"""
class Process(CrudCollection):
__tablename__ = "processes"
__table_args__ = {"comment": "İş süreçlerinin tanımlamalarını tutar"}
name = Column(String, nullable=False, comment="Süreç adı")
employee_processes = relationship("EmployeeProcess", back_populates="process")
emails = relationship("Email", back_populates="process")
class EmployeeProcess(CrudCollection):
__tablename__ = "employee_processes"
__table_args__ = {
"comment": "Çalışan ile iş süreçleri arasındaki ilişkileri ve yetkileri tutar"
}
employee_id = Column(
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
)
process_id = Column(
Integer, ForeignKey("processes.id"), nullable=False, comment="Süreç ID"
)
can_add = Column(Boolean, default=False, comment="Ekleme yetkisi")
can_update = Column(Boolean, default=False, comment="Güncelleme yetkisi")
can_delete = Column(Boolean, default=False, comment="Silme yetkisi")
employee = relationship("Employee", back_populates="processes")
process = relationship("Process", back_populates="employee_processes")
class Permission(CrudCollection):
__tablename__ = "permissions"
__table_args__ = {"comment": "Yetkileri tanımlar ve çalışanlara devredilebilir"}
employee_id = Column(
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
)
granted_to = Column(
Integer,
ForeignKey("employees.id"),
nullable=True,
comment="Yetki verilen çalışan ID",
) # Temporary delegation
permission_type = Column(
String, nullable=False, comment="Yetki türü (add, update, delete)"
)
valid_until = Column(DateTime, nullable=True, comment="Geçerlilik bitiş tarihi")
employee = relationship(
"Employee", foreign_keys=[employee_id], back_populates="permissions"
)
granted_employee = relationship("Employee", foreign_keys=[granted_to])
class Performance(CrudCollection):
__tablename__ = "performances"
__table_args__ = {"comment": "Çalışanların performanslarını tutar"}
employee_id = Column(
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
)
review_date = Column(DateTime, nullable=False, comment="Değerlendirme tarihi")
score = Column(Float, nullable=False, comment="Performans puanı")
notes = Column(String, nullable=True, comment="Notlar")
employee = relationship("Employee", back_populates="performances")
class Salary(CrudCollection):
__tablename__ = "salaries"
__table_args__ = {"comment": "Çalışanların maaş bilgilerini tutar"}
employee_id = Column(
Integer, ForeignKey("employees.id"), nullable=False, comment="Çalışan ID"
)
salary_amount = Column(Float, nullable=False, comment="Maaş miktarı")
effective_date = Column(DateTime, nullable=False, comment="Geçerlilik tarihi")
employee = relationship("Employee", back_populates="salaries")
class Email(CrudCollection):
__tablename__ = "emails"
__table_args__ = {
"comment": "İş süreçlerine ve çalışanlara e-posta gönderimlerini takip eder"
}
process_id = Column(
Integer, ForeignKey("processes.id"), nullable=False, comment="Süreç ID"
)
recipient = Column(String, nullable=False, comment="Alıcı e-posta adresi")
subject = Column(String, nullable=False, comment="E-posta konusu")
body = Column(String, nullable=False, comment="E-posta içeriği")
sent_date = Column(
DateTime, default=func.now(), nullable=False, comment="Gönderim tarihi"
)
process = relationship("Process", back_populates="emails")
class Phone(CrudCollection):
__tablename__ = "phones"
__table_args__ = {"comment": "Organizasyonlara ait telefon bilgilerini tutar"}
organization_id = Column(
Integer,
ForeignKey("organizations.id"),
nullable=False,
comment="Organizasyon ID",
)
phone_number = Column(String, nullable=False, comment="Telefon numarası")
phone_type = Column(
String, nullable=False, comment="Telefon türü (Sabit, Mobil vb.)"
)
organization = relationship("Organization", back_populates="phones")
class Menu(CrudCollection):
__tablename__ = "menus"
__table_args__ = (
Index("ix_menus_title", "title"),
{"comment": "Menü öğelerini tutar"},
)
title = Column(String, nullable=False, comment="Menü başlığı")
link = Column(String, nullable=False, comment="Menü bağlantısı")
icon = Column(String, nullable=True, comment="Menü simgesi")
order = Column(Integer, nullable=False, default=0, comment="Menü sıralaması")
organization_id = Column(
Integer,
ForeignKey("organizations.id"),
nullable=False,
comment="Organizasyon ID",
)
page_id = Column(Integer, ForeignKey("pages.id"), nullable=True, comment="Sayfa ID")
sub_menus = relationship(
"SubMenu", back_populates="menu", cascade="all, delete-orphan"
)
organization = relationship("Organization", back_populates="menus")
page = relationship("Page", back_populates="menus")
class SubMenu(CrudCollection):
__tablename__ = "sub_menus"
__table_args__ = (
Index("ix_sub_menus_title", "title"),
{"comment": "Alt menü öğelerini tutar"},
)
menu_id = Column(
Integer, ForeignKey("menus.id"), nullable=False, comment="Ana Menü ID"
)
title = Column(String, nullable=False, comment="Alt Menü başlığı")
link = Column(String, nullable=False, comment="Alt Menü bağlantısı")
icon = Column(String, nullable=True, comment="Alt Menü simgesi")
order = Column(Integer, nullable=False, default=0, comment="Alt Menü sıralaması")
layer = Column(Integer, nullable=False, default=0, comment="Alt Menü seviyesi")
page_id = Column(Integer, ForeignKey("pages.id"), nullable=True, comment="Sayfa ID")
menu = relationship("Menu", back_populates="sub_menus")
page = relationship("Page", back_populates="sub_menus")
class Page(CrudCollection):
__tablename__ = "pages"
__table_args__ = {"comment": "Uygulamada kullanılacak sayfaları tutar"}
title = Column(String, nullable=False, comment="Sayfa başlığı")
path = Column(String, nullable=False, comment="Sayfa yolu")
menus = relationship("Menu", back_populates="page")
sub_menus = relationship("SubMenu", back_populates="page")
functions = relationship("Function", back_populates="page")
class Function(CrudCollection):
__tablename__ = "functions"
__table_args__ = {
"comment": "Uygulamada kullanılacak fonksiyon parçacıklarını tutar"
}
name = Column(String, nullable=False, comment="Fonksiyon adı")
description = Column(String, nullable=True, comment="Fonksiyon açıklaması")
code = Column(String, nullable=False, comment="Fonksiyon kodu")
page_id = Column(
Integer, ForeignKey("pages.id"), nullable=False, comment="Sayfa ID"
)
page = relationship("Page", back_populates="functions")
from sqlalchemy.exc import NoResultFound
def authenticate(email=None, phone_number=None, password=None):
try:
if email:
user = session.query(User).filter(User.email == email).one()
elif phone_number:
user = session.query(User).filter(User.phone_number == phone_number).one()
else:
return False
# Şifre doğrulama (gerçek şifre doğrulama fonksiyonu kullanılmalıdır)
if user.password_hash == password:
login_attempt = LoginAttempt(user_id=user.id, success=True)
session.add(login_attempt)
session.commit()
return True
else:
login_attempt = LoginAttempt(user_id=user.id, success=False)
session.add(login_attempt)
session.commit()
return False
except NoResultFound:
return False
# PostgreSQL veritabanına bağlan
engine = create_engine("postgresql://username:password@localhost/mydatabase")
Base.metadata.create_all(engine)
# Oturum oluştur
Session = sessionmaker(bind=engine)
session = Session()
# Örnek veriler ekle
company = Company(name="My Company", tax_number="1234567890")
session.add(company)
session.commit()
organization = Organization(name="IT Department", company_id=company.id)
session.add(organization)
session.commit()
location = Location(
name="Main Office",
address="123 Main St",
location_type="Office",
company_id=company.id,
organization_id=organization.id,
)
session.add(location)
session.commit()
person = Person(
first_name="John",
last_name="Doe",
identity_number="9876543210",
mother_name="Jane Doe",
father_name="Joe Doe",
birth_place="New York",
birth_date="1980-01-01",
gender="Male",
nationality_code="US",
)
session.add(person)
session.commit()
employee = Employee(person_id=person.id, organization_id=organization.id)
session.add(employee)
session.commit()
user = User(
person_id=person.id,
email="john.doe@example.com",
phone_number="555-1234",
password_hash="hashed_password",
)
session.add(user)
session.commit()
login_attempt = LoginAttempt(user_id=user.id, success=True)
session.add(login_attempt)
session.commit()
process = Process(name="Code Review")
session.add(process)
session.commit()
employee_process = EmployeeProcess(
employee_id=employee.id,
process_id=process.id,
can_add=True,
can_update=True,
can_delete=False,
)
session.add(employee_process)
session.commit()
permission = Permission(
employee_id=employee.id, permission_type="add", valid_until=None
)
session.add(permission)
session.commit()
performance = Performance(employee_id=employee.id, review_date="2023-01-01", score=4.5)
session.add(performance)
session.commit()
salary = Salary(
employee_id=employee.id,
amount=5000.0,
effective_from="2023-01-01",
effective_to="2024-01-01",
)
session.add(salary)
session.commit()
phone1 = Phone(
organization_id=organization.id, phone_number="555-1234", phone_type="mobil"
)
session.add(phone1)
phone2 = Phone(
organization_id=organization.id, phone_number="555-5678", phone_type="sabit"
)
session.add(phone2)
session.commit()
email = Email(process_id=process.id, email_address="codereview@example.com")
session.add(email)
session.commit()

View File

@ -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

View File

@ -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] ???

View File

@ -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

View File

@ -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]

View File

@ -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[]

View File

@ -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

View File

@ -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
...

View File

@ -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)

View File

@ -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]

View File

@ -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,

View File

@ -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
]}

View File

@ -0,0 +1,9 @@
Notlar
ApiEnum Dropdown her seferinde load üretiyor onun yerine obje attribute olarak ekle
__enums__ = {
"abc": [],
"abcd": []
}

View File

@ -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

View File

@ -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
}
],
}

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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/

View File

@ -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.

View File

@ -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]

View File

@ -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

View File

@ -0,0 +1,10 @@
1- Geçen yıla ait toplantıda 2nolu 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-3nolu 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.

View File

@ -0,0 +1,140 @@
{
"_id": {
"$oid": "662a85f05b8acaaa3b37238c"
},
"user_id": 7,
"menu": {
"only_menu_item": false,
"item_order": 0,
"layer": 0,
"app_name": "Tanımlama Menüsü",
"app_description": "Tanımlama Menüsü",
"app_path": "",
"uu_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
"app_parent_items_id": null,
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APP166d9a3f495e4261baabdd456e9d294b",
"children": [
{
"only_menu_item": false,
"item_order": 10,
"layer": 1,
"app_name": "Firma İşlemleri",
"app_description": "Firma İşlemleri",
"app_path": "",
"uu_id": "d1aa4365-b1ef-4c91-ac8e-e3289f7eb075",
"app_parent_items_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APPd1aa4365b1ef4c91ac8ee3289f7eb075",
"children": [
{
"only_menu_item": true,
"item_order": 20,
"layer": 2,
"app_name": "Firma Tanımlama",
"app_description": "Firma Tanımlama",
"app_path": "create_company",
"uu_id": "a3c60a25-ff46-4872-b209-9e501dde7b73",
"app_parent_items_id": "d1aa4365-b1ef-4c91-ac8e-e3289f7eb075",
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APPa3c60a25ff464872b2099e501dde7b73"
}
]
},
{
"only_menu_item": false,
"item_order": 30,
"layer": 1,
"app_name": "Personel İşlemleri",
"app_description": "Personel İşlemleri",
"app_path": "",
"uu_id": "eebb591d-842b-4495-8721-e09552665a06",
"app_parent_items_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APPeebb591d842b44958721e09552665a06",
"children": [
{
"only_menu_item": true,
"item_order": 40,
"layer": 2,
"app_name": "Kişi Tanımlama",
"app_description": "Kişi Tanımlama",
"app_path": "create_person",
"uu_id": "0c6c8cd2-f6b7-471f-9671-5cc1ac9f502e",
"app_parent_items_id": "eebb591d-842b-4495-8721-e09552665a06",
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APP0c6c8cd2f6b7471f96715cc1ac9f502e"
}
]
},
{
"only_menu_item": false,
"item_order": 50,
"layer": 1,
"app_name": "Bina İşlemleri",
"app_description": "Bina İşlemleri",
"app_path": "",
"uu_id": "66627ebb-0425-425f-bc0f-8a943eb0a3ca",
"app_parent_items_id": "166d9a3f-495e-4261-baab-dd456e9d294b",
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APP66627ebb0425425fbc0f8a943eb0a3ca",
"children": [
{
"only_menu_item": true,
"item_order": 60,
"layer": 2,
"app_name": "Bina ve bölüm tanımlama",
"app_description": "Bina ve bölüm tanımlama",
"app_path": "create_build",
"uu_id": "173c4d8e-5577-4d4d-8712-f6fa2fbc8019",
"app_parent_items_id": "66627ebb-0425-425f-bc0f-8a943eb0a3ca",
"after_separator": false,
"row_limit": 100,
"read": true,
"write": false,
"delete": false,
"report_print": false,
"report_export": false,
"program_name": "APP173c4d8e55774d4d8712f6fa2fbc8019"
}
]
}
]
}
}

View File

@ -0,0 +1,229 @@
import json
data = '{"menu":[{"only_menu_item":false,"item_order":0,"layer":0,"app_name":"Tanımlama Menüsü","app_description":"Tanımlama Menüsü","app_path":"","uu_id":"166d9a3f-495e-4261-baab-dd456e9d294b","app_parent_items_id":null,"after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP166d9a3f495e4261baabdd456e9d294b"},{"only_menu_item":false,"item_order":10,"layer":1,"app_name":"Firma İşlemleri","app_description":"Firma İşlemleri","app_path":"","uu_id":"d1aa4365-b1ef-4c91-ac8e-e3289f7eb075","app_parent_items_id":"166d9a3f-495e-4261-baab-dd456e9d294b","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APPd1aa4365b1ef4c91ac8ee3289f7eb075"},{"only_menu_item":true,"item_order":20,"layer":2,"app_name":"Firma Tanımlama","app_description":"Firma Tanımlama","app_path":"create_company","uu_id":"a3c60a25-ff46-4872-b209-9e501dde7b73","app_parent_items_id":"d1aa4365-b1ef-4c91-ac8e-e3289f7eb075","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APPa3c60a25ff464872b2099e501dde7b73"},{"only_menu_item":false,"item_order":30,"layer":1,"app_name":"Personel İşlemleri","app_description":"Personel İşlemleri","app_path":"","uu_id":"eebb591d-842b-4495-8721-e09552665a06","app_parent_items_id":"166d9a3f-495e-4261-baab-dd456e9d294b","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APPeebb591d842b44958721e09552665a06"},{"only_menu_item":true,"item_order":40,"layer":2,"app_name":"Kişi Tanımlama","app_description":"Kişi Tanımlama","app_path":"create_person","uu_id":"0c6c8cd2-f6b7-471f-9671-5cc1ac9f502e","app_parent_items_id":"eebb591d-842b-4495-8721-e09552665a06","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP0c6c8cd2f6b7471f96715cc1ac9f502e"},{"only_menu_item":false,"item_order":50,"layer":1,"app_name":"Bina İşlemleri","app_description":"Bina İşlemleri","app_path":"","uu_id":"66627ebb-0425-425f-bc0f-8a943eb0a3ca","app_parent_items_id":"166d9a3f-495e-4261-baab-dd456e9d294b","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP66627ebb0425425fbc0f8a943eb0a3ca"},{"only_menu_item":true,"item_order":60,"layer":2,"app_name":"Bina ve bölüm tanımlama","app_description":"Bina ve bölüm tanımlama","app_path":"create_build","uu_id":"173c4d8e-5577-4d4d-8712-f6fa2fbc8019","app_parent_items_id":"66627ebb-0425-425f-bc0f-8a943eb0a3ca","after_separator":false,"row_limit":100,"read":true,"write":false,"delete":false,"report_print":false,"report_export":false,"program_name":"APP173c4d8e55774d4d8712f6fa2fbc8019"}]}'
class Menu:
def __init__(self, json_data):
self.data = {}
self.json = json_data
self.app_name = None
self.app_description = None
self.app_path = None
self.uu_id = None
self.app_parent_items_id = None
self.children = {}
self.only_menu_item = None
self.item_order = None
self.layer = None
self.before_separator = None
self.row_limit = None
self.read = None
self.write = None
self.delete = None
self.report_print = None
self.report_export = None
self.program_name = None
self.dct = {}
self.import_data()
def add_item(
self,
only_menu_item,
item_order,
layer,
app_name,
app_description,
app_path,
uu_id,
app_parent_items_id,
before_separator,
row_limit,
read,
write,
delete,
report_print,
report_export,
program_name,
):
self.app_name = app_name
self.app_description = app_description
self.app_path = app_path
self.uu_id = uu_id
self.app_parent_items_id = app_parent_items_id
self.children = {}
self.only_menu_item = only_menu_item
self.item_order = item_order
self.layer = layer
self.before_separator = before_separator
self.row_limit = row_limit
self.read = read
self.write = write
self.delete = delete
self.report_print = report_print
self.report_export = report_export
self.program_name = program_name
self.dct = dict(
app_parent_items_id=app_parent_items_id,
uu_id=uu_id,
app_name=app_name,
children={},
app_path=app_path,
app_description=app_description,
only_menu_item=self.only_menu_item,
item_order=self.item_order,
layer=self.layer,
before_separator=self.before_separator,
row_limit=self.row_limit,
read=self.read,
write=self.write,
delete=self.delete,
report_print=self.report_print,
report_export=self.report_export,
program_name=self.program_name,
)
xx = self.find_data(self.data, str(app_parent_items_id))
if not xx:
self.data[self.uu_id] = self.dct
else:
xx["children"][self.uu_id] = self.dct
# xx.self.children[self.uu_id] = self.dct
# self.add_data(self.data, None)
def find_data(self, search_data, find_text):
if find_text is None:
return None
for x, y in search_data.items():
if x == find_text:
print(find_text, " bulundu")
# y["children"].append(self.dct)
return y
if "children" in y and len(y["children"]) > 0:
ret = self.find_data(y["children"], find_text)
if ret is not None:
return ret
return None
@staticmethod
def show_col(i, y):
print(
"layer :",
i,
" app_parent_items_id",
y["app_parent_items_id"],
"uu_id",
y["uu_id"],
"app_name",
y["app_name"],
"app_path",
y["app_path"],
"app_description",
y["app_description"],
"only_menu_item",
y["only_menu_item"],
"item_order",
y["item_order"],
"layer",
y["layer"],
"before_separator",
y["before_separator"],
"row_limit",
y["row_limit"],
"read",
y["read"],
"write",
y["write"],
"delete",
y["delete"],
"report_print",
y["report_print"],
"report_export",
y["report_export"],
"program_name",
y["program_name"],
)
def show_data(self):
# print(self.data)
for x, y in self.data.items():
self.show_col(0, y)
if type(y) is dict:
for a, b in y["children"].items():
self.show_col(1, b)
if type(y) is dict:
for c, d in b["children"].items():
self.show_col(2, d)
if type(y) is dict:
for e, f in d["children"].items():
self.show_col(3, f)
# print("show Dat :", x, y)
return self.data
def import_data(self):
if type(self.json) is str:
print("string miş")
self.json = json.loads(self.json)
for item, value in self.json.items():
if type(value) is list:
for x in range(len(value)):
print(f"t:{type(value[x])} : {value[x]}")
if type(value[x]) is list:
print("list", x)
if type(value[x]) is dict:
print(
value[x]["app_name"],
value[x]["app_description"],
value[x]["app_path"],
value[x]["uu_id"],
value[x]["app_parent_items_id"],
[],
value[x]["only_menu_item"],
value[x]["item_order"],
value[x]["layer"],
value[x]["after_separator"],
value[x]["row_limit"],
value[x]["read"],
value[x]["write"],
value[x]["delete"],
value[x]["report_print"],
value[x]["report_export"],
value[x]["program_name"],
)
self.add_item(
value[x]["only_menu_item"],
value[x]["item_order"],
value[x]["layer"],
value[x]["app_name"],
value[x]["app_description"],
value[x]["app_path"],
value[x]["uu_id"],
value[x]["app_parent_items_id"],
value[x]["after_separator"],
value[x]["row_limit"],
value[x]["read"],
value[x]["write"],
value[x]["delete"],
value[x]["report_print"],
value[x]["report_export"],
value[x]["program_name"],
)
# self.add_item(value[x]["app_name"], app_description, app_path, uu_id, app_parent_items_id):
# self.app_name = app_name
# for child in item.children:
# print(f" - {child.app_name}")
(0, [1, 3, 5])
(1, [2])
(3, [4])
(5, [6])
(4, [7])
menu = Menu(json.loads(data))
print("*" * 100)
menu.show_data()

View File

@ -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)))

View File

@ -0,0 +1,27 @@
Add via[Field] to @ login_via_credentials
Check is_occupant is True or False @ login_via_credentials
Add middleware @endpoint-controller to @ Event.Controller
If Events2Occupants and Events2Employees are not found for user request, response 401 Unauthorized
Also check user priority before Events2Occupants and Events2Employees
/home/berkay/evyos-apis/wag_api_service/shared_functions
Add default http errors status and message over Config Class
Change login and token object with occupant and employee
Add middleware to check user priority
Event rendering function must check with
Module -> Event
For each event add step and required previous step
Redis Cache TOKEN(encrypted) + UUID(encrypted) = Object (encrypted)
Occupant {
people_id,
occupant_id
}
Employee {
priority_id (Nullable | User),
*duty_id
}

View File

@ -0,0 +1,30 @@
GSM Projesi 30.11.2023 -315,00 TL
GSM Projesi 31.12.2023 -300,00 TL
Doğalgaz_Anakolon Projesi 31.10.2023 -1.733,33 TL
Doğalgaz_Anakolon Projesi 30.11.2023 -1.750,00 TL
Doğalgaz_Anakolon Projesi 31.12.2023 -1.100,00 TL
Yan Alan Projesi 31.10.2023 -495,83 TL
Yan Alan Projesi 30.11.2023 -400,00 TL
Kazan çıkışı ana boru değişim projesi 29.02.2024 -180,00 TL
Kazan çıkışı ana boru değişim projesi 31.03.2024 -150,00 TL
Kazan Genleşme Tankı değişim projesi 30.04.2024 -250,00 TL
Kazan Genleşme Tankı değişim projesi 31.05.2024 -300,00 TL
2024 1 nolu proje toplamı 31.07.2024 -585
1 - Bina boru satışı -₺1.580,00
3 - Bina su depo temizliği projesi ₺3.000,00
4 - Çatı Camlarının değişim projesi ₺1.000,00
8 - Bina Uydu Bakım Projesi ₺1.700,00
2 - Bina iç tadilat, elektrik ve boya işleri projesi ₺42.200,00
5 - Dış kapının değişim projesi ₺24.000,00
9- Hurda Aliminyum Satışı -₺2.600,00
6 - Kazan borlularının ana kolondan sökülmesi projesi ₺22.500,00
7 - Yol tarafı ile bahçe tarafı logar tadilat projesi ₺0,00
16.09.2024 10:28 -2.000,00 6.327,91 0 TL dogalgaz bakimi icin
20.08.2024 13:53 -8.000,00 257,70 0 TL tadilat bedeli
15.07.2024 11:52 -500,00 7.104,23 0 TL REMZİ SU
13.07.2024 10:35 -2.400,00 6.104,23 0 TL SANTIYE TEKNIK ANKARA 0412
13.06.2024 13:37 -750,00 16.939,09 0 TL cam değişimi
12.06.2024 10:41 -3.000,00 16.701,74 0 TL depo temizliği için ödenen
10.06.2024 13:38 -200,00 19.701,74 0 TL cam için ödenen

View File

@ -0,0 +1,14 @@
1 ₺4.120,00
1 - Bina boru satışı -₺1.580,00
3 - Bina su depo temizliği projesi ₺3.000,00
4 - Çatı Camlarının değişim projesi ₺1.000,00
8 - Bina Uydu Bakım Projesi ₺1.700,00
2 ₺63.600,00
2 - Bina iç tadilat, elektrik ve boya işleri projesi ₺42.200,00
5 - Dış kapının değişim projesi ₺24.000,00
9- Hurda Aliminyum Satışı -₺2.600,00
4 ₺22.500,00
6 - Kazan borlularının ana kolondan sökülmesi projesi ₺22.500,00
3 ₺0,00
7 - Yol tarafı ile bahçe tarafı logar tadilat projesi ₺0,00
Genel Toplam ₺90.220,00

View File

@ -0,0 +1,23 @@
{
"login_sup":
{
"domain": "evyos.com.tr",
"access_key": "karatay.berkay.sup@evyos.com.tr",
"password": "string",
"remember_me": false
},
"login_occupant":
{
"domain": "evyos.com.tr",
"access_key": "gdemirel@example.com",
"password": "string",
"remember_me": false
},
"select_sup": {
"company_uu_id": "0c8b808c-0f3b-4030-a2e7-681ed4478b97"
},
"select_occupant": {
"occupant_uu_id": "16dc4457-4c71-4a87-bd7a-53e87f6657d5",
"build_part_uu_id": "295de6a4-e5ba-4f3a-b5c0-02dff0578dc2"
}
}

View File

@ -0,0 +1,34 @@
{
"build":
{
"gov_address_code": "123456",
"build_name": "Beaver Build",
"build_no": "56",
"build_types": "A",
"max_floor": 12,
"underground_floor": 1,
"build_date": "01.01.2021",
"tax_no": "1234567890",
"lift_count": 0,
"heating_system": true,
"cooling_system": false,
"hot_water_system": false,
"block_service_man_count": 0,
"security_service_man_count": 0,
"garage_count": 2
},
"build_part":
{
"build_uu_id": "19d53a0c-1fa8-4011-8c91-75c05d357838",
"address_gov_code": "132456789101112",
"part_no": 1,
"part_level": 0,
"build_part_type_uu_id": "8eeeedd2-82b2-46d2-8611-4ea3d31dc122",
"part_code": 1,
"part_gross_size": 90,
"part_net_size": 90,
"human_livable": true,
"part_direction": "9fcbc4fa-245e-42a4-b4e2-6e2eb3222d3d",
"current_owner_person_uu_id": "bd96727c-2732-4432-98f3-516c403b0f6d"
}
}

View File

@ -0,0 +1,31 @@
{
"create_companies" :[
{
"formal_name": "Evyos Ankara Bölge Müdürlüğü",
"company_type": "Commercial",
"commercial_type": "Branch",
"public_name": "Evyos Ankara Bölge Müdürlüğü",
"company_tag": "Ankara Bölge Müdürlüğü",
"default_lang_type": "TR",
"default_money_type": "TL"
},
{
"formal_name": "Evyos İzmir Bölge Müdürlüğü",
"company_type": "Commercial",
"commercial_type": "Branch",
"public_name": "Evyos İzmir Bölge Müdürlüğü",
"company_tag": "İzmir Bölge Müdürlüğü",
"default_lang_type": "TR",
"default_money_type": "TL"
},
{
"formal_name": "Evyos İstanbul Bölge Müdürlüğü",
"company_type": "Commercial",
"commercial_type": "Branch",
"public_name": "Evyos İstanbul Bölge Müdürlüğü",
"company_tag": "İstanbul Bölge Müdürlüğü",
"default_lang_type": "TR",
"default_money_type": "TL"
}
]
}

View File

@ -0,0 +1,63 @@
{
"decision_book":
{
"build_uu_id": "19d53a0c-1fa8-4011-8c91-75c05d357838",
"period_start_date": "2024-07-01",
"period_stop_date": "2025-06-30",
"decision_type": "DMB",
"meeting_date": "2024-06-26 21:44:20.749 +0300",
"is_out_sourced": false
},
"decision_book_item":[
{
"item_order": 1,
"item_comment": "Geçen yıla ait toplantıda 2nolu 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-3nolu 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"
}
]
}

View File

@ -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}
}
}

View File

@ -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}
}
}

View File

@ -0,0 +1,781 @@
import typing
from typing import Union
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 (
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_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 system_arrow, client_arrow
from api_validations.core_response import AlchemyJsonResponse
class AuthenticationLoginEventMethods(MethodToEvent):
event_type = "LOGIN"
event_description = "Login via domain and access key : [email] | [phone]"
event_category = "AUTHENTICATION"
__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: Request,
):
access_dict = Users.login_user_with_credentials(data=data, request=request)
if not access_dict.get("user", None):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
)
if not access_dict.get("access_object", None):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="This User has no active role registered. Please contact your administrator.",
)
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": access_dict.get("user", None).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: Union[EmployeeSelection, OccupantSelection],
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
from api_objects import OccupantToken, CompanyToken
if isinstance(token_dict, EmployeeTokenObject):
if data.company_uu_id not in token_dict.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.filter_one(
Companies.uu_id == data.company_uu_id,
).data:
department_ids = [
department.id
for department in Departments.filter_all(
Departments.company_id == selected_company.id,
).data
]
duties_ids = [
duties.id
for duties in Duties.filter_all(
Duties.company_id == selected_company.id,
).data
]
staff_ids = [
staff.id
for staff in Staff.filter_all(
Staff.duties_id.in_(duties_ids),
).data
]
employee = Employees.filter_one(
Employees.people_id == token_dict.person_id,
Employees.staff_id.in_(staff_ids),
).data
reachable_event_list_id = Event2Employee.get_event_id_by_employee_id(
employee_id=employee.id
)
staff = Staff.filter_one(
Staff.id == employee.staff_id,
).data
duties = Duties.filter_one(
Duties.id == staff.duties_id,
).data
department = Departments.filter_one(
Departments.id == duties.department_id,
).data
bulk_id = Duty.filter_by_one(system=True, duty_code="BULK").data
bulk_duty_id = Duties.filter_by_one(
company_id=selected_company.id,
duties_id=bulk_id.id,
**Duties.valid_record_dict,
).data
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,
),
)
return JSONResponse(
content={
"completed": True,
"message": "Company is selected successfully",
},
status_code=status.HTTP_200_OK,
)
elif isinstance(token_dict, OccupantTokenObject):
occupant_type = OccupantTypes.filter_by_one(
system=True, uu_id=data.occupant_uu_id
).data
if not occupant_type:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Occupant Type is not found",
)
build_part = BuildParts.filter_by_one(
system=True, uu_id=data.build_part_uu_id
).data
if not build_part:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Build Part is not found",
)
build = Build.filter_one(
Build.id == build_part.build_id,
).data
related_company = RelationshipEmployee2Build.filter_one(
RelationshipEmployee2Build.member_id == build.id,
).data
company_related = Companies.filter_one(
Companies.id == related_company.company_id,
).data
responsible_employee = Employees.filter_one(
Employees.id == related_company.employee_id,
).data
if selected_occupant_type := BuildLivingSpace.filter_one(
BuildLivingSpace.occupant_type == occupant_type.id,
BuildLivingSpace.person_id == token_dict.person_id,
BuildLivingSpace.build_parts_id == build_part.id,
).data:
reachable_event_list_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,
),
)
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_check_token_is_valid(
cls,
request,
):
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,
):
access_token = str(request.headers.get(Auth.ACCESS_TOKEN_TAG))
if token_user := get_object_via_access_key(request=request):
if found_user := Users.filter_one(
Users.uu_id == token_user.get("uu_id"),
).data:
user_token = UsersTokens.filter_one(
UsersTokens.domain == found_user.domain_name,
UsersTokens.user_id == found_user.id,
UsersTokens.token_type == "RememberMe",
).data
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,
data: ChangePassword,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
if found_user := Users.filter_one(
Users.id == token_dict.user_id,
).data:
if found_user.check_password(data.old_password):
found_user.create_password(
found_user=found_user, 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,
data: CreatePassword,
):
if not data.re_password == data.password:
raise HTTPException(
status_code=status.HTTP_406_NOT_ACCEPTABLE, detail="Password must match"
)
found_user = Users.filter_one(
Users.password_token == data.password_token,
).data
if not found_user:
return JSONResponse(
content={
"completed": False,
"message": "Record not found",
"data": {},
},
status_code=status.HTTP_202_ACCEPTED,
)
found_user.create_password(found_user=found_user, password=data.password)
# 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,
)
class AuthenticationResetPasswordEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"af9e121e-24bb-44ac-a616-471d5754360e": "authentication_reset_password",
}
@classmethod
def authentication_reset_password(cls, data: Forgot):
from sqlalchemy import or_
found_user = Users.query.filter(
or_(
Users.email == str(data.access_key).lower(),
Users.phone_number == str(data.access_key).replace(" ", ""),
),
).first()
if not found_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Given access key or domain is not matching with the any user record.",
)
reset_password_token = found_user.reset_password_token(found_user=found_user)
send_email_completed = send_email(
subject=f"Dear {found_user.user_tag}, a password reset request has been received.",
receivers=[str(found_user.email)],
html=change_your_password_template(
user_name=found_user.user_tag,
forgot_link=ApiStatic.forgot_link(forgot_key=reset_password_token),
),
)
if not send_email_completed:
raise found_user.raise_http_exception(
status_code=400, message="Email can not be sent. Try again later"
)
return JSONResponse(
content={
"completed": True,
"message": "Password change link is sent to your email or phone",
"data": found_user.get_dict(),
},
status_code=status.HTTP_200_OK,
)
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: Union[EmployeeTokenObject, OccupantTokenObject],
):
found_user = Users.filter_one(
Users.uu_id == token_dict.person_uu_id,
).data
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, token_user in already_tokens.items():
redis_cli.delete(key)
selected_user = Users.filter_one(
Users.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, data: Logout, token_dict: Union[EmployeeTokenObject, OccupantTokenObject]
):
from api_services.redis.functions import get_object_via_user_uu_id
if not token_dict:
return JSONResponse(
content={
"completed": False,
"message": "Logout is not successfully completed",
"data": None,
},
status_code=status.HTTP_202_ACCEPTED,
)
token_users = get_object_via_user_uu_id(token_dict.user_uu_id)
for token, token_user in token_users.items():
if token_user["domain"] == data.domain:
selected_user = Users.filter_one(
Users.uu_id == token_dict.user_uu_id,
).data
redis_cli.delete(token)
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,
)
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: typing.Union[EmployeeSelection, OccupantSelection],
):
token_refresher = UsersTokens.filter_by_one(
system=True, 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.filter_one(
Users.id == token_refresher.user_id,
*Users.valid_record_args(Users),
):
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(system_arrow.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: typing.Union[EmployeeSelection, OccupantSelection],
):
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(system_arrow.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: typing.Union[EmployeeSelection, OccupantSelection],
):
found_user = Users.check_user_exits(
access_key=data.access_key, domain=data.domain
)
expired_str = str(
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
)
expired_int = int(
client_arrow.get(
system_arrow.now() - system_arrow.get(str(found_user.expiry_ends))
).days
)
expiry_ends = system_arrow.get(str(found_user.expiry_ends))
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": client_arrow.get(expiry_ends),
"expired_str": client_arrow.get(expired_str),
"expired_int": expired_int,
},
},
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")
)
AuthenticationResetPasswordEventMethod = AuthenticationResetPasswordEventMethods(
action=ActionsSchema(endpoint="/authentication/reset_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")
)

View File

@ -0,0 +1,167 @@
from typing import Union
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.validations_request 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 AlchemyJsonResponse
class EventBindOccupantEventMethods(MethodToEvent):
event_type = "UPDATE"
__event_keys__ = {
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": "bind_events_occupant_super_user",
}
__event_validation__ = {
"5702f0a9-fe8f-4aae-922e-6e04b497ef6a": RegisterEvents2Occupant
}
@classmethod
def bind_events_occupant_super_user(
cls,
data: RegisterEvents2Occupant,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
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.filter_one(
BuildParts.uu_id == data.build_part_uu_id,
BuildParts.active == True,
).data
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.filter_by_one(
uu_id=data.occupant_uu_id
).data
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_all(
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.filter_one(
BuildLivingSpace.build_parts_id == occupants_build_part.id,
BuildLivingSpace.occupant_type == occupant_occupant_type.id,
BuildLivingSpace.active == True,
).data
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:
Events.save()
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",
}
__event_validation__ = {
"c93a3009-65a0-498d-9191-04484d5cde81": RegisterEvents2Occupant
}
@classmethod
def bind_events_employee(
cls,
data: RegisterEvents2Occupant,
token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
):
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")
)

View File

@ -0,0 +1,111 @@
@classmethod
def select_action(cls, duty_id, filter_expr: list = None):
from application.base import AlchemyResponse
keys_list = list(cls.__table__.columns) + list(
RelationshipDutyUser.__table__.columns
)
keys = [str(_.table) + "*" + str(_.name) for _ in keys_list]
data_list = []
if filter_expr is not None:
filter_expr = (RelationshipDutyUser.duty_id == duty_id, *filter_expr)
data = (
cls.session.query(
*cls.__table__.columns, *RelationshipDutyUser.__table__.columns
)
.select_from(cls)
.join(RelationshipDutyUser, RelationshipDutyUser.member_id == cls.id)
.filter(*filter_expr)
)
return AlchemyResponse(
query=data, data=data_list if data_list else data.all(), count=data.count()
)
data = (
cls.session.query(
*cls.__table__.columns, *RelationshipDutyUser.__table__.columns
)
.select_from(cls)
.join(RelationshipDutyUser, RelationshipDutyUser.member_id == cls.id)
.filter(RelationshipDutyUser.duty_id == duty_id)
)
for _ in data.all():
temp_dict = {}
for ix, item in enumerate(_):
table, key = str(keys[ix]).split("*")[0], str(keys[ix]).split("*")[1]
if table in temp_dict:
temp_dict[table][key] = item
else:
temp_dict[table] = {}
temp_dict[table][key] = item
data_list.append(temp_dict)
return AlchemyResponse(
query=data, data=data_list if data_list else data.all(), count=data.count()
)
def create_filter_with_options(model, options: ListOptions, duty_id):
from application.base import AlchemyResponse
if options.query:
model.query_filter = options.query
model.filter_attr = options
if hasattr(model, "select_action"):
list_of_model_records = model.select_action(duty_id=duty_id)
else:
list_of_model_records = model.filter_by_non_deleted()
if hasattr(list_of_model_records.data, "get_dict"):
if not list_of_model_records.count:
return AlchemyResponse(
query=list_of_model_records.query,
count=list_of_model_records.count,
data=[],
)
return AlchemyResponse(
query=list_of_model_records.query,
count=list_of_model_records.count,
data=[_.get_dict() for _ in list_of_model_records.data],
)
if not list_of_model_records.count:
return AlchemyResponse(
query=list_of_model_records.query,
count=list_of_model_records.count,
data=[],
)
return AlchemyResponse(
query=list_of_model_records.query,
count=list_of_model_records.count,
data=model.joined_to_dict(list_of_model_records.data),
)
@classmethod
def joined_to_dict(cls, joined_list: list):
exclude = list(cls.__exclude__fields__) + [
"is_confirmed",
"deleted",
"replication_id",
"id",
]
serialized_list = []
new_dict = {}
for joined_dict_list in joined_list:
for joined_dict in joined_dict_list:
return_dict = {}
for key, val in joined_dict_list[joined_dict].items():
if key not in exclude and "_id" not in key:
if val is None:
return_dict[key] = None
elif key == "active":
return_dict[key] = bool(val)
elif isinstance(val, int) or isinstance(val, float):
return_dict[key] = float(val)
elif isinstance(val, bool):
return_dict[key] = bool(val)
else:
return_dict[key] = str(val)
if key == "uu_id":
return_dict["uu_id"] = str(val)
new_dict[joined_dict] = return_dict
serialized_list.append(new_dict)
return serialized_list

29
api_configs/__init__.py Normal file
View File

@ -0,0 +1,29 @@
from api_configs.configs import (
Config,
ApiStatic,
Auth,
WagDatabase,
WagRedis,
TestRedis,
HagRedis,
MongoConfig,
TestMongo,
RelationAccess,
EmailConfig,
TestDatabase,
)
__all__ = [
"Config",
"ApiStatic",
"Auth",
"WagDatabase",
"WagRedis",
"TestRedis",
"HagRedis",
"MongoConfig",
"TestMongo",
"RelationAccess",
"EmailConfig",
"TestDatabase",
]

152
api_configs/configs.py Normal file
View File

@ -0,0 +1,152 @@
import datetime
class Config:
INSECURE_PATHS = [
"/",
"/metrics",
"/openapi.json",
"/docs",
"/redoc",
"/auth/login",
"/favicon.ico",
"/docs/oauth2-redirect",
"/authentication/select",
"/authentication/login",
"/authentication/logout",
"/authentication/refresher",
"/authentication/refresh",
"/authentication/disconnect",
"/authentication/create_password",
"/authentication/reset_password",
"/authentication/forgot",
"/authentication/valid",
]
NOT_SECURE_PATHS = [
"/access/endpoints/available",
"/access/endpoint/available",
"/validations/endpoint",
"/authentication/avatar",
]
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/password/create?tokenUrl="
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.46"
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"]

View File

@ -0,0 +1,152 @@
import datetime
class Config:
INSECURE_PATHS = [
"/",
"/metrics",
"/openapi.json",
"/docs",
"/redoc",
"/auth/login",
"/favicon.ico",
"/docs/oauth2-redirect",
"/authentication/select",
"/authentication/login",
"/authentication/logout",
"/authentication/refresher",
"/authentication/refresh",
"/authentication/disconnect",
"/authentication/create_password",
"/authentication/reset_password",
"/authentication/forgot",
"/authentication/valid",
]
NOT_SECURE_PATHS = [
"/access/endpoints/available",
"/access/endpoint/available",
"/validations/endpoint",
"/authentication/avatar",
]
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/password/create?tokenUrl="
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.46"
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"]