import uuid import datetime from pymongo import ReturnDocument from app.config import TaskEnv from app.models.monito_physical_progress import PhysicalProgressModel, LastRecord from core.repositories.base import BaseRepository from core.service.mongo_db import use_collection from core.utils.crudify import mongo_inserter from app.repositories.project import ProjectRepository COLLECTION = TaskEnv.CLN_MONITOR_PYSICAL MODEL = PhysicalProgressModel class PhysicalProgressRepository(BaseRepository): def __init__(self): super().__init__(collection=TaskEnv.CLN_MONITOR_PYSICAL, model=PhysicalProgressModel) async def search_last(self, connection: str, _inp: LastRecord, first: int, last: int): m_first = _inp.date_at - datetime.timedelta(days=first) print(m_first) m_end = _inp.date_at - datetime.timedelta(days=last) print(m_end) last = await use_collection(connection).find({ 'project_id': _inp.project_id, 'date_at': {'$gte': m_first, '$lte': m_end} }).sort("$natural", -1).to_list(None) if last: return last[0] else: return {} async def last_record(self, _inp: LastRecord): send = {'month': {}, 'three_month': {}, 'before':{}} if _inp.id: find_record = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).find_one({"_id":_inp.id}) if _inp.id: before = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).find({ 'project_id': _inp.project_id, 'created_at': {'$lt': find_record['created_at']}}).sort("$natural", -1).to_list(None) else: before = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).find({ 'project_id': _inp.project_id, }).sort("$natural", -1).to_list(None) if before: send['before'] = before[0] last = await self.search_last(TaskEnv.CLN_MONITOR_PYSICAL, _inp, 35, 25) if last: send['month'] = last three_month = await self.search_last(TaskEnv.CLN_MONITOR_PYSICAL, _inp, 95, 85) if three_month: send['three_month'] = three_month _avg = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).aggregate([ {'$match':{'project_id':_inp.project_id, "date_at": {"$lt": _inp.date_at}}}, {'$group': {'_id': None, 'avg': {'$avg': "$real"}, 'sum':{'$sum': "$real"}, 'count':{'$sum': 1}}} ]).to_list(None) if _avg: send['avg'] = _avg[0] else: send['avg'] = {} return send async def create(self, _inp: MODEL): create = await mongo_inserter(_inp, COLLECTION, getter=self.get) await ProjectRepository().set_sts_two_for_monitor(_inp.project_id) return create async def list_by_project(self,_id:uuid.UUID): _get = await use_collection(COLLECTION).find({"project_id":_id}).to_list(None) return _get async def update(self, _id: uuid.UUID, update: MODEL): _get = await use_collection(COLLECTION).find_one({"_id": _id}) res = await use_collection(COLLECTION).find_one_and_update({"_id":_id},{"$set":update.mongo_dict()},return_document=ReturnDocument.AFTER) _get_model = MODEL(**_get) if _get_model.real != update.real: _list = await use_collection(COLLECTION).find({"project_id":_get_model.project_id, "date_at":{"$gt":_get_model.date_at}}).to_list(None) if _list: for i in _list: _i_model = MODEL(**i) _avg = await use_collection(TaskEnv.CLN_MONITOR_PYSICAL).aggregate([ {'$match': {'project_id': update.project_id, "date_at": {"$lt": _i_model.date_at}}}, {'$group': {'_id': None, 'avg': {'$avg': "$real"}}} ]).to_list(None) _model = LastRecord( project_id= _i_model.project_id, date_at= _i_model.date_at ) _last = await self.last_record(_model) unset = {} _update = {'medium_progress': _avg[0]['avg']} if _last['month']: _update.update({'last_month':_last['month']['real']}) else: unset.update({'last_month': None}) if _last['three_month']: _update.update({'last_three_month': _last['three_month']['real']}) else: unset.update({'last_three_month': None}) if unset: await use_collection(COLLECTION).update_one({"_id": _i_model.id}, {"$set":_update, "$unset":unset}) else: await use_collection(COLLECTION).update_one({"_id": _i_model.id},{"$set": _update}) return res