Compare commits

...

28 Commits

Author SHA1 Message Date
7fead5486b fix(db): modify 'rents' SQL table structure
The commit modifies the 'rents' SQL table:
- Replaces the improperly quoted table name with correct syntax: from 'rents' to `rents`.
- Changes `id` field data type from tinyint to varchar.
- Updates database dump's completion timestamp.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 14:56:37 +02:00
5cc214a29b schema
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 14:55:07 +02:00
65a6ae2e3c feat(routes): update rent related routes
- The "/affected" route has been updated to now use the `RentController.getAssignedToUser` method.
- The "/affected/all" route, which was previously not implemented, now utilizes the `RentController.getAll` function.
- These changes will help facilitate the retrieval of individual and all rented vehicles.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:18:46 +02:00
83d07a2812 feat(services): add availability check in rent service
A new condition was added in `rent.service.ts` to check if a vehicle is available before executing the rent operation. It also logs an error if the vehicle is not available.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:18:33 +02:00
e8acfd7b30 feat(services): update condition checks in model.service.ts
Updated the condition checks in the 'delete' and 'fetch' methods of the `model.service.ts`. Now, it properly checks if the model exists by examining the first item of the result array, instead of considering the result array itself. This resolves issues where fetching or deleting a model with a non-existent slug would incorrectly attempt to perform operations considering the empty array as valid input.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:18:15 +02:00
438ae4b5d0 fix(controllers): update model slug in updateModel function
The model slug has been updated to use `req.params["modelSlug"]` instead of `body.slug_name` in the `updateModel` function, ensuring the correct slug is used when checking if the model exists.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:17:58 +02:00
6ccc899320 feat(interfaces): add isAvailable field to IDbVehicle interface
The IDbVehicle interface has been updated to include an optional `isAvailable` field. This field can be used to check the availability status of a vehicle.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:17:47 +02:00
5afb6e22bf feat(services): update getBySlug function in MySQL services
The `getBySlug` function originally returned a single database model by slug from the MySQL handler. It has been updated to return a list of database models by slug name. Error handling for failed query executions is also included.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:17:37 +02:00
bdba2f6e29 feat(controllers): add rent controller
- Implemented functionality for creating, updating, and getting rent information.
- Created `createRent`, `updateRent`, `getAllAssigned`, and `getAssignedToUser` functions in the `rent.controller.ts` file.
- These functions handle all the interactions related to renting vehicles.

Issue: #25
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 13:17:25 +02:00
30c6f2e3f1 feat(services): remove unused import from rent.service.ts
The `body` import from "express-validator" has been removed from rent.service.ts as it was not used. Also, an error handler for deleting rent was updated to always return false on encountering an error, improving the error handling mechanism.

Issue: #24
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 12:02:36 +02:00
b47ec6c440 feat(services): add error logging in rent.service
A logging feature is added in the `rent.service.ts` to log any errors when attempting to delete rent. This feature helps in diagnosing issues during rent deletion.

Issue: #24
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 12:01:56 +02:00
b4f200cb32 feat(inspectionProfiles): increase TypeScript code redundancy threshold
The minimum size for the TypeScript language in the duplicated code check has been increased. This update reduces the sensitivity of the code redundancy inspection, potentially reducing false positive results.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 12:01:03 +02:00
ec53fcb247 feat(services): add rent service functions
This commit introduces new functions to handle rental services in the src/services/rent.service.ts. Functions created handle rental CRUD operations such as createRentService, updateRentService, deleteRentService, also additional utility functions such as getUserRentService and getRentByIdService that deal with user-associated rentals were introduced. These new functions serve to simplify rental management and improve our services for rental handling.

Issue: #24
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 12:00:48 +02:00
371d960cf3 feat(services): update getById method in mysql.service
- Update the getById method in mysql.service to return an array of vehicles instead of a single vehicle
- Add a new getById method to retrieve array of rental information by rental ID
- Improve the documentation to match the modifications in both methods' functionalities

Issue: #23
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:59:58 +02:00
3525fb12e6 feat(routes): add create vehicle function to route
This commit hooks up the `VehicleController.create` function to the route handling post requests at `/veh/new`. With this change, admin users can add new vehicles via this endpoint.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:23:13 +02:00
82afff9878 feat(services): add update function in mysql service
This commit adds an `update` function to the `mysql.service.ts`. This new function will update a rent record in the database. It takes a database handler object and a rent object containing the updated data, and returns a Promise that resolves to the status result of the update operation. The function will throw an error if an issue occurs during the update operation.

Issue: #23
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:23:00 +02:00
fef2bda082 refactor(services): simplify SQL query strings and reformat function parameters
This commit includes the following changes in `mysql.service.ts` file:
- Simplify SQL query strings for `UPDATE` and `INSERT` commands in various methods to make them more readable.
- Reformat parameters in `getAllModelsFromCategory` and `delete` methods for better readability.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:18:30 +02:00
f87aecaf75 feat(routes): update endpoints in rentRouter
Update `rentRouter.ts` to include `VehicleController` methods in route handlers.
- Add `VehicleController.getAll` to "/veh/all" route.
- Update "/veh/:vehicleId" route to include `VehicleController.getById`, `VehicleController.update`, and `VehicleController.delete`.

Issue: #22
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:17:45 +02:00
170b9a5693 feat(controllers): implement vehicle controller
Added a new `vehicle.controller.ts` file under controllers. It includes multiple functions related to vehicle management such as `createVehicle`, `updateVehicle`, `getAllVehicle`, `getVehicleById`, `getAvailableVehicle`, and `deleteVehicle`. These functions handle the creation, updates, retrieval, and deletion of a vehicle respectively. With these additions, the application now has the ability to manage vehicles through the `VehicleController` module.

Issue: #22
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:17:23 +02:00
c9ca39ddfa feat(services): update code formatting in vehicle.service.ts
- Modify import statement format and standardize indentation across the entire file.
- Add line breaks and commas where needed for better readability.
- Remove unnecessary comments and white space.
- Ensure consistent usage of semicolons.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 11:01:54 +02:00
da028ea2c4 feat(services): update CRUD operations in mysql.service.ts
In this commit:
- Implemented factorize method to standardize data processing and update operations for users, brands, models, categories, and rents.
- Updated SQL syntax to improve code hygiene and readability.
- Added debug mode checks to improve performance in production.
- Added exception handling for possible errors during SQL query execution.
- Added additional methods to get assigned vehicles to a user and all assigned vehicles from the database.
- Added missing delete method for vehicle and rent tables.

Issue: #23 & #21
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 10:30:57 +02:00
1c643b3625 feat(interfaces): add optional id property to IDbRent interface
A new optional `id` property has been added to `IDbRent` interface in the `interfaces` scope. This allows for more flexibility when working with rent objects in the database.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 09:52:07 +02:00
33d6793758 refactor(others): rename database table rent to rents
The database table `rent` has been renamed to `rents` to better align with naming conventions. The related DROP TABLE and CREATE TABLE commands have been updated accordingly in `db.sql`.

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 09:51:42 +02:00
c95ac03680 feat(others): update database schema
- Change `LastIntrospectionLocalTimestamp` date in `brief_05` schema
- Rename table `rent` to `rents`
- Update `id` column `DasType` to `varchar(36)|0s`

Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-03 09:51:24 +02:00
03fc5307e6 feat(services): add deleteVehicleService function to vehicle service
A new function `deleteVehicleService` is added to `vehicle.service.ts` to handle the vehicle deletion process. It will return true if the operation is successful, and false if it fails or encounters an error.

