From 2db4cbe6a009028af31956b61141c1fa1abb548a Mon Sep 17 00:00:00 2001
From: Madiwka3 <madi.turgunov.03@gmail.com>
Date: Wed, 8 Nov 2023 17:39:55 +0600
Subject: [PATCH 1/3] Did an initial bugfix, all features seem to be working

---
 app/apis/v1/route_auction.py        |  4 +++
 app/apis/v1/route_fuelingtask.py    | 49 +++++++++++++++++---------
 app/apis/v1/route_maintenancejob.py |  8 ++++-
 app/apis/v1/route_task.py           |  6 ++--
 app/db/models/fuelingtask.py        |  2 +-
 app/db/repository/auction.py        |  2 ++
 app/db/repository/drivetask.py      |  4 +--
 app/db/repository/fuelingtask.py    | 53 ++++++++++++++++++++++-------
 app/db/repository/maintenancejob.py | 13 +++++--
 app/schemas/carpart.py              |  9 ++---
 app/schemas/drivetask.py            |  2 +-
 app/schemas/fuelingtask.py          | 34 ++++++++++++------
 app/schemas/maintenancejob.py       |  2 +-
 13 files changed, 133 insertions(+), 55 deletions(-)

diff --git a/app/apis/v1/route_auction.py b/app/apis/v1/route_auction.py
index bc9d31b..eefc1b4 100644
--- a/app/apis/v1/route_auction.py
+++ b/app/apis/v1/route_auction.py
@@ -32,6 +32,10 @@ def getAuction(
     current_user: User = Depends(get_current_user),
 ):
     auction = get_auction_by_id(id, db)
+    if auction is None:
+        raise HTTPException(
+            status_code=404, detail="Auction with this ID does not exist"
+        )
     return auction
 
 
diff --git a/app/apis/v1/route_fuelingtask.py b/app/apis/v1/route_fuelingtask.py
index ae1b8b9..403d577 100644
--- a/app/apis/v1/route_fuelingtask.py
+++ b/app/apis/v1/route_fuelingtask.py
@@ -4,14 +4,21 @@ from db.session import get_db
 from db.repository.fuelingtask import (
     create_fueling_task,
     delete_fueling_task,
-    get_fueling_task_by_id
+    get_fueling_task_by_id,
+    get_all_fueling_tasks,
+)
+from schemas.fuelingtask import (
+    CreateFuelingTask,
+    OutputFuelingTask,
+    OutputFuelingTaskMin,
+    OutputFuelingTaskList,
 )
-from schemas.fuelingtask import CreateFuelingTask, OutputFuelingTask
 from db.models.user import User
 from apis.v1.route_auth import get_current_user
 
 router = APIRouter()
 
