Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions app/src/core/domain/entities/orders/order-coords-core.entity.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { CustomBusinessException } from '@core/domain/exceptions';
import { CodeError } from '@core/domain/exceptions/error';

/**
* A utility class for validating and processing geographical coordinates related to orders.
* Includes methods to validate latitude, longitude, and calculate distances between geographical points.
*/
export class OrderCoordsCoreEntity {
/**
* Valida as coordenadas de latitude e longitude.
* Lança uma exceção se a latitude ou longitude forem inválidas.
* @param latitude Latitude a ser validada.
* @param longitude Longitude a ser validada.
* @throws CustomBusinessException Exceção lançada se a latitude ou longitude forem inválidas.
* Validates latitude and longitude coordinates.
* Ensures that the latitude is between -90 and 90, and the longitude is between -180 and 180.
*
* @param {string} latitude - The latitude value to validate.
* @param {string} longitude - The longitude value to validate.
* @throws {CustomBusinessException} - Thrown if the latitude or longitude is invalid.
*/
public static validateCoordinates(latitude: string, longitude: string): void {
if (!(this.isValidLatitude(parseFloat(latitude)) && this.isValidLongitude(parseFloat(longitude)))) {
Expand All @@ -16,13 +21,14 @@ export class OrderCoordsCoreEntity {
}

/**
* Calcula a distância entre dois pontos geográficos utilizando a fórmula de Haversine.
* Se a distância entre os pontos for maior que 200 metros, lança uma exceção.
* @param latitude1 Latitude do primeiro ponto.
* @param longitude1 Longitude do primeiro ponto.
* @param latitude2 Latitude do segundo ponto.
* @param longitude2 Longitude do segundo ponto.
* @throws CustomBusinessException Exceção lançada se a distância entre os pontos for maior que 200 metros.
* Validates the distance between two geographical points using the Haversine formula.
* If the calculated distance exceeds 200 meters, an exception is thrown.
*
* @param {string} latitude1 - Latitude of the first point.
* @param {string} longitude1 - Longitude of the first point.
* @param {string} latitude2 - Latitude of the second point.
* @param {string} longitude2 - Longitude of the second point.
* @throws {CustomBusinessException} - Thrown if the distance between the points exceeds 200 meters.
*/
public static validateDistance(latitude1: string, longitude1: string, latitude2: string, longitude2: string): void {
const lat1 = parseFloat(latitude1);
Expand All @@ -45,14 +51,34 @@ export class OrderCoordsCoreEntity {
}
}

private static degreesToRadians(degrees: number) {
/**
* Converts a value from degrees to radians.
*
* @param {number} degrees - The value in degrees to convert.
* @returns {number} - The equivalent value in radians.
*/
private static degreesToRadians(degrees: number): number {
return (degrees * Math.PI) / 180;
}

/**
* Checks if a latitude value is valid.
* A valid latitude is a number between -90 and 90.
*
* @param {number} lat - The latitude value to validate.
* @returns {boolean} - `true` if the latitude is valid, otherwise `false`.
*/
private static isValidLatitude(lat: number): boolean {
return !isNaN(lat) && lat >= -90 && lat <= 90;
}

/**
* Checks if a longitude value is valid.
* A valid longitude is a number between -180 and 180.
*
* @param {number} lon - The longitude value to validate.
* @returns {boolean} - `true` if the longitude is valid, otherwise `false`.
*/
private static isValidLongitude(lon: number): boolean {
return !isNaN(lon) && lon >= -180 && lon <= 180;
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/core/domain/entities/orders/order-core.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { OrderTotalHoursCoreEntity } from '@core/domain/entities/orders/order-total-hours-core.entity';
import { OrderStatus } from '@core/domain/enums';
import { OrderTotalHoursCoreEntity } from '@core/domain/entities/orders';

export class OrderCoreEntity {
id: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { OrderCoreEntity } from '@core/domain/entities/orders/order-core.entity';
import { OrderStatus } from '@core/domain/enums';
import { OrderCoreEntity } from '@core/domain/entities/orders';

export class OrderCreationCoreEntity {
serviceDescription: string;
Expand Down
39 changes: 37 additions & 2 deletions app/src/core/domain/entities/orders/order-end-core.entity.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { OrderCoreEntity } from '@core/domain/entities/orders/order-core.entity';
import { OrderStatus } from '@core/domain/enums';
import { OrderCoreEntity } from '@core/domain/entities/orders';
import { CustomBusinessException, CustomResourceNotFoundException } from '@core/domain/exceptions';
import { CodeError } from '@core/domain/exceptions/error';

/**
* Represents the entity responsible for ending a work order, including attributes and validations related to the end process.
*/
export class OrderEndCoreEntity {
/**
* The end date and time of the order, recorded in ISO 8601 format.
*/
endDatetime: string;

/**
* Optional comment provided at the end of the order.
*/
endComment?: string;

/**
* Latitude recorded at the end of the order.
*/
recordedLatitude: string;

/**
* Longitude recorded at the end of the order.
*/
recordedLongitude: string;

/**
* The status of the order, set to "FINISHED" when the entity is created.
*/
readonly status: OrderStatus;

/**
* Creates a new instance of `OrderEndCoreEntity` to end an order.
*
* @param {string} id - The unique identifier of the order.
* @param {string} employeeId - The unique identifier of the employee responsible for the order.
*/
constructor(
readonly id: string,
readonly employeeId: string,
Expand All @@ -19,6 +47,13 @@ export class OrderEndCoreEntity {
this.status = OrderStatus.FINISHED;
}

/**
* Validates whether an order can be ended based on the provided entity.
*
* @param {OrderCoreEntity} entityCore - The entity representing the order to be validated.
* @throws {CustomResourceNotFoundException} - Thrown if the order entity is not found.
* @throws {CustomBusinessException} - Thrown if the order's status is not "IN_PROGRESS".
*/
public static validateOrderEnd(entityCore: OrderCoreEntity): void {
if (!entityCore) {
throw new CustomResourceNotFoundException(CodeError.ORDER_NOT_FOUND);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { OrderTotalHoursCoreEntity } from '@core/domain/entities/orders/order-total-hours-core.entity';
import { GenericPaginationCoreEntity } from '@core/domain/entities/common/generic-pagination-core.entity';
import { OrderCoreEntity } from '@core/domain/entities/orders/order-core.entity';
import { PaginationCoreEntity } from '@core/domain/entities/common/pagination-core.entity';
import { OrderTotalHoursCoreEntity, OrderCoreEntity } from '@core/domain/entities/orders';
import { GenericPaginationCoreEntity, PaginationCoreEntity } from '@core/domain/entities/common';

export class OrderPaginationCoreEntity extends GenericPaginationCoreEntity<OrderCoreEntity> {
readonly totalHours: OrderTotalHoursCoreEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { OrderStatus } from '@core/domain/enums';

export class OrderQuantityStatusEntity {
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PaginationCoreEntity } from '@core/domain/entities/common/pagination-core.entity';
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { PaginationCoreEntity } from '@core/domain/entities/common';
import { OrderStatus } from '@core/domain/enums';

export class OrderQueryCoreEntity {
status?: OrderStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { PeriodGroup } from '@core/domain/enums/period-group.enum';
import { OrderStatus, PeriodGroup } from '@core/domain/enums';

export class OrderQueryQuantityStatusCoreEntity {
status?: OrderStatus;
Expand Down
35 changes: 33 additions & 2 deletions app/src/core/domain/entities/orders/order-start-core.entity.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
import { OrderStatus } from '@core/domain/enums/order-status.enum';
import { OrderCoreEntity } from '@core/domain/entities/orders/order-core.entity';
import { OrderStatus } from '@core/domain/enums';
import { OrderCoreEntity } from '@core/domain/entities/orders';
import { CustomBusinessException, CustomResourceNotFoundException } from '@core/domain/exceptions';
import { CodeError } from '@core/domain/exceptions/error';

/**
* Represents the entity responsible for starting a work order, including attributes and validations related to the start process.
*/
export class OrderStartCoreEntity {
/**
* The start date and time of the order, recorded in ISO 8601 format.
*/
startDatetime: string;

/**
* Latitude recorded at the start of the order.
*/
recordedLatitude: string;

/**
* Longitude recorded at the start of the order.
*/
recordedLongitude: string;

/**
* The status of the order, set to "IN_PROGRESS" when the entity is created.
*/
readonly status: OrderStatus;

/**
* Creates a new instance of `OrderStartCoreEntity` to start an order.
*
* @param {string} id - The unique identifier of the order.
* @param {string} employeeId - The unique identifier of the employee responsible for the order.
*/
constructor(
readonly id: string,
readonly employeeId: string,
Expand All @@ -18,6 +42,13 @@ export class OrderStartCoreEntity {
this.status = OrderStatus.IN_PROGRESS;
}

/**
* Validates whether an order can be started based on the provided entity.
*
* @param {OrderCoreEntity} entityCore - The entity representing the order to be validated.
* @throws {CustomResourceNotFoundException} - Thrown if the order entity is not found.
* @throws {CustomBusinessException} - Thrown if the order's status is not "OPEN".
*/
public static validateOrderStart(entityCore: OrderCoreEntity): void {
if (!entityCore) {
throw new CustomResourceNotFoundException(CodeError.ORDER_NOT_FOUND);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,46 @@
import { OrderCoreEntity } from '@core/domain/entities/orders/order-core.entity';
import { OrderCoreEntity } from '@core/domain/entities/orders';

/**
* Represents an entity that calculates and stores the total time difference between two dates
* or the total accumulated time from a list of OrderCoreEntity instances in hours, minutes, and seconds.
* Provides methods to calculate time differences, as well as aggregate time from multiple order entities.
*/
export class OrderTotalHoursCoreEntity {
/**
* The total number of hours in the time difference or accumulated time.
* Initialized to 0 by default.
*/
hours: number;

/**
* The total number of minutes in the time difference or accumulated time.
* Initialized to 0 by default.
*/
minutes: number;

/**
* The total number of seconds in the time difference or accumulated time.
* Initialized to 0 by default.
*/
seconds: number;

/**
* Initializes the OrderTotalHoursCoreEntity instance with default values (0 hours, 0 minutes, and 0 seconds).
*/
constructor() {
this.hours = 0;
this.minutes = 0;
this.seconds = 0;
}

/**
* Calcula a diferença de tempo entre duas datas e retorna uma nova instância de OrderTotalHoursCoreEntity
* contendo a diferença em horas, minutos e segundos.
* Calculates the time difference between two dates and returns a new instance of OrderTotalHoursCoreEntity
* containing the difference in hours, minutes, and seconds.
*
* @param {string} startDatetime - A data/hora de início no formato ISO 8601.
* @param {string} endDatetime - A data/hora de término no formato ISO 8601.
* @returns {OrderTotalHoursCoreEntity} - Uma instância contendo a diferença de tempo em horas, minutos e segundos.
* @param {string} startDatetime - The start date/time in ISO 8601 format (e.g., '2024-12-29T08:00:00Z').
* @param {string} endDatetime - The end date/time in ISO 8601 format (e.g., '2024-12-29T12:45:30Z').
* @returns {OrderTotalHoursCoreEntity} - An instance containing the time difference in hours, minutes, and seconds.
* @throws {Error} - Throws an error if the date format is invalid.
*/
public static calculate(startDatetime: string, endDatetime: string): OrderTotalHoursCoreEntity {
const entity = new OrderTotalHoursCoreEntity();
Expand All @@ -36,10 +59,11 @@ export class OrderTotalHoursCoreEntity {
}

/**
* Calcula o total de horas, minutos e segundos a partir de uma lista de entidades OrderCoreEntity.
* Calculates the total hours, minutes, and seconds from a list of OrderCoreEntity instances.
* It aggregates the total time across all items in the list.
*
* @param {OrderCoreEntity[]} items - Uma lista de instâncias de OrderCoreEntity.
* @returns {OrderTotalHoursCoreEntity} - Uma instância contendo o tempo total acumulado em horas, minutos e segundos.
* @param {OrderCoreEntity[]} items - A list of OrderCoreEntity instances, each containing a 'totalHours' field.
* @returns {OrderTotalHoursCoreEntity} - An instance containing the total accumulated time in hours, minutes, and seconds.
*/
public static calculateTotal(items: OrderCoreEntity[]): OrderTotalHoursCoreEntity {
if (!items || items.length === 0) {
Expand All @@ -52,28 +76,38 @@ export class OrderTotalHoursCoreEntity {
}

/**
* Calcula a diferença em segundos entre duas datas.
* Calculates the difference in seconds between two dates.
* This is a helper method used by `calculate` to determine the total time difference.
*
* @param {Date} start - Data de início.
* @param {Date} end - Data de término.
* @returns {number} - Diferença em segundos.
* @param {Date} start - The start date.
* @param {Date} end - The end date.
* @returns {number} - The difference in seconds.
*/
private static calculateSecondsDiff(start: Date, end: Date): number {
return Math.floor((end.getTime() - start.getTime()) / 1000);
}

/**
* Converte segundos em uma instância de OrderTotalHoursCoreEntity contendo horas, minutos e segundos.
* Converts a total number of seconds into an instance of OrderTotalHoursCoreEntity containing hours, minutes, and seconds.
*
* @param {number} totalSeconds - O total de segundos a ser convertido.
* @returns {OrderTotalHoursCoreEntity} - Uma instância contendo horas, minutos e segundos.
* @param {number} totalSeconds - The total number of seconds to convert.
* @returns {OrderTotalHoursCoreEntity} - An instance containing the converted hours, minutes, and seconds.
* @throws {Error} - Throws an error if the totalSeconds is negative or not a valid number.
*/
private static secondsToHoursMinutesSeconds(totalSeconds: number): OrderTotalHoursCoreEntity {
if (isNaN(totalSeconds) || totalSeconds < 0) {
throw new Error('Invalid totalSeconds value. It must be a non-negative number.');
}

const hours = Math.floor(totalSeconds / 3600); // Calculate full hours
const remainingSecondsAfterHours = totalSeconds % 3600; // Remaining seconds after hours
const minutes = Math.floor(remainingSecondsAfterHours / 60); // Calculate full minutes
const seconds = remainingSecondsAfterHours % 60; // Remaining seconds after minutes

const entity = new OrderTotalHoursCoreEntity();
entity.hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
entity.minutes = Math.floor(totalSeconds / 60);
entity.seconds = totalSeconds % 60;
entity.hours = hours;
entity.minutes = minutes;
entity.seconds = seconds;
return entity;
}
}
Loading