Files
sakhteman/app/repositories/project.py
T

359 lines
15 KiB
Python
Raw Normal View History

2025-06-06 12:48:56 +03:30
import datetime
2024-12-31 07:14:34 +03:30
import json
2024-06-08 00:01:04 +03:30
import uuid
2024-02-15 00:17:51 +03:30
from uuid import UUID
2024-12-31 07:14:34 +03:30
import requests
2024-03-14 15:33:17 +03:30
from fastapi import HTTPException
2024-06-08 00:01:04 +03:30
from app.config import TaskEnv
2026-06-19 23:51:11 +03:30
from app.models.project import ProjectModel, UpdateSts, ProjectSts, Design, ProjectStatusAgreement, ListWithIds
2024-02-15 00:17:51 +03:30
from core.repositories.base import BaseRepository
from core.service.mongo_db import use_collection
2024-09-12 13:39:00 +03:30
from core.utils.table_engine import TableEngineRequestType, TableEngineExport
from core.utils.te import NewTableEngine
2024-12-31 07:14:34 +03:30
from typing import TypeVar, List
2024-02-15 00:17:51 +03:30
COLLECTION = "project"
2024-09-12 13:39:00 +03:30
T = TypeVar('T')
2025-06-06 20:25:29 +03:30
2024-02-15 00:17:51 +03:30
class ProjectRepository(BaseRepository[ProjectModel]):
def __init__(self):
super().__init__(collection=COLLECTION, model=ProjectModel)
2025-06-06 20:25:29 +03:30
def create_code(self, coding: ProjectModel):
2024-02-15 00:17:51 +03:30
code = str(coding.counter)
2025-06-06 20:25:29 +03:30
print("code1", code)
2024-02-15 00:17:51 +03:30
if len(code) < 4:
code = code.rjust(4, '0')
print("code2", code)
code = coding.design.nature + coding.design.type + code
return code
2025-01-19 00:04:33 +03:30
async def create_report_price(self, _inp: ProjectModel):
if _inp.monitor and _inp.monitor.detail and _inp.monitor.detail.first_amount:
price = {
'_id': uuid.uuid4(),
'project_id': _inp.id,
'first_amount': _inp.monitor.detail.first_amount
}
await use_collection(TaskEnv.CLN_PROJECT_PRICE_REPORT).insert_one(price)
return True
2025-06-06 20:25:29 +03:30
async def update_report_price(self, update: ProjectModel):
2025-01-19 00:04:33 +03:30
if update.monitor and update.monitor.detail and update.monitor.detail.first_amount:
price = await use_collection(TaskEnv.CLN_PROJECT_PRICE_REPORT).find_one({'project_id': update.id})
if not price:
price = {
'_id': uuid.uuid4(),
'project_id': update.id,
'first_amount': update.monitor.detail.first_amount
}
await use_collection(TaskEnv.CLN_PROJECT_PRICE_REPORT).insert_one(price)
else:
2025-06-06 20:25:29 +03:30
await use_collection(TaskEnv.CLN_PROJECT_PRICE_REPORT).update_one({'project_id': update.id}, {
'$set': {'first_amount': update.monitor.detail.first_amount}})
2025-01-19 00:04:33 +03:30
return True
2024-02-15 00:17:51 +03:30
2025-06-06 20:25:29 +03:30
def creat_date_delay(self, coding: ProjectModel):
start_date = coding.monitor.detail.date_create_project
first_time_months = int(coding.monitor.detail.first_time)
new_month = start_date.month + first_time_months
new_year = start_date.year + (new_month - 1) // 12
new_month = (new_month - 1) % 12 + 1
return start_date.replace(year=new_year, month=new_month)
async def create(self, coding: ProjectModel):
2024-02-15 00:17:51 +03:30
coding.counter = 1
2026-06-10 00:31:45 +03:30
last_project = await use_collection(COLLECTION).find({}).sort("counter", -1).to_list(None)
2024-02-15 00:17:51 +03:30
if last_project:
2025-06-06 20:25:29 +03:30
coding.counter = last_project[0]["counter"] + 1
2024-02-15 00:17:51 +03:30
code = self.create_code(coding)
2026-06-10 00:31:45 +03:30
coding.design.code = code
2025-01-18 23:42:08 +03:30
coding.init_id().cu_at()
2024-02-15 00:17:51 +03:30
if coding.monitor:
2026-06-10 00:31:45 +03:30
coding.monitor.code = code
2025-01-10 19:12:14 +03:30
coding.has_monitor = True
2025-01-19 00:04:33 +03:30
await self.create_report_price(coding)
2025-06-06 12:37:06 +03:30
if coding.monitor.detail.date_create_project and coding.monitor.detail.first_time:
2025-06-06 20:25:29 +03:30
coding.date_delay = self.creat_date_delay(coding)
2025-01-11 00:00:16 +03:30
else:
coding.has_monitor = False
2025-01-18 23:42:08 +03:30
2024-02-15 00:17:51 +03:30
await use_collection(COLLECTION).insert_one(coding.mongo_dict())
2025-01-24 11:35:48 +03:30
if coding.design.status_agreement:
2025-06-06 20:25:29 +03:30
_model = ProjectStatusAgreement(
project_id=coding.id,
status=coding.design.status_agreement
2025-01-24 11:35:48 +03:30
).init_id().cu_at()
await use_collection(TaskEnv.CLN_PROJECT_AGREEMENT).insert_one(_model.mongo_dict())
2024-02-15 00:17:51 +03:30
return await self.get(coding.id)
async def update(self, _id: UUID, update: ProjectModel):
2026-01-02 18:48:31 +03:30
old_project_dict = await use_collection(COLLECTION).find_one({"_id": _id})
old_project = ProjectModel(**old_project_dict)
2024-02-15 00:17:51 +03:30
if update.monitor and not old_project.monitor:
code = self.create_code(update)
2026-06-10 00:31:45 +03:30
update.monitor.code = code
2025-06-06 20:25:29 +03:30
if update.design.nature != old_project.design.nature or update.design.type != old_project.design.type:
2024-02-15 00:17:51 +03:30
code = self.create_code(update)
2026-06-10 00:31:45 +03:30
update.design.code = code
2024-02-15 00:17:51 +03:30
if update.monitor:
2026-06-10 00:31:45 +03:30
update.monitor.code = code
2025-01-10 19:35:39 +03:30
if update.monitor:
update.has_monitor = True
await self.update_report_price(update)
2026-01-02 18:48:31 +03:30
old_detail = old_project_dict.get("monitor", {}).get("detail", {})
old_date = old_detail.get("date_create_project")
old_first_time = old_detail.get("first_time")
update_dict = update.mongo_dict()
new_detail = update_dict.get("monitor", {}).get("detail", {})
new_date = new_detail.get("date_create_project")
new_first_time = new_detail.get("first_time")
can_calculate = (new_date is not None and new_first_time is not None)
if can_calculate and ((old_date is None or new_date != old_date)or(old_first_time is None or new_first_time != old_first_time)):
2025-06-06 20:25:29 +03:30
update.date_delay = self.creat_date_delay(update) + datetime.timedelta(days=update.all_delay_day)
2024-02-15 00:17:51 +03:30
update.u_at()
2025-06-06 20:25:29 +03:30
await use_collection(COLLECTION).update_one({"_id": _id}, {"$set": update.mongo_dict()})
2025-01-24 11:35:48 +03:30
if old_project.design.status_agreement != update.design.status_agreement:
_model = ProjectStatusAgreement(
project_id=_id,
status=update.design.status_agreement
).init_id().cu_at()
await use_collection(TaskEnv.CLN_PROJECT_AGREEMENT).insert_one(_model.mongo_dict())
2024-03-05 00:48:22 +03:30
return await self.get(_id)
2024-03-14 15:33:17 +03:30
async def update_design_sts(self, _id: UUID, update: UpdateSts):
2025-06-06 20:25:29 +03:30
old_project = await use_collection(COLLECTION).find_one({"_id": _id})
2024-03-14 15:33:17 +03:30
if not old_project:
2025-06-06 20:25:29 +03:30
raise HTTPException(status_code=400, detail='این پروژه وجود ندارد')
await use_collection(COLLECTION).update_one({"_id": _id}, {"$set": {
'design.sts': update.sts, 'design.reason_stop': update.reason_stop
2024-03-14 15:33:17 +03:30
}})
2024-06-08 00:01:04 +03:30
sts_class = ProjectSts(
2025-06-06 20:25:29 +03:30
project_id=_id,
type='design',
sts=update.sts,
description=update.reason_stop
2024-06-08 00:01:04 +03:30
).init_id().cu_at()
await use_collection(TaskEnv.CLN_PROJECT_STS).insert_one(sts_class.mongo_dict())
return await self.get(_id)
async def update_monitor_sts(self, _id: UUID, update: UpdateSts):
2025-06-06 20:25:29 +03:30
old_project = await use_collection(COLLECTION).find_one({"_id": _id})
2024-06-08 00:01:04 +03:30
if not old_project:
2025-06-06 20:25:29 +03:30
raise HTTPException(status_code=400, detail='این پروژه وجود ندارد')
await use_collection(COLLECTION).update_one({"_id": _id}, {"$set": {
'monitor.sts': update.sts, 'monitor.reason_sts': update.reason_stop
2024-06-08 00:01:04 +03:30
}})
sts_class = ProjectSts(
2025-06-06 20:25:29 +03:30
project_id=_id,
type='monitor',
sts=update.sts,
description=update.reason_stop
2024-06-08 00:01:04 +03:30
).init_id().cu_at()
await use_collection(TaskEnv.CLN_PROJECT_STS).insert_one(sts_class.mongo_dict())
return await self.get(_id)
2024-03-14 15:33:17 +03:30
async def delete(self, _id: UUID):
2025-06-06 20:25:29 +03:30
old_project = await use_collection(COLLECTION).find_one({"_id": _id})
2024-03-14 15:33:17 +03:30
if not old_project:
2025-06-06 20:25:29 +03:30
raise HTTPException(status_code=400, detail='این پروژه وجود ندارد')
await use_collection(COLLECTION).update_one({"_id": _id}, {"$set": {
'sts': 2,
2024-03-14 15:33:17 +03:30
}})
return True
2024-09-12 14:52:19 +03:30
async def restore(self, _id: UUID):
2025-06-06 20:25:29 +03:30
old_project = await use_collection(COLLECTION).find_one({"_id": _id})
2024-09-12 14:52:19 +03:30
if not old_project:
2025-06-06 20:25:29 +03:30
raise HTTPException(status_code=400, detail='این پروژه وجود ندارد')
await use_collection(COLLECTION).update_one({"_id": _id}, {"$set": {
'sts': 1,
2024-09-12 14:52:19 +03:30
}})
return True
2024-03-05 00:48:22 +03:30
async def list_project_design(self):
project = await use_collection(COLLECTION).find({
'$or': [
{'has_monitor': False},
{'monitor': {'$exists': 0}},
{
'has_monitor': True,
'monitor.has_design': True
}
]
}).to_list(None)
2024-03-05 00:48:22 +03:30
return project
async def list_project_monitor(self):
2025-06-06 20:25:29 +03:30
project = await use_collection(COLLECTION).find({'monitor': {"$exists": 1}}).to_list(None)
2024-06-08 00:01:04 +03:30
return project
2025-06-06 20:25:29 +03:30
async def list_sts_design(self, _id: uuid.UUID):
2024-06-08 00:01:04 +03:30
sts_project = await use_collection(TaskEnv.CLN_PROJECT_STS).find({
2025-06-06 20:25:29 +03:30
"project_id": _id,
"type": "design"
2024-06-08 00:01:04 +03:30
}).to_list(None)
return sts_project
2025-06-06 20:25:29 +03:30
async def list_sts_monitor(self, _id: uuid.UUID):
2024-06-08 00:01:04 +03:30
sts_project = await use_collection(TaskEnv.CLN_PROJECT_STS).find({
2025-06-06 20:25:29 +03:30
"project_id": _id,
"type": "monitor"
2024-06-08 00:01:04 +03:30
}).to_list(None)
return sts_project
2024-12-31 07:14:34 +03:30
async def list_project(self):
project = await use_collection(TaskEnv.CLN_PROJECT).find({}).to_list(None)
return project
2026-06-19 23:51:11 +03:30
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
2025-06-06 20:25:29 +03:30
async def set_sts_two_for_monitor(self, project_id: uuid.UUID):
2024-06-08 00:01:04 +03:30
project = await use_collection(TaskEnv.CLN_PROJECT).find_one({"_id": project_id})
if not ('sts' in project['monitor'] and project['monitor']['sts'] > 1):
await use_collection(TaskEnv.CLN_PROJECT).update_one(
{'_id': project_id},
2025-06-06 20:25:29 +03:30
{"$set": {"monitor.sts": 2}})
2024-06-08 00:01:04 +03:30
sts_class = ProjectSts(
project_id=project_id,
type='monitor',
sts=2
).init_id().cu_at()
await use_collection(TaskEnv.CLN_PROJECT_STS).insert_one(sts_class.mongo_dict())
2024-09-12 13:39:00 +03:30
return True
2025-11-02 19:13:34 +03:30
async def getList(self, state: str='null'):
if not state == 'null':
projects = await use_collection(TaskEnv.CLN_PROJECT).find({"sts": 1,"design.state":state }).to_list(None)
else:
projects = await use_collection(TaskEnv.CLN_PROJECT).find({"sts": 1}).to_list(None)
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
2024-09-12 13:39:00 +03:30
async def fetch_delete(self, _input: TableEngineRequestType) -> TableEngineExport[T]:
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(
2024-09-12 13:39:00 +03:30
query_class=use_collection(self.COLLECTION),
soft_deleted=True,
model=self.MODEL,
2025-12-22 00:43:07 +03:30
search_cols=['design.title'],
extra_filter=extra_filter,
2024-09-12 13:39:00 +03:30
inputs=_input.te) \
.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
2024-09-19 12:17:16 +03:30
async def fetch(self, _input: TableEngineRequestType) -> TableEngineExport[T]:
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(
2024-09-19 12:17:16 +03:30
query_class=use_collection(self.COLLECTION),
soft_deleted=True,
model=self.MODEL,
2025-12-22 00:43:07 +03:30
search_cols=['design.title'],
extra_filter=extra_filter,
2024-09-19 12:17:16 +03:30
inputs=_input.te) \
.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
2024-12-31 07:14:34 +03:30
async def get_all(self):
url = 'http://api.khanesaziceco.ir/api/api/project/table'
2025-06-06 20:25:29 +03:30
headers = {
2025-06-14 21:43:46 +03:30
'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkua2hhbmVzYXppY2Vjby5pclwvYXBpXC9hdXRoXC9sb2dpbiIsImlhdCI6MTc0OTg0NjExMSwiZXhwIjoxNzUyNDM4MTExLCJuYmYiOjE3NDk4NDYxMTEsImp0aSI6Ikh6OURsZHR2U2FVRU5rd24iLCJzdWIiOjEzNiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.C7vRTRbhKrKuoFd334imKAIYFnU-9ygCIFmrwiPGVxY'}
2024-12-31 07:14:34 +03:30
data = {"page": 1,
"limit": 400,
2025-06-06 20:25:29 +03:30
"sort": "_id"
2024-12-31 07:14:34 +03:30
}
2025-06-06 20:25:29 +03:30
res = requests.post(url, data=json.dumps(data), headers=headers)
2024-12-31 07:14:34 +03:30
a = res.json()
obj = []
2025-06-14 21:43:46 +03:30
rows = a['rows']
rows.reverse()
for i in rows:
2025-06-06 20:25:29 +03:30
_set = ProjectModel(
2024-12-31 07:14:34 +03:30
sts=1,
counter=i['id'],
design=Design(**i),
created_at=i['created_at'],
updated_at=i['updated_at'],
).init_id()
2024-12-31 07:14:34 +03:30
obj.append(_set.mongo_dict())
2025-06-14 21:43:46 +03:30
await use_collection(TaskEnv.CLN_PROJECT).insert_many(obj)
2024-12-31 07:14:34 +03:30
return res.json()
async def create_project_price(self):
2025-06-06 20:25:29 +03:30
projects = await use_collection(TaskEnv.CLN_PROJECT).find(
{'monitor.detail.first_amount': {'$exists': 1}}).to_list(None)
for project in projects:
sum_status = 0
sum_adjust = 0
2025-06-06 20:25:29 +03:30
status = await use_collection(TaskEnv.CLN_FINANCIAL_STATUS).find(
{'project_id': project['_id'], 'amount': {'$exists': 1}}).to_list(None)
if status:
for i in status:
sum_status += i['amount']
2025-06-06 20:25:29 +03:30
adjust = await use_collection(TaskEnv.CLN_FINANCIAL_ADJUST).find(
{'project_id': project['_id'], 'amount': {'$exists': 1}}).to_list(None)
if adjust:
for i in adjust:
sum_adjust += i['amount']
price = {
'_id': uuid.uuid4(),
'project_id': project['_id'],
'first_amount': project['monitor']['detail']['first_amount'],
2025-06-06 20:25:29 +03:30
'amount_status': sum_status,
'amount_adjust': sum_adjust
}
await use_collection(TaskEnv.CLN_PROJECT_PRICE_REPORT).insert_one(price)