Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
5da6304
Update websocket to only notify when the order is updated
andres15alvarez May 10, 2025
3e3e629
Create socket to notify when the delivery is updated
andres15alvarez May 10, 2025
08952ae
add sales prediction model
iabrahaamxs May 11, 2025
89b4004
add days without orders to the model
iabrahaamxs May 11, 2025
282791f
add DTOs
iabrahaamxs May 11, 2025
0721f38
refactor sales service
iabrahaamxs May 11, 2025
42a03e4
restrict endpoint access to ADMIN and BRANCH_ADMIN roles
iabrahaamxs May 11, 2025
bb28006
add swagger documentation
iabrahaamxs May 11, 2025
d602559
fix query optional
iabrahaamxs May 11, 2025
86ff849
Add promo type to product dto
andres15alvarez May 12, 2025
5e5b3a9
Add left join with promo
andres15alvarez May 12, 2025
9d3b88a
add migration to enable PostGIS extension
iabrahaamxs May 12, 2025
8e9a4d1
assign nearest branch on delivery using PostGIS
iabrahaamxs May 12, 2025
86450b1
fix NotFoundException message
iabrahaamxs May 12, 2025
2b8a497
validate user before confirming order payment
iabrahaamxs May 12, 2025
81d1f8c
add swagger documentation
iabrahaamxs May 12, 2025
e3ba38f
remove console.log from payment confirmation service
iabrahaamxs May 12, 2025
cf6138a
add SSE
Dazzlin00 May 13, 2025
2febeab
change findOne to findOneWithUser
iabrahaamxs May 13, 2025
d1a60be
add price
Dazzlin00 May 13, 2025
8c6d795
add active principle
Dazzlin00 May 13, 2025
2677e83
Revert "add price"
Dazzlin00 May 13, 2025
86ac04f
Feature/API-69/validate-payment-confirmation
andres15alvarez May 13, 2025
59c68de
Merge branch 'dev' into features/API-65/find-nearest-branch
andres15alvarez May 13, 2025
2cb859e
Merge branch 'dev' into API-60/Create-active-principle-entity
andres15alvarez May 13, 2025
16396ee
features/API-65/find-nearest-branch
andres15alvarez May 13, 2025
b055f47
API-63/Server-Send-Event-for-Notifications
andres15alvarez May 13, 2025
10c2668
Api 60/create-active-principle-entity
andres15alvarez May 13, 2025
e3f8540
feature/add-promo-product-presentation
andres15alvarez May 13, 2025
4578ec2
add flags to user entity
iabrahaamxs May 13, 2025
254e446
price added and modified subtotal
Dazzlin00 May 14, 2025
505b0a9
fix
Dazzlin00 May 14, 2025
bb2b59a
feature/API-64/notify-order-update-only-by-socket
andres15alvarez May 14, 2025
de8258c
Merge branch 'dev' into features/API-66/user-entity-adjustments
iabrahaamxs May 14, 2025
1a16db4
Remove order by product priority
andres15alvarez May 14, 2025
1ba3594
Fix error handling and set wsId blank
andres15alvarez May 14, 2025
d0f2e21
fix
Dazzlin00 May 14, 2025
da8a52d
Merge branch 'dev' into features/API-71/Adjustment-of-accounts-in-sal…
Dazzlin00 May 14, 2025
e6f5cf9
imports AuthModule, UserModule and BranchModule
iabrahaamxs May 14, 2025
3dd7df5
add send email to the created account
iabrahaamxs May 14, 2025
f5de2c2
Merge branch 'dev' into features/API-66/user-entity-adjustments
iabrahaamxs May 14, 2025
64065a0
fix column isGenericPassword default false
iabrahaamxs May 14, 2025
c28965a
Merge branch 'dev' into API-68/Order-creation-calculation-settings
andres15alvarez May 14, 2025
89e13fe
features/Api-68/order-creation-calculation-settings
andres15alvarez May 14, 2025
86b7259
Features/api-71/adjustment-of-accounts-in-sales-report
andres15alvarez May 14, 2025
5ebca33
Set default value to 0
andres15alvarez May 14, 2025
8a26c90
add isGenericPassword to false when changing password
iabrahaamxs May 14, 2025
5daae99
Merge branch 'dev' into features/API-66/user-entity-adjustments
iabrahaamxs May 14, 2025
282ffb2
features/API-66/user-entity-adjustments
andres15alvarez May 15, 2025
76a387c
Create endpoint for bulk update user role and is validated column
andres15alvarez May 16, 2025
ce3bc37
Create bulk update for order status
andres15alvarez May 16, 2025
ce705c9
Create bulk update for product presentation visibility
andres15alvarez May 16, 2025
f41ce43
Create bulk delete and bulk update for promos
andres15alvarez May 16, 2025
3f99b0b
Create bulk delete and bulk update for coupons
andres15alvarez May 16, 2025
b9912be
add paymentConfirmation to orderDetail entity
iabrahaamxs May 16, 2025
4944b7b
Fix inner dto for plain properties
andres15alvarez May 17, 2025
b56ce89
feature/API-54/create-bulk-actions
andres15alvarez May 17, 2025
4f7f768
Refactor and adjust permission of user by role
andres15alvarez May 17, 2025
629b646
feature/API-70/adjust-role-guards-permission
andres15alvarez May 17, 2025
844a456
Fix missing order delivery service un order module
andres15alvarez May 17, 2025
e4d38e1
Fix merge conflict
andres15alvarez May 17, 2025
ca4aa12
Fix epoch times and add branch id to filter
andres15alvarez May 17, 2025
391694a
Get user branch if the user is branch admin
andres15alvarez May 17, 2025
9c0c889
features/API-61/sales-prediction-model
andres15alvarez May 17, 2025
3ea97d0
add paymentConfirmation to ResponseOrderDetailDTO
iabrahaamxs May 18, 2025
fcd0254
Merge branch 'dev' into feature/API-72/add-payment-confirmation-in-or…
iabrahaamxs May 18, 2025
218d067
add price to ResponseOrderDetailDTO
iabrahaamxs May 18, 2025
c907c27
feature/API-72/add-payment-confirmation-in-order-detail
andres15alvarez May 18, 2025
f8b2fa3
Add uuid validation
andres15alvarez May 18, 2025
0d0c18e
Merge branch 'dev' of andres15alvarez:PharmaTechVe/api into dev
andres15alvarez May 18, 2025
67f5ad6
Add default event
andres15alvarez May 18, 2025
40a8873
Create dto to update coordinates of a delivery
andres15alvarez May 19, 2025
1dc7560
Create event to update coordinates
andres15alvarez May 19, 2025
3ba90ca
features/API-62/update-coordinates-with-socket
andres15alvarez May 19, 2025
0990add
Delete useless console log
andres15alvarez May 19, 2025
88c6952
Update response inventory dto
andres15alvarez May 19, 2025
3ca2456
Replace query for querybuilder
andres15alvarez May 19, 2025
7b463e2
Use plaint to instance to return inventories data
andres15alvarez May 19, 2025
861f71d
Expose stockQuantity property
andres15alvarez May 19, 2025
cba0f50
Fix city dto to expose all the properties
andres15alvarez May 19, 2025
8f77555
Add branch dto and missing mobile customer property to user dto
andres15alvarez May 19, 2025
fec15ac
Use same filter to count
andres15alvarez May 19, 2025
f3f0619
csv upload is updated
Dazzlin00 May 21, 2025
95285ae
features/api-74/update-csv-upload
andres15alvarez May 21, 2025
58a1dc1
Update relation between order and payment confirmation
andres15alvarez May 27, 2025
74f0a87
Add relation in query of order detail
andres15alvarez May 27, 2025
032db75
Add discount to order detail
andres15alvarez May 27, 2025
3d34ae4
Add discount and subtotal with discount
andres15alvarez May 28, 2025
dc99d97
Add discount field to dto
andres15alvarez May 28, 2025
bf88b3d
hotfix/payment-confirmation-relation
andres15alvarez May 28, 2025
a5c61e5
Use query builder to properly filter by search query
andres15alvarez May 29, 2025
5311cb0
Create lot endpoint to list all
andres15alvarez May 29, 2025
ae72e3f
Update find all to use query builder version
andres15alvarez May 29, 2025
1a590ef
Import new lot service and controller
andres15alvarez May 29, 2025
bd5018a
Validate if the promo is expired
andres15alvarez May 29, 2025
abd0f24
Fix subtotal in sales report
andres15alvarez May 29, 2025
e444029
Fix filter lot by branch id
andres15alvarez May 29, 2025
e967481
Create inventory movement for manual update of stock
andres15alvarez May 29, 2025
31630a3
Generate random password
andres15alvarez May 29, 2025
9ffd2ec
Seed default admin user
andres15alvarez May 29, 2025
782b62b
Upgrade version to 1.0.0
andres15alvarez May 29, 2025
ae4573e
Merge branch 'main' into dev
andres15alvarez May 29, 2025
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
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ PHARMATECH_SENDER="Andy de Pharmatech <notifications@pharmatech.site>"
# Resemd
RESEND_API_KEY=