+
 @router.post("/", response_model=OutputFuelingTask, status_code=status.HTTP_201_CREATED)
 def create_fuelingtask(
     fuelingtask: CreateFuelingTask = Depends(),
@@ -28,19 +35,18 @@ def create_fuelingtask(
     )
     print("Created FuelTask")
     if fuelingtask_res == "nodriver":
-        raise HTTPException(
-            status_code=404, detail="Driver ID not found"
-        )
+        raise HTTPException(status_code=404, detail="Driver ID not found")
 
     if fuelingtask_res == "novehicle":
-        raise HTTPException(
-            status_code=404, detail="Vehicle ID not found"
-        )
+        raise HTTPException(status_code=404, detail="Vehicle ID not found")
     return fuelingtask_res
 
 
-
-@router.get("/{fueling_task_id}", response_model=OutputFuelingTask, status_code=status.HTTP_200_OK)
+@router.get(
+    "/{fueling_task_id}",
+    response_model=OutputFuelingTask,
+    status_code=status.HTTP_200_OK,
+)
 def get_fuelingtask(
     fueling_task_id: int,
     db: Session = Depends(get_db),
@@ -50,26 +56,35 @@ def get_fuelingtask(
         raise HTTPException(
             status_code=403, detail="You are not authorized to perform this action"
         )
-    
+
     fuelingtask = get_fueling_task_by_id(fueling_task_id, db)
     if fuelingtask == "notfound":
-        raise HTTPException(
-            status_code=404, detail="fuck off"
-        )
+        raise HTTPException(status_code=404, detail="fuck off")
     return fuelingtask
 
+
 @router.delete("/{fueling_task_id}", status_code=status.HTTP_204_NO_CONTENT)
 def delete_fuelingtask(
     fueling_task_id: int,
     db: Session = Depends(get_db),
     current_user: User = Depends(get_current_user),
 ):
-    if current_user.Role != "FuelingPerson" and current_user.Role != "Admin":
+    if current_user.Role != "Fueling" and current_user.Role != "Admin":
         raise HTTPException(
             status_code=403, detail="You are not authorized to perform this action"
         )
 
     if not delete_fueling_task(fueling_task_id, db):
+        raise HTTPException(status_code=404, detail="Fueling task not found")
+
+
+@router.get("/", response_model=OutputFuelingTaskList, status_code=status.HTTP_200_OK)
+def get_all(
+    db: Session = Depends(get_db), current_user: User = Depends(get_current_user)
+):
+    if current_user.Role != "Admin" and current_user.Role != "Fueling":
         raise HTTPException(
-            status_code=404, detail="Fueling task not found"
-        )
\ No newline at end of file
+            status_code=403, detail="You are not authorized to perform this action"
+        )
+    tasks = get_all_fueling_tasks(db)
+    return tasks
diff --git a/app/apis/v1/route_maintenancejob.py b/app/apis/v1/route_maintenancejob.py
index 00222e0..f3a1639 100644
--- a/app/apis/v1/route_maintenancejob.py
+++ b/app/apis/v1/route_maintenancejob.py
@@ -34,7 +34,9 @@ def create_maintenancejob(
     return maintenancejob_res
 
 
-@router.post("/carpart", response_model = ShowCarPart ,status_code=status.HTTP_201_CREATED)
+@router.post(
+    "/carpart", response_model=ShowCarPart, status_code=status.HTTP_201_CREATED
+)
 def create_carpart(
     car_part: CreateCarPart = Depends(),
     db: Session = Depends(get_db),
@@ -82,6 +84,10 @@ def get_maintenancejob(
         )
 
     maintenancejob = get_maintenance_job(maintenance_job_id, db)
+    if maintenancejob is None:
+        raise HTTPException(
+            status_code=404, detail="Maintenance job with this id does not exist"
+        )
     print(maintenancejob)
     return maintenancejob
 
diff --git a/app/apis/v1/route_task.py b/app/apis/v1/route_task.py
index 756dfe8..168ace4 100644
--- a/app/apis/v1/route_task.py
+++ b/app/apis/v1/route_task.py
@@ -165,14 +165,16 @@ def getActiveRoute(
     return route
 
 
-@router.get("/myroutes", status_code=status.HTTP_200_OK)
+@router.get("/myroutes/", status_code=status.HTTP_200_OK)
 def getMyRoutes(
     db: Session = Depends(get_db),
     current_user: User = Depends(get_current_user),
 ):
+    print("here")
     if current_user.Role != "Driver":
         raise HTTPException(
-            status_code=403, detail="You are not authorized to perform this action"
+            status_code=403,
+            detail="You are not a driver, you can't have routes, silly!",
         )
     routes = get_my_routes(current_user.Id, db)
     if routes == "notdriver":
diff --git a/app/db/models/fuelingtask.py b/app/db/models/fuelingtask.py
index 4d837fa..bfd0442 100644
--- a/app/db/models/fuelingtask.py
+++ b/app/db/models/fuelingtask.py
@@ -10,7 +10,7 @@ class FuelingTask(Base):
     CreatedById = Column(ForeignKey("user.Id"), nullable=False)
     Date = Column(DateTime, nullable=False)
     Description = Column(String, nullable=True)
-    Cost = Column(Integer, nullable=False)
+    Cost = Column(Float, nullable=False)
     FuelRefilled = Column(Float, nullable=False)
     GasStationName = Column(String, nullable=False)
     ImageBefore = Column(LargeBinary, nullable=False)
diff --git a/app/db/repository/auction.py b/app/db/repository/auction.py
index e98dda8..00efa1c 100644
--- a/app/db/repository/auction.py
+++ b/app/db/repository/auction.py
@@ -14,6 +14,8 @@ def get_all_auctions(db: Session):
 
 def get_auction_by_id(id: int, db: Session):
     auction = db.query(Auction).filter(Auction.Id == id).first()
+    if not auction:
+        return None
     auction.car = auction.vehicle
     return auction
 
diff --git a/app/db/repository/drivetask.py b/app/db/repository/drivetask.py
index 3e8e391..f33ae20 100644
--- a/app/db/repository/drivetask.py
+++ b/app/db/repository/drivetask.py
@@ -63,10 +63,10 @@ def get_tasks_by_driver(driver_id: int, db: Session):
 
 def get_task_by_id(task_id: int, db: Session):
     task = db.query(DriveTask).filter(DriveTask.Id == task_id).first()
-    task.Driver = task.CreatedBy.__dict__
-    task.Driver["AssignedVehicle"] = task.CreatedBy.vehicle
     if not task:
         return "notaskfound"
+    task.Driver = task.CreatedBy.__dict__
+    task.Driver["AssignedVehicle"] = task.CreatedBy.vehicle
     return task
 
 
diff --git a/app/db/repository/fuelingtask.py b/app/db/repository/fuelingtask.py
index 6b3cd7e..5a083c4 100644
--- a/app/db/repository/fuelingtask.py
+++ b/app/db/repository/fuelingtask.py
@@ -7,16 +7,17 @@ from db.models.fuelingtask import FuelingTask
 from db.repository.user import get_car_driver, get_user_by_id
 from db.repository.vehicle import get_vehicle_by_id
 
-def create_fueling_task(fueling_task: CreateFuelingTask, current_user: int, db: Session):
-    
+
+def create_fueling_task(
+    fueling_task: CreateFuelingTask, current_user: int, db: Session
+):
     if not get_vehicle_by_id(fueling_task.VehicleId, db=db):
         return "novehicle"
-    
+
     driver = get_car_driver(fueling_task.VehicleId, db=db)
-    
+
     if not driver:
         return "nodriver"
-
     fueling_task_object = FuelingTask(
         DriverId=driver.Id,
         VehicleId=fueling_task.VehicleId,
@@ -35,31 +36,59 @@ def create_fueling_task(fueling_task: CreateFuelingTask, current_user: int, db:
     print(driver.__dict__)
     driverobj = driver.__dict__
     driverobj["AssignedVehicle"] = driver.vehicle.__dict__
-    fueling_task_object.Driver = driverobj
-    return fueling_task_object
+    resobj = fueling_task_object.__dict__
+    resobj["Driver"] = driverobj
+    ia = fueling_task_object.ImageAfter
+    ib = fueling_task_object.ImageBefore
+    if ia is not None:
+        ia = base64.b64encode(ia).decode("ascii")
+    if ib is not None:
+        ib = base64.b64encode(ib).decode("ascii")
+    resobj["ImageBefore"] = ib
+    resobj["ImageAfter"] = ia
+    return resobj
 
 
 def delete_fueling_task(fueling_task_id: int, db: Session):
-    fueling_task = db.query(FuelingTask).filter(FuelingTask.Id == fueling_task_id).first()
+    fueling_task = (
+        db.query(FuelingTask).filter(FuelingTask.Id == fueling_task_id).first()
+    )
     if fueling_task:
         db.delete(fueling_task)
         db.commit()
         return True
     return False
 
+
 def get_fueling_task_by_id(fuel_task_id: int, db: Session):
     fuel_task = db.query(FuelingTask).filter(FuelingTask.Id == fuel_task_id).first()
     if not fuel_task:
         return "notfound"
-    res = fuel_task.__dict__ 
+    res = fuel_task.__dict__
     driver = get_user_by_id(fuel_task.DriverId, role="Driver", db=db)
     driver_obj = driver.__dict__
     imagebefore = fuel_task.ImageBefore
     imageafter = fuel_task.ImageAfter
-    imagebeforeBase64 = base64.b64encode(imagebefore).decode('ascii')
-    imageafterBase64 = base64.b64encode(imageafter).decode('ascii')
+    imagebeforeBase64 = base64.b64encode(imagebefore).decode("ascii")
+    imageafterBase64 = base64.b64encode(imageafter).decode("ascii")
     res["ImageBefore"] = imagebeforeBase64
     res["ImageAfter"] = imageafterBase64
     res["Driver"] = driver_obj
     res["Driver"]["AssignedVehicle"] = driver.vehicle
-    return res
\ No newline at end of file
+    return res
+
+
+def get_all_fueling_tasks(db: Session):
+    fuel_task = db.query(FuelingTask).all()
+    result = []
+    for task in fuel_task:
+        res = task.__dict__
+        res["ImageBefore"] = ""
+        res["ImageAfter"] = ""
+        driver = get_user_by_id(task.DriverId, role="Driver", db=db)
+        driver_obj = driver.__dict__
+        res["Driver"] = driver_obj
+        res["Driver"]["AssignedVehicle"] = driver.vehicle
+        result.append(res)
+    x = {"FuelingTasks": result}
+    return x
diff --git a/app/db/repository/maintenancejob.py b/app/db/repository/maintenancejob.py
index d977e10..667fa0a 100644
--- a/app/db/repository/maintenancejob.py
+++ b/app/db/repository/maintenancejob.py
@@ -53,16 +53,23 @@ def calculate_total_cost(car_parts: CarPart):
 
 def get_all_maintenance_jobs(db: Session):
     maintenancejobs = db.query(MaintenanceJob).all()
+    print("DB Access complete")
     result = []
     for job in maintenancejobs:
         job_dict = job.__dict__
+        print(job_dict)
         job_dict["CarPartsList"] = [part.__dict__ for part in job.CarParts]
+        print(len(job_dict["CarPartsList"]))
         for part in job_dict["CarPartsList"]:
-            part["image"] = base64.b64encode(part["ImageURL"]).decode("ascii")
+            if (part["ImageURL"] is None) or (part["ImageURL"] == ""):
+                part["image"] = ""
+            else:
+                part["image"] = base64.b64encode(part["ImageURL"]).decode("ascii")
         job_dict["TotalCost"] = calculate_total_cost(job.CarParts)
         job_dict["AssignedTo"] = job.CreatedBy.__dict__
         job_dict["Vehicle"] = job.Vehicle.__dict__
         result.append(job_dict)
+    print("Returning...")
     return maintenancejobs
 
 
@@ -70,11 +77,13 @@ def get_maintenance_job(maintenancejob_id: int, db: Session):
     maintenancejob = (
         db.query(MaintenanceJob).filter(MaintenanceJob.Id == maintenancejob_id).first()
     )
+    if maintenancejob is None:
+        return None
     res = maintenancejob.__dict__
     res["CarPartsList"] = [part.__dict__ for part in maintenancejob.CarParts]
     for part in maintenancejob.CarPartsList:
         part["image"] = base64.b64encode(part["ImageURL"]).decode("ascii")
-    
+
     # print(type(result.CarPartsList))
     res["TotalCost"] = calculate_total_cost(maintenancejob.CarParts)
     # print(result.TotalCost)
diff --git a/app/schemas/carpart.py b/app/schemas/carpart.py
index e2e3770..8ebf37e 100644
--- a/app/schemas/carpart.py
+++ b/app/schemas/carpart.py
@@ -1,4 +1,3 @@
-
 from fastapi import Form, UploadFile
 from pydantic import BaseModel, Field
 from dataclasses import dataclass
@@ -9,10 +8,8 @@ class CreateCarPart(BaseModel):
     Name: str = Form(...)
     Number: str = Form(...)
     Condition: str = Form(...)
-    Cost: int = Form(...)
+    Cost: float = Form(...)
     image: UploadFile = Form(...)
-    
-
 
 
 class ShowCarPart(BaseModel):
@@ -20,5 +17,5 @@ class ShowCarPart(BaseModel):
     Name: str = Field(...)
     Number: str = Field(...)
     Condition: str = Field(...)
-    Cost: int = Field(...)
-    image: str = Field(...)
\ No newline at end of file
+    Cost: float = Field(...)
+    image: str = Field(...)
diff --git a/app/schemas/drivetask.py b/app/schemas/drivetask.py
index 2132f08..57eef64 100644
--- a/app/schemas/drivetask.py
+++ b/app/schemas/drivetask.py
@@ -5,7 +5,7 @@ from typing import Optional
 
 
 class CreateTask(BaseModel):
-    DriverId: int = Field()
+    DriverId: int = Field(...)
     Description: str = Field(..., min_length=3, max_length=200)
     StartLocation: tuple[str, str] = Field(...)
     EndLocation: tuple[str, str] = Field(...)
diff --git a/app/schemas/fuelingtask.py b/app/schemas/fuelingtask.py
index fbbed6c..94ee7df 100644
--- a/app/schemas/fuelingtask.py
+++ b/app/schemas/fuelingtask.py
@@ -3,29 +3,43 @@ from fastapi import Form, UploadFile
 from datetime import datetime
 from schemas.user import ShowDriver
 
+
 class CreateFuelingTask(BaseModel):
     VehicleId: int = Form(...)
     Description: str = Form(...)
     Date: datetime = Form(...)
-    Cost: int = Form(...)
-    FuelRefilled: int = Form(...)
+    Cost: float = Form(...)
+    FuelRefilled: float = Form(...)
     GasStationName: str = Form(...)
     ImageBefore: UploadFile = Form(...)
     ImageAfter: UploadFile = Form(...)
-    model_config={
-        "arbitrary_types_allowed": True
-    }
+    model_config = {"arbitrary_types_allowed": True}
+
 
 class OutputFuelingTask(BaseModel):
+    Id: int = Field(...)
     VehicleId: int = Field(...)
     Description: str = Field(...)
     Date: datetime = Field(...)
-    Cost: int = Field(...)
-    FuelRefilled: int = Field(...)
+    Cost: float = Field(...)
+    FuelRefilled: float = Field(...)
     GasStationName: str = Field(...)
     Driver: ShowDriver | None
     ImageBefore: str = Field(...)
     ImageAfter: str = Field(...)
-    model_config={
-        "arbitrary_types_allowed": True
-    }
\ No newline at end of file
+    model_config = {"arbitrary_types_allowed": True}
+
+
+class OutputFuelingTaskMin(BaseModel):
+    Id: int = Field(...)
+    VehicleId: int = Field(...)
+    Description: str = Field(...)
+    Date: datetime = Field(...)
+    Cost: float = Field(...)
+    FuelRefilled: float = Field(...)
+    GasStationName: str = Field(...)
+    Driver: ShowDriver | None
+
+
+class OutputFuelingTaskList(BaseModel):
+    FuelingTasks: list[OutputFuelingTaskMin]
diff --git a/app/schemas/maintenancejob.py b/app/schemas/maintenancejob.py
index 312f57c..3fee841 100644
--- a/app/schemas/maintenancejob.py
+++ b/app/schemas/maintenancejob.py
@@ -18,6 +18,6 @@ class OutputMaintenanceJob(BaseModel):
     Description: str
     Date: datetime
     CarPartsList: Optional[List[ShowCarPart]]
-    TotalCost: int
+    TotalCost: float
     Vehicle: OutputVehicle
     AssignedTo: ShowUser

From b1f0eeb1fe5871331552da64500ddf841480917e Mon Sep 17 00:00:00 2001
From: Saruar <saruar.ryskaliyev@nu.edu.kz>
Date: Wed, 8 Nov 2023 21:37:29 +0600
Subject: [PATCH 2/3] Search functionality

---
 app/.DS_Store             | Bin 0 -> 6148 bytes
 app/apis/v1/route_user.py |  33 +++++++++++++++++++++++++++++++--
 app/db/repository/user.py |   9 +++++++++
 app/schemas/user.py       |  19 +++++++++++++++++++
 4 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 app/.DS_Store

diff --git a/app/.DS_Store b/app/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..8defa378e4ddf097e94317713c170c5e96a63488
GIT binary patch
literal 6148
zcmeH~K?=e^3`G;|qTr@Wm$UHz-e4$t0xzH-h#)G8uIK3fWP)IIEh0aV{7Gg)>05Lf
z5z+p(or`oL(!xz;W?^88ypfHZWiQwJ>T*1sjyu$>K8mxphIca9k8KJGkN^pg011%5
z4-v3?8`e&$GLirZkie6GeIF9sG>4X|{^>yQ5dhkt?1r_^63}D?Xbvq^QGsbp4;roN
zV~Ewg9h%}?4lPw{yJ!p_8c$Z6VqjX^MH3R3W)}t$Ab|maam_os|CjJj^Z%fQDG89k
zpApbzv0C(askmF;UeD_5sM@-~p?)0U<tG4%UBy$l8}^eepgFWuMFqwm0mr~V0$(NY
E08QW$zyJUM

literal 0
HcmV?d00001

diff --git a/app/apis/v1/route_user.py b/app/apis/v1/route_user.py
index 2490d0d..6cf1569 100644
--- a/app/apis/v1/route_user.py
+++ b/app/apis/v1/route_user.py
@@ -1,12 +1,14 @@
 # Routes for user. MAIN PART OF THE API
-from fastapi import APIRouter, HTTPException, status
+from math import ceil
+from fastapi import APIRouter, HTTPException, status, Query
 from sqlalchemy.orm import Session
+from sqlalchemy import or_
 from fastapi import Depends
 from typing import List, Annotated
 from apis.v1.route_auth import get_current_user
 from core.config import settings
 from db.models.user import User
-from schemas.user import UserCreate, ShowUser, ShowDriver, DriverCreate
+from schemas.user import UserCreate, ShowUser, ShowDriver, DriverCreate, OutputUser, UsersPage
 from db.session import get_db
 from db.repository.user import (
     create_new_user,
@@ -15,9 +17,11 @@ from db.repository.user import (
     replace_user_data,
     create_new_driver,
     delete_user_data,
+    get_users_by_name
 )
 
 
+
 router = APIRouter()
 
 
@@ -126,3 +130,28 @@ def delete_user(
     if result == "userNotFound":
         raise HTTPException(status_code=404, detail="User not found")
     return result
+
+
+@router.get("/search/", response_model=UsersPage)
+def search_users(db: Session = Depends(get_db), name: str = None, role: str = None, page: int = 1, per_page: int = 20):
+    query = db.query(User).filter(User.Name.like(f"{name}%"))
+    if role is not None and role != "Admin":
+        query = query.filter(User.Role == role)
+    total_users = query.count()
+    total_pages = ceil(total_users / per_page)
+    users = query.offset((page - 1) * per_page).limit(per_page).all()
+
+    output_users = [OutputUser(
+        id= user.Id,
+        Name=user.Name,
+        MiddleName = user.MiddleName,
+        LastName=user.LastName,
+        ContactNumber=user.ContactNumber,
+        Address=user.Address,
+        Email=user.Email,
+        Role=user.Role,
+        AssignedVehicle= None
+    ) for user in users]
+
+
+    return {"users": output_users, "total_pages": total_pages}
diff --git a/app/db/repository/user.py b/app/db/repository/user.py
index 6499ca4..9ea9534 100644
--- a/app/db/repository/user.py
+++ b/app/db/repository/user.py
@@ -83,6 +83,15 @@ def list_users(db: Session, role: str = "Any"):
     users = db.query(User).filter((User.Role == role) | (role == "Any")).all()
     return users
 
+def get_users_by_name(db: Session, name: str = "", role: str = None, page: int = 1, per_page: int = 20):
+    if role == "Admin":
+        return None
+    if role is None:
+        users = db.query(User).filter(User.Name.like(f"{name}%"), User.Role != "Admin")
+    else:
+        users = db.query(User).filter(User.Name.like(f"{name}%"), User.Role == role)
+    users = users.offset((page - 1) * per_page).limit(per_page).all()
+    return users
 
 def replace_user_data(user_id: int, user_data: UserCreate, db: Session):
     user = db.query(User).filter(User.Id == user_id).first()
diff --git a/app/schemas/user.py b/app/schemas/user.py
index 61b4ff1..3496fc0 100644
--- a/app/schemas/user.py
+++ b/app/schemas/user.py
@@ -1,6 +1,7 @@
 # Purpose: User schema for pydantic (validation, inside-api usage)
 
 from pydantic import BaseModel, EmailStr, Field
+from typing import Optional, List
 
 
 class UserCreate(BaseModel):
@@ -36,6 +37,24 @@ class ShowUser(BaseModel):
         validate_assignment = True
 
 
+class OutputUser(BaseModel):
+    id: int
+    Name: str
+    MiddleName: Optional[str]
+    LastName: str
+    ContactNumber: str
+    Address: str
+    Email: EmailStr
+    Role: str
+    AssignedVehicle: Optional[str]  # replace str with the actual type of AssignedVehicle
+
+    class Config:
+        orm_mode = True
+
+class UsersPage(BaseModel):
+    users: List[OutputUser]
+    total_pages: int
+
 class ShowDriverNoVehicle(ShowUser):
     DrivingLicenseNumber: str | None
 

From 89cbdce1d287199fc0fab99f06714676a9ce398c Mon Sep 17 00:00:00 2001
From: Madiwka3 <madi.turgunov.03@gmail.com>
Date: Wed, 8 Nov 2023 21:56:34 +0600
Subject: [PATCH 3/3] some slight refactoring

---
 app/apis/v1/route_user.py | 43 ++++++++++++++++-----------------------
 app/db/repository/user.py | 37 +++++++++++++++++++++++++++++++--
 app/schemas/user.py       |  6 +++++-
 3 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/app/apis/v1/route_user.py b/app/apis/v1/route_user.py
index 6cf1569..f8920d1 100644
--- a/app/apis/v1/route_user.py
+++ b/app/apis/v1/route_user.py
@@ -8,7 +8,14 @@ from typing import List, Annotated
 from apis.v1.route_auth import get_current_user
 from core.config import settings
 from db.models.user import User
-from schemas.user import UserCreate, ShowUser, ShowDriver, DriverCreate, OutputUser, UsersPage
+from schemas.user import (
+    UserCreate,
+    ShowUser,
+    ShowDriver,
+    DriverCreate,
+    OutputUser,
+    UsersPage,
+)
 from db.session import get_db
 from db.repository.user import (
     create_new_user,
@@ -17,11 +24,11 @@ from db.repository.user import (
     replace_user_data,
     create_new_driver,
     delete_user_data,
-    get_users_by_name
+    get_users_by_name,
+    user_search_query,
 )
 
 
-
 router = APIRouter()
 
 
@@ -133,25 +140,11 @@ def delete_user(
 
 
 @router.get("/search/", response_model=UsersPage)
-def search_users(db: Session = Depends(get_db), name: str = None, role: str = None, page: int = 1, per_page: int = 20):
-    query = db.query(User).filter(User.Name.like(f"{name}%"))
-    if role is not None and role != "Admin":
-        query = query.filter(User.Role == role)
-    total_users = query.count()
-    total_pages = ceil(total_users / per_page)
-    users = query.offset((page - 1) * per_page).limit(per_page).all()
-
-    output_users = [OutputUser(
-        id= user.Id,
-        Name=user.Name,
-        MiddleName = user.MiddleName,
-        LastName=user.LastName,
-        ContactNumber=user.ContactNumber,
-        Address=user.Address,
-        Email=user.Email,
-        Role=user.Role,
-        AssignedVehicle= None
-    ) for user in users]
-
-
-    return {"users": output_users, "total_pages": total_pages}
+def search_users(
+    db: Session = Depends(get_db),
+    name: str = None,
+    role: str = None,
+    page: int = 1,
+    per_page: int = 20,
+):
+    return user_search_query(db=db, name=name, role=role, page=page, per_page=per_page)
diff --git a/app/db/repository/user.py b/app/db/repository/user.py
index 9ea9534..d1ad2ec 100644
--- a/app/db/repository/user.py
+++ b/app/db/repository/user.py
@@ -1,7 +1,8 @@
 # Creating a new user in the database
+from math import ceil
 from sqlalchemy.orm import Session
 
-from schemas.user import UserCreate, DriverCreate
+from schemas.user import OutputUser, UserCreate, DriverCreate
 from db.models.user import User
 from core.hashing import Hasher
 from db.models.drivetask import DriveTask
@@ -83,7 +84,10 @@ def list_users(db: Session, role: str = "Any"):
     users = db.query(User).filter((User.Role == role) | (role == "Any")).all()
     return users
 
-def get_users_by_name(db: Session, name: str = "", role: str = None, page: int = 1, per_page: int = 20):
+
+def get_users_by_name(
+    db: Session, name: str = "", role: str = None, page: int = 1, per_page: int = 20
+):
     if role == "Admin":
         return None
     if role is None:
@@ -93,6 +97,7 @@ def get_users_by_name(db: Session, name: str = "", role: str = None, page: int =
     users = users.offset((page - 1) * per_page).limit(per_page).all()
     return users
 
+
 def replace_user_data(user_id: int, user_data: UserCreate, db: Session):
     user = db.query(User).filter(User.Id == user_id).first()
     if not user:
@@ -121,3 +126,31 @@ def delete_user_data(id: int, db: Session):
     db.delete(user)
     db.commit()
     return "userDeleted"
+
+
+def user_search_query(
+    db: Session, name: str = "", role: str = None, page: int = 1, per_page: int = 20
+):
+    query = db.query(User).filter(User.Name.like(f"{name}%"))
+    if role is not None and role != "Admin":
+        query = query.filter(User.Role == role)
+    total_users = query.count()
+    total_pages = ceil(total_users / per_page)
+    users = query.offset((page - 1) * per_page).limit(per_page).all()
+
+    output_users = [
+        OutputUser(
+            id=user.Id,
+            Name=user.Name,
+            MiddleName=user.MiddleName,
+            LastName=user.LastName,
+            ContactNumber=user.ContactNumber,
+            Address=user.Address,
+            Email=user.Email,
+            Role=user.Role,
+            AssignedVehicle=None,
+        )
+        for user in users
+    ]
+
+    return {"users": output_users, "total_pages": total_pages}
diff --git a/app/schemas/user.py b/app/schemas/user.py
index 3496fc0..1a9f188 100644
--- a/app/schemas/user.py
+++ b/app/schemas/user.py
@@ -46,15 +46,19 @@ class OutputUser(BaseModel):
     Address: str
     Email: EmailStr
     Role: str
-    AssignedVehicle: Optional[str]  # replace str with the actual type of AssignedVehicle
+    AssignedVehicle: Optional[
+        str
+    ]  # replace str with the actual type of AssignedVehicle
 
     class Config:
         orm_mode = True
 
+
 class UsersPage(BaseModel):
     users: List[OutputUser]
     total_pages: int
 
+
 class ShowDriverNoVehicle(ShowUser):
     DrivingLicenseNumber: str | None