Compare commits

...
9 Commits
18 changed files with 1104 additions and 698 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ class SubRecord(pydantic.BaseModel):
class Record(BaseModel): class Record(BaseModel):
id: Optional[uuid.UUID] = Field(alias='_id') id: Optional[uuid.UUID] = Field(alias='_id')
title: str = Field(description='عنوان در این فیلد قرار میگیرد') title: str = Field(description='عنوان در این فیلد قرار میگیرد')
send: SubRecord = Field(description='اطلاعات ارسال در این فیلد ذخیره می شود') send: Optional[SubRecord] = Field(description='اطلاعات ارسال در این فیلد ذخیره می شود')
receive: Optional[SubRecord] = Field(description='اطلاعات دریافت در این فیلد ذخیره می شود') receive: Optional[SubRecord] = Field(description='اطلاعات دریافت در این فیلد ذخیره می شود')
class RecordModel(Record): class RecordModel(Record):
+3
View File
@@ -151,5 +151,8 @@ class ProjectStatusAgreement(BaseModel):
project_id: Optional[uuid.UUID] = Field(description="کد شناسایی پروژه در این فیلد قرار می گیرد") project_id: Optional[uuid.UUID] = Field(description="کد شناسایی پروژه در این فیلد قرار می گیرد")
status:str status:str
class ListWithIds(pydantic.BaseModel):
ids: list[uuid.UUID]
+5 -1
View File
@@ -22,10 +22,14 @@ class DelayDonutDetail(pydantic.BaseModel):
project_id:uuid.UUID project_id:uuid.UUID
select:Literal['financial','force_major','technical'] select:Literal['financial','force_major','technical']
class DonutReport(pydantic.BaseModel):
only_current: bool = Field(default=False, description='فقط پروژه‌های نظارت جاری؛ مقدار false برای همه پروژه‌های نظارت')
class DonutList(pydantic.BaseModel): class DonutList(pydantic.BaseModel):
type: int = Field(description='مقدار وارد شده در گزارش قبل') type: int = Field(description='مقدار وارد شده در گزارش قبل')
donut_select: str = Field(description='آیتم دونات انتخاب شده') donut_select: str = Field(description='آیتم دونات انتخاب شده')
class PhysicalMonth(pydantic.BaseModel): class PhysicalMonth(pydantic.BaseModel):
from_date:datetime.datetime from_date:datetime.datetime
to_date:datetime.datetime to_date:datetime.datetime
+4 -3
View File
@@ -87,6 +87,7 @@ class ContractRepository(BaseRepository):
{'$match':query['query']}, {'$match':query['query']},
{'$group': {"_id": None, 'count': {'$sum': 1},'sum':{"$sum":"$amount"}}} {'$group': {"_id": None, 'count': {'$sum': 1},'sum':{"$sum":"$amount"}}}
]).to_list(None) ]).to_list(None)
return count[0] print(count)
else: if len(count)>0:
return [] return count[0]
return []
+740 -652
View File
File diff suppressed because it is too large Load Diff
@@ -139,6 +139,34 @@ class PhysicalProgressRepository(BaseRepository):
else: else:
await use_collection(COLLECTION).update_one({"_id": _i_model.id},{"$set": _update}) await use_collection(COLLECTION).update_one({"_id": _i_model.id},{"$set": _update})
return True return True
# for recalc medium progress in database
# async def recalc_medium_progress(self):
# print('111111111111111111111')
# coll = use_collection(TaskEnv.CLN_MONITOR_PYSICAL)
# project_ids = await coll.distinct(
# "project_id",
# {"deleted_at": {"$exists": False}},
# )
# print('222222222222222222222')
#
# updated = 0
# for pid in project_ids:
# print('piiiiiidf',pid)
# records = await coll.find({
# "project_id": pid,
# "deleted_at": {"$exists": False},
# }).sort([("date_at", 1), ("_id", 1)]).to_list(None)
#
# total = 0
# for i, rec in enumerate(records, start=1):
# total += rec.get("real") or 0
# await coll.update_one(
# {"_id": rec["_id"]},
# {"$set": {"medium_progress": round(total / i, 1)}},
# )
# updated += 1
#
# return {"projects": len(project_ids), "updated": updated}
+72 -12
View File
@@ -7,7 +7,7 @@ import requests
from fastapi import HTTPException from fastapi import HTTPException
from app.config import TaskEnv from app.config import TaskEnv
from app.models.project import ProjectModel, UpdateSts, ProjectSts, Design, ProjectStatusAgreement from app.models.project import ProjectModel, UpdateSts, ProjectSts, Design, ProjectStatusAgreement, ListWithIds
from core.repositories.base import BaseRepository from core.repositories.base import BaseRepository
from core.service.mongo_db import use_collection from core.service.mongo_db import use_collection
from core.utils.table_engine import TableEngineRequestType, TableEngineExport from core.utils.table_engine import TableEngineRequestType, TableEngineExport
@@ -66,14 +66,14 @@ class ProjectRepository(BaseRepository[ProjectModel]):
async def create(self, coding: ProjectModel): async def create(self, coding: ProjectModel):
coding.counter = 1 coding.counter = 1
last_project = await use_collection(COLLECTION).find({}).sort("$natural", -1).to_list(None) last_project = await use_collection(COLLECTION).find({}).sort("counter", -1).to_list(None)
if last_project: if last_project:
coding.counter = last_project[0]["counter"] + 1 coding.counter = last_project[0]["counter"] + 1
code = self.create_code(coding) code = self.create_code(coding)
coding.design.code = 'D' + code coding.design.code = code
coding.init_id().cu_at() coding.init_id().cu_at()
if coding.monitor: if coding.monitor:
coding.monitor.code = 'S' + code coding.monitor.code = code
coding.has_monitor = True coding.has_monitor = True
await self.create_report_price(coding) await self.create_report_price(coding)
if coding.monitor.detail.date_create_project and coding.monitor.detail.first_time: if coding.monitor.detail.date_create_project and coding.monitor.detail.first_time:
@@ -95,12 +95,12 @@ class ProjectRepository(BaseRepository[ProjectModel]):
old_project = ProjectModel(**old_project_dict) old_project = ProjectModel(**old_project_dict)
if update.monitor and not old_project.monitor: if update.monitor and not old_project.monitor:
code = self.create_code(update) code = self.create_code(update)
update.monitor.code = 'S' + code update.monitor.code = code
if update.design.nature != old_project.design.nature or update.design.type != old_project.design.type: if update.design.nature != old_project.design.nature or update.design.type != old_project.design.type:
code = self.create_code(update) code = self.create_code(update)
update.design.code = 'D' + code update.design.code = code
if update.monitor: if update.monitor:
update.monitor.code = 'S' + code update.monitor.code = code
if update.monitor: if update.monitor:
update.has_monitor = True update.has_monitor = True
await self.update_report_price(update) await self.update_report_price(update)
@@ -175,7 +175,16 @@ class ProjectRepository(BaseRepository[ProjectModel]):
return True return True
async def list_project_design(self): async def list_project_design(self):
project = await use_collection(COLLECTION).find({'monitor': {"$exists": 0}}).to_list(None) project = await use_collection(COLLECTION).find({
'$or': [
{'has_monitor': False},
{'monitor': {'$exists': 0}},
{
'has_monitor': True,
'monitor.has_design': True
}
]
}).to_list(None)
return project return project
async def list_project_monitor(self): async def list_project_monitor(self):
@@ -200,6 +209,13 @@ class ProjectRepository(BaseRepository[ProjectModel]):
project = await use_collection(TaskEnv.CLN_PROJECT).find({}).to_list(None) project = await use_collection(TaskEnv.CLN_PROJECT).find({}).to_list(None)
return project return project
async def list_project_with_select(self):
project = await use_collection(TaskEnv.CLN_PROJECT).find({},{"_id":1,"design.title":1,"design.code":1}).to_list(None)
return project
async def list_project_with_ids(self,inp:ListWithIds):
projects = await use_collection(TaskEnv.CLN_PROJECT).find({"_id":{"$in":inp.ids}}).to_list(None)
return projects
async def set_sts_two_for_monitor(self, project_id: uuid.UUID): async def set_sts_two_for_monitor(self, project_id: uuid.UUID):
project = await use_collection(TaskEnv.CLN_PROJECT).find_one({"_id": project_id}) project = await use_collection(TaskEnv.CLN_PROJECT).find_one({"_id": project_id})
if not ('sts' in project['monitor'] and project['monitor']['sts'] > 1): if not ('sts' in project['monitor'] and project['monitor']['sts'] > 1):
@@ -224,25 +240,69 @@ class ProjectRepository(BaseRepository[ProjectModel]):
return projects return projects
@staticmethod
def _has_design_sts_filter(te_input) -> bool:
if not te_input:
return False
f_list = getattr(te_input, 'f', None) if not isinstance(te_input, dict) else te_input.get('f')
if not f_list:
return False
for scope in f_list:
items = scope.get('items', []) if isinstance(scope, dict) else getattr(scope, 'items', [])
if items:
for item in items:
col = item.get('col') if isinstance(item, dict) else getattr(item, 'col', '')
if col == 'design.sts':
return True
return False
async def fetch_delete(self, _input: TableEngineRequestType) -> TableEngineExport[T]: async def fetch_delete(self, _input: TableEngineRequestType) -> TableEngineExport[T]:
return await NewTableEngine.mongo( extra_filter = [{'sts': 2}]
if self._has_design_sts_filter(_input.te if _input else None):
extra_filter.append({
'$or': [
{'has_monitor': False},
{'monitor': {'$exists': False}},
{'has_monitor': True, 'monitor.has_design': True}
]
})
result = await NewTableEngine.mongo(
query_class=use_collection(self.COLLECTION), query_class=use_collection(self.COLLECTION),
soft_deleted=True, soft_deleted=True,
model=self.MODEL, model=self.MODEL,
search_cols=['design.title'], search_cols=['design.title'],
extra_filter=[{'sts': 2}], extra_filter=extra_filter,
inputs=_input.te) \ inputs=_input.te) \
.to_dict() .to_dict()
if result and result.rows:
for row in result.rows:
if row.monitor and row.monitor.has_design is False:
row.design.sts = None
return result
async def fetch(self, _input: TableEngineRequestType) -> TableEngineExport[T]: async def fetch(self, _input: TableEngineRequestType) -> TableEngineExport[T]:
return await NewTableEngine.mongo( extra_filter = [{'sts': 1}]
if self._has_design_sts_filter(_input.te if _input else None):
extra_filter.append({
'$or': [
{'has_monitor': False},
{'monitor': {'$exists': False}},
{'has_monitor': True, 'monitor.has_design': True}
]
})
result = await NewTableEngine.mongo(
query_class=use_collection(self.COLLECTION), query_class=use_collection(self.COLLECTION),
soft_deleted=True, soft_deleted=True,
model=self.MODEL, model=self.MODEL,
search_cols=['design.title'], search_cols=['design.title'],
extra_filter=[{'sts': 1}], extra_filter=extra_filter,
inputs=_input.te) \ inputs=_input.te) \
.to_dict() .to_dict()
if result and result.rows:
for row in result.rows:
if row.monitor and row.monitor.has_design is False:
row.design.sts = None
return result
async def get_all(self): async def get_all(self):
url = 'http://api.khanesaziceco.ir/api/api/project/table' url = 'http://api.khanesaziceco.ir/api/api/project/table'
+187 -9
View File
@@ -3,20 +3,30 @@ from datetime import time
from app.config import TaskEnv from app.config import TaskEnv
from app.models.project import ProjectPriceReport from app.models.project import ProjectPriceReport
from app.models.report import StatusReport, ReportCountry, DonutList, DelayDonutDetail, PhysicalMonth from app.models.report import StatusReport, ReportCountry, DonutList, DonutReport, DelayDonutDetail, PhysicalMonth
from core.service.mongo_db import use_collection from core.service.mongo_db import use_collection
class ReportRepository(): class ReportRepository():
async def project_status(self, _inp: StatusReport, type): async def project_status(self, _inp: StatusReport, type):
if _inp.state: if _inp.state:
match = {f'{type}.sts': {'$exists': 1}, 'design.state': _inp.state} match = {f'{type}.sts': {'$exists': 1}, 'design.state': _inp.state,'sts':1}
else: else:
match = {f'{type}.sts': {'$exists': 1}} match = {f'{type}.sts': {'$exists': 1},'sts':1}
if _inp.type_id: if _inp.type_id:
match.update({'design.type_id': _inp.type_id}) match.update({'design.type_id': _inp.type_id})
if _inp.nature_id: if _inp.nature_id:
match.update({'design.nature_id': _inp.nature_id}) match.update({'design.nature_id': _inp.nature_id})
if type == 'design':
match.update({
'$or': [
{'has_monitor': False},
{
'monitor.has_design': True,
'has_monitor': True
}
]
})
if type == 'monitor' and _inp.monitor_type: if type == 'monitor' and _inp.monitor_type:
match.update({'monitor.base_information.type': _inp.monitor_type}) match.update({'monitor.base_information.type': _inp.monitor_type})
report = await use_collection(TaskEnv.CLN_PROJECT).aggregate([ report = await use_collection(TaskEnv.CLN_PROJECT).aggregate([
@@ -140,6 +150,64 @@ class ReportRepository():
]).to_list(None) ]).to_list(None)
return report return report
async def donut_v2(self, _select: int, _inp: DonutReport):
project_filter = {"has_monitor": True}
if _inp.only_current:
project_filter["monitor.sts"] = 2
report = None
if _select == 1:
report = await use_collection(TaskEnv.CLN_PROJECT).aggregate([
{"$match": project_filter},
{"$group": {"_id": "$design.nature_id", 'count': {'$sum': 1}}}
]).to_list(None)
elif _select == 2:
report = await use_collection(TaskEnv.CLN_PROJECT).aggregate([
{"$match": project_filter},
{
"$group": {
"_id": {
"$cond": [
{"$lt": ["$design.building_infrastructure", 1000]}, # Check if a < 10
"less_than_1000",
{
"$cond": [
{"$and": [{"$gte": ["$design.building_infrastructure", 1000]},
{"$lt": ["$design.building_infrastructure", 5000]}]},
# Check if 10 <= a < 20
"between_1000_and_5000",
{
"$cond": [
{"$and": [{"$gte": ["$design.building_infrastructure", 5000]},
{"$lt": ["$design.building_infrastructure", 15000]}]},
"between_5000_and_15000",
{
"$cond": [
{"$and": [{"$gte": ["$design.building_infrastructure", 15000]},
{"$lt": ["$design.building_infrastructure", 30000]}]},
"between_15000_and_30000",
"greater_than_or_equal_30000" # Otherwise, a >= 30
]
}
]
}
]
}
]
},
"total": {"$sum": 1},
}
}
]).to_list(None)
elif _select == 3:
report = await use_collection(TaskEnv.CLN_PROJECT).aggregate([
{"$match": project_filter},
{"$group": {"_id": "$design.type_id", 'count': {'$sum': 1}}}
]).to_list(None)
return report
async def list_donut(self, _inp: DonutList): async def list_donut(self, _inp: DonutList):
_filter = None _filter = None
if _inp.type == 1: if _inp.type == 1:
@@ -220,6 +288,13 @@ class ReportRepository():
async def categorize_deviation(self): async def categorize_deviation(self):
report = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).aggregate( report = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).aggregate(
[{"$match": {"deviation": {"$exists": True, "$ne": None}}}, [{"$match": {"deviation": {"$exists": True, "$ne": None}}},
{"$lookup": {
"from": TaskEnv.CLN_PROJECT,
"localField": "project_id",
"foreignField": "_id",
"as": "project"
}},
{"$match": {"project.monitor.sts": 2}},
{"$group": { {"$group": {
"_id": { "_id": {
"$cond": [ "$cond": [
@@ -257,6 +332,28 @@ class ReportRepository():
]).to_list(None) ]).to_list(None)
return report return report
async def delay_donut_all_v2(self, _inp: DonutReport):
project_filter = {"project.has_monitor": True}
if _inp.only_current:
project_filter["project.monitor.sts"] = 2
report = await use_collection(TaskEnv.CLN_BILL_DELAY).aggregate([
{"$lookup": {
"from": TaskEnv.CLN_PROJECT,
"localField": "project_id",
"foreignField": "_id",
"as": "project"
}},
{"$match": project_filter},
{'$group': {"_id": None, "total_financial": {"$sum": "$financial.total"},
"total_force_major": {"$sum": "$force_major.total"},
"total_technical": {"$sum": "$technical.total"},
"total_extra_new_work": {"$sum": "$extra_new_work"},
"total_other": {"$sum": "$other"},
}}
]).to_list(None)
return report
async def list_delay_donut(self, _select: str): async def list_delay_donut(self, _select: str):
get_list = [] get_list = []
_map = {'1': 'financial.total', '2': 'force_major.total', '3': 'technical.total', '4': 'extra_new_work', _map = {'1': 'financial.total', '2': 'force_major.total', '3': 'technical.total', '4': 'extra_new_work',
@@ -402,20 +499,55 @@ class ReportRepository():
to_date = datetime.combine(_inp.to_date.date(), time.max) to_date = datetime.combine(_inp.to_date.date(), time.max)
from_date = _inp.from_date.combine(_inp.from_date.date(), time.min) from_date = _inp.from_date.combine(_inp.from_date.date(), time.min)
result = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).aggregate([ result = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).aggregate([
{"$match":{"date_at":{"$lte":to_date,"$gte":from_date}}},
{ {
"$sort": {'date_at': -1} "$match": {
"date_at": {
"$lte": to_date,
"$gte": from_date
}
}
}, },
{"$group": {
{'_id': {"year": "$year", "month": "$month"}, "$lookup": {
'avg': {'$avg': "$real"}}, "from": TaskEnv.CLN_PROJECT,
} "localField": "project_id",
"foreignField": "_id",
"as": "project"
}
},
{"$match": {"project.monitor.sts": 2}},
{
"$group": {
"_id": {
"year": "$year",
"month": "$month"
},
"avg": {
"$avg": "$real"
},
"sort_date": {
"$max": "$date_at"
}
}
},
{
"$sort": {
"sort_date": -1
}
}
]).to_list(None) ]).to_list(None)
return result return result
async def design_progress_status(self): async def design_progress_status(self):
result = await use_collection("design_progress").aggregate([ result = await use_collection("design_progress").aggregate([
{'$match':{'complete_at':{"$exists":0},'parent_id':{"$exists":0}}}, {'$match':{'complete_at':{"$exists":0},'parent_id':{"$exists":0}}},
{"$lookup": {
"from": TaskEnv.CLN_PROJECT,
"localField": "project_id",
"foreignField": "_id",
"as": "project"
}},
{"$match": {"project.design.sts": 2}},
{"$group": {"$group":
{'_id': '$type', {'_id': '$type',
'count': {'$sum': 1}, 'count': {'$sum': 1},
@@ -428,6 +560,13 @@ class ReportRepository():
async def design_progress_status_state(self): async def design_progress_status_state(self):
result = await use_collection("design_progress").aggregate([ result = await use_collection("design_progress").aggregate([
{'$match':{'complete_at':{"$exists":0},'parent_id':{"$exists":0}}}, {'$match':{'complete_at':{"$exists":0},'parent_id':{"$exists":0}}},
{"$lookup": {
"from": TaskEnv.CLN_PROJECT,
"localField": "project_id",
"foreignField": "_id",
"as": "project"
}},
{"$match": {"project.design.sts": 2}},
{"$group": {"$group":
{'_id': {'state':"$state",'type':'$type'}, {'_id': {'state':"$state",'type':'$type'},
'count': {'$sum': 1}, 'count': {'$sum': 1},
@@ -532,6 +671,45 @@ class ReportRepository():
res['audit_program'] = result res['audit_program'] = result
return res return res
# فرآیند طراحی گانت چارت
async def design_chart(self, project_id: uuid):
list_design_progress = await use_collection('design_progress').find({"project_id": project_id}).sort('type', 1).to_list(None)
if not list_design_progress:
return {}
list_design_progress_ids = [doc["_id"] for doc in list_design_progress]
list_design_progress_record = await use_collection('design_progress_record').find({"design_progress_id": {"$in":list_design_progress_ids}}).to_list(None)
grouped_records = {}
for i in list_design_progress:
t = i["type"]
st = i.get("sub_type")
if st:
grouped_records.setdefault(t, {})[st] = {
"progress": i,
"records": []
}
else:
grouped_records.setdefault(t, {
"progress": i,
"records": []
})
print(grouped_records)
for item in list_design_progress:
for record in list_design_progress_record:
if record["design_progress_id"] == item['_id']:
if 'sub_type' not in item:
grouped_records[item['type']]["records"].append(record)
else:
grouped_records[item['type']][item['sub_type']]["records"].append(record)
return grouped_records
+8 -3
View File
@@ -18,9 +18,9 @@ def design():
def monitor(): def monitor():
pass pass
@router.get('/progress1', tags=_tag_base) @router.get('/progress/madarek', tags=_tag_base)
@shrink(repo.addProgress1) @shrink(repo.madarek)
def addProgress1(): def madarek():
pass pass
@router.get('/progress/physical', tags=_tag_base) @router.get('/progress/physical', tags=_tag_base)
@@ -89,6 +89,11 @@ def addProgressTender():
def changeStatus(): def changeStatus():
pass pass
@router.get('/change/design/metri/sts', tags=_tag_base)
@shrink(repo.changeStatusWithMetri)
def changeStatusWithMetri():
pass
@router.get('/progress/monitor/physical', tags=_tag_base) @router.get('/progress/monitor/physical', tags=_tag_base)
@shrink(repo.progressMonitorPhysical) @shrink(repo.progressMonitorPhysical)
def progressMonitor(): def progressMonitor():
+5
View File
@@ -25,6 +25,11 @@ def create(coding: ThisModel = Body(...)):
def last_record(last:LastRecord): def last_record(last:LastRecord):
pass pass
# @router.get('/progress/rediv', response_model=list[dict], tags=_tag_base, description='پیشرفت فیزیکی')
# @shrink(repo.recalc_medium_progress)
# def recalc_medium_progress():
# pass
@router.get('/list/{_id}', response_model=List[ThisModel], tags=_tag_base, description='پیشرفت فیزیکی') @router.get('/list/{_id}', response_model=List[ThisModel], tags=_tag_base, description='پیشرفت فیزیکی')
@shrink(repo.list_by_project) @shrink(repo.list_by_project)
def list_by_project(_id: UUID): def list_by_project(_id: UUID):
+10 -1
View File
@@ -3,7 +3,7 @@ from uuid import UUID
from fastapi import Body from fastapi import Body
from app.models.project import ProjectModel, UpdateSts from app.models.project import ProjectModel, UpdateSts, ListWithIds
from app.repositories.project import ProjectRepository from app.repositories.project import ProjectRepository
from core.app import app from core.app import app
from core.utils.router import generate_router, shrink from core.utils.router import generate_router, shrink
@@ -32,6 +32,15 @@ def list_project_design():
def list_project_monitor(): def list_project_monitor():
pass pass
@router.post('/list/ids', response_model=ThisModel, tags=_tag_base)
@shrink(repo.list_project_with_ids)
def list_project_with_ids(inp:ListWithIds):
pass
@router.get('/list/all', response_model=List[ThisModel], tags=_tag_base)
@shrink(repo.list_project_with_select)
def list_project_with_select():
pass
@router.get('/list/project', response_model=List[ThisModel], tags=_tag_base) @router.get('/list/project', response_model=List[ThisModel], tags=_tag_base)
@shrink(repo.list_project) @shrink(repo.list_project)
def list_project(): def list_project():
+20 -4
View File
@@ -2,7 +2,7 @@ import uuid
from fastapi import Body from fastapi import Body
from app.models.report import StatusReport, ReportCountry, DonutList, DelayDonutDetail, PhysicalMonth from app.models.report import StatusReport, ReportCountry, DonutList, DonutReport, DelayDonutDetail, PhysicalMonth
from app.repositories.report import ReportRepository from app.repositories.report import ReportRepository
from core.app import app from core.app import app
from core.utils.router import generate_router, shrink from core.utils.router import generate_router, shrink
@@ -62,15 +62,25 @@ def sum_add_time_end_project():
@shrink(repo.delay_donut_all) @shrink(repo.delay_donut_all)
def delay_donut_all(): def delay_donut_all():
pass pass
@router.post('/donut-v2/delay/all', tags=_tag_base)
@shrink(repo.delay_donut_all_v2)
def delay_donut_all_v2(_inp: DonutReport = Body(...)):
pass
#لیست پروژه ها را نمایش میده #لیست پروژه ها را نمایش میده
@router.get('/donut/delay/{_select}', tags=_tag_base) @router.get('/donut/delay/{_select}', tags=_tag_base)
@shrink(repo.list_delay_donut) @shrink(repo.list_delay_donut)
def list_delay_donut(_select): def list_delay_donut(_select):
pass pass
#تفکیک پروژه ها بر حسب زیربنا و تفکیک ماهیت پروژه و تفکیک بر حسب نوع پروژه #تفکیک پروژه ها بر حسب زیربنا و تفکیک ماهیت پروژه و تفکیک بر حسب نوع پروژه
@router.get('/donut/{_select}', tags=_tag_base) @router.post('/donut/{_select}', tags=_tag_base)
@shrink(repo.donut) @shrink(repo.donut)
def donut(_select:int): def donut(_select: int, _inp: DonutReport = Body(...)):
pass
@router.post('/donut-v2/{_select}', tags=_tag_base)
@shrink(repo.donut_v2)
def donut_v2(_select: int, _inp: DonutReport = Body(...)):
pass pass
@router.post('/list-donut', tags=_tag_base) @router.post('/list-donut', tags=_tag_base)
@@ -139,4 +149,10 @@ def status_agreement_progress():
def get_extra_project(project_id: uuid.UUID): def get_extra_project(project_id: uuid.UUID):
pass pass
app.include_router(router) # فرآیند طراحی گانت چارت
@router.get('/design/chart/{project_id}', tags=_tag_base)
@shrink(repo.design_chart)
def design_chart(project_id: uuid.UUID):
pass
app.include_router(router)
+3 -3
View File
@@ -4,7 +4,7 @@ auth:
algorithm: 'HS256' algorithm: 'HS256'
access_token_expire_minutes: 43201 access_token_expire_minutes: 43201
refresh_token_expire_minutes: 43200 refresh_token_expire_minutes: 43200
url: 'https://auth.hacoupian.net/v2/auth/validate-token' url: 'http://pm.khanesaziceco.ir/api/api/me'
cache_prefix_key: 'auth_key_' cache_prefix_key: 'auth_key_'
cache_ttl: 360 cache_ttl: 360
@@ -68,11 +68,11 @@ database:
db: 'omde' db: 'omde'
limiter_redis: limiter_redis:
url: 'redis://192.168.15.76:6379' url: 'redis://172.16.1.194:6379'
db: '' db: ''
auth_redis: auth_redis:
url: 'redis://192.168.15.231:6379' url: 'redis://172.16.1.194:6379'
db: '1' db: '1'
neo4j: neo4j:
+3 -3
View File
@@ -23,9 +23,8 @@ async def validate_token(_input: ValidateTokenInput):
_cache_auth = await redis_get(f'{conf.auth.cache_prefix_key}{_cache_key}', conf.database.get('auth_redis')) _cache_auth = await redis_get(f'{conf.auth.cache_prefix_key}{_cache_key}', conf.database.get('auth_redis'))
if not _cache_auth: if not _cache_auth:
client = httpx.AsyncClient() client = httpx.AsyncClient()
headers = {'Content-Type': 'application/json', } headers = {'Content-Type': 'application/json', 'Authorization':'Bearer '+_input.token}
result = await client.request('GET', conf.auth.url, json=_input.dict(), headers=headers)
result = await client.request('POST', conf.auth.url, json=_input.dict(), headers=headers)
export = result.text export = result.text
if 'application/json' in result.headers['content-type']: if 'application/json' in result.headers['content-type']:
export = result.json() export = result.json()
@@ -35,6 +34,7 @@ async def validate_token(_input: ValidateTokenInput):
if 'v2' in conf.auth.url: if 'v2' in conf.auth.url:
export = export.get('data') export = export.get('data')
print(export)
await redis_set(f'{conf.auth.cache_prefix_key}{_cache_key}', export, conf.database.get('auth_redis'), await redis_set(f'{conf.auth.cache_prefix_key}{_cache_key}', export, conf.database.get('auth_redis'),
ex=conf.auth.cache_ttl) ex=conf.auth.cache_ttl)
+3 -3
View File
@@ -8,12 +8,12 @@ from core.models.base import BaseModel
class UserModel(BaseModel): class UserModel(BaseModel):
id: Optional[Union[uuid.UUID, str]] = Field(alias='_id') id: Optional[Union[uuid.UUID, str, int]] = Field(alias='_id')
username: Optional[str] username: Optional[str]
mobile: Optional[str] mobile: Optional[str]
name: Optional[str] name: Optional[str]
first_name: Optional[str] fname: Optional[str]
last_name: Optional[str] lname: Optional[str]
is_su: Optional[bool] is_su: Optional[bool]
unit: Optional[str] unit: Optional[str]
avatar: Optional[str] avatar: Optional[str]
+7 -3
View File
@@ -10,7 +10,8 @@ from .utils.Models import TableEngineExport
class NewTableEngine: class NewTableEngine:
def __init__(self, query_class, model, inputs, mode, engine: AbstractEngine, extra_filter, def __init__(self, query_class, model, inputs, mode, engine: AbstractEngine, extra_filter,
default_sort_by, joins, search_cols, options=None, soft_deleted=False, unselect={}, return_query=False): default_sort_by, joins, search_cols, options=None, soft_deleted=False, unselect={}, return_query=False,
collation={'locale': 'fa'}):
self.model = model self.model = model
self.query_class = query_class self.query_class = query_class
self.mode = mode self.mode = mode
@@ -29,6 +30,7 @@ class NewTableEngine:
self.search_cols = search_cols self.search_cols = search_cols
self.unselect = unselect self.unselect = unselect
self.return_query = return_query self.return_query = return_query
self.collation = collation
self.engine = engine(self) self.engine = engine(self)
@staticmethod @staticmethod
@@ -38,10 +40,12 @@ class NewTableEngine:
mode: WorkingMode = WorkingMode.Development, mode: WorkingMode = WorkingMode.Development,
extra_filter=None, extra_filter=None,
soft_deleted=False, soft_deleted=False,
default_sort_by=None, joins=None, search_cols=[] ,unselect={}, return_query=False): default_sort_by=None, joins=None, search_cols=[] ,unselect={}, return_query=False,
collation={'locale': 'fa'}):
return NewTableEngine(query_class, model, inputs, mode, engine=MongoEngine, extra_filter=extra_filter, return NewTableEngine(query_class, model, inputs, mode, engine=MongoEngine, extra_filter=extra_filter,
default_sort_by=default_sort_by, joins=joins, search_cols=search_cols, default_sort_by=default_sort_by, joins=joins, search_cols=search_cols,
soft_deleted=soft_deleted,unselect=unselect, return_query=return_query) soft_deleted=soft_deleted,unselect=unselect, return_query=return_query,
collation=collation)
@staticmethod @staticmethod
def mssql(query_class, model, inputs, mode: WorkingMode = WorkingMode.Development, extra_filter=None, def mssql(query_class, model, inputs, mode: WorkingMode = WorkingMode.Development, extra_filter=None,
+1
View File
@@ -17,6 +17,7 @@ class AbstractEngineClass(abc.ABC):
self.soft_deleted = table_engine.soft_deleted self.soft_deleted = table_engine.soft_deleted
self.unselect = table_engine.unselect self.unselect = table_engine.unselect
self.return_query = table_engine.return_query self.return_query = table_engine.return_query
self.collation = {'locale': 'fa'}
@abc.abstractmethod @abc.abstractmethod
def exe(self): def exe(self):
+4
View File
@@ -54,6 +54,10 @@ class MongoEngine(AbstractEngineClass):
else: else:
tmp = tmp.sort(sort_by) tmp = tmp.sort(sort_by)
is_natural = isinstance(sort_by, dict) and sort_by.get('key_or_list') == '$natural'
if getattr(self, 'collation', None) and not is_natural:
tmp = tmp.collation(self.collation)
if self.input.e and self.input.e.ot: if self.input.e and self.input.e.ot:
res = await tmp.to_list(None) res = await tmp.to_list(None)
self.input.e.d = await self.generate_output(res) self.input.e.d = await self.generate_output(res)