ADMIN_PASSWORD=
ADMIN_PASSWORD=
ADMIN_EMAIL=
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "api",
"version": "0.5.0",
"version": "1.0.0",
"description": "",
"author": "",
"private": true,
Expand All @@ -19,6 +19,7 @@
"test:watch": "vitest run --watch --config vitest.config.ts",
"test:coverage": "vitest run --coverage.enabled --coverage.all --config vitest.config.ts",
"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js",
"migration:create": "npm run typeorm -- migration:create",
"migration:generate": "npm run typeorm -- migration:generate -d ./src/database/typeorm.config.ts",
"migration:run": "npm run typeorm -- migration:run -d ./src/database/typeorm.config.ts",
"migration:revert": "npm run typeorm -- migration:revert -d ./src/database/typeorm.config.ts",
Expand Down
66 changes: 66 additions & 0 deletions src/active-principle/active-principle.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {
Controller,
Get,
Query,
UseGuards,
UseInterceptors,
HttpStatus,
} from '@nestjs/common';
import { ActivePrincipleService } from './active-principle.service';
import { RolesGuard } from 'src/auth/roles.guard';
import { AuthGuard } from 'src/auth/auth.guard';
import { Roles } from 'src/auth/roles.decorador';
import { UserRole } from 'src/user/entities/user.entity';
import { PaginationInterceptor } from 'src/utils/pagination.interceptor';
import { PaginationQueryDTO } from 'src/utils/dto/pagination.dto';
import { Pagination } from 'src/utils/pagination.decorator';
import {
ApiOperation,
ApiQuery,
ApiResponse,
getSchemaPath,
} from '@nestjs/swagger';
import { ResponseActivePrincipleDTO } from './dto/active-principle.dto';
import { PaginationDTO } from 'src/utils/dto/pagination.dto';