Issue: #21
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-02 16:51:32 +02:00
b6a2a74ba0 feat(services): add multiple vehicle services
Implemented `getAllVehiclesService`, `getVehicleByIdService` and `getAvailableVehicleService` in `vehicle.service.ts`. Each of these services fetches respective data from the MySQL database, handles errors, and returns the data along with a timestamp.

Issue: #21
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-02 16:49:13 +02:00
f310bedeff feat(services): add vehicle update functionality in vehicle.service.ts
An `updateVehicleService` function has been introduced in `vehicle.service.ts` to enable vehicle data updates in the application. The function handles data validation, updates the MySQL database, and logs the process status.

Issue: #21
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-02 16:39:50 +02:00
838ea4ad22 feat(services): add new vehicle service
This commit introduces a new file `vehicle.service.ts` which includes a function for creating new vehicles. It uses MySQL service for data handling and includes error handling and logging functionalities. The changes help in improving the code modularity and providing a specific service for vehicle management.

Issue: #21
Signed-off-by: Mathis <yidhra@tuta.io>
2024-05-02 16:37:28 +02:00
14 changed files with 1089 additions and 144 deletions

View File

@@ -1036,7 +1036,7 @@ brief\\_05|schema||user_brief05||UPDATE|G</Grants>
</schema>
<schema id="325" parent="1" name="brief_05">
<Current>1</Current>
<LastIntrospectionLocalTimestamp>2024-04-29.12:54:42</LastIntrospectionLocalTimestamp>
<LastIntrospectionLocalTimestamp>2024-05-03.07:39:06</LastIntrospectionLocalTimestamp>
<CollationName>latin1_swedish_ci</CollationName>
</schema>
<user id="326" parent="1" name="user_brief05"/>
@@ -1063,7 +1063,7 @@ brief\\_05|schema||user_brief05||UPDATE|G</Grants>
<Engine>InnoDB</Engine>
<CollationName>latin1_swedish_ci</CollationName>
</table>
<table id="332" parent="325" name="rent">
<table id="332" parent="325" name="rents">
<Engine>InnoDB</Engine>
<CollationName>latin1_swedish_ci</CollationName>
</table>
@@ -1270,7 +1270,7 @@ brief\\_05|schema||user_brief05||UPDATE|G</Grants>
<Position>7</Position>
</column>
<column id="376" parent="332" name="id">
<DasType>tinyint(1)|0s</DasType>
<DasType>varchar(36)|0s</DasType>
<NotNull>1</NotNull>
<Position>8</Position>
</column>

View File

@@ -3,7 +3,7 @@
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="114" name="TypeScript" />
<language minSize="174" name="TypeScript" />
</Languages>
</inspection_tool>
</profile>

10
db.sql
View File

