Проекты
- +Интервал выполнения
+Задачи
{{ material.created_date }}
+{{ material.userRole }}
{{ material.deliveryDate}}
+diff --git a/backend/dao/project.py b/backend/dao/project.py
index e31ee32..6474d61 100644
--- a/backend/dao/project.py
+++ b/backend/dao/project.py
@@ -1,11 +1,13 @@
+from datetime import datetime
+import re
from bson import ObjectId
from dao.base import BaseDao
from database import db
-from schemas.project import ProjectCreate, ProjectResponse, Procurement, Stage, Risk, ProcurementResponse, \
+from schemas.project import ProjectCreate, ProjectResponse, Procurement, ProjectStatus, Stage, Risk, ProcurementResponse, \
RiskResponse, \
StageResponse, ProjectUpdate, RiskUpdate, ProcurementUpdate, StageUpdate
-from schemas.user import User, Contact, ContactResponse
+from schemas.user import Role, User, Contact, ContactResponse
from schemas.utils import object_id_to_str, generate_id, get_date_now
@@ -47,20 +49,24 @@ async def get_project_by_name(cls, project_name: str) -> ProjectResponse | None:
return ProjectResponse(**project)
@classmethod
- async def get_all_projects(cls) -> list[ProjectResponse] | list[None]:
- cursor = cls.collection.find()
- projects_list = await cursor.to_list()
- result = []
- for project in projects_list:
- project = object_id_to_str(project)
- result.append(ProjectResponse(**project))
- return result
-
- @classmethod
- async def get_projects_by_user(cls, user_id: str) -> list[ProjectResponse] | list[None]:
- cursor = cls.collection.find(
- {f"contacts.{user_id}": {"$exists": True}}
- )
+ async def get_all_projects(cls, project_name: str = "", project_status: ProjectStatus = ProjectStatus.none_status,
+ start_date: datetime = None, end_date: datetime = None, user_id: str = "") -> list[ProjectResponse] | list[None]:
+
+ filters = {}
+
+ if project_name:
+ filters["name"] = {"$regex": project_name, "$options": "i"}
+ if project_status:
+ filters["status"] = str(project_status.value)
+ if start_date:
+ filters["start_date"] = {"$gte": start_date}
+ if end_date:
+ filters["end_date"] = {"$lte": end_date}
+ if user_id:
+ filters[f"contacts.{user_id}"] = {"$exists": True}
+
+ print(filters)
+ cursor = cls.collection.find(filters)
projects_list = await cursor.to_list()
result = []
for project in projects_list:
@@ -166,17 +172,48 @@ async def delete_procurement(cls, project_id: str, procurement_id: str) -> str |
)
@classmethod
- async def get_procurements_by_project_id(cls, project_id: str) -> list[ProcurementResponse] | list[None] | None:
- project = await cls.collection.find_one({"_id": ObjectId(project_id)}, {"procurements": 1})
+ async def get_procurements_by_project_id(cls, project_id: str, name: str = "", creator_role: Role = None, state: bool = None,
+ start_date: datetime = None, end_date: datetime = None) -> list[ProcurementResponse] | list[None] | None:
+
+ procurements = []
+ project = await cls.collection.find_one({"_id": ObjectId(project_id)})
if project and "procurements" in project:
- procurements = [ProcurementResponse(id=procurement_id, **procurement_data) for
- procurement_id, procurement_data
- in
- project["procurements"].items()]
- return procurements
+ for procurement_id, procurement in project.get("procurements", {}).items():
+
+ if name:
+ name_match = re.search(name, procurement["item_name"], re.IGNORECASE)
+ else:
+ name_match = True
+
+ if creator_role:
+ role_match = procurement["created_by"]["role"] == creator_role
+ else:
+ role_match = True
+
+ if state is not None:
+ state_match = procurement["inStock"] == state
+ else:
+ state_match = True
+
+ if start_date and procurement["delivery_date"] is not None:
+ start_date_match = start_date <= procurement["delivery_date"]
+ else:
+ start_date_match = True
+
+
+ if end_date and procurement["delivery_date"] is not None:
+ end_date_match = end_date >= procurement["delivery_date"]
+ else:
+ end_date_match = True
+
+ if name_match and state_match and role_match and start_date_match and end_date_match:
+ procurements.append(
+ ProcurementResponse(id=procurement_id, **procurement)
+ )
+
elif project is None:
return None
- return []
+ return procurements
@classmethod
async def get_procurement_by_id(cls, project_id: str, procurement_id: str) -> ProcurementResponse | None:
@@ -247,15 +284,38 @@ async def delete_stage(cls, project_id: str, stage_id: str) -> str | None:
return stage_id
@classmethod
- async def get_stages_by_project_id(cls, project_id: str) -> list[StageResponse] | list[None] | None:
+ async def get_stages_by_project_id(cls, project_id: str, name: str = "", start_date: datetime = None,
+ end_date: datetime = None) -> list[StageResponse] | list[None] | None:
project = await cls.collection.find_one({"_id": ObjectId(project_id)}, {"stages": 1})
+
+ stages = []
if project and "stages" in project:
- stages = [StageResponse(id=stage_id, **stage_data) for stage_id, stage_data in
- project["stages"].items()]
- return stages
+ for stage_id, stage in project.get("stages", {}).items():
+
+ if name:
+ name_match = re.search(name, stage["name"], re.IGNORECASE)
+ else:
+ name_match = True
+
+ if start_date:
+ start_date_match = start_date <= stage["start_date"]
+ else:
+ start_date_match = True
+
+
+ if end_date:
+ end_date_match = end_date >= stage["end_date"]
+ else:
+ end_date_match = True
+
+ if name_match and start_date_match and end_date_match:
+ stages.append(
+ StageResponse(id=stage_id, **stage)
+ )
+
elif project is None:
return None
- return []
+ return stages
@classmethod
async def get_stage_by_id(cls, project_id: str, stage_id: str) -> StageResponse | None:
@@ -319,15 +379,23 @@ async def delete_risk(cls, project_id: str, risk_id: str) -> str | None:
return risk_id
@classmethod
- async def get_risks_by_project_id(cls, project_id: str) -> list[RiskResponse] | list[None] | None:
+ async def get_risks_by_project_id(cls, project_id: str, name: str = "") -> list[RiskResponse] | list[None] | None:
project = await cls.collection.find_one({"_id": ObjectId(project_id)}, {"risks": 1})
+
+ risks = []
if project and "risks" in project:
- risks = [RiskResponse(id=risk_id, **risk_data) for risk_id, risk_data in
- project["risks"].items()]
- return risks
+
+ for risk_id, risk in project.get("risks", {}).items():
+ if name:
+ name_match = re.search(name, risk["name"], re.IGNORECASE)
+ else:
+ name_match = True
+
+ if name_match:
+ risks.append(RiskResponse(id=risk_id, **risk))
elif project is None:
return None
- return []
+ return risks
@classmethod
async def get_risk_by_id(cls, project_id: str, risk_id: str) -> RiskResponse | None:
diff --git a/backend/dao/task.py b/backend/dao/task.py
index ea4354e..639811d 100644
--- a/backend/dao/task.py
+++ b/backend/dao/task.py
@@ -1,8 +1,10 @@
+from datetime import datetime
+import re
from bson import ObjectId
from dao.base import BaseDao
from database import db
-from schemas.task import Task, TaskResponse, TaskUpdate, TaskStatusUpdate, ProjectTaskResponse
+from schemas.task import Task, TaskResponse, TaskStatus, TaskUpdate, TaskStatusUpdate, ProjectTaskResponse
from schemas.user import Worker
from schemas.utils import generate_id, get_date_now
@@ -98,14 +100,17 @@ async def update_task_status(cls, project_id: str, stage_id: str, task_id: str,
}
}
)
-
+
if updated_id is None:
return None
return await cls.get_task_by_id(project_id, stage_id, task_id)
@classmethod
- async def get_tasks_by_stage_id(cls, project_id: str, stage_id: str) -> list[TaskResponse] | list[None]:
+ async def get_tasks_by_stage_id(cls, project_id: str, stage_id: str, task_name: str = "", project_name: str = "",
+ task_status: TaskStatus = TaskStatus.none_status,
+ start_date: datetime = None, end_date: datetime = None) -> list[TaskResponse] | \
+ list[None]:
project = await cls.collection.find_one(
{
"_id": ObjectId(project_id),
@@ -116,15 +121,45 @@ async def get_tasks_by_stage_id(cls, project_id: str, stage_id: str) -> list[Tas
if not project or "stages" not in project or stage_id not in project["stages"]:
return []
- tasks = project["stages"][stage_id].get("tasks", {})
+ tasks = []
+
+ for task_id, task in project["stages"][stage_id].get("tasks", {}).items():
+
+ if task_name:
+ name_match = re.search(task_name, task["name"], re.IGNORECASE)
+ print(f'name match is: {name_match}')
+ else:
+ name_match = True
+
+ if task_status:
+ status_match = task_status == task["status"]
+ print(f'status match is: {status_match}')
+ else:
+ status_match = True
- tasks_list = [
- TaskResponse(id=task_id, **task_data) for task_id, task_data in tasks.items()
- ]
- return tasks_list
+ if start_date:
+ start_date_match = start_date <= task["start_date"]
+ else:
+ start_date_match = True
+
+ if end_date:
+ end_date_match = end_date >= task["end_date"]
+ else:
+ end_date_match = True
+
+ if status_match and name_match and start_date_match and end_date_match:
+ tasks.append(TaskResponse(
+ id=task_id,
+ **task
+ ))
+ return tasks
@classmethod
- async def get_all_tasks_by_user(cls, user_id: str) -> list[ProjectTaskResponse] | list[None]:
+ async def get_all_tasks_by_user(cls, user_id: str, task_name: str = "", project_name: str = "",
+ task_status: TaskStatus = TaskStatus.none_status,
+ start_date: datetime = None, end_date: datetime = None) -> list[
+ ProjectTaskResponse] | \
+ list[None]:
cursor = cls.collection.find(
{
"stages": {
@@ -133,20 +168,68 @@ async def get_all_tasks_by_user(cls, user_id: str) -> list[ProjectTaskResponse]
}
)
+ search_params = {}
+
+ if task_name:
+ search_params["name"] = task_name
+ if project_name:
+ search_params["project_name"] = project_name
+ if task_status:
+ search_params["status"] = task_status
+ if start_date is not None:
+ search_params["start_date"] = start_date
+ if end_date is not None:
+ search_params["end_date"] = end_date
+
tasks = []
async for project in cursor:
+
+ if "project_name" in search_params:
+ project_match = re.search(search_params["project_name"], project["name"], re.IGNORECASE)
+ print(f'project match is: {project_match}')
+ else:
+ project_match = True
+
+ if project_match is None:
+ continue
+
for stage_id, stage in project.get("stages", {}).items():
for task_id, task in stage.get("tasks", {}).items():
for worker_id, worker in task.get("workers", {}).items():
if worker_id == user_id:
- tasks.append(ProjectTaskResponse(
- id=task_id,
- project_id=str(project["_id"]),
- project_name=project["name"],
- stage_id=str(stage_id),
- **task
- ))
+ if "name" in search_params:
+ name_match = re.search(search_params["name"], task["name"], re.IGNORECASE)
+ print(f'name match is: {name_match}')
+ else:
+ name_match = True
+
+ if "status" in search_params:
+ status_match = search_params["status"] == task["status"]
+ print(f'status match is: {status_match}')
+ else:
+ status_match = True
+
+ if "start_date" in search_params:
+ start_date_match = search_params["start_date"] <= task["start_date"]
+ else:
+ start_date_match = True
+
+ if "end_date" in search_params:
+ end_date_match = search_params["end_date"] >= task["end_date"]
+ else:
+ end_date_match = True
+
+ if status_match and name_match and start_date_match and end_date_match:
+ tasks.append(ProjectTaskResponse(
+ id=task_id,
+ project_id=str(project["_id"]),
+ project_name=project["name"],
+ stage_id=str(stage_id),
+ **task
+ ))
+
+ print(f'Finded tasks: {len(tasks)}')
return tasks
@classmethod
diff --git a/backend/database.py b/backend/database.py
index 8cffb77..eb8caa5 100644
--- a/backend/database.py
+++ b/backend/database.py
@@ -1,3 +1,4 @@
+from datetime import datetime
import json
from bson import ObjectId
@@ -44,8 +45,24 @@ def load_default_data():
with open(settings.DEFAULT_DATA_FILE, "r") as file:
data = json.load(file)
+ def convert_dates(item):
+ if isinstance(item, dict):
+ for key, value in item.items():
+ if isinstance(value, str):
+ # Попробуем распознать ISO формат
+ try:
+ item[key] = datetime.fromisoformat(value)
+ except ValueError:
+ pass # Если это не дата, оставляем строку
+ elif isinstance(value, (list, dict)):
+ convert_dates(value)
+ elif isinstance(item, list):
+ for sub_item in item:
+ convert_dates(sub_item)
+
for collection_name, documents in data.items():
for doc in documents:
+ convert_dates(doc)
if "_id" in doc:
doc["_id"] = ObjectId(doc["_id"])
diff --git a/backend/dump/dump.json b/backend/dump/dump.json
index 9a26548..f61d7f9 100755
--- a/backend/dump/dump.json
+++ b/backend/dump/dump.json
@@ -1,111 +1,4 @@
{
- "chat": [
- {
- "_id": "6756c5c7bdb8727a5b52c6bf",
- "participants": {
- "67372742c192aa85549e9682": {
- "name": "Сидоров Виктор Александрович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- },
- "67372636c192aa85549e9681": {
- "name": "Смирнова Елена Петровна",
- "lastSeen": "2024-12-09T09:37:14.201000"
- }
- },
- "lastMessage": {
- "content": "Это вполне возможно. Мы можем начать с покраски одного из коридоров и, если вам понравится, продолжим по всему зданию. Учитываем все пожелания по срокам и материалам.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000"
- },
- "created_at": "2024-12-09T09:37:14.203000",
- "updated_at": "2024-12-09T10:31:18.369000"
- },
- {
- "_id": "6756c5e5bdb8727a5b52c6c1",
- "participants": {
- "67372742c192aa85549e9682": {
- "name": "Сидоров Виктор Александрович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- },
- "673727fdc192aa85549e9683": {
- "name": "Кузнецов Алексей Сергеевич",
- "lastSeen": "2024-12-09T09:37:14.201000"
- }
- },
- "lastMessage": {
- "content": "Хорошо, я сейчас привезу дополнительный крепеж. Пожалуйста, продолжайте работы.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000"
- },
- "created_at": "2024-12-09T09:37:14.203000",
- "updated_at": "2024-12-09T10:31:36.210000"
- },
- {
- "_id": "6756c5fabdb8727a5b52c6c3",
- "participants": {
- "67372742c192aa85549e9682": {
- "name": "Сидоров Виктор Александрович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- },
- "67372863c192aa85549e9684": {
- "name": "Морозов Сергей Иванович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- }
- },
- "lastMessage": {
- "content": "Отлично, давайте ускорим процесс, чтобы не задерживать покраску. Проверю материал для покраски, если все в порядке — начинаем сразу.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000"
- },
- "created_at": "2024-12-09T09:37:14.203000",
- "updated_at": "2024-12-09T10:31:48.671000"
- },
- {
- "_id": "6756c638bdb8727a5b52c6c5",
- "participants": {
- "67372742c192aa85549e9682": {
- "name": "Сидоров Виктор Александрович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- },
- "67372917c192aa85549e9685": {
- "name": "Петров Николай Андреевич",
- "lastSeen": "2024-12-09T09:37:14.201000"
- }
- },
- "lastMessage": {
- "content": "Понял, проверим. В принципе, монтаж можно закончить в течение двух дней, и после этого сделаем финальную проверку.",
- "sender": "67372917c192aa85549e9685",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000"
- },
- "created_at": "2024-12-09T09:37:14.203000",
- "updated_at": "2024-12-09T10:34:27.285000"
- },
- {
- "_id": "6756c64dbdb8727a5b52c6c7",
- "participants": {
- "67372742c192aa85549e9682": {
- "name": "Сидоров Виктор Александрович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- },
- "6756bc2ebdb8727a5b52c6bd": {
- "name": "Страков Александр Викторович",
- "lastSeen": "2024-12-09T09:37:14.201000"
- }
- },
- "lastMessage": {
- "content": "Спасибо, все будет сделано в срок.",
- "sender": "6756bc2ebdb8727a5b52c6bd",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000"
- },
- "created_at": "2024-12-09T09:37:14.203000",
- "updated_at": "2024-12-09T10:35:27.685000"
- }
- ],
"project": [
{
"_id": "6756bd40bdb8727a5b52c6be",
@@ -417,323 +310,323 @@
"procurements": {
"a6a1dc83-ad03-4456-8a37-e8b07545267e": {
"item_name": "Цемент",
- "quantity": "200",
- "price": "50000.0",
+ "quantity": 200,
+ "price": 50000,
"inStock": false,
"units": "тонна",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:12:20.972000"
},
"57413bee-1178-4766-9f1b-7cb29293c5de": {
"item_name": "Песок",
- "quantity": "150",
- "price": "3500.0",
+ "quantity": 150,
+ "price": 3500,
"inStock": false,
"units": "тонна",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:12:41.084000"
},
"1354033e-7fb0-4ddc-b25b-7bd0fa6ba539": {
"item_name": "Штукатурка",
- "quantity": "500",
- "price": "350.0",
+ "quantity": 500,
+ "price": 350,
"inStock": true,
"units": "м²",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:12:56.834000"
},
"fd56d28c-9076-418b-90a8-31c7f16b95b0": {
"item_name": "Окна",
- "quantity": "100",
- "price": "50000.0",
+ "quantity": 100,
+ "price": 50000,
"inStock": true,
"units": "шт",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:13:37.428000"
},
"ed330a35-8b10-494d-b978-a133bbacfbc2": {
"item_name": "Двери",
- "quantity": "15",
- "price": "8000.0",
+ "quantity": 15,
+ "price": 8000,
"inStock": false,
"units": "шт",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:13:49.387000"
},
"e5506d75-8f1f-4d7a-a0cc-0c7335722b4f": {
"item_name": "Подмости строительные",
- "quantity": "50",
- "price": "1000.0",
+ "quantity": 50,
+ "price": 1000,
"inStock": false,
"units": "м",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:13:59.971000"
},
"b7c84174-5bbb-4d76-a54e-2fd784679e9d": {
"item_name": "Электрический кабель",
- "quantity": "1000",
- "price": "50.0",
+ "quantity": 1000,
+ "price": 50,
"inStock": false,
"units": "м",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:14:11.607000"
},
"bcb2261a-1d36-475c-8e47-252f0f6827e8": {
"item_name": " Трубопровод для водоснабжения",
- "quantity": "500",
- "price": "150.0",
+ "quantity": 500,
+ "price": 150,
"inStock": true,
"units": "м",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:14:23.472000"
},
"5110aa18-4ebe-47d1-8b00-76e56a3acab5": {
"item_name": "Сантехнические смесители",
- "quantity": "80",
- "price": "2500.0",
+ "quantity": 80,
+ "price": 2500,
"inStock": true,
"units": "шт",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:14:35.417000"
},
"29ca81be-ed65-4763-b81c-a4cce63e3963": {
"item_name": "Краска для стен",
- "quantity": "300",
- "price": "800.0",
+ "quantity": 300,
+ "price": 800,
"inStock": false,
"units": "л",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:14:48.438000"
},
"b48c23b7-92b2-4c2c-bbb1-5a147775f13c": {
"item_name": "Ламинат",
- "quantity": "500",
- "price": "1200.0",
+ "quantity": 500,
+ "price": 1200,
"inStock": false,
"units": "м²",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:15:00.355000"
},
"56ad52f1-3afb-4246-a18f-5c38685d9f51": {
"item_name": "Обои",
- "quantity": "200",
- "price": "1500.0",
+ "quantity": 200,
+ "price": 1500,
"inStock": false,
"units": "рулоны",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:15:15.174000"
},
"303d6523-e9f6-4377-975a-e587fdff7cdc": {
"item_name": "Полы из линолеума",
- "quantity": "250",
- "price": "900.0",
+ "quantity": 250,
+ "price": 900,
"inStock": true,
"units": "м²",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:15:28.612000"
},
"d00037af-4757-4185-9625-bf792fdb3b44": {
"item_name": "Гипсокартон",
- "quantity": "150",
- "price": "350.0",
+ "quantity": 150,
+ "price": 350,
"inStock": false,
"units": "лист",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:15:44.344000"
},
"c1ff43ed-56b3-42b0-805f-67a659865eff": {
"item_name": "Сухая строительная смесь",
- "quantity": "200",
- "price": "700.0",
+ "quantity": 200,
+ "price": 700,
"inStock": false,
"units": "мешки",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:15:53.238000"
},
"8f65d657-2a19-4f92-8917-8a7bd81d81d1": {
"item_name": "Строительные ножницы",
- "quantity": "20",
- "price": "600.0",
+ "quantity": 20,
+ "price": 600,
"inStock": true,
"units": "м²",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:16:03.652000"
},
"c77e1ca4-fa48-4df7-bd3d-1aede1bf5dda": {
"item_name": "Плитка керамическая",
- "quantity": "300",
- "price": "1500.0",
+ "quantity": 300,
+ "price": 1500,
"inStock": true,
"units": "м²",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:16:14.088000"
},
"40944af6-8cac-40d7-b2b4-3b9b0a09e12d": {
"item_name": "Строительный клей",
- "quantity": "500",
- "price": "250.0",
+ "quantity": 500,
+ "price": 250,
"inStock": true,
"units": "кг",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:16:28.933000"
},
"fe711323-4aa4-48d2-a38e-0c012a9bce36": {
"item_name": "Освежители воздуха",
- "quantity": "50",
- "price": "10.0",
+ "quantity": 50,
+ "price": 10,
"inStock": true,
"units": "шт",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:16:42.219000"
},
"4a627919-40b7-4e66-af9a-d624268aef6b": {
"item_name": "Ручной инструмент (молоты, отвертки и т.п.)",
- "quantity": "100",
- "price": "500.0",
+ "quantity": 100,
+ "price": 500,
"inStock": false,
"units": "шт",
- "delivery_date": null,
+ "delivery_date": "2024-12-12T00:00:00",
"created_by": {
"username": "Иванов Иван Иванович",
"role": "Администратор",
- "created_at": "2024-12-09T09:37:14.076000",
- "updated_at": "2024-12-09T09:37:14.076000"
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
},
"created_at": "2024-12-09T09:37:14.156000",
- "updated_at": "2024-12-09T09:37:14.156000"
+ "updated_at": "2024-12-12T14:16:55.157000"
}
},
"risks": {
@@ -768,142 +661,1333 @@
"updated_at": "2024-12-09T09:37:14.152000"
}
}
- }
- ],
- "message": [
- {
- "_id": "6756c5c8bdb8727a5b52c6c0",
- "content": "Здравствуйте! Начали работы по ремонту, сейчас завершаем демонтаж старых окон и дверей. Планируем завершить на этой неделе. Могу ли я уточнить, есть ли еще пожелания по дизайну помещений?",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000",
- "chatId": "6756c5c7bdb8727a5b52c6bf",
- "receiver": "67372636c192aa85549e9681"
- },
- {
- "_id": "6756c5e5bdb8727a5b52c6c2",
- "content": "Алексей, как идут работы по установке окон? Нужно ли вам помочь с инструментами или материалами?",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000",
- "chatId": "6756c5e5bdb8727a5b52c6c1",
- "receiver": "673727fdc192aa85549e9683"
- },
- {
- "_id": "6756c5fabdb8727a5b52c6c4",
- "content": "Сергей, как продвигается штукатурка стен в аудиториях? Нужно ли провести дополнительные проверки?",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000",
- "chatId": "6756c5fabdb8727a5b52c6c3",
- "receiver": "67372863c192aa85549e9684"
- },
- {
- "_id": "6756c638bdb8727a5b52c6c6",
- "content": "Николай, как идет монтаж сантехники в санузлах? Есть ли какие-то проблемы с трубами или оборудованием?",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000",
- "chatId": "6756c638bdb8727a5b52c6c5",
- "receiver": "67372917c192aa85549e9685"
- },
- {
- "_id": "6756c64dbdb8727a5b52c6c8",
- "content": "Александр, как идет прокладка электропроводки? Вижу, что уже начали монтировать розетки и выключатели. Как там?",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T09:37:14.202000",
- "chatId": "6756c64dbdb8727a5b52c6c7",
- "receiver": "6756bc2ebdb8727a5b52c6bd"
- },
- {
- "_id": "6756c66bbdb8727a5b52c6c9",
- "content": "Здравствуйте! Спасибо за обновления. По поводу дизайна — хотелось бы изменить цвет стен на более светлый, например, на пастельный оттенок. Как думаете, это возможно?",
- "sender": "67372636c192aa85549e9681",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:28:59.579000",
- "chatId": "6756c5c7bdb8727a5b52c6bf",
- "receiver": "67372742c192aa85549e9682"
- },
- {
- "_id": "6756c692bdb8727a5b52c6ca",
- "content": "Все идет по плану, окна устанавливаем без задержек. Единственное — немного не хватает крепежа, но это решаемо.",
- "sender": "673727fdc192aa85549e9683",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:29:38.701000",
- "chatId": "6756c5e5bdb8727a5b52c6c1",
- "receiver": "67372742c192aa85549e9682"
- },
- {
- "_id": "6756c6afbdb8727a5b52c6cb",
- "content": "Стены почти готовы, еще один слой штукатурки, и можно будет приступать к покраске. Пока не вижу проблем, работаем как надо.",
- "sender": "67372863c192aa85549e9684",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:30:07.463000",
- "chatId": "6756c5fabdb8727a5b52c6c3",
- "receiver": "67372742c192aa85549e9682"
- },
- {
- "_id": "6756c6c7bdb8727a5b52c6cc",
- "content": "В целом все идет по плану. Мы установили трубы для горячей и холодной воды, подключили раковины и унитазы. Немного сложности возникли с установкой душевых кабин — не все крепежи подошли.",
- "sender": "67372917c192aa85549e9685",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:30:31.982000",
- "chatId": "6756c638bdb8727a5b52c6c5",
- "receiver": "67372742c192aa85549e9682"
- },
- {
- "_id": "6756c6d8bdb8727a5b52c6cd",
- "content": "Электропроводка готова в двух аудиториях и коридоре. Прокладываем дальше в другие помещения. Но возникла небольшая проблема с проводами для освещения в одном из кабинетов, надо будет заменить их на более мощные.",
- "sender": "6756bc2ebdb8727a5b52c6bd",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:30:48.973000",
- "chatId": "6756c64dbdb8727a5b52c6c7",
- "receiver": "67372742c192aa85549e9682"
- },
- {
- "_id": "6756c6f6bdb8727a5b52c6ce",
- "content": "Это вполне возможно. Мы можем начать с покраски одного из коридоров и, если вам понравится, продолжим по всему зданию. Учитываем все пожелания по срокам и материалам.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:31:18.370000",
- "chatId": "6756c5c7bdb8727a5b52c6bf",
- "receiver": "67372636c192aa85549e9681"
- },
- {
- "_id": "6756c708bdb8727a5b52c6cf",
- "content": "Хорошо, я сейчас привезу дополнительный крепеж. Пожалуйста, продолжайте работы.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:31:36.212000",
- "chatId": "6756c5e5bdb8727a5b52c6c1",
- "receiver": "673727fdc192aa85549e9683"
- },
- {
- "_id": "6756c714bdb8727a5b52c6d0",
- "content": "Отлично, давайте ускорим процесс, чтобы не задерживать покраску. Проверю материал для покраски, если все в порядке — начинаем сразу.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:31:48.673000",
- "chatId": "6756c5fabdb8727a5b52c6c3",
- "receiver": "67372863c192aa85549e9684"
- },
- {
- "_id": "6756c728bdb8727a5b52c6d1",
- "content": "Понял. Если понадобятся дополнительные крепежи, скажите, привезу. Как насчет проверки всех соединений на герметичность? Лучше это сделать до завершения.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:32:08.331000",
- "chatId": "6756c638bdb8727a5b52c6c5",
- "receiver": "67372917c192aa85549e9685"
},
{
- "_id": "6756c738bdb8727a5b52c6d2",
- "content": "Понял, замена проводов — это важный момент. Постарайтесь решить это как можно быстрее. Важно, чтобы освещение было стабильным и безопасным.",
- "sender": "67372742c192aa85549e9682",
- "status": "Не прочитано",
- "timestamp": "2024-12-09T10:32:24.202000",
- "chatId": "6756c64dbdb8727a5b52c6c7",
+ "_id": "675af13aabc17c42c3e4a419",
+ "name": "Ремонт кафедры информационных технологий",
+ "description": "Проект направлен на обновление и ремонт помещений кафедры для улучшения условий работы сотрудников и студентов.",
+ "start_date": "2025-01-15T00:00:00",
+ "end_date": "2025-06-01T00:00:00",
+ "status": "Новый",
+ "created_at": "2024-12-12T14:20:42.561000",
+ "updated_at": "2024-12-12T14:20:42.561000",
+ "contacts": {
+ "67372487c192aa85549e9680": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "67372636c192aa85549e9681": {
+ "username": "Смирнова Елена Петровна",
+ "role": "Заказчик",
+ "updated_at": "2024-12-12T14:21:57.086000",
+ "created_at": "2024-11-15T10:45:10.050000"
+ },
+ "67372742c192aa85549e9682": {
+ "username": "Сидоров Виктор Александрович",
+ "role": "Прораб",
+ "updated_at": "2024-12-12T14:22:04.041000",
+ "created_at": "2024-11-15T10:49:38.947000"
+ },
+ "673727fdc192aa85549e9683": {
+ "username": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий",
+ "updated_at": "2024-12-12T14:22:09.739000",
+ "created_at": "2024-11-15T10:52:45.608000"
+ },
+ "67372863c192aa85549e9684": {
+ "username": "Морозов Сергей Иванович",
+ "role": "Рабочий",
+ "updated_at": "2024-12-12T14:22:22.331000",
+ "created_at": "2024-11-15T10:54:27.989000"
+ },
+ "67372917c192aa85549e9685": {
+ "username": "Петров Николай Андреевич",
+ "role": "Рабочий",
+ "updated_at": "2024-12-12T14:22:29.064000",
+ "created_at": "2024-11-15T10:57:27.551000"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "username": "Страков Александр Викторович",
+ "role": "Рабочий",
+ "updated_at": "2024-12-12T14:22:34.030000",
+ "created_at": "2024-12-09T09:45:18.794000"
+ }
+ },
+ "stages": {
+ "7d53e57b-280d-4f2b-86fc-81d063411937": {
+ "name": "Оценка состояния помещений",
+ "start_date": "2024-12-15T00:00:00",
+ "end_date": "2024-12-31T00:00:00",
+ "tasks": {
+ "aa147135-f15d-45d8-8963-ca242fc53af1": {
+ "name": "Осмотр помещений",
+ "description": "Проведение визуального осмотра состояния стен, потолков, пола, электропроводки, мебели и оборудования.",
+ "status": "Нет статуса",
+ "start_date": "2024-12-15T00:00:00",
+ "end_date": "2024-12-20T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ },
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ },
+ "4eceb1d4-b8c1-4c62-bb50-b67acd4397ef": {
+ "name": "Составление отчета о состоянии",
+ "description": "Составление подробного отчета по результатам осмотра с указанием необходимых работ.",
+ "status": "Нет статуса",
+ "start_date": "2024-12-21T00:00:00",
+ "end_date": "2024-12-31T00:00:00",
+ "workers": {
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.696000",
+ "updated_at": "2024-12-12T14:08:55.696000"
+ },
+ "97499e24-22ca-4952-8fed-31d35f83f8be": {
+ "name": "Составление плана работ и сметы",
+ "start_date": "2025-02-01T00:00:00",
+ "end_date": "2025-02-15T00:00:00",
+ "tasks": {
+ "202bdeca-f4a1-497a-b199-a7b946c6fbf5": {
+ "name": "Подготовка плана работ",
+ "description": "Разработка поэтапного плана проведения ремонта.",
+ "status": "Нет статуса",
+ "start_date": "2025-02-01T00:00:00",
+ "end_date": "2025-02-10T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ },
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ },
+ "26a1daf8-ffaa-419a-b878-011baddd0b64": {
+ "name": "Расчет сметы",
+ "description": "Подготовка сметы с учетом стоимости материалов, услуг и оборудования.",
+ "status": "Нет статуса",
+ "start_date": "2025-02-11T00:00:00",
+ "end_date": "2025-02-15T00:00:00",
+ "workers": {
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.696000",
+ "updated_at": "2024-12-12T14:08:55.696000"
+ },
+ "9e1a92b2-a4fc-4f86-a8d4-e82cb8b65a06": {
+ "name": "Закупка материалов",
+ "start_date": "2025-02-16T00:00:00",
+ "end_date": "2025-03-15T00:00:00",
+ "tasks": {
+ "6ca059f1-632d-4e58-a197-8bd5e4053123": {
+ "name": "Составление списка закупок",
+ "description": "Определение и согласование необходимого списка материалов.",
+ "status": "Нет статуса",
+ "start_date": "2025-02-16T00:00:00",
+ "end_date": "2025-02-20T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ },
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ },
+ "02cf1a1d-ad00-4cf2-b02d-8c7f0bdcb445": {
+ "name": "Закупка и доставка материалов",
+ "description": "Заключение договоров с поставщиками, доставка материалов на объект.",
+ "status": "Нет статуса",
+ "start_date": "2025-02-21T00:00:00",
+ "end_date": "2025-03-15T00:00:00",
+ "workers": {
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.696000",
+ "updated_at": "2024-12-12T14:08:55.696000"
+ },
+ "6507b769-ed5d-49d2-9649-5a9aee37e6c8": {
+ "name": "Ремонтные работы",
+ "start_date": "2025-03-16T00:00:00",
+ "end_date": "2025-05-30T00:00:00",
+ "tasks": {
+ "3fe5ad42-7839-4082-a3dc-c3ef3cb40aea": {
+ "name": "Демонтаж старых покрытий",
+ "description": "Удаление старого покрытия пола, обоев, потолка.",
+ "status": "Нет статуса",
+ "start_date": "2025-03-16T00:00:00",
+ "end_date": "2025-03-31T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:38:21.682000"
+ },
+ "e04e66a9-2185-45bb-a6c9-a116843d0bc1": {
+ "name": "Укладка нового покрытия",
+ "description": "Установка нового покрытия пола, покраска стен, потолка.",
+ "status": "Нет статуса",
+ "start_date": "2025-04-01T00:00:00",
+ "end_date": "2025-04-30T00:00:00",
+ "workers": {
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ },
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ },
+ "b988c10c-dc93-4388-8946-2b907ac5d6f8": {
+ "name": "Установка мебели и оборудования",
+ "description": "Установка и настройка мебели, оборудования и электроники.",
+ "status": "Нет статуса",
+ "start_date": "2025-05-01T00:00:00",
+ "end_date": "2025-05-30T00:00:00",
+ "workers": {
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ },
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.696000",
+ "updated_at": "2024-12-12T14:08:55.696000"
+ },
+ "3d6a5e16-bd06-4fec-b0fc-3f63b74c810b": {
+ "name": "Приемка работ",
+ "start_date": "2025-06-01T00:00:00",
+ "end_date": "2025-06-01T00:00:00",
+ "tasks": {
+ "6abfc2c8-e5a0-4815-9622-681ab7f8c2cf": {
+ "name": "Финальная проверка",
+ "description": "Проверка качества выполненных работ и соответствия смете.",
+ "status": "Нет статуса",
+ "start_date": "2025-06-01T00:00:00",
+ "end_date": "2025-06-01T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.688000",
+ "updated_at": "2024-12-12T14:08:55.688000"
+ }
+ },
+ "created_at": "2024-12-12T14:08:55.696000",
+ "updated_at": "2024-12-12T14:08:55.696000"
+ }
+ },
+ "procurements": {
+ "f50c003a-82ce-47dd-b36b-ff988955663e": {
+ "item_name": "Линолеум",
+ "quantity": "150",
+ "price": "350.0",
+ "inStock": false,
+ "units": "м²",
+ "delivery_date": "2025-03-05T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-12-12T14:08:55.704000",
+ "updated_at": "2024-12-12T14:08:55.704000"
+ },
+ "e332fffc-b67b-4143-a7cd-68b8fda32910": {
+ "item_name": "Краска акриловая белая",
+ "quantity": "500",
+ "price": "500.0",
+ "inStock": false,
+ "units": "л",
+ "delivery_date": "2025-03-10T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-12-12T14:08:55.704000",
+ "updated_at": "2024-12-12T14:08:55.704000"
+ },
+ "9f5d4fb0-9518-4406-968e-2c107b5f9cd3": {
+ "item_name": "Столы",
+ "quantity": "20",
+ "price": "400.0",
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2025-03-15T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-12-12T14:08:55.704000",
+ "updated_at": "2024-12-12T14:08:55.704000"
+ },
+ "81705202-64c6-468f-8b17-ab4ed91eadfa": {
+ "item_name": "Стулья",
+ "quantity": "50",
+ "price": "2000.0",
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2024-03-15T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-12-12T14:08:55.704000",
+ "updated_at": "2024-12-12T14:08:55.704000"
+ },
+ "29a23bc0-07a6-4698-a5f4-9b4326d15e51": {
+ "item_name": "Электропроводка",
+ "quantity": "200",
+ "price": "100.0",
+ "inStock": false,
+ "units": "м",
+ "delivery_date": "2025-03-08T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-12-12T14:08:55.704000",
+ "updated_at": "2024-12-12T14:08:55.704000"
+ }
+ },
+ "risks": {
+ "5a2caaf9-1b07-45d5-8a00-3845057240db": {
+ "name": "Несоответствие сроков поставок",
+ "description": "Поставки материалов могут задержаться из-за логистических проблем. Это может увеличить сроки ремонта.",
+ "created_at": "2024-12-12T14:08:55.700000",
+ "updated_at": "2024-12-12T14:08:55.700000"
+ },
+ "1eef10c9-d006-4543-89e7-0ea31b8ef0a9": {
+ "name": "Превышение сметы",
+ "description": "Стоимость материалов и работ может оказаться выше, чем предполагалось, из-за непредвиденных расходов.",
+ "created_at": "2024-12-12T14:08:55.700000",
+ "updated_at": "2024-12-12T14:08:55.700000"
+ },
+ "4421dfba-028b-4b17-9217-96b15e2de038": {
+ "name": "Низкое качество работ",
+ "description": "Некачественное выполнение ремонтных работ может потребовать дополнительных затрат на исправление ошибок.",
+ "created_at": "2024-12-12T14:08:55.700000",
+ "updated_at": "2024-12-12T14:08:55.700000"
+ }
+ }
+ },
+ {
+ "_id": "673729e3c192aa85549e9686",
+ "name": "Ремонт аудитории для проведения лекций",
+ "description": "Проект включает ремонт аудитории, предназначенной для лекционных занятий, с целью создания комфортных условий для студентов и преподавателей. Работы будут включать:\n\n1) Обновление напольного покрытия.\n2) Покраску стен и потолка.\n3) Установку современной системы освещения.\n4) Ремонт оконных конструкций для улучшения теплоизоляции.\n5) Установку мультимедийного оборудования и акустической системы.\n6) Организацию эргономичной мебели для студентов и преподавателей.\n\nЦель проекта — улучшение условий обучения и повышение функциональности учебного пространства.",
+ "start_date": "2024-11-20T00:00:00",
+ "end_date": "2025-01-15T00:00:00",
+ "status": "Нет статуса",
+ "created_at": "2024-11-15T10:15:25.216000",
+ "updated_at": "2024-11-15T10:15:25.216000",
+ "contacts": {
+ "67372636c192aa85549e9681": {
+ "username": "Смирнова Елена Петровна",
+ "role": "Заказчик",
+ "created_at": "2024-11-15T10:15:25.147000",
+ "updated_at": "2024-11-15T10:15:25.147000"
+ },
+ "67372742c192aa85549e9682": {
+ "username": "Сидоров Виктор Александрович",
+ "role": "Прораб"
+ },
+ "67372487c192aa85549e9680": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор"
+ },
+ "673727fdc192aa85549e9683": {
+ "username": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ },
+ "67372863c192aa85549e9684": {
+ "username": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ },
+ "67372917c192aa85549e9685": {
+ "username": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "username": "Страков Александр Викторович",
+ "role": "Рабочий",
+ "updated_at": "2024-12-12T14:49:11.642000",
+ "created_at": "2024-12-09T09:45:18.794000"
+ }
+ },
+ "stages": {
+ "9c6592aa-3e70-4fb5-893e-7b6a1595e888": {
+ "name": "Подготовительные работы",
+ "start_date": "2024-11-20T00:00:00",
+ "end_date": "2024-11-27T00:00:00",
+ "tasks": {
+ "dcc43db4-e696-43c4-87ac-e9c30575d395": {
+ "name": "Осмотр помещения и оценка состояния",
+ "description": "Команда специалистов проводит обследование аудитории для выявления текущего состояния стен, пола, окон, потолка и коммуникаций. Это позволит определить объем необходимых работ и составить детальный план.",
+ "status": "Нет статуса",
+ "start_date": "2024-11-20T00:00:00",
+ "end_date": "2024-11-20T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "2876848d-fc04-4bda-914e-6b216b826dbf": {
+ "name": "Составление технического задания и утверждение сметы",
+ "description": "На основании осмотра формируется техническое задание с подробным перечнем работ. Смета согласовывается с администрацией вуза.",
+ "status": "Нет статуса",
+ "start_date": "2024-11-22T00:00:00",
+ "end_date": "2024-11-23T00:00:00",
+ "workers": {
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "ce53dd56-0c53-4673-bb10-67bef2ad743d": {
+ "name": "Закупка материалов и оборудования",
+ "description": "Закупаются все необходимые строительные материалы, инструменты, а также мультимедийное оборудование согласно утвержденной смете.",
+ "status": "Нет статуса",
+ "start_date": "2024-11-24T00:00:00",
+ "end_date": "2024-11-27T00:00:00",
+ "workers": {
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.205000",
+ "updated_at": "2024-11-15T10:15:25.205000"
+ },
+ "7237b577-4582-4fbd-82de-99d464f6a219": {
+ "name": "Демонтажные работы",
+ "start_date": "2024-11-28T00:00:00",
+ "end_date": "2024-12-05T00:00:00",
+ "tasks": {
+ "0a8f1a1b-9b19-49db-9ca1-7e8b1749d373": {
+ "name": "Удаление старого напольного покрытия",
+ "description": "Полностью удаляется старый линолеум и основание, чтобы подготовить поверхность для укладки нового покрытия.",
+ "status": "Нет статуса",
+ "start_date": "2024-11-28T00:00:00",
+ "end_date": "2024-11-29T00:00:00",
+ "workers": {
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "a66dfc7d-fc8a-427f-b678-57285d4bffcc": {
+ "name": "Демонтаж повреждённых оконных рам",
+ "description": "Старые окна, которые не соответствуют современным стандартам теплоизоляции, удаляются, а проемы подготавливаются для установки новых рам.",
+ "status": "Нет статуса",
+ "start_date": "2024-11-30T00:00:00",
+ "end_date": "2024-12-01T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-12-12T14:50:31.004000"
+ },
+ "a213e016-34f5-4b18-a883-c30866aa7f0f": {
+ "name": "Очистка стен и потолка от старой краски",
+ "description": "Удаляется старая краска со стен и потолка с использованием специальных инструментов, чтобы обеспечить надежное сцепление нового покрытия.",
+ "status": "Нет статуса",
+ "start_date": "2024-12-02T00:00:00",
+ "end_date": "2024-12-05T00:00:00",
+ "workers": {
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.205000",
+ "updated_at": "2024-11-15T10:15:25.205000"
+ },
+ "bf1542cd-c418-4865-8d1a-0fa0a79078e9": {
+ "name": "Основные ремонтные работы",
+ "start_date": "2024-12-06T00:00:00",
+ "end_date": "2025-01-05T00:00:00",
+ "tasks": {
+ "fa28dd46-2c18-410b-ae4a-7b44386371cf": {
+ "name": "Укладка нового напольного покрытия",
+ "description": "На подготовленное основание укладывается современное покрытие, обеспечивающее долговечность и эстетичный вид.",
+ "status": "Нет статуса",
+ "start_date": "2024-12-06T00:00:00",
+ "end_date": "2024-12-10T00:00:00",
+ "workers": {
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "fe01d0a9-48f6-4e27-8658-ef3d0831e4b3": {
+ "name": "Покраска стен и потолка",
+ "description": "Стены и потолок окрашиваются в согласованный цвет с использованием устойчивых к истиранию материалов.",
+ "status": "Нет статуса",
+ "start_date": "2024-12-11T00:00:00",
+ "end_date": "2024-11-20T00:00:00",
+ "workers": {
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "c2f7e35d-a481-4ea3-95db-1a596f3130f7": {
+ "name": "Установка новых оконных рам",
+ "description": "Производится монтаж энергосберегающих окон с улучшенной тепло- и шумоизоляцией.",
+ "status": "Нет статуса",
+ "start_date": "2024-12-21T00:00:00",
+ "end_date": "2024-11-27T00:00:00",
+ "workers": {
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.205000",
+ "updated_at": "2024-11-15T10:15:25.205000"
+ },
+ "efb41624-6aa1-4664-ad7f-6240fd0dba6f": {
+ "name": "Завершающие работы",
+ "start_date": "2025-01-06T00:00:00",
+ "end_date": "2025-01-15T00:00:00",
+ "tasks": {
+ "c0454b96-93cf-41a9-b4da-c439a7c0c3a8": {
+ "name": "Установка мультимедийного оборудования",
+ "description": "В аудитории монтируется проектор, экран и другие мультимедийные устройства, необходимые для проведения лекций.",
+ "status": "Нет статуса",
+ "start_date": "2025-01-06T00:00:00",
+ "end_date": "2025-01-08T00:00:00",
+ "workers": {
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "d0b6acb3-fe00-425f-9365-7ef6140cb8f9": {
+ "name": "Монтаж освещения и акустической системы",
+ "description": "Устанавливаются современные светильники и акустическая система для улучшения освещенности и звукового сопровождения.",
+ "status": "Нет статуса",
+ "start_date": "2025-01-09T00:00:00",
+ "end_date": "2025-01-12T00:00:00",
+ "workers": {
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ },
+ "ed645ecc-b1ed-42a3-b4a3-c139d94431cd": {
+ "name": "Размещение мебели и финальная уборка",
+ "description": "Размещаются новые парты, стулья и мебель для преподавателей. Затем проводится генеральная уборка помещения.",
+ "status": "Нет статуса",
+ "start_date": "2025-01-13T00:00:00",
+ "end_date": "2025-01-15T00:00:00",
+ "workers": {
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "role": "Рабочий"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.201000",
+ "updated_at": "2024-11-15T10:15:25.201000"
+ }
+ },
+ "created_at": "2024-11-15T10:15:25.205000",
+ "updated_at": "2024-11-15T10:15:25.205000"
+ }
+ },
+ "procurements": {
+ "df5c22f0-2e58-49b0-b9dc-fb806a01978c": {
+ "item_name": "Линолеум коммерческий",
+ "quantity": 120,
+ "price": 850,
+ "inStock": false,
+ "units": "м²",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:52:47.254000"
+ },
+ "134f5225-9880-422b-bf56-bdfce255d2b2": {
+ "item_name": "Краска акриловая белая",
+ "quantity": 20,
+ "price": 450,
+ "inStock": true,
+ "units": "л",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:53:03.593000"
+ },
+ "0a8c6703-8368-4525-81a0-13a8fa90b83c": {
+ "item_name": "Грунтовка глубокого проникновения",
+ "quantity": 15,
+ "price": 350,
+ "inStock": false,
+ "units": "л",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:53:17.071000"
+ },
+ "73055c76-b215-44c4-9d62-7974c04ac839": {
+ "item_name": "Кисти малярные (широкие)",
+ "quantity": 10,
+ "price": 150,
+ "inStock": true,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:53:31.571000"
+ },
+ "c2739518-e219-49cb-8db7-36d4cc60bbc3": {
+ "item_name": "Валики для покраски",
+ "quantity": 8,
+ "price": 150,
+ "inStock": true,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:53:47.642000"
+ },
+ "f9ae1bb9-28d7-45a5-900c-fa5312631b0b": {
+ "item_name": "Рамы оконные пластиковые",
+ "quantity": 5,
+ "price": 15000,
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:54:07.626000"
+ },
+ "d36b8ddc-6220-4829-872d-62dd02c21704": {
+ "item_name": "Герметик силиконовый",
+ "quantity": 10,
+ "price": 300,
+ "inStock": true,
+ "units": "тюбик",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:54:29.018000"
+ },
+ "520318ee-f0f1-4996-9486-0edd1e2d9729": {
+ "item_name": "Стеклопакеты энергосберегающие",
+ "quantity": 5,
+ "price": 10000,
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:54:46.360000"
+ },
+ "c1f5d224-857a-400c-8662-6e3e2941aebb": {
+ "item_name": "Лампы светодиодные",
+ "quantity": 15,
+ "price": 500,
+ "inStock": true,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:55:03.531000"
+ },
+ "27a07069-fcc0-4e83-9cfd-f253dac62f6d": {
+ "item_name": "Светильники потолочные",
+ "quantity": 10,
+ "price": 2500,
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:55:17.888000"
+ },
+ "9633572d-01e0-4514-b0b8-14b4d0cc9349": {
+ "item_name": "Кабель силовой медный",
+ "quantity": 50,
+ "price": 200,
+ "inStock": true,
+ "units": "м",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:55:32.465000"
+ },
+ "653356de-e89c-44db-91ca-fcb650e641ab": {
+ "item_name": "Электрические розетки",
+ "quantity": 10,
+ "price": 350,
+ "inStock": true,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:55:47.113000"
+ },
+ "24ba719c-2fc6-4f2a-83ef-34d2d88fbf57": {
+ "item_name": "Выключатели",
+ "quantity": 8,
+ "price": 400,
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:55:58.742000"
+ },
+ "58d9e796-d703-4c9f-8e94-ed48316f8168": {
+ "item_name": "Штукатурка цементная",
+ "quantity": 25,
+ "price": 150,
+ "inStock": false,
+ "units": "кг",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:56:11.267000"
+ },
+ "f495540d-1e17-4b97-b6dd-9eb3f47718ba": {
+ "item_name": "Плитка напольная",
+ "quantity": 100,
+ "price": 1200,
+ "inStock": false,
+ "units": "м²",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:56:22.536000"
+ },
+ "70c46d2a-11f6-41ac-a824-b678bd1f8895": {
+ "item_name": "Звуковые панели",
+ "quantity": 20,
+ "price": 3000,
+ "inStock": true,
+ "units": "м²",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:56:38.113000"
+ },
+ "9fac5fa6-7785-41a0-9437-c10d99afdc7f": {
+ "item_name": "Кабельные каналы",
+ "quantity": 30,
+ "price": 100,
+ "inStock": true,
+ "units": "м",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:57:16.867000"
+ },
+ "42a26f90-a7a5-4293-b10f-fc27bd739f0d": {
+ "item_name": "Скотч малярный",
+ "quantity": 12,
+ "price": 50,
+ "inStock": true,
+ "units": "рулоны",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:57:44.608000"
+ },
+ "4905ea7c-4d44-449f-8913-0570ac8646f2": {
+ "item_name": "Шурупы",
+ "quantity": 300,
+ "price": 3,
+ "inStock": false,
+ "units": "шт",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:58:19.526000"
+ },
+ "eb0da436-c556-4032-b845-b2f3190ccf7e": {
+ "item_name": "Мебель (стулья и парты)",
+ "quantity": 30,
+ "price": 5000,
+ "inStock": false,
+ "units": "комплект",
+ "delivery_date": "2024-11-25T00:00:00",
+ "created_by": {
+ "username": "Иванов Иван Иванович",
+ "role": "Администратор",
+ "created_at": "2024-12-12T14:08:55.626000",
+ "updated_at": "2024-12-12T14:08:55.626000"
+ },
+ "created_at": "2024-11-15T10:15:25.211000",
+ "updated_at": "2024-12-12T14:58:34.415000"
+ }
+ },
+ "risks": {
+ "09f196fb-30fc-44c1-9f6c-135292fe4e84": {
+ "name": "Задержка поставок материалов",
+ "description": "Некоторые материалы, такие как оконные рамы или напольная плитка, могут не быть доставлены вовремя из-за проблем с логистикой или отсутствия на складе у поставщика. Это может повлиять на соблюдение сроков выполнения этапов проекта.",
+ "created_at": "2024-11-15T10:15:25.208000",
+ "updated_at": "2024-11-15T10:15:25.208000"
+ },
+ "14e6455c-ad46-42b2-bea9-45d8f6d07aaa": {
+ "name": "Перерасход бюджета",
+ "description": "В процессе ремонта может возникнуть необходимость закупки дополнительных материалов или привлечения дополнительных специалистов, что приведёт к превышению запланированной сметы.",
+ "created_at": "2024-11-15T10:15:25.208000",
+ "updated_at": "2024-11-15T10:15:25.208000"
+ },
+ "b0fd7611-0318-49c1-9230-66476e183901": {
+ "name": "Непредвиденные технические проблемы",
+ "description": "Во время демонтажных или основных работ могут быть обнаружены скрытые дефекты, такие как повреждённые коммуникации или несоответствие состояния конструкций изначальной оценке, что увеличит время и стоимость работ.",
+ "created_at": "2024-11-15T10:15:25.208000",
+ "updated_at": "2024-11-15T10:15:25.208000"
+ },
+ "2b5e5f16-6515-44c8-a208-06ea5735e2dd": {
+ "name": "Недостаточная квалификация рабочих",
+ "description": "Ошибки или низкое качество выполнения работ со стороны подрядчиков могут привести к необходимости переделки и увеличению сроков выполнения проекта.",
+ "created_at": "2024-11-15T10:15:25.208000",
+ "updated_at": "2024-11-15T10:15:25.208000"
+ },
+ "dffdf2d1-bc94-4ac0-917e-a809a884c8c0": {
+ "name": "Проблемы с согласованием",
+ "description": "Задержки в утверждении проекта, сметы или промежуточных результатов ремонта администрацией вуза могут приостановить выполнение работ и привести к сдвигу графика.",
+ "created_at": "2024-11-15T10:15:25.208000",
+ "updated_at": "2024-11-15T10:15:25.208000"
+ }
+ }
+ }
+ ],
+ "user": [
+ {
+ "_id": "67372487c192aa85549e9680",
+ "email": "admin1@example.com",
+ "name": "Иван",
+ "lastname": "Иванов",
+ "middlename": "Иванович",
+ "password": "$2b$12$2BkJdyuM0uQwYlMM.x7DXOUMP.k9S9CVQNiSdzuZPUwa4TNLoZWbS",
+ "role": "Администратор",
+ "created_at": "2024-11-15T10:37:59.101000",
+ "updated_at": "2024-11-15T10:37:59.101000"
+ },
+ {
+ "_id": "67372636c192aa85549e9681",
+ "email": "customer1@example.com",
+ "name": "Елена",
+ "lastname": "Смирнова",
+ "middlename": "Петровна",
+ "password": "$2b$12$vjPWtVwwAFh.SCjDXeopXuJBAKfPhksDbybWwgvtCT9kek0e.xnEq",
+ "role": "Заказчик",
+ "created_at": "2024-11-15T10:45:10.050000",
+ "updated_at": "2024-11-15T10:45:10.050000"
+ },
+ {
+ "_id": "67372742c192aa85549e9682",
+ "email": "foreman1@example.com",
+ "name": "Виктор",
+ "lastname": "Сидоров",
+ "middlename": "Александрович",
+ "password": "$2b$12$IfZrTTAy.G8C4wOt3U.DheiDmIAvYs5Wn0YViE4Yy5wVlvF2TdgMa",
+ "role": "Прораб",
+ "created_at": "2024-11-15T10:49:38.947000",
+ "updated_at": "2024-11-15T10:49:38.947000"
+ },
+ {
+ "_id": "673727fdc192aa85549e9683",
+ "email": "worker1@example.com",
+ "name": "Алексей",
+ "lastname": "Кузнецов",
+ "middlename": "Сергеевич",
+ "password": "$2b$12$DKcsmtlsWSGHqeBOuaLO0OZEzPheM1Ew.rG3xoftKNhyrA89dLacm",
+ "role": "Рабочий",
+ "created_at": "2024-11-15T10:52:45.608000",
+ "updated_at": "2024-11-15T10:52:45.608000"
+ },
+ {
+ "_id": "67372863c192aa85549e9684",
+ "email": "worker2@example.com",
+ "name": "Сергей",
+ "lastname": "Морозов",
+ "middlename": " Иванович",
+ "password": "$2b$12$u0Ncvro827IXItz1vczNW.MiMFGWfd3vvBycD3sONrerFS4.Us2bu",
+ "role": "Рабочий",
+ "created_at": "2024-11-15T10:54:27.989000",
+ "updated_at": "2024-11-15T10:54:27.989000"
+ },
+ {
+ "_id": "67372917c192aa85549e9685",
+ "email": "worker3@example.com",
+ "name": "Николай",
+ "lastname": "Петров",
+ "middlename": "Андреевич",
+ "password": "$2b$12$WjclQu47rcwq8klB0edBzeHh5MjsbgP5e.W2csflFARv12QKjC9OW",
+ "role": "Рабочий",
+ "created_at": "2024-11-15T10:57:27.551000",
+ "updated_at": "2024-11-15T10:57:27.551000"
+ },
+ {
+ "_id": "6756bc2ebdb8727a5b52c6bd",
+ "email": "worker4@example.com",
+ "name": " Александр",
+ "lastname": "Страков",
+ "middlename": "Викторович",
+ "password": "$2b$12$SbY50Fat.OJ40hOz.9Gequ3rW34.1IDEGeQtahUhljUCiMKEmjtQa",
+ "role": "Рабочий",
+ "updated_at": "2024-12-09T09:45:18.794000",
+ "created_at": "2024-12-09T09:45:18.794000"
+ }
+ ],
+ "chat": [
+ {
+ "_id": "6756c5c7bdb8727a5b52c6bf",
+ "participants": {
+ "67372742c192aa85549e9682": {
+ "name": "Сидоров Виктор Александрович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ },
+ "67372636c192aa85549e9681": {
+ "name": "Смирнова Елена Петровна",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ }
+ },
+ "lastMessage": {
+ "content": "Это вполне возможно. Мы можем начать с покраски одного из коридоров и, если вам понравится, продолжим по всему зданию. Учитываем все пожелания по срокам и материалам.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000"
+ },
+ "created_at": "2024-12-09T09:37:14.203000",
+ "updated_at": "2024-12-09T10:31:18.369000"
+ },
+ {
+ "_id": "6756c5e5bdb8727a5b52c6c1",
+ "participants": {
+ "67372742c192aa85549e9682": {
+ "name": "Сидоров Виктор Александрович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ },
+ "673727fdc192aa85549e9683": {
+ "name": "Кузнецов Алексей Сергеевич",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ }
+ },
+ "lastMessage": {
+ "content": "Хорошо, я сейчас привезу дополнительный крепеж. Пожалуйста, продолжайте работы.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000"
+ },
+ "created_at": "2024-12-09T09:37:14.203000",
+ "updated_at": "2024-12-09T10:31:36.210000"
+ },
+ {
+ "_id": "6756c5fabdb8727a5b52c6c3",
+ "participants": {
+ "67372742c192aa85549e9682": {
+ "name": "Сидоров Виктор Александрович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ },
+ "67372863c192aa85549e9684": {
+ "name": "Морозов Сергей Иванович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ }
+ },
+ "lastMessage": {
+ "content": "Отлично, давайте ускорим процесс, чтобы не задерживать покраску. Проверю материал для покраски, если все в порядке — начинаем сразу.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000"
+ },
+ "created_at": "2024-12-09T09:37:14.203000",
+ "updated_at": "2024-12-09T10:31:48.671000"
+ },
+ {
+ "_id": "6756c638bdb8727a5b52c6c5",
+ "participants": {
+ "67372742c192aa85549e9682": {
+ "name": "Сидоров Виктор Александрович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ },
+ "67372917c192aa85549e9685": {
+ "name": "Петров Николай Андреевич",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ }
+ },
+ "lastMessage": {
+ "content": "Понял, проверим. В принципе, монтаж можно закончить в течение двух дней, и после этого сделаем финальную проверку.",
+ "sender": "67372917c192aa85549e9685",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000"
+ },
+ "created_at": "2024-12-09T09:37:14.203000",
+ "updated_at": "2024-12-09T10:34:27.285000"
+ },
+ {
+ "_id": "6756c64dbdb8727a5b52c6c7",
+ "participants": {
+ "67372742c192aa85549e9682": {
+ "name": "Сидоров Виктор Александрович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ },
+ "6756bc2ebdb8727a5b52c6bd": {
+ "name": "Страков Александр Викторович",
+ "lastSeen": "2024-12-09T09:37:14.201000"
+ }
+ },
+ "lastMessage": {
+ "content": "Спасибо, все будет сделано в срок.",
+ "sender": "6756bc2ebdb8727a5b52c6bd",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000"
+ },
+ "created_at": "2024-12-09T09:37:14.203000",
+ "updated_at": "2024-12-09T10:35:27.685000"
+ }
+ ],
+ "message": [
+ {
+ "_id": "6756c5c8bdb8727a5b52c6c0",
+ "content": "Здравствуйте! Начали работы по ремонту, сейчас завершаем демонтаж старых окон и дверей. Планируем завершить на этой неделе. Могу ли я уточнить, есть ли еще пожелания по дизайну помещений?",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000",
+ "chatId": "6756c5c7bdb8727a5b52c6bf",
+ "receiver": "67372636c192aa85549e9681"
+ },
+ {
+ "_id": "6756c5e5bdb8727a5b52c6c2",
+ "content": "Алексей, как идут работы по установке окон? Нужно ли вам помочь с инструментами или материалами?",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000",
+ "chatId": "6756c5e5bdb8727a5b52c6c1",
+ "receiver": "673727fdc192aa85549e9683"
+ },
+ {
+ "_id": "6756c5fabdb8727a5b52c6c4",
+ "content": "Сергей, как продвигается штукатурка стен в аудиториях? Нужно ли провести дополнительные проверки?",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000",
+ "chatId": "6756c5fabdb8727a5b52c6c3",
+ "receiver": "67372863c192aa85549e9684"
+ },
+ {
+ "_id": "6756c638bdb8727a5b52c6c6",
+ "content": "Николай, как идет монтаж сантехники в санузлах? Есть ли какие-то проблемы с трубами или оборудованием?",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000",
+ "chatId": "6756c638bdb8727a5b52c6c5",
+ "receiver": "67372917c192aa85549e9685"
+ },
+ {
+ "_id": "6756c64dbdb8727a5b52c6c8",
+ "content": "Александр, как идет прокладка электропроводки? Вижу, что уже начали монтировать розетки и выключатели. Как там?",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T09:37:14.202000",
+ "chatId": "6756c64dbdb8727a5b52c6c7",
+ "receiver": "6756bc2ebdb8727a5b52c6bd"
+ },
+ {
+ "_id": "6756c66bbdb8727a5b52c6c9",
+ "content": "Здравствуйте! Спасибо за обновления. По поводу дизайна — хотелось бы изменить цвет стен на более светлый, например, на пастельный оттенок. Как думаете, это возможно?",
+ "sender": "67372636c192aa85549e9681",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:28:59.579000",
+ "chatId": "6756c5c7bdb8727a5b52c6bf",
+ "receiver": "67372742c192aa85549e9682"
+ },
+ {
+ "_id": "6756c692bdb8727a5b52c6ca",
+ "content": "Все идет по плану, окна устанавливаем без задержек. Единственное — немного не хватает крепежа, но это решаемо.",
+ "sender": "673727fdc192aa85549e9683",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:29:38.701000",
+ "chatId": "6756c5e5bdb8727a5b52c6c1",
+ "receiver": "67372742c192aa85549e9682"
+ },
+ {
+ "_id": "6756c6afbdb8727a5b52c6cb",
+ "content": "Стены почти готовы, еще один слой штукатурки, и можно будет приступать к покраске. Пока не вижу проблем, работаем как надо.",
+ "sender": "67372863c192aa85549e9684",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:30:07.463000",
+ "chatId": "6756c5fabdb8727a5b52c6c3",
+ "receiver": "67372742c192aa85549e9682"
+ },
+ {
+ "_id": "6756c6c7bdb8727a5b52c6cc",
+ "content": "В целом все идет по плану. Мы установили трубы для горячей и холодной воды, подключили раковины и унитазы. Немного сложности возникли с установкой душевых кабин — не все крепежи подошли.",
+ "sender": "67372917c192aa85549e9685",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:30:31.982000",
+ "chatId": "6756c638bdb8727a5b52c6c5",
+ "receiver": "67372742c192aa85549e9682"
+ },
+ {
+ "_id": "6756c6d8bdb8727a5b52c6cd",
+ "content": "Электропроводка готова в двух аудиториях и коридоре. Прокладываем дальше в другие помещения. Но возникла небольшая проблема с проводами для освещения в одном из кабинетов, надо будет заменить их на более мощные.",
+ "sender": "6756bc2ebdb8727a5b52c6bd",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:30:48.973000",
+ "chatId": "6756c64dbdb8727a5b52c6c7",
+ "receiver": "67372742c192aa85549e9682"
+ },
+ {
+ "_id": "6756c6f6bdb8727a5b52c6ce",
+ "content": "Это вполне возможно. Мы можем начать с покраски одного из коридоров и, если вам понравится, продолжим по всему зданию. Учитываем все пожелания по срокам и материалам.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:31:18.370000",
+ "chatId": "6756c5c7bdb8727a5b52c6bf",
+ "receiver": "67372636c192aa85549e9681"
+ },
+ {
+ "_id": "6756c708bdb8727a5b52c6cf",
+ "content": "Хорошо, я сейчас привезу дополнительный крепеж. Пожалуйста, продолжайте работы.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:31:36.212000",
+ "chatId": "6756c5e5bdb8727a5b52c6c1",
+ "receiver": "673727fdc192aa85549e9683"
+ },
+ {
+ "_id": "6756c714bdb8727a5b52c6d0",
+ "content": "Отлично, давайте ускорим процесс, чтобы не задерживать покраску. Проверю материал для покраски, если все в порядке — начинаем сразу.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:31:48.673000",
+ "chatId": "6756c5fabdb8727a5b52c6c3",
+ "receiver": "67372863c192aa85549e9684"
+ },
+ {
+ "_id": "6756c728bdb8727a5b52c6d1",
+ "content": "Понял. Если понадобятся дополнительные крепежи, скажите, привезу. Как насчет проверки всех соединений на герметичность? Лучше это сделать до завершения.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:32:08.331000",
+ "chatId": "6756c638bdb8727a5b52c6c5",
+ "receiver": "67372917c192aa85549e9685"
+ },
+ {
+ "_id": "6756c738bdb8727a5b52c6d2",
+ "content": "Понял, замена проводов — это важный момент. Постарайтесь решить это как можно быстрее. Важно, чтобы освещение было стабильным и безопасным.",
+ "sender": "67372742c192aa85549e9682",
+ "status": "Не прочитано",
+ "timestamp": "2024-12-09T10:32:24.202000",
+ "chatId": "6756c64dbdb8727a5b52c6c7",
"receiver": "6756bc2ebdb8727a5b52c6bd"
},
{
@@ -978,84 +2062,5 @@
"chatId": "6756c64dbdb8727a5b52c6c7",
"receiver": "67372742c192aa85549e9682"
}
- ],
- "user": [
- {
- "_id": "67372487c192aa85549e9680",
- "email": "admin1@example.com",
- "name": "Иван",
- "lastname": "Иванов",
- "middlename": "Иванович",
- "password": "$2b$12$2BkJdyuM0uQwYlMM.x7DXOUMP.k9S9CVQNiSdzuZPUwa4TNLoZWbS",
- "role": "Администратор",
- "created_at": "2024-11-15T10:37:59.101000",
- "updated_at": "2024-11-15T10:37:59.101000"
- },
- {
- "_id": "67372636c192aa85549e9681",
- "email": "customer1@example.com",
- "name": "Елена",
- "lastname": "Смирнова",
- "middlename": "Петровна",
- "password": "$2b$12$vjPWtVwwAFh.SCjDXeopXuJBAKfPhksDbybWwgvtCT9kek0e.xnEq",
- "role": "Заказчик",
- "created_at": "2024-11-15T10:45:10.050000",
- "updated_at": "2024-11-15T10:45:10.050000"
- },
- {
- "_id": "67372742c192aa85549e9682",
- "email": "foreman1@example.com",
- "name": "Виктор",
- "lastname": "Сидоров",
- "middlename": "Александрович",
- "password": "$2b$12$IfZrTTAy.G8C4wOt3U.DheiDmIAvYs5Wn0YViE4Yy5wVlvF2TdgMa",
- "role": "Прораб",
- "created_at": "2024-11-15T10:49:38.947000",
- "updated_at": "2024-11-15T10:49:38.947000"
- },
- {
- "_id": "673727fdc192aa85549e9683",
- "email": "worker1@example.com",
- "name": "Алексей",
- "lastname": "Кузнецов",
- "middlename": "Сергеевич",
- "password": "$2b$12$DKcsmtlsWSGHqeBOuaLO0OZEzPheM1Ew.rG3xoftKNhyrA89dLacm",
- "role": "Рабочий",
- "created_at": "2024-11-15T10:52:45.608000",
- "updated_at": "2024-11-15T10:52:45.608000"
- },
- {
- "_id": "67372863c192aa85549e9684",
- "email": "worker2@example.com",
- "name": "Сергей",
- "lastname": "Морозов",
- "middlename": " Иванович",
- "password": "$2b$12$u0Ncvro827IXItz1vczNW.MiMFGWfd3vvBycD3sONrerFS4.Us2bu",
- "role": "Рабочий",
- "created_at": "2024-11-15T10:54:27.989000",
- "updated_at": "2024-11-15T10:54:27.989000"
- },
- {
- "_id": "67372917c192aa85549e9685",
- "email": "worker3@example.com",
- "name": "Николай",
- "lastname": "Петров",
- "middlename": "Андреевич",
- "password": "$2b$12$WjclQu47rcwq8klB0edBzeHh5MjsbgP5e.W2csflFARv12QKjC9OW",
- "role": "Рабочий",
- "created_at": "2024-11-15T10:57:27.551000",
- "updated_at": "2024-11-15T10:57:27.551000"
- },
- {
- "_id": "6756bc2ebdb8727a5b52c6bd",
- "email": "worker4@example.com",
- "name": " Александр",
- "lastname": "Страков",
- "middlename": "Викторович",
- "password": "$2b$12$SbY50Fat.OJ40hOz.9Gequ3rW34.1IDEGeQtahUhljUCiMKEmjtQa",
- "role": "Рабочий",
- "updated_at": "2024-12-09T09:45:18.794000",
- "created_at": "2024-12-09T09:45:18.794000"
- }
]
}
\ No newline at end of file
diff --git a/backend/routers/data.py b/backend/routers/data.py
index 16bf70a..b8a5874 100644
--- a/backend/routers/data.py
+++ b/backend/routers/data.py
@@ -74,13 +74,28 @@ async def import_database(file: UploadFile):
detail=f"Collection '{collection_name}' does not exist in the database."
)
+ def convert_dates(item):
+ if isinstance(item, dict):
+ for key, value in item.items():
+ if isinstance(value, str):
+ # Попробуем распознать ISO формат
+ try:
+ item[key] = datetime.fromisoformat(value)
+ except ValueError:
+ pass # Если это не дата, оставляем строку
+ elif isinstance(value, (list, dict)):
+ convert_dates(value)
+ elif isinstance(item, list):
+ for sub_item in item:
+ convert_dates(sub_item)
+
# Импорт данных
for collection_name, documents in data.items():
if not isinstance(documents, list):
raise HTTPException(status_code=400, detail=f"Collection '{collection_name}' must contain a list of documents")
- # Преобразование _id в ObjectId
for doc in documents:
+ convert_dates(doc)
if "_id" in doc:
doc["_id"] = ObjectId(doc["_id"])
diff --git a/backend/routers/procurement.py b/backend/routers/procurement.py
index acd02f9..fb7eb66 100644
--- a/backend/routers/procurement.py
+++ b/backend/routers/procurement.py
@@ -1,8 +1,9 @@
+from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from dao.project import ProjectDao
from schemas.project import ProjectResponse, Procurement, ProcurementResponse, ProcurementUpdate
-from schemas.user import Contact, User
+from schemas.user import Contact, Role, User
from utils.role import get_foreman_role
from utils.token import get_current_user
@@ -25,8 +26,10 @@ async def add_procurement(project_id: str, procurement_data: Procurement, forema
@router.get("/{project_id}/get_procurements", response_model=dict[str, list[ProcurementResponse] | list[None]])
-async def get_procurements(project_id: str, user: User = Depends(get_current_user)):
- procurements = await ProjectDao.get_procurements_by_project_id(project_id)
+async def get_procurements(project_id: str, name: str = "", creator_role: Role = None,
+ state: bool = None, start_date: datetime = None, end_date: datetime = None,
+ user: User = Depends(get_current_user)):
+ procurements = await ProjectDao.get_procurements_by_project_id(project_id, name, creator_role, state, start_date, end_date)
if procurements is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
diff --git a/backend/routers/project.py b/backend/routers/project.py
index 64cf9c2..e25214d 100644
--- a/backend/routers/project.py
+++ b/backend/routers/project.py
@@ -1,7 +1,8 @@
+from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from dao.user import UserDao
-from schemas.project import ProjectResponse, ProjectCreate, ProjectUpdate
+from schemas.project import ProjectResponse, ProjectCreate, ProjectStatus, ProjectUpdate
from schemas.user import User, Role, UserResponse, ContactResponse, UserCreateSchema
from utils.role import get_customer_role, get_foreman_role
from utils.token import get_current_user
@@ -56,10 +57,12 @@ async def remove_project(project_id: str, user: User = Depends(get_foreman_role)
@router.get("/all", response_model=list[ProjectResponse])
-async def get_all(user: User = Depends(get_current_user)):
+async def get_all(project_name: str = "", project_status: ProjectStatus = None,
+ start_date: datetime = None, end_date: datetime = None,
+ user = Depends(get_current_user)):
if user.role == Role.admin:
- return await ProjectDao.get_all_projects()
- return await ProjectDao.get_projects_by_user(user.id)
+ return await ProjectDao.get_all_projects(project_name, project_status, start_date, end_date)
+ return await ProjectDao.get_all_projects(project_name, project_status, start_date, end_date, user.id)
@router.get("/get_users/{project_id}", response_model=list[ContactResponse | None])
diff --git a/backend/routers/risk.py b/backend/routers/risk.py
index db2b393..0a0135b 100644
--- a/backend/routers/risk.py
+++ b/backend/routers/risk.py
@@ -21,8 +21,8 @@ async def add_stage(project_id: str, risk_data: Risk, foreman: User = Depends(ge
@router.get("/{project_id}/get_risks", response_model=dict[str, list[RiskResponse] | list[None]])
-async def get_risks(project_id: str, user: User = Depends(get_current_user)):
- risks = await ProjectDao.get_risks_by_project_id(project_id)
+async def get_risks(project_id: str, name: str = "", user: User = Depends(get_current_user)):
+ risks = await ProjectDao.get_risks_by_project_id(project_id, name)
if risks is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
diff --git a/backend/routers/stage.py b/backend/routers/stage.py
index 97062e5..e7342a0 100644
--- a/backend/routers/stage.py
+++ b/backend/routers/stage.py
@@ -1,3 +1,4 @@
+from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from dao.project import ProjectDao
@@ -21,8 +22,10 @@ async def add_stage(project_id: str, stage_data: Stage, foreman: User = Depends(
@router.get("/{project_id}/get_stages", response_model=dict[str, list[StageResponse] | list[None]])
-async def get_stages(project_id: str, user: User = Depends(get_current_user)):
- stages = await ProjectDao.get_stages_by_project_id(project_id)
+async def get_stages(project_id: str, name: str = "",
+ start_date: datetime = None, end_date: datetime = None,
+ user: User = Depends(get_current_user)):
+ stages = await ProjectDao.get_stages_by_project_id(project_id, name, start_date, end_date)
if stages is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
diff --git a/backend/routers/task.py b/backend/routers/task.py
index 7eb8b38..89134dc 100644
--- a/backend/routers/task.py
+++ b/backend/routers/task.py
@@ -1,8 +1,9 @@
+from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from dao.project import ProjectDao
from dao.task import TaskDAO
-from schemas.task import Task, TaskResponse, TaskUpdate, ProjectTaskResponse, TaskStatusUpdate
+from schemas.task import Task, TaskResponse, TaskStatus, TaskUpdate, ProjectTaskResponse, TaskStatusUpdate
from schemas.user import User, Worker
from utils.role import get_foreman_role
from utils.token import get_current_user
@@ -54,6 +55,7 @@ async def update_task(project_id: str, stage_id: str, task_id: str, task_data: T
)
return task
+
@router.put('/update_status_task/{project_id}/{stage_id}/{task_id}', response_model=TaskResponse)
async def update_status_task(project_id: str, stage_id: str, task_id: str, task_data: TaskStatusUpdate,
user: User = Depends(get_current_user)):
@@ -67,14 +69,27 @@ async def update_status_task(project_id: str, stage_id: str, task_id: str, task_
@router.get('/get_stage_tasks/{project_id}/{stage_id}', response_model=list[TaskResponse] | list[None])
-async def get_stage_tasks(project_id: str, stage_id: str):
- tasks = await TaskDAO.get_tasks_by_stage_id(project_id, stage_id)
+async def get_stage_tasks(project_id: str, stage_id: str, task_name: str = "", project_name: str = "",
+ task_status: TaskStatus = None,
+ start_date: datetime = None, end_date: datetime = None,
+ user: User = Depends(get_current_user)):
+ tasks = await TaskDAO.get_tasks_by_stage_id(
+ project_id, stage_id, task_name,
+ project_name, task_status,
+ start_date, end_date
+ )
return tasks
@router.get('/get_all', response_model=list[ProjectTaskResponse] | list[None])
-async def get_all_tasks(user: User = Depends(get_current_user)):
- tasks = await TaskDAO.get_all_tasks_by_user(user.id)
+async def get_all_tasks(task_name: str = "", project_name: str = "", task_status: TaskStatus = None,
+ start_date: datetime = None, end_date: datetime = None,
+ user: User = Depends(get_current_user)):
+ tasks = await TaskDAO.get_all_tasks_by_user(
+ user.id, task_name,
+ project_name, task_status,
+ start_date, end_date
+ )
return tasks
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
new file mode 100644
index 0000000..4094e7f
--- /dev/null
+++ b/docker-compose.dev.yml
@@ -0,0 +1,49 @@
+services:
+ db:
+ image: mongo:8.0.3
+ container_name: mongo_db
+ environment:
+ - MONGO_INITDB_ROOT_USERNAME=admin
+ - MONGO_INITDB_ROOT_PASSWORD=password123
+ - MONGO_INITDB_DATABASE=fastapi
+ volumes:
+ - mongo:/data/db
+ ports:
+ - "27017:27017"
+ networks:
+ - app-network
+
+ app-backend:
+ container_name: repair-backend
+ restart: on-failure
+ ports:
+ - "127.0.0.1:8000:8000"
+ volumes:
+ - "./backend:/app"
+ build: ./backend
+ depends_on:
+ - db
+ networks:
+ - app-network
+
+ app-frontend:
+ container_name: repair-frontend
+ restart: on-failure
+ build: ./frontend
+ ports:
+ - "127.0.0.1:8080:8080"
+ networks:
+ - app-network
+ volumes:
+ - "./frontend:/app"
+ - "/app/node_modules"
+
+
+volumes:
+ mongo:
+
+networks:
+ app-network:
+ driver: bridge
+
+
diff --git a/frontend/src/src/components/AdminComponent.vue b/frontend/src/src/components/AdminComponent.vue
new file mode 100644
index 0000000..5b94cca
--- /dev/null
+++ b/frontend/src/src/components/AdminComponent.vue
@@ -0,0 +1,326 @@
+
+ {{ user.lastname }} {{ user.name }} {{ user.middlename }} Должность - {{ user.role }}Данные приложения
+
+ Просмотр пользователей
+
Интервал выполнения
+{{ material.created_date }}
+{{ material.userRole }}
{{ material.deliveryDate}}
+Дата доставки
+ + - + +{{ user.lastname }} {{ user.name }} {{ user.middlename }}
-Должность - {{ user.role }}
-{{ user.lastname }} {{ user.name }} {{ user.middlename }}
+Должность - {{ user.role }}
+Дата начала
- +Дата конца
- +{{ errorMessage }}
@@ -44,7 +54,11 @@ export default { this.errorMessage = 'Пожалуйста, заполните все поля'; return; } - + // Проверка на корректность дат + if (new Date(this.endDate) < new Date(this.startDate)) { + this.errorMessage = 'Дата окончания не может быть раньше даты начала'; + return; + } const dataToSend = { name: this.projectName, description: this.projectDescription, diff --git a/frontend/src/src/components/project/ProjectComponent.vue b/frontend/src/src/components/project/ProjectComponent.vue index eca2686..563221b 100644 --- a/frontend/src/src/components/project/ProjectComponent.vue +++ b/frontend/src/src/components/project/ProjectComponent.vue @@ -53,7 +53,7 @@ export default { // Логика перехода на страницу проекта setProjectId(this.projectId); setProjectName(this.projectName); - this.$router.push(`/project`); + this.$router.push(`/project/${this.projectId}`); }, }, }; diff --git a/frontend/src/src/components/project/ProjectPage.vue b/frontend/src/src/components/project/ProjectPage.vue index fad6245..86b624f 100644 --- a/frontend/src/src/components/project/ProjectPage.vue +++ b/frontend/src/src/components/project/ProjectPage.vue @@ -120,16 +120,18 @@ export default { start_date: this.formatToDateTime(this.dateStart), end_date: this.formatToDateTime(this.dateEnd) }; - console.log(dataToSend) + // console.log(dataToSend) try { - const res = await axios.put(`/api/projects/update/${getProjectId()}`, dataToSend, { + await axios.put(`/api/projects/update/${getProjectId()}`, dataToSend, { headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, withCredentials: true, }); - console.log(res); + this.$store.commit("addStartProject", this.dateStart); + this.$store.commit("addEndProject", this.dateEnd); + // console.log(res); } catch (error) { if(error.response.status === 401){ this.$store.commit('removeUsers'); // Изменяем состояние @@ -192,7 +194,9 @@ export default { userName: contact.username, role: contact.role, })); - console.log(this.contacts); + this.$store.commit("addStartProject", this.dateStart); + this.$store.commit("addEndProject", this.dateEnd); + // console.log(this.contacts); } catch (error) { if(error.response.status === 401){ this.$store.commit('removeUsers'); // Изменяем состояние diff --git a/frontend/src/src/components/risk/RisksPage.vue b/frontend/src/src/components/risk/RisksPage.vue index e213a58..cca4c45 100644 --- a/frontend/src/src/components/risk/RisksPage.vue +++ b/frontend/src/src/components/risk/RisksPage.vue @@ -7,7 +7,11 @@Интервал выполнения
+ + - + +Начало
- +Конец
- +Начало
- +Конец
- +Название задачи | -Начало | -Конец | -Статус | -
---|---|---|---|
Название задачи | +Начало | +Конец | +Статус | +
{{ task.taskName }} | -{{ task.startDate }} | -{{ task.endDate }} | -{{ task.status }} | -{{ task.taskName }} | +{{ task.startDate }} | +{{ task.endDate }} | +{{ task.status }} | +