@Controller('active-principle')
export class ActivePrincipleController {
constructor(
private readonly activePrincipleService: ActivePrincipleService,
) {}

@UseGuards(AuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
@Get()
@UseInterceptors(PaginationInterceptor)
@ApiOperation({ summary: 'List active principles' })
@ApiQuery({ name: 'q', required: false, description: 'Search term' })
@ApiQuery({ name: 'page', required: false, type: Number, example: 1 })
@ApiQuery({ name: 'limit', required: false, type: Number, example: 10 })
@ApiResponse({
description: 'Successful retrieval',
status: HttpStatus.OK,
schema: {
allOf: [
{ $ref: getSchemaPath(PaginationDTO) },
{
properties: {
results: {
type: 'array',
items: { $ref: getSchemaPath(ResponseActivePrincipleDTO) },
},
},
},
],
},
})
async findAll(
@Pagination() pagination: PaginationQueryDTO,
@Query('q') q?: string,
): Promise<{ data: ResponseActivePrincipleDTO[]; total: number }> {
const { page, limit } = pagination;
const data = await this.activePrincipleService.findAll(page, limit, q);
const total = await this.activePrincipleService.countActivePrinciples(q);
return { data, total };
}
}
13 changes: 13 additions & 0 deletions src/active-principle/active-principle.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ActivePrinciple } from './entities/active-principle.entity';
import { ActivePrincipleController } from './active-principle.controller';
import { ActivePrincipleService } from './active-principle.service';
import { AuthModule } from 'src/auth/auth.module';

@Module({
imports: [TypeOrmModule.forFeature([ActivePrinciple]), AuthModule],
controllers: [ActivePrincipleController],
providers: [ActivePrincipleService],
})
export class ActivePrincipleModule {}
30 changes: 30 additions & 0 deletions src/active-principle/active-principle.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, ILike } from 'typeorm';
import { ActivePrinciple } from './entities/active-principle.entity';

@Injectable()
export class ActivePrincipleService {
constructor(
@InjectRepository(ActivePrinciple)
private readonly activePrincipleRepository: Repository<ActivePrinciple>,
) {}

async findAll(
page: number,
limit: number,
q?: string,
): Promise<ActivePrinciple[]> {
const where = q ? { name: ILike(`%${q}%`) } : {};
return await this.activePrincipleRepository.find({
where,
skip: (page - 1) * limit,
take: limit,
});
}

async countActivePrinciples(q?: string): Promise<number> {
const where = q ? { name: ILike(`%${q}%`) } : {};
return await this.activePrincipleRepository.count({ where });
}
}
10 changes: 10 additions & 0 deletions src/active-principle/dto/active-principle.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsString } from 'class-validator';

export class ResponseActivePrincipleDTO {
@Expose()
@ApiProperty({ example: 'Acetaminophen' })
@IsString()
name: string;
}
8 changes: 8 additions & 0 deletions src/active-principle/entities/active-principle.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BaseModel } from 'src/utils/entity';
import { Column, Entity } from 'typeorm';

