Files
sakhteman/app/repositories/monitor_physical_progress.py

174 lines
7.7 KiB
Python

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, mongo_soft_deleter
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})
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)
print('avg',_avg)
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": {"$lte": _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
async def delete(self, _id: uuid.UUID):
_get = await use_collection(COLLECTION).find_one({"_id": _id})
await mongo_soft_deleter(_id, COLLECTION)
_get_model = MODEL(**_get)
_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': _get_model.project_id, "date_at": {"$lte": _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 = {}
if _avg[0]['avg']:
_update = {'medium_progress': round(_avg[0]['avg'], 1)}
else:
_update = {'medium_progress': 0}
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 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}