@@ -74,13 +74,13 @@ CREATE TABLE `models` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `rent`
-- Table structure for table `rents`
--
DROP TABLE IF EXISTS `rent`;
DROP TABLE IF EXISTS `rents`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `rent` (
CREATE TABLE `rents` (
`vehicle_id` varchar(36) NOT NULL,
`user_id` varchar(36) NOT NULL,
`active` tinyint(1) NOT NULL,
@@ -88,7 +88,7 @@ CREATE TABLE `rent` (
`eat` date NOT NULL,
`need_survey` tinyint(1) DEFAULT NULL,
`km_at_start` int(11) DEFAULT NULL,
`id` tinyint(1) NOT NULL,
`id` varchar(36) NOT NULL,
PRIMARY KEY (`id`),
KEY `rent_vehicles_id_fk` (`vehicle_id`),
KEY `rent_users_id_fk` (`user_id`),
@@ -152,4 +152,4 @@ CREATE TABLE `vehicles` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2024-04-29 14:54:00
-- Dump completed on 2024-05-03 14:56:07

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

@@ -42,7 +42,7 @@ async function createModel(req: Request, res: Response): Promise<Response> {
async function updateModel(req: Request, res: Response): Promise<Response> {
const body: IDbModel = req.body;
const doesExist = await ModelService.getBySlug(`${body.slug_name}`);
const doesExist = await ModelService.getBySlug(`${req.params["modelSlug"]}`);
if (!doesExist) {
logger.error("Model does not exist");
return res.status(404).json({

View File

@@ -0,0 +1,150 @@
import { isDebugMode } from "@utils/debugState";
import type { Request, Response } from "express";
import { Logger } from "tslog";
import RentService from "@services/rent.service";
import {HttpStatusCode} from "@interfaces/requests/HttpStatusCode";
import type IDbRent from "@interfaces/database/IDbRent";
import JwtService from "@services/jwt.service";
import UserService from "@services/user.service";
const logger = new Logger({
name: "RentController",
});
async function createRent(req: Request, res: Response): Promise<Response> {
try {
const rentData: IDbRent = req.body;
if (!rentData.active || !rentData.need_survey || !rentData.eat || !rentData.iat || !rentData.user_id || !rentData.vehicle_id || !rentData.km_at_start || !rentData.active) {
logger.error("Invalid rent data");
return res.status(HttpStatusCode.BadRequest).json({
error: "Invalid rent data",
});
}
const rent = await RentService.create(rentData);
logger.info(`\n\n> Rent created successfully! (ID: ${rentData.vehicle_id})\n`);
return res.status(201).json({
message: "Rent created successfully",
rent,
});
} catch (error) {
logger.error(`\n\n> Failed to create rent !\n${error}\n`);
return res.status(500).json({
error: "Failed to create rent",
});
}
}
async function updateRent(req: Request, res: Response): Promise<Response> {
const body: IDbRent = req.body;
if (!body.vehicle_id || !body.user_id || !body.active || !body.need_survey || !body.eat || !body.iat || !body.km_at_start) {
logger.error("Invalid rent data");
return res.status(HttpStatusCode.BadRequest).json({
error: "Invalid rent data",
});
}
const rentId = req.params["rentId"];
if (!rentId || rentId.length !== 36) {
logger.error("Invalid rent ID");
return res.status(HttpStatusCode.BadRequest).json({
error: "Invalid rent ID",
});
}
const result = await RentService.update({
id: rentId,
vehicle_id: ``,
user_id: ``,
active: !!body.active,
need_survey: !!body.need_survey,
eat: body.eat,
iat: body.iat,
km_at_start: body.km_at_start,
})
if (!result) {
logger.error(`Failed to update rent with ID: ${rentId}`);
return res.status(HttpStatusCode.InternalServerError).json({
error: `Failed to update rent with ID: ${rentId}`,
});
}
logger.info(`Rent with ID: ${rentId} updated successfully`);
return res.status(HttpStatusCode.Ok).json({
message: `Rent with ID: ${rentId} updated successfully`,
});
}
async function getAllAssigned(res: Response): Promise<Response> {
const rents = await RentService.getAll();
if (rents.length === 0) {
return res.status(HttpStatusCode.NotFound).json({
error: "No assigned rents found",
});
}
return res.status(HttpStatusCode.Ok).json({
iat: Date.now(),
rents: rents,
total: rents.length
});
}
async function getAssignedToUser(req: Request, res: Response): Promise<Response> {
const authHeader = req.headers.authorization;
const bearerToken = authHeader?.split(" ")[1];
if (!bearerToken) {
logger.warn(`Bearer token not provided (${req.ip})`);
return res
.type("application/json")
.status(HttpStatusCode.Unauthorized)
.json({
error: "Unauthorized",
});
}
const payload = await JwtService.verify(bearerToken);
if (!payload || !payload.sub) {
logger.warn(`Unauthorized access attempt (${req.ip})`);
return res
.type("application/json")
.status(HttpStatusCode.Unauthorized)
.json({
error: "Unauthorized",
});
}
const sourceUser = await UserService.getFromId(payload.sub);
if (!sourceUser) {
return res.type("application/json").status(HttpStatusCode.ImATeapot).json({
error: "You dont exist anymore",
});
}
const userId: string = payload.sub;
if (!userId || userId.length !== 36) {
logger.error("Invalid user ID");
return res.status(HttpStatusCode.BadRequest).json({
error: "Invalid user ID",
});
}
let targetId = userId
if ("is_admin" in sourceUser && sourceUser.is_admin) {
targetId = req.body.targetId || userId
}
const rents = await RentService.getUserRent(targetId);
if (!rents) {
return res.status(HttpStatusCode.NotFound).json({
error: "No assigned rents found for the user",
});
}
return res.status(HttpStatusCode.Ok).json({
iat: Date.now(),
rents: rents,
total: rents.length,
});
}
if (isDebugMode()) logger.debug("\nController loaded.");
const RentController = {
create: createRent,
update: updateRent,
getAll: getAllAssigned,
getAssignedToUser,
};
export default RentController;

View File

@@ -0,0 +1,174 @@
import type { IDbVehicle } from "@interfaces/database/IDbVehicle";
import VehicleService from "@services/vehicle.service";
import { isDebugMode } from "@utils/debugState";
import type { Request, Response } from "express";
import { Logger } from "tslog";
//import {validationResult} from "express-validator";
const logger = new Logger({
name: "VehicleController",
});
/**
* Creates a new vehicle in the database.
*
* @param {Request} req - The request object containing the vehicle details in the body.
* @param {Response} res - The response object used to send the result of the operation.
* @returns {Promise<Response>} The response with the result of the operation.
*/
async function createVehicle(req: Request, res: Response): Promise<Response> {
const body: IDbVehicle = req.body;
const createResult = await VehicleService.create({
plate_number: `${body.plate_number}`,
model_id: `${body.plate_number}`,
odometer: Number.parseInt(`${body.odometer}`),
health_state: Number.parseInt(`${body.health_state}`),
});
if (!createResult) {
logger.error("Failed to create vehicle");
return res.status(500).json({
error: "Failed to create vehicle",
});
}
logger.info(`Vehicle created successfully ! (${body.plate_number})`);
return res.status(201).json({
message: "Vehicle created successfully",
});
}
/**
* Updates a vehicle in the database.
*
* @param {Request} req - The request object containing the vehicle data in the request body and the vehicle ID in the request parameters.
* @param {Response} res - The response object used to send the result of the update operation.
*
* @return {Promise<Response>} A promise that resolves to the response object with a status and a JSON body indicating the result of the update operation.
*/
async function updateVehicle(req: Request, res: Response): Promise<Response> {
const body: IDbVehicle = req.body;
const vehicleId = req.params["vehicleId"];
if (!vehicleId || vehicleId.length !== 36) {
if (isDebugMode()) logger.error("Vehicle ID is missing");
return res.status(400).json({
error: "Vehicle ID is missing or not valid",
});
}
const updateResult = await VehicleService.update({
plate_number: `${body.plate_number}`,
model_id: `${body.plate_number}`,
odometer: Number.parseInt(`${body.odometer}`),
health_state: Number.parseInt(`${body.health_state}`),
});
if (!updateResult) {
logger.error("Failed to update vehicle");
return res.status(500).json({
error: "Failed to update vehicle",
});
}
logger.info(`Vehicle updated successfully ! (${body.plate_number})`);
return res.status(200).json({
message: "Vehicle updated successfully",
});
}
/**
* Retrieves all vehicles from the vehicle service.
*
* @param {Response} res - The response object from the client.
* @returns {Promise<Response>} A promise that resolves to a response object containing the result of the operation. The result is a JSON object containing all vehicles.
*/
async function getAllVehicle(res: Response): Promise<Response> {
const getAllVehicleResult = await VehicleService.getAll();
if (!getAllVehicleResult) {
logger.error("Failed to get all vehicles");
return res.status(500).json({
error: "Failed to get all vehicles",
});
}
return res.status(200).json(getAllVehicleResult);
}
/**
* Retrieves the available vehicles from the VehicleService
*
* @param {Response} res - The Response object to send the result to
* @returns {Promise<Response<any, Record<string, any>>>} - A promise that resolves to a Response object containing the available vehicles or an error message
*/
async function getAvailableVehicle(res: Response): Promise<Response<any, Record<string, any>>> {
const getAvailableVehicleResult = await VehicleService.getAvailable();
if (!getAvailableVehicleResult) {
logger.error("Failed to get available vehicles");
return res.status(500).json({
error: "Failed to get available vehicles",
});
}
return res.status(200).json(getAvailableVehicleResult);
}
/**
* Retrieves a vehicle by its ID.
*
* @param {Request} req - The request object containing the vehicle ID.
* @param {Response} res - The response object used to send the result.
*
* @return {Promise<Response>} A promise that resolves to the result of the retrieval operation.
*/
async function getVehicleById(req: Request, res: Response): Promise<Response> {
const vehicleId = req.params["vehicleId"];
if (!vehicleId || vehicleId.length !== 36) {
if (isDebugMode()) logger.error("Vehicle ID is missing or not valid");
return res.status(400).json({
error: "Vehicle ID is missing or not valid",
});
}
const getVehicleResult = await VehicleService.getById(vehicleId);
if (!getVehicleResult) {
logger.error(`Failed to get vehicle by ID: ${vehicleId}`);
return res.status(500).json({
error: `Failed to get vehicle by ID: ${vehicleId}`,
});
}
return res.status(200).json(getVehicleResult);
}
/**
* Deletes a vehicle.
*
* @param {Object} req - The request object.
* @param {Object} res - The response object.
*
* @return {Promise<Response>} A promise that resolves to the response JSON object.
*/
async function deleteVehicle(req: Request, res: Response): Promise<Response> {
const vehicleId = req.params["vehicleId"];
if (!vehicleId || vehicleId.length !== 36) {
if (isDebugMode()) logger.error("Vehicle ID is missing or not valid");
return res.status(400).json({
error: "Vehicle ID is missing or not valid",
});
}
const deleteResult = await VehicleService.delete(vehicleId);
if (!deleteResult) {
logger.error(`Failed to delete vehicle with ID: ${vehicleId}`);
return res.status(500).json({
error: `Failed to delete vehicle with ID: ${vehicleId}`,
});
}
logger.info(`Vehicle deleted successfully ! (ID: ${vehicleId})`);
return res.status(200).json({
message: "Vehicle deleted successfully",
});
}
if (isDebugMode()) logger.debug("\nController loaded.");
const VehicleController = {
create: createVehicle,
update: updateVehicle,
getAll: getAllVehicle,
delete: deleteVehicle,
getById: getVehicleById,
getAvailable: getAvailableVehicle,
};
export default VehicleController;

View File

@@ -1,4 +1,5 @@
export interface IDbRent {
id?: string;
vehicle_id: string;
user_id: string;
active: boolean;

View File

@@ -4,4 +4,5 @@ export interface IDbVehicle {
model_id: string;
odometer: number;
health_state: number;
isAvailable?: boolean;
}

View File

@@ -1,27 +1,29 @@
import AdminGuard from "@validators/AdminGuard";
import UserGuard from "@validators/UserGuard";
import express, { type Router } from "express";
import VehicleController from "@controllers/vehicle.controller";
import RentController from "@controllers/rent.controller";
const RentRouter: Router = express.Router();
// Get rent affected to the user
RentRouter.route("/affected").get(UserGuard);
RentRouter.route("/affected").get(UserGuard, RentController.getAssignedToUser);
// Get all vehicle in rent (admin only)
RentRouter.route("/affected/all").get(AdminGuard);
RentRouter.route("/affected/all").get(AdminGuard, RentController.getAll);
// Add a new vehicle (admin only)
RentRouter.route("/veh/new").post(AdminGuard);
RentRouter.route("/veh/new").post(AdminGuard, VehicleController.create);
// Get all vehicles
RentRouter.route("/veh/all").get();
RentRouter.route("/veh/all").get(VehicleController.getAll);
// Rent a specific vehicle
RentRouter.route("/veh/rent/:vehicleId").post(UserGuard);
RentRouter.route("/veh/:vehicleId")
.get(UserGuard)
.patch(AdminGuard)
.delete(AdminGuard);
.get(UserGuard, VehicleController.getById)
.patch(AdminGuard, VehicleController.update)
.delete(AdminGuard, VehicleController.delete);
export default RentRouter;

View File

@@ -80,12 +80,14 @@ async function deleteModel(modelSlug: string): Promise<boolean> {
}
logger.info(`Deleting model with ID: ${modelSlug}`);
const doesExist = await MysqlService.Model.getBySlug(DbHandler, modelSlug);
if (!doesExist || !doesExist.id) {
if (!doesExist[0]) {
logger.warn(`Model with slug ${modelSlug} not found`);
return false;
}
const target = doesExist[0]
if (!target.id) return false;
try {
await MysqlService.Model.delete(DbHandler, doesExist.id);
await MysqlService.Model.delete(DbHandler, target.id);
logger.info("Deletion Successful !");
return true;
} catch (error) {
@@ -104,11 +106,11 @@ async function getBySlugModel(modelSlug: string): Promise<IDbModel | null> {
logger.info(`Fetching model with slug: ${modelSlug}`);
try {
const model = await MysqlService.Model.getBySlug(DbHandler, modelSlug);
if (!model) {
if (!model[0]) {
logger.warn(`Model with slug ${modelSlug} not found`);
return null;
}
return model;
return model[0];
} catch (error) {
logger.error(`Error fetching model by slug: ${error}`);
return null;

View File

@@ -6,6 +6,7 @@ import type {
IDbFactorizeOutput,
} from "@interfaces/database/IDbFactorize";
import type { IDbModel } from "@interfaces/database/IDbModel";
import type IDbRent from "@interfaces/database/IDbRent";
import type { IDbStatusResult } from "@interfaces/database/IDbStatusResult";
import type { IDbUser } from "@interfaces/database/IDbUser";
import type { IDbVehicle } from "@interfaces/database/IDbVehicle";
@@ -180,7 +181,6 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
handler
.factorize({
values: data,
@@ -194,8 +194,9 @@ const MySqlService = {
})`;
try {
handler.Logger.trace(_sql);
handler.Logger.trace(valuesArray);
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode()) handler.Logger.trace(valuesArray);
//ToTest
handler.execute(_sql, valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
@@ -224,13 +225,24 @@ const MySqlService = {
handler
.factorize({
values: data,
actionName: `Update user ID::${data.id}`,
actionName: "Update user..",
})
.then((result) => {
const _sql = `UPDATE "users" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
handler.execute(_sql, result._valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
.then((factorizeResult) => {
const _sql = `UPDATE users SET (${factorizeResult._keysTemplate}) WERE id VALUES(${factorizeResult._questionMarksFields})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode())
handler.Logger.trace(factorizeResult._valuesArray);
//ToTest
handler
.execute(_sql, factorizeResult._valuesArray)
.then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
@@ -238,10 +250,19 @@ const MySqlService = {
});
},
//ToTest
/**
* Retrieves user information from the database based on the provided user ID.
*
* @param {MysqlHandler} handler - The MySQL handler instance.
* @param {string} userId - The user ID used to locate the user in the database.
* @returns {Promise<Array<IDbUser>>} A promise that resolves with an array of user objects matching the provided user ID.
* @throws {string} Throws an error if the provided user ID is invalid.
* @throws {Error} Throws*/
getById(handler: MysqlHandler, userId: string): Promise<Array<IDbUser>> {
return new Promise((resolve, reject) => {
if (userId.length !== 36) return reject("Id invalid");
const _sql = "SELECT * FROM `users` WHERE `id` = ?";
const _sql = "SELECT * FROM users WHERE id VALUES(?)";
const _values = [userId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -253,6 +274,7 @@ const MySqlService = {
});
},
//ToTest
/**
* Retrieves all users from the database.
*
@@ -262,7 +284,7 @@ const MySqlService = {
*/
getAll(handler: MysqlHandler): Promise<Array<IDbUser>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `users`";
const _sql = "SELECT * FROM users";
try {
handler.query(_sql).then((result) => {
return resolve(result as unknown as Array<IDbUser>);
@@ -284,7 +306,7 @@ const MySqlService = {
getByEmail(handler: MysqlHandler, email: string): Promise<Array<IDbUser>> {
return new Promise((resolve, reject) => {
if (!email) return reject("email is undefined");
const _sql = "SELECT * FROM `users` WHERE `email` = ?";
const _sql = "SELECT * FROM users WHERE email VALUES(?)";
const _values = [email];
try {
handler.execute(_sql, _values).then((result) => {
@@ -296,6 +318,7 @@ const MySqlService = {
});
},
//ToTest
/**
* Retrieves the admin state for a given user ID.
*
@@ -309,9 +332,10 @@ const MySqlService = {
userId: string,
): Promise<boolean> {
return new Promise((resolve, reject) => {
const _sql = "SELECT `is_admin` FROM `users` WHERE `id` = ?";
const _sql = "SELECT is_admin FROM users WHERE id VALUES(?)";
const _values = [userId];
try {
//FIX Output type
const isAdmin = handler.execute(
_sql,
_values,
@@ -336,7 +360,7 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!userId) return reject("Id is undefined");
if (userId.length !== 36) return reject("Id invalid");
const _sql = "DELETE FROM `users` WHERE `id` = ?";
const _sql = "DELETE FROM users WHERE id VALUES(?)";
const _values = [userId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -361,20 +385,29 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
handler
.factorize({
values: data,
actionName: "Inserting new brand",
})
.then((result) => {
const valuesArray = result._valuesArray;
const template = result._keysTemplate;
const _sql = `INSERT INTO brands (${template + `, id`}) VALUES(${
result._questionMarksFields
})`;
const _sql =
"INSERT INTO `brands`(`id`,`display_name`, `slug_name`, `image_blob`) VALUES (?, ?, ?, ?)";
const _values = [
data.id,
data.display_name,
data.slug_name,
data.image_blob,
];
try {
resolve(handler.execute(_sql, _values) as unknown as IDbStatusResult);
} catch (err: unknown) {
reject(err as Error);
}
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode()) handler.Logger.trace(valuesArray);
//ToTest
handler.execute(_sql, valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
});
},
@@ -394,13 +427,24 @@ const MySqlService = {
handler
.factorize({
values: data,
actionName: `Update brand ID::${data.id}`,
actionName: "Update brand..",
})
.then((result) => {
const _sql = `UPDATE "brands" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
handler.execute(_sql, result._valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
.then((factorizeResult) => {
const _sql = `UPDATE brands SET (${factorizeResult._keysTemplate}) WERE id VALUES(${factorizeResult._questionMarksFields})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode())
handler.Logger.trace(factorizeResult._valuesArray);
//ToTest
handler
.execute(_sql, factorizeResult._valuesArray)
.then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
@@ -417,7 +461,7 @@ const MySqlService = {
*/
getAll(handler: MysqlHandler): Promise<Array<IDbBrand>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `brands`";
const _sql = "SELECT * FROM brands";
try {
handler.query(_sql).then((result) => {
return resolve(result as unknown as Array<IDbBrand>);
@@ -441,7 +485,7 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!brandId) return reject("Id is undefined");
if (brandId.length !== 36) return reject("Id invalid");
const _sql = "SELECT * FROM `brands` WHERE `id` = ?";
const _sql = "SELECT * FROM brands WHERE id VALUES(?)";
const _values = [brandId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -464,7 +508,7 @@ const MySqlService = {
getBySlug(handler: MysqlHandler, brandSlug: string): Promise<IDbBrand> {
return new Promise((resolve, reject) => {
if (!brandSlug) return reject("slug is undefined");
const _sql = "SELECT * FROM `brands` WHERE `slug_name` = ?";
const _sql = "SELECT * FROM brands WHERE slug_name VALUES(?)";
const _values = [brandSlug];
try {
handler.execute(_sql, _values).then((result) => {
@@ -489,7 +533,7 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!brandId) return reject("Id is undefined");
if (brandId.length !== 36) return reject("Id invalid");
const _sql = "DELETE FROM `brands` WHERE `id` = ?";
const _sql = "DELETE FROM brands WHERE id VALUES(?)";
const _values = [brandId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -513,7 +557,7 @@ const MySqlService = {
*/
getAll(handler: MysqlHandler): Promise<Array<IDbModel>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models`";
const _sql = "SELECT * FROM models";
try {
handler.query(_sql).then((result) => {
return resolve(result as unknown as Array<IDbModel>);
@@ -525,20 +569,20 @@ const MySqlService = {
},
/**
* Retrieves a database model by slug from a given MySQL handler.
* Retrieves a list of database models by slug name.
*
* @param {MysqlHandler} handler - The MySQL handler instance.
* @param {string} modelSlug - The slug of the model to retrieve.
* @return {Promise<IDbModel>} A promise that resolves with the retrieved model.
* @throws {Error} If there was an error executing the query.
* @param {MysqlHandler} handler - The MySQL handler used to execute the query.
* @param {string} modelSlug - The slug name of the model to retrieve.
* @return {Promise<Array<IDbModel>>} - A promise that resolves to an array of database models.
* @throws {Error} - If an error occurs during the execution of the query.
*/
getBySlug(handler: MysqlHandler, modelSlug: string): Promise<IDbModel> {
getBySlug(handler: MysqlHandler, modelSlug: string): Promise<Array<IDbModel>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models` WHERE `slug_name` = ?";
const _sql = "SELECT * FROM models WHERE slug_name VALUES(?)";
const _values = [modelSlug];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbModel);
return resolve(result as unknown as Array<IDbModel>);
});
} catch (err: unknown) {
reject(err as Error);
@@ -555,7 +599,7 @@ const MySqlService = {
*/
getById(handler: MysqlHandler, modelId: string): Promise<IDbModel> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models` WHERE `id` = ?";
const _sql = "SELECT * FROM models WHERE id VALUES(?)";
const _values = [modelId];
try {
resolve(handler.execute(_sql, _values) as unknown as IDbModel);
@@ -577,26 +621,29 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
handler
.factorize({
values: data,
actionName: "Inserting new model",
})
.then((factorizedResult) => {
const valuesArray = factorizedResult._valuesArray;
const template = factorizedResult._keysTemplate;
const _sql = `INSERT INTO users (${template + `, id`}) VALUES(${
factorizedResult._questionMarksFields
})`;
const _sql =
"INSERT INTO `models`(`slug_name`,`display_name`, `brand_id`, `category_id`, `image_blob`, `is_trending`, `base_price`, `id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
const _values = [
data.slug_name,
data.display_name,
data.brand_id,
data.category_id,
data.image_blob,
data.is_trending,
data.base_price,
data.id,
];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbStatusResult);
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode()) handler.Logger.trace(valuesArray);
//ToTest
handler.execute(_sql, valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
@@ -618,13 +665,24 @@ const MySqlService = {
handler
.factorize({
values: data,
actionName: `Update users ID::${data.id}`,
actionName: "Update model..",
})
.then((result) => {
const _sql = `UPDATE "users" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
handler.execute(_sql, result._valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
.then((factorizeResult) => {
const _sql = `UPDATE models SET (${factorizeResult._keysTemplate}) WERE id VALUES(${factorizeResult._questionMarksFields})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode())
handler.Logger.trace(factorizeResult._valuesArray);
//ToTest
handler
.execute(_sql, factorizeResult._valuesArray)
.then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
@@ -645,7 +703,7 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!modelId) return reject("Id is undefined");
if (modelId.length !== 36) return reject("Id invalid");
const _sql = "DELETE FROM `models` WHERE `id` = ?";
const _sql = "DELETE FROM models WHERE id VALUES(?)";
const _values = [modelId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -669,23 +727,29 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
handler
.factorize({
values: data,
actionName: "Inserting new vehicle",
})
.then((factorizedResult) => {
const valuesArray = factorizedResult._valuesArray;
const template = factorizedResult._keysTemplate;
const _sql = `INSERT INTO models (${template + `, id`}) VALUES(${
factorizedResult._questionMarksFields
})`;
const _sql =
"INSERT INTO `vehicles`(`model_id`, `plate_number`, `odometer`, `health_state`, `id`) VALUES (?, ?, ?, ?, ?)";
const _values = [
data.model_id,
data.plate_number,
data.odometer,
data.health_state,
data.id,
];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbStatusResult);
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode()) handler.Logger.trace(valuesArray);
//ToTest
handler.execute(_sql, valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
@@ -705,13 +769,24 @@ const MySqlService = {
handler
.factorize({
values: data,
actionName: `Update vehicle ID::${data.id}`,
actionName: "Update vehicle..",
})
.then((result) => {
const _sql = `UPDATE "vehicles" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
handler.execute(_sql, result._valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
.then((factorizeResult) => {
const _sql = `UPDATE vehicles SET (${factorizeResult._keysTemplate}) WERE id VALUES(${factorizeResult._questionMarksFields})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode())
handler.Logger.trace(factorizeResult._valuesArray);
//ToTest
handler
.execute(_sql, factorizeResult._valuesArray)
.then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
@@ -720,22 +795,22 @@ const MySqlService = {
},
/**
* Retrieves a vehicle from the database by its ID.
* Retrieves an array of vehicles from the database by a given vehicle ID.
*
* @param {MysqlHandler} handler - The instance of the MySQL handler.
* @param {MysqlHandler} handler - The MySQL handler object for executing database queries.
* @param {string} vehicleId - The ID of the vehicle to retrieve.
* @returns {Promise<IDbVehicle>} - A promise that resolves to the retrieved vehicle.
* @throws {Error} - If an error occurs while retrieving the vehicle.
* @returns {Promise<Array<IDbVehicle>>} - A promise that resolves with an array of vehicles matching the ID.
* @throws {Error} - If there is an error executing the query or the ID is invalid.
*/
getById(handler: MysqlHandler, vehicleId: string): Promise<IDbVehicle> {
getById(handler: MysqlHandler, vehicleId: string): Promise<Array<IDbVehicle>> {
return new Promise((resolve, reject) => {
if (!vehicleId) return reject("Id is undefined");
if (vehicleId.length !== 36) return reject("Id invalid");
const _sql = "SELECT * FROM `vehicles` WHERE `id` = ?";
const _sql = "SELECT * FROM vehicles WHERE id VALUES(?)";
const _values = [vehicleId];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbVehicle);
return resolve(result as unknown as Array<IDbVehicle>);
});
} catch (err: unknown) {
reject(err as Error);
@@ -752,7 +827,7 @@ const MySqlService = {
*/
getAll(handler: MysqlHandler): Promise<Array<IDbVehicle>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `models`";
const _sql = "SELECT * FROM models";
try {
handler.query(_sql).then((result) => {
return resolve(result as unknown as Array<IDbVehicle>);
@@ -772,7 +847,7 @@ const MySqlService = {
*/
getAvailable(handler: MysqlHandler): Promise<Array<IDbVehicle>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `vehicles` WERE `isAvailable` = 1";
const _sql = "SELECT * FROM vehicles WERE isAvailable = 1";
try {
handler.query(_sql).then((result) => {
return resolve(result as unknown as Array<IDbVehicle>);
@@ -782,6 +857,22 @@ const MySqlService = {
}
});
},
delete(handler: MysqlHandler, vehicleId: string): Promise<IDbStatusResult> {
return new Promise((resolve, reject) => {
if (!vehicleId) return reject("Id is undefined");
if (vehicleId.length !== 36) return reject("Id invalid");
const _sql = "DELETE FROM vehicle WHERE id VALUES(?)";
const _values = [vehicleId];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
},
Category: {
/**
@@ -796,17 +887,29 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
handler
.factorize({
values: data,
actionName: "Inserting new category",
})
.then((factorizedResult) => {
const valuesArray = factorizedResult._valuesArray;
const template = factorizedResult._keysTemplate;
const _sql = `INSERT INTO categories (${
template + `, id`
}) VALUES(${factorizedResult._questionMarksFields})`;
const _sql =
"INSERT INTO `categories`(`id`,`slug_name`, `display_name`) VALUES (?, ?, ?)";
const _values = [data.id, data.slug_name, data.display_name];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbStatusResult);
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode()) handler.Logger.trace(valuesArray);
//ToTest
handler.execute(_sql, valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
@@ -825,13 +928,24 @@ const MySqlService = {
handler
.factorize({
values: data,
actionName: `Update category ID::${data.id}`,
actionName: "Update brand..",
})
.then((result) => {
const _sql = `UPDATE "categories" SET ${result._keysTemplate} WHERE 'id' = '${data.id}'`;
handler.execute(_sql, result._valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
.then((factorizeResult) => {
const _sql = `UPDATE categories SET (${factorizeResult._keysTemplate}) WERE id VALUES(${factorizeResult._questionMarksFields})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode())
handler.Logger.trace(factorizeResult._valuesArray);
//ToTest
handler
.execute(_sql, factorizeResult._valuesArray)
.then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
@@ -850,7 +964,7 @@ const MySqlService = {
*/
getAll(handler: MysqlHandler): Promise<Array<IDbCategory>> {
return new Promise((resolve, reject) => {
const _sql = "SELECT * FROM `categories`";
const _sql = "SELECT * FROM categories";
try {
resolve(handler.query(_sql) as unknown as Array<IDbCategory>);
} catch (err: unknown) {
@@ -872,7 +986,7 @@ const MySqlService = {
): Promise<IDbCategory> {
return new Promise((resolve, reject) => {
if (!categorySlug) return reject("slug is undefined");
const _sql = "SELECT * FROM `categories` WHERE `slug_name` = ?";
const _sql = "SELECT * FROM categories WHERE slug_name VALUES(?)";
const _values = [categorySlug];
try {
handler.execute(_sql, _values).then((result) => {
@@ -895,7 +1009,7 @@ const MySqlService = {
return new Promise((resolve, reject) => {
if (!categoryId) return reject("slug is undefined");
if (categoryId.length !== 36) return reject("Id invalid");
const _sql = "SELECT * FROM `categories` WHERE `id` = ?";
const _sql = "SELECT * FROM categories WHERE id VALUES(?)";
const _values = [categoryId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -916,11 +1030,14 @@ const MySqlService = {
* @returns {Promise<IDbStatusResult>} - A promise that resolves to the database status result after deletion.
* @throws {Error} - If an error occurs while executing the deletion query.
*/
delete(handler: MysqlHandler, categoryId: string) {
delete(
handler: MysqlHandler,
categoryId: string,
): Promise<IDbStatusResult> {
return new Promise((resolve, reject) => {
if (!categoryId) return reject("Id is undefined");
if (categoryId.length !== 36) return reject("Id invalid");
const _sql = "DELETE FROM `categories` WHERE `id` = ?";
const _sql = "DELETE FROM categories WHERE id VALUES(?)";
const _values = [categoryId];
try {
handler.execute(_sql, _values).then((result) => {
@@ -931,7 +1048,198 @@ const MySqlService = {
}
});
},
//TODO Get models in category
//ToTest
/**
* Retrieves all models from a specific category.
*
* @param {MysqlHandler} handler - The MySQL handler object used for executing the query.
* @param {string} categoryId - The ID of the category.
* @return {Promise<Array<IDbModel>>} - A promise that resolves to an array of database models belonging to the specified category.
*/
getAllModelsFromCategory(
handler: MysqlHandler,
categoryId: string,
): Promise<Array<IDbModel>> {
return new Promise((resolve, reject) => {
const _sql =
"SELECT models.* FROM models INNER JOIN categories ON models.category_id = categories.id WHERE categories.id VALUES(?)";
try {
handler.execute(_sql, [categoryId]).then((result) => {
return resolve(result as unknown as Array<IDbModel>);
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
},
Rent: {
//ToTest
insert(handler: MysqlHandler, data: IDbRent): Promise<IDbStatusResult> {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
handler
.factorize({
values: data,
actionName: "Inserting new rent",
})
.then((factorizedResult) => {
const valuesArray = factorizedResult._valuesArray;
const template = factorizedResult._keysTemplate;
const _sql = `INSERT INTO rents (${template + `, id`}) VALUES(${
factorizedResult._questionMarksFields
})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode()) handler.Logger.trace(valuesArray);
//ToTest
handler.execute(_sql, valuesArray).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
});
},
//ToTest
/**
* Retrieves the assigned vehicles for a given user.
*
* @param {MysqlHandler} handler - The MySQL handler used to execute the database query.
* @param {string} userId - The ID of the user.
* @returns {Promise<Array<IDbVehicle>>} A promise that resolves to an array of assigned vehicles.
* @throws {Error} If an error occurs during the execution of the query.
* @throws {string} If the user ID is undefined or invalid.
*/
getAssignedToUser(
handler: MysqlHandler,
userId: string,
): Promise<Array<IDbVehicle>> {
return new Promise((resolve, reject) => {
if (!userId) return reject("Id is undefined");
if (userId.length !== 36) return reject("Id invalid");
const _sql =
"SELECT vehicle.* FROM rent JOIN vehicles ON rent.vehicle_id = vehicles.id WHERE user_id AND active = 1 VALUES(?)";
const _values = [userId];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as Array<IDbVehicle>);
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
/**
* Retrieves rental information from the database by rental ID.
*
* @param {MysqlHandler} handler - The instance of the MySQL handler used to execute the query.
* @param {string} rentId - The ID of the rental to retrieve.
*
* @returns {Promise<Array<IDbRent>>} A promise that resolves with an array of rental information
* or rejects with an error message if the ID is undefined or invalid.
*/
getById(handler: MysqlHandler, rentId: string): Promise<Array<IDbRent>> {
return new Promise((resolve, reject) => {
if (!rentId) return reject("Id is undefined");
if (rentId.length !== 36) return reject("Id invalid");
const _sql = "SELECT * FROM rents WHERE id VALUES(?)";
const _values = [rentId];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as Array<IDbRent>);
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
//ToTest
/**
* Retrieves all assigned vehicles from the database.
*
* @param {MysqlHandler} handler - The MySQL handler object used for executing the query.
*
* @returns {Promise<Array<IDbVehicle>>} A Promise that resolves with an array of assigned vehicles.
* @throws {Error} If an error occurs during query execution or result conversion.
*/
getAllAssigned(handler: MysqlHandler): Promise<Array<IDbVehicle>> {
return new Promise((resolve, reject) => {
const _sql =
"SELECT vehicle.* FROM rent JOIN vehicles ON rent.vehicle_id = vehicles.id WHERE active = 1";
try {
handler.query(_sql).then((result) => {
return resolve(result as unknown as Array<IDbVehicle>);
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
//ToTest
/**
* Updates a rent record in the database.
*
* @param {MysqlHandler} handler - The database handler object.
* @param {IDbRent} data - The rent object containing the updated data.
* @returns {Promise<IDbStatusResult>} - A promise that resolves to the status result of the update operation.
* @throws {Error} - If an error occurs during the update operation.
*/
update(handler: MysqlHandler, data: IDbRent): Promise<IDbStatusResult> {
return new Promise((resolve, reject) => {
if (!data.id) return reject("Id is undefined");
if (data.id.length !== 36) return reject("Id invalid");
try {
handler
.factorize({
values: data,
actionName: "Update rent..",
})
.then((factorizeResult) => {
const _sql = `UPDATE rents SET (${factorizeResult._keysTemplate}) WERE id = ? VALUES(${factorizeResult._questionMarksFields})`;
try {
if (isDebugMode()) handler.Logger.trace(_sql);
if (isDebugMode())
handler.Logger.trace(factorizeResult._valuesArray);
//ToTest
handler
.execute(_sql, factorizeResult._valuesArray)
.then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
delete(handler: MysqlHandler, rentId: string): Promise<IDbStatusResult> {
return new Promise((resolve, reject) => {
if (!rentId) return reject("Id is undefined");
if (rentId.length !== 36) return reject("Id invalid");
const _sql = "DELETE FROM rents WHERE id VALUES(?)";
const _values = [rentId];
try {
handler.execute(_sql, _values).then((result) => {
return resolve(result as unknown as IDbStatusResult);
});
} catch (err: unknown) {
reject(err as Error);
}
});
},
},
};

View File

@@ -0,0 +1,182 @@
//import { ErrorType, type ISError } from "@interfaces/services/ISError";
import MySqlService from "@services/mysql.service";
import { isDebugMode } from "@utils/debugState";
import { Logger } from "tslog";
import { v4 } from "uuid";
import IDbRent from "@interfaces/database/IDbRent";
const logger = new Logger({
name: "RentService",
});
const DbHandler = new MySqlService.Handler("RentService");
async function createRentService(data: IDbRent): Promise<boolean> {
if (isDebugMode()) logger.debug(`\n\n> Creating a new rent...\n`);
const wantedVehicleId = data.id;
const targetUserId = data.user_id;
if (!targetUserId || !wantedVehicleId) {
logger.error(`Missing targetUserId or targetVehicleId`);
return false;
}
const userIfExist = await MySqlService.User.getById(DbHandler, targetUserId);
if (!userIfExist[0]) {
logger.error(`User does not exist`);
return false;
}
const targetUser = userIfExist[0]
if (!targetUser.id) return false;
const vehicleIfExist = await MySqlService.Vehicle.getById(DbHandler, wantedVehicleId);
if (!vehicleIfExist[0] || !vehicleIfExist[0].id) {
logger.error(`Vehicle does not exist`);
return false;
}
const vehicleId = vehicleIfExist[0].id
if (!vehicleIfExist[0].isAvailable) {
logger.error(`Vehicle is not available`);
return false;
}
try {
const result = await MySqlService.Rent.insert(DbHandler, {
id: v4(),
vehicle_id: vehicleId,
user_id: targetUser.id,
active: data.active,
iat: new Date(Date.parse(`${data.iat}`)),
eat: new Date(Date.parse(`${data.eat}`)),
need_survey: data.need_survey,
km_at_start: Number.parseInt(`${data.km_at_start}`)
});
if (result.affectedRows !== 0) {
logger.info("\n\n> Success !");
return true;
}
return false;
} catch (error) {
logger.error(`\n\n> Error creating category: \n${error}\n`);
return false;
}
}
async function updateRentService(data: IDbRent) {
if (isDebugMode()) logger.debug(`\n\n> Updating a rent...\n`);
const wantedVehicleId = data.id;
const targetUserId = data.user_id;
if (!targetUserId || !wantedVehicleId || !data.id) {
logger.error(`Missing targetUserId or targetVehicleId`);
return false;
}
const rentIfExist = await MySqlService.Rent.getById(DbHandler, data.id);
if (!rentIfExist[0]) {
logger.error(`Rent does not exist`);
return false;
}
const rentId = rentIfExist[0].id;
if (!rentId) {
logger.error(`RentId does not exist`);
return false;
}
const userIfExist = await MySqlService.User.getById(DbHandler, targetUserId);
if (!userIfExist[0]) {
logger.error(`User does not exist`);
return false;
}
const targetUser = userIfExist[0]
if (!targetUser.id) return false;
const vehicleIfExist = await MySqlService.Vehicle.getById(DbHandler, wantedVehicleId);
if (!vehicleIfExist[0] || !vehicleIfExist[0].id) {
logger.error(`Vehicle does not exist`);
return false;
}
const vehicleId = vehicleIfExist[0].id
try {
const result = await MySqlService.Rent.update(DbHandler, {
id: rentId,
vehicle_id: vehicleId,
user_id: targetUser.id,
active: data.active,
iat: new Date(Date.parse(`${data.iat}`)),
eat: new Date(Date.parse(`${data.eat}`)),
need_survey: data.need_survey,
km_at_start: Number.parseInt(`${data.km_at_start}`)
});
if (result.affectedRows !== 0) {
logger.info("\n\n> Success !");
return true;
}
return false;
} catch (error) {
logger.error(`\n\n> Error updating category: \n${error}\n`);
return false;
}
}
async function getAllAssignedRentService() {
const result = await MySqlService.Rent.getAllAssigned(DbHandler);
if (result.length > 0) {
return result;
}
logger.warn(`No assigned rents found`);
return [];
}
async function getRentByIdService(rentId: string) {
if (!rentId || rentId.length !== 36) {
logger.warn(`Id missing or not conform`)
return false;
}
const rent = await MySqlService.Rent.getById(DbHandler, rentId);
if (rent.length > 0) {
return rent[0];
}
logger.warn(`Rent not found`);
return null;
}
async function deleteRentService(rentId: string) {
const rentIfExist = await MySqlService.Rent.getById(DbHandler, rentId);
if (!rentIfExist[0]) {
logger.error(`Rent does not exist`);
return false;
}
const target = rentIfExist[0]
if (!target.id) return false;
try {
const result = await MySqlService.Rent.delete(DbHandler, target.id);
if (result.affectedRows !== 0) {
logger.info("\n\n> Success !");
return true;
}
return false;
} catch (error) {
logger.error(`\n\n> Error deleting rent: \n${error}\n`);
return false
}
}
async function getUserRentService(userId: string) {
if (!userId) {
logger.warn(`Missing userId`);
return false;
}
const rents = await MySqlService.Rent.getAssignedToUser(DbHandler, userId);
if (rents.length > 0) {
return rents;
}
logger.warn(`No rents found for user`);
return false;
}
if (isDebugMode()) logger.debug("\nService loaded.");
const VehicleService = {
create: createRentService,
update: updateRentService,
getAll: getAllAssignedRentService,
getById: getRentByIdService,
delete: deleteRentService,
getUserRent: getUserRentService,
};
export default VehicleService;

View File

@@ -0,0 +1,125 @@
import type { IDbVehicle } from "@interfaces/database/IDbVehicle";
//import { ErrorType, type ISError } from "@interfaces/services/ISError";
import MySqlService from "@services/mysql.service";
import { isDebugMode } from "@utils/debugState";
import { Logger } from "tslog";
import { v4 } from "uuid";
const logger = new Logger({
name: "VehicleService",
});
const DbHandler = new MySqlService.Handler("VehicleService");
async function createVehicleService(data: IDbVehicle) {
if (isDebugMode()) logger.debug(`\n\n> Creating a new vehicle...\n`);
try {
const result = await MySqlService.Vehicle.insert(DbHandler, {
id: v4(),
plate_number: data.plate_number,
model_id: data.model_id,
odometer: data.odometer | 0,
health_state: data.health_state,
});
if (result.affectedRows !== 0) {
logger.info("\n\n> Success !");
return true;
}
return false;
} catch (error) {
logger.error(`\n\n> Error creating category: \n${error}\n`);
return false;
}
}
async function updateVehicleService(data: IDbVehicle) {
if (isDebugMode()) logger.debug(`\n\n> Updating vehicle...\n`);
try {
if (!data.id) {
return false;
}
const result = await MySqlService.Vehicle.update(DbHandler, {
id: data.id,
plate_number: data.plate_number,
model_id: data.model_id,
odometer: data.odometer | 0,
health_state: data.health_state,
});
if (result.affectedRows !== 0) {
logger.info("\n\n> Success !");
return true;
}
return false;
} catch (error) {
logger.error(`\n\n> Error updating vehicle: \n${error}\n`);
return false;
}
}
async function getAllVehiclesService() {
try {
const result = await MySqlService.Vehicle.getAll(DbHandler);
return {
iat: Date.now(),
vehicles: result,
total: result.length,
};
} catch (error) {
logger.error(`\n\n> Error getting vehicles: \n${error}\n`);
return false;
}
}
async function getVehicleByIdService(vehicleId: string) {
try {
const result = await MySqlService.Vehicle.getById(DbHandler, vehicleId);
return {
iat: Date.now(),
vehicle: result,
};
} catch (error) {
logger.error(`\n\n> Error getting vehicle by id: \n${error}\n`);
return false;
}
}
async function getAvailableVehicleService() {
try {
const result = await MySqlService.Vehicle.getAvailable(DbHandler);
return {
iat: Date.now(),
vehicles: result,
total: result.length,
};
} catch (error) {
logger.error(`\n\n> Error getting available vehicles: \n${error}\n`);
return false;
}
}
async function deleteVehicleService(vehicleId: string) {
try {
const result = await MySqlService.Vehicle.delete(DbHandler, vehicleId);
if (result.affectedRows !== 0) {
logger.info("\n\n> Success !");
return true;
}
return false;
} catch (error) {
logger.error(`\n\n> Error deleting vehicle: \n${error}\n`);
return false;
}
}
if (isDebugMode()) logger.debug("\nService loaded.");
const VehicleService = {
create: createVehicleService,
update: updateVehicleService,
getAll: getAllVehiclesService,
getById: getVehicleByIdService,
delete: deleteVehicleService,
getAvailable: getAvailableVehicleService,
};
export default VehicleService;