@Entity()
export class ActivePrinciple extends BaseModel {
@Column({ type: 'varchar', length: 255 })
name: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddActivePrincipleMigration1747107651171
implements MigrationInterface
{
name = 'AddActivePrincipleMigration1747107651171';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "active_principle" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), "deleted_at" TIMESTAMP, "name" character varying(255) NOT NULL, CONSTRAINT "PK_872c6d07a950a9ec64da5714eb6" PRIMARY KEY ("id"))`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "active_principle"`);
}
}
4 changes: 4 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { CartModule } from './cart/cart.module';
import { RecommendationModule } from './recommendation/recommendation.module';
import { ReportsModule } from './reports/reports.module';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { SalesModule } from './sales/sales.module';
import { ActivePrincipleModule } from './active-principle/active-principle.module';

@Module({
imports: [
Expand Down Expand Up @@ -67,6 +69,8 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
CartModule,
RecommendationModule,
ReportsModule,
SalesModule,
ActivePrincipleModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
2 changes: 2 additions & 0 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
import { UserService } from 'src/user/user.service';
import { EmailModule } from 'src/email/email.module';
import { AuthGuard } from './auth.guard';
import { BranchModule } from 'src/branch/branch.module';

@Module({
imports: [
forwardRef(() => UserModule),
forwardRef(() => BranchModule),
ConfigModule,
JwtModule.registerAsync({
useFactory: (configService: ConfigService) => ({
Expand Down
5 changes: 4 additions & 1 deletion src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ export class AuthService {

async updatePassword(user: User, newPasswod: string): Promise<boolean> {
const password = await this.encryptPassword(newPasswod);
await this.userService.update(user, { password });
await this.userService.update(user, {
password,
isGenericPassword: false,
});
return true;
}

Expand Down
5 changes: 3 additions & 2 deletions src/branch/branch.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Module } from '@nestjs/common';
import { forwardRef, Module } from '@nestjs/common';
import { BranchService } from './branch.service';
import { BranchController } from './branch.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
Expand All @@ -14,9 +14,10 @@ import { State } from 'src/state/entities/state.entity';
@Module({
imports: [
TypeOrmModule.forFeature([Branch, City, State, Country]),
AuthModule,
forwardRef(() => AuthModule),
],
controllers: [BranchController],
providers: [BranchService, CityService, StateService, CountryService],
exports: [BranchService],
})
export class BranchModule {}
16 changes: 16 additions & 0 deletions src/branch/branch.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,20 @@ export class BranchService {
});
return deleted.affected === 1;
}

async findNearestBranch(lat: number, lng: number): Promise<Branch> {
const branch = await this.branchRepository
.createQueryBuilder('branch')
.orderBy(
`ST_DistanceSphere(ST_MakePoint(branch.longitude, branch.latitude), ST_MakePoint(:lng, :lat))`,
)
.setParameters({ lat, lng })
.getOne();

if (!branch) {
throw new NotFoundException('No closer branch found');
}

return branch;
}
}
15 changes: 12 additions & 3 deletions src/branch/dto/branch.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsNotEmpty, IsNumber, IsString, Max, Min } from 'class-validator';
import { Expose, Type } from 'class-transformer';
import {
IsNotEmpty,
IsNumber,
IsString,
IsUUID,
Max,
Min,
} from 'class-validator';
import { CityDTO } from 'src/city/dto/city.dto';
import { BaseDTO } from 'src/utils/dto/base.dto';

Expand Down Expand Up @@ -36,6 +43,7 @@ class BranchDTO {

export class CreateBranchDTO extends BranchDTO {
@IsNotEmpty()
@IsUUID()
@ApiProperty({ description: 'The city id of the branch' })
cityId: string;
}
Expand All @@ -44,6 +52,7 @@ export class UpdateBranchDTO extends PartialType(CreateBranchDTO) {}

export class ResponseBranchDTO extends IntersectionType(BranchDTO, BaseDTO) {
@Expose()
@ApiProperty({ description: 'The city of the branch' })
@ApiProperty({ description: 'The city of the branch', type: CityDTO })
@Type(() => CityDTO)
city: CityDTO;
}
1 change: 0 additions & 1 deletion src/database/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
password: configService.get('POSTGRES_PASSWORD'),
database: configService.get('POSTGRES_NAME'),
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
subscribers: [__dirname + '/../**/*.subscriber{.ts,.js}'],
synchronize: false,
ssl: configService.get<boolean>('POSTGRES_SSL', false),
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class EnablePostgisExtensionMigration1747014730112
implements MigrationInterface
{
name = 'EnablePostgisExtensionMigration1747014730112';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS postgis`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP EXTENSION IF EXISTS postgis`);
}
}
Loading