Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60f59287c6 | ||
|
|
16881b9c0a | ||
|
|
7a783994fd | ||
|
|
2e3a506c81 | ||
|
|
4c92d28496 | ||
|
|
8050870b0b | ||
|
|
570037c6d9 | ||
|
|
1a08f98548 | ||
|
|
7d27c9a0ff | ||
|
|
59c51fb817 | ||
|
|
df5fc86821 | ||
|
|
82ac15af6f | ||
|
|
da3051fe5e | ||
|
|
67173f3a6c | ||
|
|
b27fee6ece | ||
|
|
c7d084fa91 | ||
| b17a94342b | |||
|
|
9535f75301 | ||
|
|
9a19d9660e | ||
|
|
7ea099d611 | ||
|
|
cecfa1030a | ||
|
|
8e94cdd97a | ||
|
|
a1fd355171 | ||
|
|
439c986583 | ||
|
|
19115d50fe | ||
|
|
3c27de26b9 | ||
|
|
c08b8bb19f | ||
|
|
2a45c0b522 | ||
|
|
72ffa77ba6 | ||
|
|
7b8e595a92 | ||
|
|
5fd62322ad | ||
|
|
36529727a0 | ||
|
|
c1f03cdf43 | ||
|
|
3616b57a73 | ||
|
|
a2c2ed2a68 | ||
|
|
45d57cee8d | ||
|
|
0e59a652b0 | ||
|
|
75a537aab4 |
4
api.http
4
api.http
@ -1,5 +1,9 @@
|
|||||||
GET http://192.168.1.96:3006
|
GET http://192.168.1.96:3006
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
GET http://localhost:3000/oracle/GetRegions/1
|
||||||
###
|
###
|
||||||
|
|
||||||
GET http://localhost:3000/oracle/SearchHolder/1
|
GET http://localhost:3000/oracle/SearchHolder/1
|
||||||
|
|||||||
15
package-lock.json
generated
15
package-lock.json
generated
@ -35,7 +35,7 @@
|
|||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"pdf-merger-js": "^5.1.2",
|
"pdf-merger-js": "^5.1.2",
|
||||||
"pdfkit": "^0.17.1",
|
"pdfkit": "^0.17.1",
|
||||||
"pg": "^8.13.3",
|
"pg": "^8.16.3",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
@ -56,6 +56,7 @@
|
|||||||
"@types/mssql": "^9.1.7",
|
"@types/mssql": "^9.1.7",
|
||||||
"@types/node": "^22.10.7",
|
"@types/node": "^22.10.7",
|
||||||
"@types/oracledb": "^6.5.4",
|
"@types/oracledb": "^6.5.4",
|
||||||
|
"@types/pg": "^8.15.5",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"eslint": "^9.31.0",
|
"eslint": "^9.31.0",
|
||||||
@ -3873,6 +3874,18 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/pg": {
|
||||||
|
"version": "8.15.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.5.tgz",
|
||||||
|
"integrity": "sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"pg-protocol": "*",
|
||||||
|
"pg-types": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/qs": {
|
"node_modules/@types/qs": {
|
||||||
"version": "6.14.0",
|
"version": "6.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"pdf-merger-js": "^5.1.2",
|
"pdf-merger-js": "^5.1.2",
|
||||||
"pdfkit": "^0.17.1",
|
"pdfkit": "^0.17.1",
|
||||||
"pg": "^8.13.3",
|
"pg": "^8.16.3",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
@ -67,6 +67,7 @@
|
|||||||
"@types/mssql": "^9.1.7",
|
"@types/mssql": "^9.1.7",
|
||||||
"@types/node": "^22.10.7",
|
"@types/node": "^22.10.7",
|
||||||
"@types/oracledb": "^6.5.4",
|
"@types/oracledb": "^6.5.4",
|
||||||
|
"@types/pg": "^8.15.5",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"eslint": "^9.31.0",
|
"eslint": "^9.31.0",
|
||||||
|
|||||||
@ -6,11 +6,13 @@ import { OriginCheckMiddleware } from './middleware/OriginCheck.middleware';
|
|||||||
import { ReqBodyKeysToUppercaseMiddleware } from './middleware/reqBodyKeysToUppercase.middleware';
|
import { ReqBodyKeysToUppercaseMiddleware } from './middleware/reqBodyKeysToUppercase.middleware';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
import { MailModule } from './mail/mail.module';
|
import { MailModule } from './mail/mail.module';
|
||||||
|
import { PaypalModule } from './paypal/paypal.module';
|
||||||
|
import { PgModule } from './pg/pg.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({ isGlobal: true }),
|
ConfigModule.forRoot({ isGlobal: true }),
|
||||||
AuthModule, DbModule, OracleModule, MailModule
|
AuthModule, PgModule, DbModule, OracleModule, MailModule, PaypalModule
|
||||||
],
|
],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [],
|
providers: [],
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
import { Body, Controller, Get, HttpCode, Post, Put, Req, Res, UseGuards, UseInterceptors } from '@nestjs/common';
|
import { Body, Controller, Get, HttpCode, Post, Put, Req, Res, UseGuards, UseInterceptors } from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { AuthLoginDTO, SendMailDTO } from './auth.dto';
|
import { AuthLoginDTO, AuthLoginOnlyDTO, SendMailDTO } from './auth.dto';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { LogoutInterceptor } from 'src/interceptors/logout.interceptor';
|
import { LogoutInterceptor } from 'src/interceptors/logout.interceptor';
|
||||||
import { RegisterGuard } from 'src/guards/register.guard';
|
import { RegisterGuard } from 'src/guards/register.guard';
|
||||||
import { RolesGuard } from 'src/guards/roles.guard';
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
import { Roles } from 'src/decorators/roles.decorator';
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { extractSubdomain } from 'src/utils/helper';
|
||||||
|
|
||||||
@ApiTags('Auth')
|
@ApiTags('Auth')
|
||||||
@Controller()
|
@Controller()
|
||||||
@ -16,11 +17,11 @@ export class AuthController {
|
|||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@Post('login')
|
@Post('1/login')
|
||||||
@HttpCode(200)
|
@HttpCode(200)
|
||||||
async loginClient(@Body() body: AuthLoginDTO, @Res({ passthrough: true }) res: Response, @Req() req: Request) {
|
async loginClienta(@Body() body: AuthLoginOnlyDTO, @Res({ passthrough: true }) res: Response, @Req() req: Request) {
|
||||||
|
|
||||||
let k: any = await this.authService.loginUser(body.P_EMAILADDR.toLowerCase(), body.P_PASSWORD, req);
|
let k: any = await this.authService.loginUser(body.P_EMAILADDR.toLowerCase(), body.P_PASSWORD, body.P_APPLICATIONNAME, req, 1);
|
||||||
|
|
||||||
if (k.access_token) {
|
if (k.access_token) {
|
||||||
res.cookie('access_token', k.access_token, {
|
res.cookie('access_token', k.access_token, {
|
||||||
@ -41,16 +42,84 @@ export class AuthController {
|
|||||||
return { statusCode: 200, message: "Logged-In Successfully", email: k.email }
|
return { statusCode: 200, message: "Logged-In Successfully", email: k.email }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('2/login')
|
||||||
|
@HttpCode(200)
|
||||||
|
async loginClientb(@Body() body: AuthLoginOnlyDTO, @Res({ passthrough: true }) res: Response, @Req() req: Request) {
|
||||||
|
|
||||||
|
let k: any = await this.authService.loginUser(body.P_EMAILADDR.toLowerCase(), body.P_PASSWORD, body.P_APPLICATIONNAME, req, 2);
|
||||||
|
|
||||||
|
if (k.access_token) {
|
||||||
|
res.cookie('access_token', k.access_token, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k.refresh_token) {
|
||||||
|
res.cookie('refresh_token', k.refresh_token, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// auth domain below
|
||||||
|
|
||||||
|
// const hostname = req.hostname;
|
||||||
|
|
||||||
|
// const isLocalhost = hostname === 'localhost' || hostname === '127.0.0.1';
|
||||||
|
|
||||||
|
// const isDevEnv = isLocalhost || hostname.startsWith('localhost') || hostname.startsWith('127.0.0.1');
|
||||||
|
|
||||||
|
// const cookieOptions: any = {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// sameSite: 'none'
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if (!isDevEnv) {
|
||||||
|
// cookieOptions.domain = hostname;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// res.cookie('access_token', k.access_token, {
|
||||||
|
// ...cookieOptions
|
||||||
|
// });
|
||||||
|
|
||||||
|
// res.cookie('refresh_token', k.refresh_token, {
|
||||||
|
// ...cookieOptions
|
||||||
|
// });
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Logged-In Successfully", email: k.email }
|
||||||
|
}
|
||||||
|
|
||||||
// @UseGuards(RegisterGuard)
|
// @UseGuards(RegisterGuard)
|
||||||
@Post('register')
|
@Post('1/register')
|
||||||
async register(@Body() body: AuthLoginDTO) {
|
async registera(@Body() body: AuthLoginDTO) {
|
||||||
return this.authService.registerUser(body);
|
return this.authService.registerUser(body, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('2/register')
|
||||||
|
async registerb(@Body() body: AuthLoginDTO) {
|
||||||
|
return this.authService.registerUser(body, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(RegisterGuard)
|
||||||
|
@Put('1/forgot-password')
|
||||||
|
async forgotPassworda(@Body() body: AuthLoginDTO, @Req() req: Request) {
|
||||||
|
return this.authService.forgotPassword(body, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(RegisterGuard)
|
||||||
|
@Put('2/forgot-password')
|
||||||
|
async forgotPasswordb(@Body() body: AuthLoginDTO, @Req() req: Request) {
|
||||||
|
return this.authService.forgotPassword(body, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseInterceptors(LogoutInterceptor)
|
@UseInterceptors(LogoutInterceptor)
|
||||||
@HttpCode(200)
|
@HttpCode(200)
|
||||||
@Post('logout')
|
@Post('1/logout')
|
||||||
async logout(@Req() req: any, @Res() res: Response) {
|
async logouta(@Req() req: any, @Res() res: Response) {
|
||||||
const refreshToken = req.user?.refreshToken;
|
const refreshToken = req.user?.refreshToken;
|
||||||
let rst: any = await this.authService.logoutUser(refreshToken);
|
let rst: any = await this.authService.logoutUser(refreshToken);
|
||||||
if (rst.statusCode === 200) {
|
if (rst.statusCode === 200) {
|
||||||
@ -68,14 +137,101 @@ export class AuthController {
|
|||||||
res.json({ ...rst })
|
res.json({ ...rst })
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(RegisterGuard)
|
@UseInterceptors(LogoutInterceptor)
|
||||||
@Put('forgot-password')
|
@HttpCode(200)
|
||||||
async forgotPassword(@Body() body: AuthLoginDTO, @Req() req: Request) {
|
@Post('2/logout')
|
||||||
return this.authService.forgotPassword(body, req);
|
async logoutb(@Req() req: any, @Res() res: Response) {
|
||||||
|
const refreshToken = req.user?.refreshToken;
|
||||||
|
let rst: any = await this.authService.logoutUser(refreshToken);
|
||||||
|
if (rst.statusCode === 200) {
|
||||||
|
res.clearCookie('access_token', {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none'
|
||||||
|
});
|
||||||
|
res.clearCookie('refresh_token', {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
// to enable auth domain
|
||||||
|
|
||||||
|
// const hostname = req.hostname;
|
||||||
|
|
||||||
|
// const isLocalhost = hostname === 'localhost' || hostname === '127.0.0.1';
|
||||||
|
|
||||||
|
// const isDevEnv = isLocalhost || hostname.startsWith('localhost') || hostname.startsWith('127.0.0.1');
|
||||||
|
|
||||||
|
// const cookieOptions: any = {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// sameSite: 'none'
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if (!isDevEnv) {
|
||||||
|
// cookieOptions.domain = hostname;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!isDevEnv) {
|
||||||
|
// res.clearCookie('access_token', {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// sameSite: 'none',
|
||||||
|
// domain: hostname
|
||||||
|
// });
|
||||||
|
// res.clearCookie('refresh_token', {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// sameSite: 'none',
|
||||||
|
// domain: hostname
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// res.clearCookie('access_token', {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// sameSite: 'none'
|
||||||
|
// });
|
||||||
|
// res.clearCookie('refresh_token', {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// sameSite: 'none'
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
res.json({ ...rst })
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('refresh-tokens')
|
@Get('1/refresh-tokens')
|
||||||
async getTokenFromRefreshToken(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
|
async getTokenFromRefreshTokena(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
|
||||||
|
let k: any = await this.authService.getTokenFromRefreshToken(req)
|
||||||
|
|
||||||
|
if (k.access_token) {
|
||||||
|
res.cookie('access_token', k.access_token, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none',
|
||||||
|
maxAge: 8 * 60 * 60 * 1000,
|
||||||
|
path: '/'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k.refresh_token) {
|
||||||
|
res.cookie('refresh_token', k.refresh_token, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: true,
|
||||||
|
sameSite: 'none',
|
||||||
|
maxAge: 8 * 60 * 60 * 1000,
|
||||||
|
path: '/'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Tokens refreshed successfully" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('2/refresh-tokens')
|
||||||
|
async getTokenFromRefreshTokenb(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
|
||||||
let k: any = await this.authService.getTokenFromRefreshToken(req)
|
let k: any = await this.authService.getTokenFromRefreshToken(req)
|
||||||
|
|
||||||
if (k.access_token) {
|
if (k.access_token) {
|
||||||
@ -102,12 +258,36 @@ export class AuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa')
|
@Roles('ua', 'sa', 'ca')
|
||||||
@Post('sendmail')
|
@Post('1/sendmail')
|
||||||
@HttpCode(200)
|
@HttpCode(200)
|
||||||
async sendMail(@Body() body: SendMailDTO) {
|
async sendMaila(@Body() body: SendMailDTO, @Req() req: Request) {
|
||||||
// let token = await this.jwtService.generateToken({ email: mail })
|
// let token = await this.jwtService.generateToken({ email: mail })
|
||||||
return this.authService.sendMail(body);
|
let appDomain;
|
||||||
|
if (req.headers.origin) {
|
||||||
|
appDomain = extractSubdomain(req.headers.origin)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appDomain = ""
|
||||||
|
}
|
||||||
|
return this.authService.sendMail(body, appDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('pua', 'psa', 'pca')
|
||||||
|
@Post('2/sendmail')
|
||||||
|
@HttpCode(200)
|
||||||
|
async sendMailb(@Body() body: SendMailDTO, @Req() req: Request) {
|
||||||
|
// let token = await this.jwtService.generateToken({ email: mail })
|
||||||
|
let appDomain;
|
||||||
|
if (req.headers.origin) {
|
||||||
|
appDomain = extractSubdomain(req.headers.origin)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appDomain = ""
|
||||||
|
}
|
||||||
|
return this.authService.sendMail(body, appDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Get('checkRoles')
|
// @Get('checkRoles')
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty, IntersectionType } from '@nestjs/swagger';
|
||||||
import { Transform, Type } from 'class-transformer';
|
import { Transform, Type } from 'class-transformer';
|
||||||
import { IsEmail, IsEnum, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
|
import { IsEmail, IsEnum, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
|
||||||
|
import { APPLICATIONNAME_DTO } from 'src/dto/property.dto';
|
||||||
|
|
||||||
export class AuthLoginDTO {
|
export class AuthLoginDTO {
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
@ -12,6 +13,8 @@ export class AuthLoginDTO {
|
|||||||
P_PASSWORD: string;
|
P_PASSWORD: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class AuthLoginOnlyDTO extends IntersectionType(AuthLoginDTO, APPLICATIONNAME_DTO) { }
|
||||||
|
|
||||||
export enum MailTypeDTO {
|
export enum MailTypeDTO {
|
||||||
REGISTER_CLIENT = "REGISTER_CLIENT",
|
REGISTER_CLIENT = "REGISTER_CLIENT",
|
||||||
REGISTER_SP = "REGISTER_SP",
|
REGISTER_SP = "REGISTER_SP",
|
||||||
|
|||||||
@ -6,9 +6,10 @@ import { ConfigService } from '@nestjs/config';
|
|||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { OracleModule } from 'src/oracle/oracle.module';
|
import { OracleModule } from 'src/oracle/oracle.module';
|
||||||
import { MailModule } from 'src/mail/mail.module';
|
import { MailModule } from 'src/mail/mail.module';
|
||||||
|
import { PgModule } from 'src/pg/pg.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [DbModule,MailModule, forwardRef(() => OracleModule)],
|
imports: [DbModule,MailModule, forwardRef(() => OracleModule), forwardRef(() => PgModule)],
|
||||||
providers: [
|
providers: [
|
||||||
AuthService,
|
AuthService,
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,9 +11,10 @@ import { UnauthorizedException } from 'src/exceptions/unauthorized.exception';
|
|||||||
import { ConflictException } from 'src/exceptions/conflict.exception';
|
import { ConflictException } from 'src/exceptions/conflict.exception';
|
||||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { UserMaintenanceService } from 'src/oracle/user-maintenance/user-maintenance.service';
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { MailService } from 'src/mail/mail.service';
|
import { MailService } from 'src/mail/mail.service';
|
||||||
|
import { UserMaintenanceService as OracleUserMaintenanceService } from 'src/oracle/user-maintenance/user-maintenance.service';
|
||||||
|
import { UserMaintenanceService as PgUserMaintenanceService } from 'src/pg/user-maintenance/user-maintenance.service';
|
||||||
|
|
||||||
|
|
||||||
interface DecodedToken {
|
interface DecodedToken {
|
||||||
@ -44,7 +45,8 @@ export class AuthService {
|
|||||||
private readonly oracleDBService: OracleDBService,
|
private readonly oracleDBService: OracleDBService,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly mailService: MailService,
|
private readonly mailService: MailService,
|
||||||
private readonly userMaintenanceService: UserMaintenanceService,
|
private readonly oracleUserMaintenanceService: OracleUserMaintenanceService,
|
||||||
|
private readonly pgUserMaintenanceService: PgUserMaintenanceService,
|
||||||
@Inject("REGISTER_SIGN_JWT") readonly REGISTER_SIGN_JWT: JwtService,
|
@Inject("REGISTER_SIGN_JWT") readonly REGISTER_SIGN_JWT: JwtService,
|
||||||
@Inject("REGISTER_VERIFY_JWT") readonly REGISTER_VERIFY_JWT: JwtService
|
@Inject("REGISTER_VERIFY_JWT") readonly REGISTER_VERIFY_JWT: JwtService
|
||||||
) {
|
) {
|
||||||
@ -245,7 +247,7 @@ export class AuthService {
|
|||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
async loginUser(username: string, password: string, req: Request): Promise<any> {
|
async loginUser(username: string, password: string, applicationName: string, req: Request, dbtype: number): Promise<any> {
|
||||||
|
|
||||||
const access_token = req.cookies?.access_token;
|
const access_token = req.cookies?.access_token;
|
||||||
const refresh_token = req.cookies?.refresh_token;
|
const refresh_token = req.cookies?.refresh_token;
|
||||||
@ -260,7 +262,14 @@ export class AuthService {
|
|||||||
try {
|
try {
|
||||||
const userSession = await this.getUserSession(username)
|
const userSession = await this.getUserSession(username)
|
||||||
|
|
||||||
const emailVerifyResponse: any = await this.userMaintenanceService.ValidateEmail({ P_EMAILADDR: username })
|
let emailVerifyResponse: any;
|
||||||
|
|
||||||
|
if (dbtype === 1) {
|
||||||
|
emailVerifyResponse = await this.oracleUserMaintenanceService.ValidateEmail({ P_EMAILADDR: username })
|
||||||
|
}
|
||||||
|
else if (dbtype === 2) {
|
||||||
|
emailVerifyResponse = await this.pgUserMaintenanceService.ValidateEmail({ P_EMAILADDR: username })
|
||||||
|
}
|
||||||
|
|
||||||
if (Array.isArray(emailVerifyResponse) && emailVerifyResponse[0].ERRORMESG) {
|
if (Array.isArray(emailVerifyResponse) && emailVerifyResponse[0].ERRORMESG) {
|
||||||
throw new BadRequestException();
|
throw new BadRequestException();
|
||||||
@ -269,13 +278,23 @@ export class AuthService {
|
|||||||
let ROLE = "";
|
let ROLE = "";
|
||||||
|
|
||||||
if (Array.isArray(emailVerifyResponse) && !emailVerifyResponse[0].ERRORMESG) {
|
if (Array.isArray(emailVerifyResponse) && !emailVerifyResponse[0].ERRORMESG) {
|
||||||
switch (emailVerifyResponse[0].SOURCE) {
|
switch ((emailVerifyResponse[0].SOURCE + "".toUpperCase())) {
|
||||||
case "USCIB": ROLE = 'ua'; break;
|
case "USCIB": ROLE = dbtype === 1 ? 'ua' : dbtype === 2 ? 'pua' : ''; break;
|
||||||
case "SP": ROLE = 'sa'; break;
|
case "SP": ROLE = dbtype === 1 ? 'sa' : dbtype === 2 ? 'psa' : ''; break;
|
||||||
case "CLIENT": ROLE = 'ca'; break;
|
case "CLIENT": ROLE = dbtype === 1 ? 'ca' : dbtype === 2 ? 'pca' : ''; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isValidCombo =
|
||||||
|
(applicationName === 'policy' && ROLE === (dbtype === 1 ? 'ua' : dbtype === 2 ? 'pua' : null)) ||
|
||||||
|
(applicationName === 'service-provider' && ROLE === (dbtype === 1 ? 'sa' : dbtype === 2 ? 'psa' : null)) ||
|
||||||
|
(applicationName === 'client' && ROLE === (dbtype === 1 ? 'ca' : dbtype === 2 ? 'pca' : null));
|
||||||
|
|
||||||
|
if (!isValidCombo) {
|
||||||
|
throw new UnauthorizedException("Authentication failed")
|
||||||
|
// console.log(!isValidCombo);
|
||||||
|
}
|
||||||
|
|
||||||
// if (ROLE === 'ua' && req.headers.origin !== 'https://policy.alphaomegainfosys.com') {
|
// if (ROLE === 'ua' && req.headers.origin !== 'https://policy.alphaomegainfosys.com') {
|
||||||
// throw new BadRequestException("Invalid username or password")
|
// throw new BadRequestException("Invalid username or password")
|
||||||
// }
|
// }
|
||||||
@ -286,22 +305,22 @@ export class AuthService {
|
|||||||
// throw new BadRequestException("Invalid username or password")
|
// throw new BadRequestException("Invalid username or password")
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (access_token && refresh_token && userSession.length > 0) {
|
// if (access_token && refresh_token && userSession.length > 0) {
|
||||||
|
|
||||||
const getSub: any = jwt.decode(refresh_token, { complete: true })
|
// const getSub: any = jwt.decode(refresh_token, { complete: true })
|
||||||
|
|
||||||
const user: any = await this.getUserDetailsById(getSub?.payload.sub)
|
// const user: any = await this.getUserDetailsById(getSub?.payload.sub)
|
||||||
|
|
||||||
if (user.email !== username) {
|
// if (user.email !== username) {
|
||||||
throw new UnauthorizedException("Authentication failed")
|
// throw new UnauthorizedException("Authentication failed")
|
||||||
}
|
// }
|
||||||
|
|
||||||
let tokens = await this.getTokenFromRefreshToken(req);
|
// let tokens = await this.getTokenFromRefreshToken(req);
|
||||||
const decoded = jwt.decode(access_token, { complete: true });
|
// const decoded = jwt.decode(access_token, { complete: true });
|
||||||
const email: any = (decoded && typeof decoded === 'object') ? (decoded as any).payload?.email : undefined;
|
// const email: any = (decoded && typeof decoded === 'object') ? (decoded as any).payload?.email : undefined;
|
||||||
return { ...tokens, email }
|
// return { ...tokens, email, ApplicationName: ROLE }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
const response = await axios.post(this.TOKEN_URL, params, {
|
const response = await axios.post(this.TOKEN_URL, params, {
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
@ -311,6 +330,9 @@ export class AuthService {
|
|||||||
|
|
||||||
return k;
|
return k;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error instanceof BadRequestException || error instanceof UnauthorizedException) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
throw new BadRequestException('Invalid username or password');
|
throw new BadRequestException('Invalid username or password');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,7 +447,6 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async forgotPassword(body: AuthLoginDTO, req: Request) {
|
async forgotPassword(body: AuthLoginDTO, req: Request) {
|
||||||
|
|
||||||
let det = await req['user'];
|
let det = await req['user'];
|
||||||
@ -499,13 +520,21 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerUser(body: AuthLoginDTO) {
|
async registerUser(body: AuthLoginDTO, dbtype: number) {
|
||||||
// let det = await req['user'];
|
// let det = await req['user'];
|
||||||
// if (det?.email !== body.P_EMAILADDR) {
|
// if (det?.email !== body.P_EMAILADDR) {
|
||||||
// throw new BadRequestException();
|
// throw new BadRequestException();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const emailVerifyResponse: any = await this.userMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR })
|
let emailVerifyResponse: any;
|
||||||
|
|
||||||
|
if (dbtype === 1) {
|
||||||
|
emailVerifyResponse = await this.oracleUserMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR })
|
||||||
|
}
|
||||||
|
else if (dbtype === 2) {
|
||||||
|
emailVerifyResponse = await this.pgUserMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Array.isArray(emailVerifyResponse) && emailVerifyResponse[0].ERRORMESG) {
|
if (Array.isArray(emailVerifyResponse) && emailVerifyResponse[0].ERRORMESG) {
|
||||||
throw new BadRequestException();
|
throw new BadRequestException();
|
||||||
@ -555,10 +584,10 @@ export class AuthService {
|
|||||||
|
|
||||||
|
|
||||||
if (Array.isArray(emailVerifyResponse) && !emailVerifyResponse[0].ERRORMESG) {
|
if (Array.isArray(emailVerifyResponse) && !emailVerifyResponse[0].ERRORMESG) {
|
||||||
switch (emailVerifyResponse[0].SOURCE) {
|
switch ((emailVerifyResponse[0].SOURCE + "".toUpperCase())) {
|
||||||
case "USCIB": ROLE = 'ua'; break;
|
case "USCIB": ROLE = dbtype === 1 ? 'ua' : dbtype === 2 ? 'pua' : ''; break;
|
||||||
case "SP": ROLE = 'sa'; break;
|
case "SP": ROLE = dbtype === 1 ? 'sa' : dbtype === 2 ? 'psa' : ''; break;
|
||||||
case "CLIENT": ROLE = 'ca'; break;
|
case "CLIENT": ROLE = dbtype === 1 ? 'ca' : dbtype === 2 ? 'pca' : ''; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,8 +734,6 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async getTokenFromRefreshToken(req: Request) {
|
async getTokenFromRefreshToken(req: Request) {
|
||||||
|
|
||||||
const refreshToken = req.cookies['refresh_token'];
|
const refreshToken = req.cookies['refresh_token'];
|
||||||
@ -815,9 +842,29 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMailTemplate(body: SendMailDTO, token: string, source: string): Promise<MailTemplateDTO | null> {
|
async getMailTemplate(body: SendMailDTO, token: string, source: string, appDomain: string): Promise<MailTemplateDTO | null> {
|
||||||
|
|
||||||
switch (body.P_MAIL_TYPE) {
|
switch (body.P_MAIL_TYPE) {
|
||||||
|
case MailTypeDTO.REGISTER_USCIB:
|
||||||
|
return {
|
||||||
|
to: body.P_TO,
|
||||||
|
subject: `🔐 Register Your Account`,
|
||||||
|
templateName: 'a',
|
||||||
|
variables: {
|
||||||
|
to: body.P_TO,
|
||||||
|
url: `https://${appDomain.toLowerCase() === "policy" ? "policy" : appDomain.toLowerCase() === "policy-1" ? "policy-1" : appDomain.toLowerCase() === "policy-2" ? "policy-2" : ""}.alphaomegainfosys.com/register`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case MailTypeDTO.REGISTER_SP:
|
||||||
|
return {
|
||||||
|
to: body.P_TO,
|
||||||
|
subject: `🔐 Register Your Account`,
|
||||||
|
templateName: 'a',
|
||||||
|
variables: {
|
||||||
|
to: body.P_TO,
|
||||||
|
url: `https://${appDomain.toLowerCase() === "sp" ? "sp" : appDomain.toLowerCase() === "sp-1" ? "sp-1" : appDomain.toLowerCase() === "sp-2" ? "sp-2" : ""}.alphaomegainfosys.com/register`
|
||||||
|
}
|
||||||
|
}
|
||||||
case MailTypeDTO.REGISTER_CLIENT:
|
case MailTypeDTO.REGISTER_CLIENT:
|
||||||
return {
|
return {
|
||||||
to: body.P_TO,
|
to: body.P_TO,
|
||||||
@ -825,7 +872,7 @@ export class AuthService {
|
|||||||
templateName: 'a',
|
templateName: 'a',
|
||||||
variables: {
|
variables: {
|
||||||
to: body.P_TO,
|
to: body.P_TO,
|
||||||
url: `https://client.alphaomegainfosys.com/register`
|
url: `https://${appDomain.toLowerCase() === "sp" ? "client" : appDomain.toLowerCase() === "sp-1" ? "client-1" : appDomain.toLowerCase() === "sp-2" ? "client-2" : ""}.alphaomegainfosys.com/register`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case MailTypeDTO.FORGOT_PASSWORD:
|
case MailTypeDTO.FORGOT_PASSWORD:
|
||||||
@ -835,9 +882,15 @@ export class AuthService {
|
|||||||
templateName: 'b',
|
templateName: 'b',
|
||||||
variables: {
|
variables: {
|
||||||
to: body.P_TO,
|
to: body.P_TO,
|
||||||
url: `${source === 'ua' ? `https://policy.alphaomegainfosys.com/forgot-password/${token}`
|
url: `${appDomain.toLowerCase() === 'policy' ? `https://policy.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
: source === 'sa' ? `https://sp.alphaomegainfosys.com/forgot-password/${token}`
|
: appDomain.toLowerCase() === 'policy-1' ? `https://policy-1.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
: source === 'ca' ? `https://client.alphaomegainfosys.com/forgot-password/${token}` : ''}`
|
: appDomain.toLowerCase() === 'policy-2' ? `https://policy-2.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
|
: appDomain.toLowerCase() === 'sp' ? `https://sp.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
|
: appDomain.toLowerCase() === 'sp-1' ? `https://sp-1.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
|
: appDomain.toLowerCase() === 'sp-2' ? `https://sp-2.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
|
: appDomain.toLowerCase() === 'client' ? `https://client.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
|
: appDomain.toLowerCase() === 'client-1' ? `https://client-1.alphaomegainfosys.com/forgot-password/${token}`
|
||||||
|
: appDomain.toLowerCase() === 'client-2' ? `https://client-2.alphaomegainfosys.com/forgot-password/${token}` : ''}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -845,7 +898,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendMail(body: SendMailDTO) {
|
async sendMail(body: SendMailDTO, appDomain: string) {
|
||||||
let token: string;
|
let token: string;
|
||||||
let ROLE: string = "";
|
let ROLE: string = "";
|
||||||
let uuid: string | undefined = undefined;
|
let uuid: string | undefined = undefined;
|
||||||
@ -870,7 +923,7 @@ export class AuthService {
|
|||||||
|
|
||||||
token = await this.generateToken({ P_TO: body.P_TO, uuid: uuid })
|
token = await this.generateToken({ P_TO: body.P_TO, uuid: uuid })
|
||||||
|
|
||||||
const mailTemplate: MailTemplateDTO | null = await this.getMailTemplate(body, token, ROLE);
|
const mailTemplate: MailTemplateDTO | null = await this.getMailTemplate(body, token, ROLE, appDomain);
|
||||||
|
|
||||||
if (!mailTemplate) {
|
if (!mailTemplate) {
|
||||||
throw new BadRequestException();
|
throw new BadRequestException();
|
||||||
|
|||||||
@ -18,3 +18,28 @@ export const getMssqlConfig = (configService: ConfigService) => ({
|
|||||||
encrypt: true,
|
encrypt: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface PgConfig {
|
||||||
|
user: string;
|
||||||
|
host: string;
|
||||||
|
database: string;
|
||||||
|
password: string;
|
||||||
|
port: number;
|
||||||
|
max: number;
|
||||||
|
idleTimeoutMillis: number;
|
||||||
|
connectionTimeoutMillis: number;
|
||||||
|
query_timeout: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const getPgConfig = (configService: ConfigService): PgConfig => ({
|
||||||
|
user: configService.get<string>('PG_USER', ''),
|
||||||
|
host: configService.get<string>('PG_HOST', ''),
|
||||||
|
database: configService.get<string>('PG_DB', ''),
|
||||||
|
password: configService.get<string>('PG_PWD', ''), // Password can be optional, e.g., if using environment variables or other auth
|
||||||
|
port: parseInt(configService.get<string>('PG_PORT', '5432'), 10),
|
||||||
|
max: parseInt(configService.get<string>('PG_MAX_CLIENTS_IN_POOL', '10'), 10), // Maximum number of clients in the pool
|
||||||
|
idleTimeoutMillis: parseInt(configService.get<string>('PG_CLIENT_IDLE', '10000'), 10), // How long a client is allowed to remain idle before being closed
|
||||||
|
connectionTimeoutMillis: parseInt(configService.get<string>('PG_CONNECTION_TIMEOUT', '0'), 10), // How long to try to establish a new connection before throwing an error
|
||||||
|
query_timeout: parseInt(configService.get<string>('PG_QUERY_TIMEOUT', '5000'), 10), // Add this line, default 5000ms (5 seconds)
|
||||||
|
});
|
||||||
@ -1,9 +1,9 @@
|
|||||||
import { Global, Module } from '@nestjs/common';
|
import { Global, Module } from '@nestjs/common';
|
||||||
import { MssqlDBService, OracleDBService } from './db.service';
|
import { MssqlDBService, OracleDBService, PgDBService } from './db.service';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
providers: [OracleDBService, MssqlDBService],
|
providers: [OracleDBService, MssqlDBService, PgDBService],
|
||||||
exports: [OracleDBService, MssqlDBService],
|
exports: [OracleDBService, MssqlDBService, PgDBService],
|
||||||
})
|
})
|
||||||
export class DbModule {}
|
export class DbModule { }
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { createPool, Pool, Connection } from 'oracledb';
|
import { createPool, Pool, Connection } from 'oracledb';
|
||||||
import { ConnectionPool } from 'mssql';
|
import { ConnectionPool } from 'mssql';
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common';
|
||||||
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { getMssqlConfig, getOracleConfig } from './db.config';
|
import { getMssqlConfig, getOracleConfig, getPgConfig } from './db.config';
|
||||||
|
import { Pool as pgPool, PoolClient } from 'pg';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OracleDBService {
|
export class OracleDBService {
|
||||||
@ -11,11 +12,13 @@ export class OracleDBService {
|
|||||||
private readonly logger = new Logger(OracleDBService.name);
|
private readonly logger = new Logger(OracleDBService.name);
|
||||||
|
|
||||||
constructor(private readonly configService: ConfigService) {
|
constructor(private readonly configService: ConfigService) {
|
||||||
|
if (process.env.DB_TYPE === "ORACLE") {
|
||||||
this.initializePool().catch(err => {
|
this.initializePool().catch(err => {
|
||||||
this.logger.error('Error initializing Oracle DB pool', err);
|
this.logger.error('Error initializing Oracle DB pool', err);
|
||||||
throw new InternalServerException();
|
throw new InternalServerException();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async initializePool(): Promise<void> {
|
private async initializePool(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
@ -62,6 +65,109 @@ export class OracleDBService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PgDBService implements OnModuleDestroy {
|
||||||
|
private pool: pgPool | null = null;
|
||||||
|
private readonly logger = new Logger(PgDBService.name);
|
||||||
|
|
||||||
|
constructor(private readonly configService: ConfigService) {
|
||||||
|
if (process.env.DB_TYPE === "PG") {
|
||||||
|
this.initializePool().catch(err => {
|
||||||
|
this.logger.error('Error initializing PostgreSQL DB pool', err);
|
||||||
|
throw new InternalServerException('Failed to initialize database pool');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.logger.warn('PG pool not initialized because DB_FOR is not PG');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the PostgreSQL connection pool.
|
||||||
|
* This method is called once when the service is instantiated.
|
||||||
|
* It attempts to create the pool and test a connection to ensure connectivity.
|
||||||
|
*/
|
||||||
|
private async initializePool(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const config = getPgConfig(this.configService);
|
||||||
|
|
||||||
|
this.pool = new pgPool({
|
||||||
|
user: config.user,
|
||||||
|
host: config.host,
|
||||||
|
database: config.database,
|
||||||
|
password: config.password,
|
||||||
|
port: config.port,
|
||||||
|
max: config.max,
|
||||||
|
idleTimeoutMillis: config.idleTimeoutMillis,
|
||||||
|
connectionTimeoutMillis: config.connectionTimeoutMillis,
|
||||||
|
query_timeout: config.query_timeout
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optional: Add an error listener to the pool.
|
||||||
|
// This listener catches errors on idle clients that might occur due to database restarts
|
||||||
|
// or network issues, allowing the pool to recover by discarding the faulty client.
|
||||||
|
this.pool.on('error', (err: Error, client: PoolClient) => {
|
||||||
|
this.logger.error('Unexpected error on idle PostgreSQL client', err, client);
|
||||||
|
// In production, you might want more sophisticated error handling,
|
||||||
|
// but for an idle client error, the pool usually handles replacing it.
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test connection: Acquire and immediately release a client to confirm the pool is functional.
|
||||||
|
const client = await this.pool.connect();
|
||||||
|
client.release(); // Release the client back to the pool after successful test
|
||||||
|
this.logger.log('PostgreSQL connection pool created and tested successfully');
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Failed to create PostgreSQL DB pool:', error);
|
||||||
|
// Re-throw to propagate the error up to the constructor, which will halt startup
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a client from the connection pool.
|
||||||
|
* This method is used by consumers of the service to get a database connection.
|
||||||
|
*
|
||||||
|
* IMPORTANT: The caller is responsible for releasing the client back to the pool
|
||||||
|
* using `client.release()` in a `finally` block to prevent connection leaks.
|
||||||
|
*
|
||||||
|
* @returns A promise that resolves to a PoolClient.
|
||||||
|
* @throws InternalServerException if the pool is not initialized or if
|
||||||
|
* it fails to acquire a connection within the configured timeout.
|
||||||
|
*/
|
||||||
|
async getConnection(): Promise<PoolClient> {
|
||||||
|
if (!this.pool) {
|
||||||
|
this.logger.error('Attempted to get a connection before pool was initialized');
|
||||||
|
throw new InternalServerException('Database connection pool not initialized');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// pool.connect() acquires a client from the pool. If no clients are available
|
||||||
|
// and the pool is at its max, it will wait until one is released or timeout occurs.
|
||||||
|
const client = await this.pool.connect();
|
||||||
|
return client;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Failed to get PostgreSQL DB connection from pool:', error);
|
||||||
|
throw new InternalServerException('Failed to acquire database connection');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the PostgreSQL connection pool gracefully.
|
||||||
|
* This method is part of the NestJS `OnModuleDestroy` lifecycle hook,
|
||||||
|
* ensuring that the pool is drained and all connections are closed when the application shuts down.
|
||||||
|
*/
|
||||||
|
async onModuleDestroy(): Promise<void> {
|
||||||
|
if (this.pool) {
|
||||||
|
try {
|
||||||
|
await this.pool.end(); // Drains the pool of all active and idle clients, then closes them.
|
||||||
|
this.logger.log('PostgreSQL DB pool closed successfully');
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Error closing PostgreSQL DB pool:', error);
|
||||||
|
// Rethrowing here will not necessarily stop the shutdown, but logs the error.
|
||||||
|
throw new InternalServerException('Failed to gracefully close database pool');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MssqlDBService {
|
export class MssqlDBService {
|
||||||
@ -98,4 +204,3 @@ export class MssqlDBService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,61 @@ export class CARNETNO_DTO {
|
|||||||
P_CARNETNO: string;
|
P_CARNETNO: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ORDERID_DTO {
|
||||||
|
@ApiProperty({ required: true, type: String, nullable: true })
|
||||||
|
@IsString()
|
||||||
|
@IsDefined({ message: 'Property P_ORDERID is required' })
|
||||||
|
P_ORDERID: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PRICE_DTO {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
// @Max(999999999, {
|
||||||
|
// message: 'Property P_PRICE must not exceed 999999999',
|
||||||
|
// })
|
||||||
|
@Min(0.01, { message: 'Property P_PRICE must be greater than zero' })
|
||||||
|
// @IsInt({ message: 'Property P_PRICE allows only whole numbers' })
|
||||||
|
@IsNumber({}, { message: 'Property P_PRICE must be a number' })
|
||||||
|
@Transform(({ value }) => Number(value))
|
||||||
|
@IsDefined({ message: 'Property P_PRICE is required' })
|
||||||
|
P_PRICE: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PAYMENTAMOUNT_DTO {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
// @Max(999999999, {
|
||||||
|
// message: 'Property P_PRICE must not exceed 999999999',
|
||||||
|
// })
|
||||||
|
@Min(0.01, { message: 'Property P_PAYMENTAMOUNT must be greater than zero' })
|
||||||
|
// @IsInt({ message: 'Property P_PRICE allows only whole numbers' })
|
||||||
|
@IsNumber({}, { message: 'Property P_PAYMENTAMOUNT must be a number' })
|
||||||
|
@Transform(({ value }) => Number(value))
|
||||||
|
@IsDefined({ message: 'Property P_PAYMENTAMOUNT is required' })
|
||||||
|
P_PAYMENTAMOUNT: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PAYMENTSTATUS_DTO {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
@IsString({ message: 'Property P_STATUS must be a string' })
|
||||||
|
@IsDefined({ message: 'Property P_STATUS is required' })
|
||||||
|
P_STATUS: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PAYMENTERROR_DTO {
|
||||||
|
@ApiProperty({ required: true, type: String, nullable: true })
|
||||||
|
@IsString({ message: 'Property P_PAYMENTERROR must be a string' })
|
||||||
|
@IsDefined({ message: 'Property P_PAYMENTERROR is required' })
|
||||||
|
P_PAYMENTERROR: string | null = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DESCRIPTION_DTO {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
@IsString()
|
||||||
|
@IsDefined({ message: 'Property P_DESCRIPTION is required' })
|
||||||
|
P_DESCRIPTION: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export class HEADERID_DTO {
|
export class HEADERID_DTO {
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
@Max(999999999, {
|
@Max(999999999, {
|
||||||
@ -60,17 +115,17 @@ export class APPLICATIONNAME_DTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class GOODS_PORT_DTO {
|
export class GOODS_PORT_DTO {
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true, type: String, nullable: true })
|
||||||
@IsString({ message: 'Property P_GOODSPORT must be a string' })
|
@IsString({ message: 'Property P_GOODSPORT must be a string' })
|
||||||
@IsDefined({ message: 'Property P_GOODSPORT is required' })
|
@IsDefined({ message: 'Property P_GOODSPORT is required' })
|
||||||
P_GOODSPORT: string;
|
P_GOODSPORT: string | null = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GOODS_COUNTRY_DTO {
|
export class GOODS_COUNTRY_DTO {
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true, type: String, nullable: true })
|
||||||
@IsString({ message: 'Property P_GOODSCOUNTRY must be a string' })
|
@IsString({ message: 'Property P_GOODSCOUNTRY must be a string' })
|
||||||
@IsDefined({ message: 'Property P_GOODSCOUNTRY is required' })
|
@IsDefined({ message: 'Property P_GOODSCOUNTRY is required' })
|
||||||
P_GOODSCOUNTRY: string;
|
P_GOODSCOUNTRY: string | null = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class REASON_CODE_DTO {
|
export class REASON_CODE_DTO {
|
||||||
@ -90,7 +145,7 @@ export class EXTENSION_PERIOD_DTO {
|
|||||||
@IsNumber({}, { message: 'Property P_EXTENSIONPERIOD must be a number' })
|
@IsNumber({}, { message: 'Property P_EXTENSIONPERIOD must be a number' })
|
||||||
@Transform(({ value }) => Number(value))
|
@Transform(({ value }) => Number(value))
|
||||||
@IsDefined({ message: 'Property P_EXTENSIONPERIOD is required' })
|
@IsDefined({ message: 'Property P_EXTENSIONPERIOD is required' })
|
||||||
P_EXTENSIONPERIOD: number;
|
P_EXTENSIONPERIOD: number = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ORDERTYPE_DTO {
|
export class ORDERTYPE_DTO {
|
||||||
@ -323,7 +378,7 @@ export class USSETS_DTO {
|
|||||||
@Transform(({ value }) => Number(value))
|
@Transform(({ value }) => Number(value))
|
||||||
@IsNumber({}, { message: 'Property P_USSETS must be a number' })
|
@IsNumber({}, { message: 'Property P_USSETS must be a number' })
|
||||||
@IsDefined({ message: 'Property P_USSETS is required' })
|
@IsDefined({ message: 'Property P_USSETS is required' })
|
||||||
P_USSETS: number;
|
P_USSETS: number = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum VOT {
|
export enum VOT {
|
||||||
|
|||||||
@ -3,8 +3,11 @@ import { IntersectionType, PartialType } from "@nestjs/swagger";
|
|||||||
import {
|
import {
|
||||||
APPLICATIONNAME_DTO, AUTHREP_DTO, AUTO_FLAG_DTO, CARNETNO_DTO, COMMERCIAL_SAMPLE_FLAG_DTO,
|
APPLICATIONNAME_DTO, AUTHREP_DTO, AUTO_FLAG_DTO, CARNETNO_DTO, COMMERCIAL_SAMPLE_FLAG_DTO,
|
||||||
COUNTRYTABLE_DTO, CUSTCOURIERNO_DTO, DELIVERYMETHOD_DTO, DELIVERYTYPE_DTO,
|
COUNTRYTABLE_DTO, CUSTCOURIERNO_DTO, DELIVERYMETHOD_DTO, DELIVERYTYPE_DTO,
|
||||||
|
DESCRIPTION_DTO,
|
||||||
EXIBITIONS_FAIR_FLAG_DTO, EXTENSION_PERIOD_DTO, FORMOFSECURITY_DTO, GLTABLE_DTO, GLTABLE_ITEMNO_OPTIONAL_DTO, GOODS_COUNTRY_DTO, GOODS_PORT_DTO, HEADERID_DTO,
|
EXIBITIONS_FAIR_FLAG_DTO, EXTENSION_PERIOD_DTO, FORMOFSECURITY_DTO, GLTABLE_DTO, GLTABLE_ITEMNO_OPTIONAL_DTO, GOODS_COUNTRY_DTO, GOODS_PORT_DTO, HEADERID_DTO,
|
||||||
HORSE_FLAG_DTO, INSPROTECTION_DTO, ITEMNO_DTO, LDIPROTECTION_DTO, ORDERTYPE_DTO, PAYMENTMETHOD_DTO,
|
HORSE_FLAG_DTO, INSPROTECTION_DTO, ITEMNO_DTO, LDIPROTECTION_DTO, ORDERID_DTO, ORDERTYPE_DTO, PAYMENTAMOUNT_DTO, PAYMENTERROR_DTO, PAYMENTMETHOD_DTO,
|
||||||
|
PAYMENTSTATUS_DTO,
|
||||||
|
PRICE_DTO,
|
||||||
PRINTGL_DTO,
|
PRINTGL_DTO,
|
||||||
PROF_EQUIPMENT_FLAG_DTO, REASON_CODE_DTO, REFNO_DTO, SHIPADDRID_DTO, SHIPCONTACTID_DTO, SHIPNAME_DTO, SHIPTOTYPE_DTO, USSETS_DTO
|
PROF_EQUIPMENT_FLAG_DTO, REASON_CODE_DTO, REFNO_DTO, SHIPADDRID_DTO, SHIPCONTACTID_DTO, SHIPNAME_DTO, SHIPTOTYPE_DTO, USSETS_DTO
|
||||||
} from "./carnet-application-property.dto";
|
} from "./carnet-application-property.dto";
|
||||||
@ -60,14 +63,19 @@ export class SaveExtensionApplicationDTO extends (IntersectionType(
|
|||||||
USERID_DTO,
|
USERID_DTO,
|
||||||
SPID_DTO,
|
SPID_DTO,
|
||||||
HEADERID_DTO,
|
HEADERID_DTO,
|
||||||
GOODS_PORT_DTO,
|
PartialType(GOODS_PORT_DTO),
|
||||||
GOODS_COUNTRY_DTO,
|
PartialType(GOODS_COUNTRY_DTO),
|
||||||
REASON_CODE_DTO,
|
REASON_CODE_DTO,
|
||||||
EXTENSION_PERIOD_DTO
|
PartialType(EXTENSION_PERIOD_DTO)
|
||||||
)) { }
|
)) { }
|
||||||
|
|
||||||
export class PrintCarnetDTO extends (IntersectionType(SPID_DTO, HEADERID_DTO, PRINTGL_DTO)) { }
|
export class PrintCarnetDTO extends (IntersectionType(SPID_DTO, HEADERID_DTO, PRINTGL_DTO)) { }
|
||||||
export class PrintGLDTO extends (IntersectionType(SPID_DTO, HEADERID_DTO)) { }
|
export class PrintGLDTO extends (IntersectionType(SPID_DTO, HEADERID_DTO)) { }
|
||||||
|
export class CapturePaymentDTO extends (IntersectionType(ORDERID_DTO, APPLICATIONNAME_DTO, PRICE_DTO, USERID_DTO)) { }
|
||||||
|
export class InitiatePaymentDTO extends (IntersectionType(APPLICATIONNAME_DTO, PRICE_DTO, DESCRIPTION_DTO, USERID_DTO)) { }
|
||||||
|
export class GetOrderDetailsDTO extends (IntersectionType(ORDERID_DTO)) { }
|
||||||
|
export class GetPaymentHistoryDTO extends (IntersectionType(APPLICATIONNAME_DTO, USERID_DTO)) { }
|
||||||
|
export class SaveHistoryDTO extends (IntersectionType(APPLICATIONNAME_DTO, ORDERID_DTO, PAYMENTAMOUNT_DTO, PAYMENTSTATUS_DTO, USERID_DTO, PartialType(PAYMENTERROR_DTO))) { }
|
||||||
|
|
||||||
export class CreateApplicationDTO extends IntersectionType(
|
export class CreateApplicationDTO extends IntersectionType(
|
||||||
SPID_DTO, CLIENTID_DTO, LOCATIONID_DTO, USERID_DTO, APPLICATIONNAME_DTO,
|
SPID_DTO, CLIENTID_DTO, LOCATIONID_DTO, USERID_DTO, APPLICATIONNAME_DTO,
|
||||||
@ -97,7 +105,7 @@ export class DeleteGenerallistItemsDTO extends IntersectionType(
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
export class AddCountriesDTO extends IntersectionType(
|
export class AddCountriesDTO extends IntersectionType(
|
||||||
HEADERID_DTO, USSETS_DTO, COUNTRYTABLE_DTO, USERID_DTO
|
HEADERID_DTO, PartialType(USSETS_DTO), COUNTRYTABLE_DTO, USERID_DTO
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
export class UpdateShippingDetailsDTO extends IntersectionType(
|
export class UpdateShippingDetailsDTO extends IntersectionType(
|
||||||
|
|||||||
@ -60,6 +60,13 @@ export class CLIENTNAME_DTO {
|
|||||||
P_CLIENTNAME: string;
|
P_CLIENTNAME: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class INDUSTRY_TYPE_DTO {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
@IsString({ message: 'Property P_INDUSTRYTYPE must be a string' })
|
||||||
|
@IsDefined({ message: 'Property P_INDUSTRYTYPE is required' })
|
||||||
|
P_INDUSTRYTYPE: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class REVENUELOCATION_DTO {
|
export class REVENUELOCATION_DTO {
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
@Length(0, 2, {
|
@Length(0, 2, {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
CLIENT_CONTACTID_DTO, CLIENTID_DTO, CLIENTLOCADDRESSTABLE_DTO, CLIENTLOCATIONID_DTO,
|
CLIENT_CONTACTID_DTO, CLIENTID_DTO, CLIENTLOCADDRESSTABLE_DTO, CLIENTLOCATIONID_DTO,
|
||||||
CLIENTNAME_DTO, LOCATIONNAME_DTO, NAMEOF_DTO, PREPARERNAME_DTO, REVENUELOCATION_DTO, STATUS_DTO
|
CLIENTNAME_DTO, INDUSTRY_TYPE_DTO, LOCATIONNAME_DTO, NAMEOF_DTO, PREPARERNAME_DTO, REVENUELOCATION_DTO, STATUS_DTO
|
||||||
} from "./manage-clients-property.dto";
|
} from "./manage-clients-property.dto";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -34,7 +34,8 @@ export class CreateClientDataDTO extends IntersectionType(
|
|||||||
PartialType(COUNTRY_DTO),
|
PartialType(COUNTRY_DTO),
|
||||||
ISSUING_REGION_DTO,
|
ISSUING_REGION_DTO,
|
||||||
REVENUELOCATION_DTO,
|
REVENUELOCATION_DTO,
|
||||||
USERID_DTO
|
USERID_DTO,
|
||||||
|
INDUSTRY_TYPE_DTO
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +50,8 @@ export class UpdateClientDTO extends IntersectionType(
|
|||||||
ZIP_DTO,
|
ZIP_DTO,
|
||||||
COUNTRY_DTO,
|
COUNTRY_DTO,
|
||||||
REVENUELOCATION_DTO,
|
REVENUELOCATION_DTO,
|
||||||
USERID_DTO
|
USERID_DTO,
|
||||||
|
INDUSTRY_TYPE_DTO
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
export class UpdateClientContactsDTO extends IntersectionType(
|
export class UpdateClientContactsDTO extends IntersectionType(
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
import { ApiProperty } from "@nestjs/swagger";
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
import { IsNumber, IsString } from "class-validator";
|
import { IsNumber, IsString } from "class-validator";
|
||||||
|
|
||||||
|
|
||||||
|
export class PCT_VALUE_DTO {
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
@IsString()
|
||||||
|
P_PCT_VALUE: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class EFFDATE_DTO {
|
export class EFFDATE_DTO {
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { HOLDERTYPE_DTO, USCIBMEMBERFLAG_DTO } from "../manage-holders/manage-ho
|
|||||||
import {
|
import {
|
||||||
BASICFEESETUPID_DTO, BONDRATESETUPID_DTO, CARGORATESETUPID_DTO, CFFEESETUPID_DTO,
|
BASICFEESETUPID_DTO, BONDRATESETUPID_DTO, CARGORATESETUPID_DTO, CFFEESETUPID_DTO,
|
||||||
COMMRATE_DTO, CSFEESETUPID_DTO, CUSTOMERTYPE_DTO, EFFDATE_DTO, EFFEESETUPID_DTO, ENDSETS_DTO,
|
COMMRATE_DTO, CSFEESETUPID_DTO, CUSTOMERTYPE_DTO, EFFDATE_DTO, EFFEESETUPID_DTO, ENDSETS_DTO,
|
||||||
ENDTIME_DTO, FEECOMMID_DTO, FEES_DTO, RATE_DTO, SPCLCOMMODITY_DTO, SPCLCOUNTRY_DTO,
|
ENDTIME_DTO, FEECOMMID_DTO, FEES_DTO, PCT_VALUE_DTO, RATE_DTO, SPCLCOMMODITY_DTO, SPCLCOUNTRY_DTO,
|
||||||
STARTSETS_DTO, STARTTIME_DTO, TIMEZONE_DTO
|
STARTSETS_DTO, STARTTIME_DTO, TIMEZONE_DTO
|
||||||
} from "./manage-fee-property.dto";
|
} from "./manage-fee-property.dto";
|
||||||
|
|
||||||
@ -36,7 +36,8 @@ export class CreateBondRateDTO extends IntersectionType(
|
|||||||
SPCLCOUNTRY_DTO,
|
SPCLCOUNTRY_DTO,
|
||||||
EFFDATE_DTO,
|
EFFDATE_DTO,
|
||||||
RATE_DTO,
|
RATE_DTO,
|
||||||
USERID_DTO
|
USERID_DTO,
|
||||||
|
PCT_VALUE_DTO
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
export class CreateCargoRateDTO extends IntersectionType(
|
export class CreateCargoRateDTO extends IntersectionType(
|
||||||
@ -100,7 +101,8 @@ export class UpdateBondRateDTO extends IntersectionType(
|
|||||||
BONDRATESETUPID_DTO,
|
BONDRATESETUPID_DTO,
|
||||||
RATE_DTO,
|
RATE_DTO,
|
||||||
EFFDATE_DTO,
|
EFFDATE_DTO,
|
||||||
USERID_DTO
|
USERID_DTO,
|
||||||
|
PCT_VALUE_DTO
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
export class UpdateCargoRateDTO extends IntersectionType(
|
export class UpdateCargoRateDTO extends IntersectionType(
|
||||||
|
|||||||
@ -100,7 +100,9 @@ export class CONTACTSTABLE_ROW_DTO extends IntersectionType(
|
|||||||
PHONE_NO_DTO,
|
PHONE_NO_DTO,
|
||||||
MOBILE_NO_DTO,
|
MOBILE_NO_DTO,
|
||||||
PartialType(FAX_NO_DTO)
|
PartialType(FAX_NO_DTO)
|
||||||
) { }
|
) {
|
||||||
|
FAX_NO: null;
|
||||||
|
}
|
||||||
|
|
||||||
export class CONTACTSTABLE_DTO {
|
export class CONTACTSTABLE_DTO {
|
||||||
@ApiProperty({ required: true, type: () => [CONTACTSTABLE_ROW_DTO] })
|
@ApiProperty({ required: true, type: () => [CONTACTSTABLE_ROW_DTO] })
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { IntersectionType } from '@nestjs/swagger';
|
import { IntersectionType } from '@nestjs/swagger';
|
||||||
import { REGION_CODE_DTO, REGIONID_DTO } from './region-property.dto';
|
import { REGION_CODE_DTO, REGIONID_DTO } from './region-property.dto';
|
||||||
import { NAME_DTO } from '../../property.dto';
|
import { NAME_DTO, SPID_DTO } from '../../property.dto';
|
||||||
|
|
||||||
export class InsertRegionsDto extends IntersectionType(REGION_CODE_DTO, NAME_DTO) { }
|
export class InsertRegionsDto extends IntersectionType(REGION_CODE_DTO, NAME_DTO, SPID_DTO) { }
|
||||||
|
|
||||||
export class UpdateRegionDto extends IntersectionType(REGIONID_DTO, NAME_DTO) { }
|
export class UpdateRegionDto extends IntersectionType(REGIONID_DTO, NAME_DTO) { }
|
||||||
|
|||||||
19
src/exceptions/notFound.exception.ts
Normal file
19
src/exceptions/notFound.exception.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { HttpException, HttpStatus } from '@nestjs/common';
|
||||||
|
|
||||||
|
export class NotFoundException extends HttpException {
|
||||||
|
constructor(
|
||||||
|
message = 'Not Found',
|
||||||
|
// errorCode = 'INTERNAL_ERROR',
|
||||||
|
// data: any = null,
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.NOT_FOUND ,
|
||||||
|
message,
|
||||||
|
// errorCode,
|
||||||
|
// data,
|
||||||
|
},
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -37,7 +37,7 @@ export class RolesGuard implements CanActivate {
|
|||||||
try {
|
try {
|
||||||
const decoded: any = jwt.decode(token);
|
const decoded: any = jwt.decode(token);
|
||||||
|
|
||||||
const roles: string[] = decoded?.resource_access?.['carnet-app']?.roles || [];
|
const roles: string[] = decoded?.resource_access?.[process.env.CLIENT_ID || '']?.roles || [];
|
||||||
const hasRole = requiredRoles.some(role => roles.includes(role));
|
const hasRole = requiredRoles.some(role => roles.includes(role));
|
||||||
|
|
||||||
if (!hasRole) {
|
if (!hasRole) {
|
||||||
@ -46,7 +46,7 @@ export class RolesGuard implements CanActivate {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new UnauthorizedException('Authentication Failed');
|
throw new UnauthorizedException('Unauthorized : Please Request Access for this Resource');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/main.ts
36
src/main.ts
@ -20,7 +20,12 @@ async function bootstrap() {
|
|||||||
'http://localhost:5173',
|
'http://localhost:5173',
|
||||||
'https://policy.alphaomegainfosys.com',
|
'https://policy.alphaomegainfosys.com',
|
||||||
'https://sp.alphaomegainfosys.com',
|
'https://sp.alphaomegainfosys.com',
|
||||||
'https://client.alphaomegainfosys.com'
|
'https://policy-2.alphaomegainfosys.com',
|
||||||
|
'https://client-2.alphaomegainfosys.com',
|
||||||
|
'https://sp-2.alphaomegainfosys.com',
|
||||||
|
'https://policy-1.alphaomegainfosys.com',
|
||||||
|
'https://client-1.alphaomegainfosys.com',
|
||||||
|
'https://sp-1.alphaomegainfosys.com',
|
||||||
],
|
],
|
||||||
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||||
preflightContinue: false,
|
preflightContinue: false,
|
||||||
@ -77,20 +82,43 @@ async function bootstrap() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// app.useGlobalPipes(new ValidationPipe({ exceptionFactory:customExceptionFactory, whitelist: true, forbidNonWhitelisted: true, transform: true }));
|
// app.useGlobalPipes(new ValidationPipe({ exceptionFactory:customExceptionFactory, whitelist: true, forbidNonWhitelisted: true, transform: true }));
|
||||||
|
|
||||||
const config = new DocumentBuilder()
|
const config = new DocumentBuilder()
|
||||||
.setTitle('API')
|
.setTitle('API')
|
||||||
.setDescription('API description')
|
.setDescription('API description')
|
||||||
.setVersion('1.0')
|
.setVersion('1.0')
|
||||||
.addServer(
|
.addServer(
|
||||||
'https://dev.alphaomegainfosys.com/test-api',
|
`https://dev.alphaomegainfosys.com/${process.env.DB_TYPE === "ORACLE" ? "test-api-1" : process.env.DB_TYPE === "PG" ? "test-api-2" : "test-api"}`,
|
||||||
'Development Server 2',
|
'Development Server 2',
|
||||||
)
|
)
|
||||||
.addServer('http://localhost:3000', 'Development Server 1')
|
.addServer('http://localhost:3000', 'Development Server 1')
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
const options: SwaggerDocumentOptions = { autoTagControllers: false };
|
const options: SwaggerDocumentOptions = { autoTagControllers: false };
|
||||||
const documentFactory = () => SwaggerModule.createDocument(app, config, options);
|
// const documentFactory = () => SwaggerModule.createDocument(app, config, options);
|
||||||
SwaggerModule.setup('api', app, documentFactory);
|
// SwaggerModule.setup('api', app, documentFactory);
|
||||||
|
|
||||||
|
const document = SwaggerModule.createDocument(app, config, options);
|
||||||
|
|
||||||
|
// 2. Remove all paths starting with /1 or exactly /1 if not PG
|
||||||
|
if (process.env.DB_TYPE === 'PG') {
|
||||||
|
for (const path of Object.keys(document.paths)) {
|
||||||
|
if (path === '/1' || path.startsWith('/1/')) {
|
||||||
|
delete document.paths[path];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.DB_TYPE === 'ORACLE') {
|
||||||
|
for (const path of Object.keys(document.paths)) {
|
||||||
|
if (path === '/2' || path.startsWith('/2/')) {
|
||||||
|
delete document.paths[path];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Setup Swagger with the modified document
|
||||||
|
SwaggerModule.setup('api', app, document);
|
||||||
|
|
||||||
app.use('/api-json', (req, res) => {
|
app.use('/api-json', (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import {
|
|||||||
AddCountriesDTO,
|
AddCountriesDTO,
|
||||||
AddGenerallistItemsDTO,
|
AddGenerallistItemsDTO,
|
||||||
CA_UpdateHolderDTO,
|
CA_UpdateHolderDTO,
|
||||||
CarnetProcessingCenterDTO, CarnetProcessingCenterDTO2, CopyCarnetDTO, CreateApplicationDTO, DeleteGenerallistItemsDTO, EditGenerallistItemsDTO, GetCarnetControlCenterDTO, GetExtendedSectionDTO, PrintCarnetDTO, PrintGLDTO, SaveCarnetApplicationDTO, SaveExtensionApplicationDTO, TransmitApplicationtoProcessDTO,
|
CapturePaymentDTO,
|
||||||
|
CarnetProcessingCenterDTO, CarnetProcessingCenterDTO2, CopyCarnetDTO, CreateApplicationDTO, DeleteGenerallistItemsDTO, EditGenerallistItemsDTO, GetCarnetControlCenterDTO, GetExtendedSectionDTO, GetOrderDetailsDTO, GetPaymentHistoryDTO, InitiatePaymentDTO, PrintCarnetDTO, PrintGLDTO, SaveCarnetApplicationDTO, SaveExtensionApplicationDTO, SaveHistoryDTO, TransmitApplicationtoProcessDTO,
|
||||||
UpdateExpGoodsAuthRepDTO,
|
UpdateExpGoodsAuthRepDTO,
|
||||||
UpdateShippingDetailsDTO
|
UpdateShippingDetailsDTO
|
||||||
} from 'src/dto/property.dto';
|
} from 'src/dto/property.dto';
|
||||||
@ -25,7 +26,7 @@ import { InternalServerException } from 'src/exceptions/internalServerError.exce
|
|||||||
@ApiTags('Carnet Application - Oracle')
|
@ApiTags('Carnet Application - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('ca', 'sa')
|
@Roles('ca', 'sa')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class CarnetApplicationController {
|
export class CarnetApplicationController {
|
||||||
|
|
||||||
constructor(private readonly carnetApplicationService: CarnetApplicationService) { }
|
constructor(private readonly carnetApplicationService: CarnetApplicationService) { }
|
||||||
@ -271,4 +272,33 @@ export class CarnetApplicationController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[payment]
|
||||||
|
|
||||||
|
@Post('InitiatePayment')
|
||||||
|
async InitiatePayment(@Body() body: InitiatePaymentDTO) {
|
||||||
|
return this.carnetApplicationService.InitiatePayment(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CompletePayment')
|
||||||
|
@HttpCode(200)
|
||||||
|
async CapturePayment(@Body() body: CapturePaymentDTO) {
|
||||||
|
return this.carnetApplicationService.CapturePayment(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Get('OrderDetails/:P_ORDERID')
|
||||||
|
async OrderDetails(@Param() body: GetOrderDetailsDTO) {
|
||||||
|
return this.carnetApplicationService.OrderDetails(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPaymentHistory/:P_APPLICATIONNAME/:P_USERID')
|
||||||
|
async GetPaymentHistory(@Param() body: GetPaymentHistoryDTO) {
|
||||||
|
return this.carnetApplicationService.GetPaymentHistory(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('SaveHistory')
|
||||||
|
@HttpCode(200)
|
||||||
|
async SaveHistory(@Body() body: SaveHistoryDTO) {
|
||||||
|
return this.carnetApplicationService.SaveHistory(body);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,10 +20,18 @@ import {
|
|||||||
CopyCarnetDTO,
|
CopyCarnetDTO,
|
||||||
GetExtendedSectionDTO,
|
GetExtendedSectionDTO,
|
||||||
SaveExtensionApplicationDTO,
|
SaveExtensionApplicationDTO,
|
||||||
CarnetProcessingCenterDTO2
|
CarnetProcessingCenterDTO2,
|
||||||
|
CapturePaymentDTO,
|
||||||
|
InitiatePaymentDTO,
|
||||||
|
GetOrderDetailsDTO,
|
||||||
|
GetPaymentHistoryDTO,
|
||||||
|
SaveHistoryDTO
|
||||||
} from 'src/dto/property.dto';
|
} from 'src/dto/property.dto';
|
||||||
import { OracleService } from '../oracle.service';
|
import { OracleService } from '../oracle.service';
|
||||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||||
|
import axios, { AxiosError, AxiosRequestConfig } from 'axios';
|
||||||
|
import { PaypalService } from 'src/paypal/paypal.service';
|
||||||
|
import { NotFoundException } from 'src/exceptions/notFound.exception';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CarnetApplicationService {
|
export class CarnetApplicationService {
|
||||||
@ -32,7 +40,8 @@ export class CarnetApplicationService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly oracleDBService: OracleDBService,
|
private readonly oracleDBService: OracleDBService,
|
||||||
private readonly oracleService: OracleService
|
private readonly oracleService: OracleService,
|
||||||
|
private readonly payPalService: PaypalService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
// [ CARNETAPPLICATION_PKG ]
|
// [ CARNETAPPLICATION_PKG ]
|
||||||
@ -960,7 +969,7 @@ export class CarnetApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return { statusCode: 200, message: "Extended successfully", ...fres[0] };
|
// return { statusCode: 200, message: "Extended successfully", ...fres[0] };
|
||||||
return fres;
|
return fres.length > 0 ? fres[0] : [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, CarnetApplicationService.name)
|
handleError(error, CarnetApplicationService.name)
|
||||||
} finally {
|
} finally {
|
||||||
@ -1582,4 +1591,376 @@ export class CarnetApplicationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [payment]
|
||||||
|
|
||||||
|
async formatAmount(amount) {
|
||||||
|
if (typeof amount !== 'number' || isNaN(amount)) {
|
||||||
|
throw new Error('Amount must be a valid number');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount < 0) {
|
||||||
|
throw new BadRequestException('Amount must be non-negative');
|
||||||
|
}
|
||||||
|
|
||||||
|
return amount.toFixed(2); // Always returns a string with 2 decimal places
|
||||||
|
}
|
||||||
|
|
||||||
|
async InitiatePayment(body: InitiatePaymentDTO) {
|
||||||
|
// console.log(body);
|
||||||
|
|
||||||
|
const quantity = 1;
|
||||||
|
let orderID: string | null = null
|
||||||
|
|
||||||
|
const formattedAmount = await this.formatAmount(body.P_PRICE * quantity);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const accessToken = await this.payPalService.generateAccessToken();
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// id: "6CU709471L678832M",
|
||||||
|
// href: "https://www.sandbox.paypal.com/checkoutnow?token=6CU709471L678832M"
|
||||||
|
// }
|
||||||
|
|
||||||
|
const response = await axios({
|
||||||
|
url: process.env.PAYPAL_BASE_URL + '/v2/checkout/orders',
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer ' + accessToken
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
intent: 'CAPTURE',
|
||||||
|
purchase_units: [
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'Carnet',
|
||||||
|
description: body.P_DESCRIPTION,
|
||||||
|
quantity: quantity,
|
||||||
|
unit_amount: {
|
||||||
|
currency_code: 'USD',
|
||||||
|
value: formattedAmount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
amount: {
|
||||||
|
currency_code: 'USD',
|
||||||
|
value: formattedAmount,
|
||||||
|
breakdown: {
|
||||||
|
item_total: {
|
||||||
|
currency_code: 'USD',
|
||||||
|
value: formattedAmount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
application_context: {
|
||||||
|
return_url: process.env.BASE_URL + '/complete-order',
|
||||||
|
cancel_url: process.env.BASE_URL + '/cancel-order',
|
||||||
|
shipping_preference: 'NO_SHIPPING',
|
||||||
|
user_action: 'PAY_NOW',
|
||||||
|
brand_name: 'test sample',
|
||||||
|
disable_funding: "card"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
orderID = response?.data?.id;
|
||||||
|
|
||||||
|
// console.log('PayPal create order response headers:', response.headers);
|
||||||
|
// console.log('PayPal create order response data:', response.data);
|
||||||
|
|
||||||
|
const save_result = await this.SaveHistory(
|
||||||
|
{
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: response?.data?.id,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "CREATED",
|
||||||
|
P_USERID: body.P_USERID
|
||||||
|
// "P_PAYMENTERROR": {}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (save_result.statusCode === 200) {
|
||||||
|
return {
|
||||||
|
id: response?.data?.id, href: response?.data?.links?.find(obj => obj.rel === 'approve')?.href
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new InternalServerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// return { id: response.data.id };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating PayPal order:', error.response?.data || error?.message || error);
|
||||||
|
|
||||||
|
|
||||||
|
await this.SaveHistory({
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: orderID,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "FAILED",
|
||||||
|
P_USERID: body.P_USERID,
|
||||||
|
P_PAYMENTERROR: orderID ? error?.message : `Error while creating ORDERID : ${error?.message}`
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
throw new InternalServerException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CapturePayment(body: CapturePaymentDTO) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const approve_result = await this.OrderDetails({ P_ORDERID: body.P_ORDERID });
|
||||||
|
|
||||||
|
const formattedAmount = await this.formatAmount(body.P_PRICE);
|
||||||
|
|
||||||
|
if (approve_result.data.id === body.P_ORDERID
|
||||||
|
&& approve_result.data.status === "APPROVED"
|
||||||
|
&& approve_result.data.purchase_units[0]?.amount?.value === formattedAmount + ""
|
||||||
|
) {
|
||||||
|
await this.SaveHistory({
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: body.P_ORDERID,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "APPROVED",
|
||||||
|
P_USERID: body.P_USERID
|
||||||
|
// P_PAYMENTERROR: `Error while capturing Payment : ${error?.message}`
|
||||||
|
});
|
||||||
|
|
||||||
|
const accessToken = await this.payPalService.generateAccessToken();
|
||||||
|
|
||||||
|
const response = await axios({
|
||||||
|
url: `${process.env.PAYPAL_BASE_URL}/v2/checkout/orders/${body.P_ORDERID}/capture`,
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${accessToken}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const capture = response?.data?.purchase_units?.[0]?.payments?.captures?.[0];
|
||||||
|
// console.log(JSON.stringify(response?.data));
|
||||||
|
|
||||||
|
await this.SaveHistory({
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: body.P_ORDERID,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "COMPLETED",
|
||||||
|
P_USERID: body.P_USERID
|
||||||
|
// P_PAYMENTERROR: `Error while capturing Payment : ${error?.message}`
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Payment successful",
|
||||||
|
amount: `${capture?.amount?.value} ${capture?.amount?.currency_code}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await this.SaveHistory({
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: body.P_ORDERID,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "FAILED",
|
||||||
|
P_USERID: body.P_USERID,
|
||||||
|
P_PAYMENTERROR: `Error while validating user approval`
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new InternalServerException("failed to save approved status");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
const status = error.response?.status || 500;
|
||||||
|
const message = error.response?.data?.message || "Payment failed due to an unexpected error.";
|
||||||
|
|
||||||
|
// Optional: log full error for debugging
|
||||||
|
console.error("PayPal Capture Error:", {
|
||||||
|
status,
|
||||||
|
message,
|
||||||
|
details: error.response?.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status === 404) {
|
||||||
|
await this.SaveHistory({
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: body.P_ORDERID,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "FAILED",
|
||||||
|
P_USERID: body.P_USERID,
|
||||||
|
P_PAYMENTERROR: `ORDERID NOT FOUND : ${error?.message}`
|
||||||
|
});
|
||||||
|
throw new NotFoundException(error.response?.data?.message || error?.message || "Resource Not Found")
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.SaveHistory({
|
||||||
|
P_APPLICATIONNAME: body.P_APPLICATIONNAME,
|
||||||
|
P_ORDERID: body.P_ORDERID,
|
||||||
|
P_PAYMENTAMOUNT: body.P_PRICE,
|
||||||
|
P_STATUS: "FAILED",
|
||||||
|
P_USERID: body.P_USERID,
|
||||||
|
P_PAYMENTERROR: `Error while capturing Payment : ${error?.message}`
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new InternalServerException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async OrderDetails(body: GetOrderDetailsDTO) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Max length of Order ID: 36 characters (UUID)
|
||||||
|
if (!body.P_ORDERID || body.P_ORDERID.length > 36) {
|
||||||
|
throw new BadRequestException("Invalid Order ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessToken = await this.payPalService.generateAccessToken();
|
||||||
|
|
||||||
|
const response = await axios({
|
||||||
|
url: `${process.env.PAYPAL_BASE_URL}/v2/checkout/orders/${body.P_ORDERID}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${accessToken}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log("PayPal Order Details:", JSON.stringify(response.data));
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Order details retrieved successfully",
|
||||||
|
data: response.data,
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
const isAxiosError = error.isAxiosError;
|
||||||
|
|
||||||
|
if (isAxiosError) {
|
||||||
|
const axiosErrorCode = error.code;
|
||||||
|
|
||||||
|
switch (axiosErrorCode) {
|
||||||
|
case 'ECONNABORTED':
|
||||||
|
case 'ETIMEDOUT':
|
||||||
|
console.error("PayPal request timed out. Please try again later.")
|
||||||
|
throw new InternalServerException("Service is currently unreachable. Please try again later.");
|
||||||
|
case 'ENOTFOUND':
|
||||||
|
case 'ECONNREFUSED':
|
||||||
|
console.error("PayPal service is currently unavailable. Please try again later.")
|
||||||
|
throw new InternalServerException("Service is currently unreachable. Please try again later.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const status = error.response?.status || 500;
|
||||||
|
const message = error.response?.data?.message || "Failed to fetch order details.";
|
||||||
|
|
||||||
|
|
||||||
|
console.error("PayPal OrderDetails Error:", {
|
||||||
|
status,
|
||||||
|
message,
|
||||||
|
details: error.response?.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status === 404) {
|
||||||
|
throw new NotFoundException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InternalServerException("A Error Occured while Processing your Request");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetPaymentHistory(body: GetPaymentHistoryDTO) {
|
||||||
|
let connection;
|
||||||
|
try {
|
||||||
|
connection = await this.oracleDBService.getConnection();
|
||||||
|
|
||||||
|
const result = await connection.execute(
|
||||||
|
`BEGIN
|
||||||
|
Pay_GetPaymentHistory(
|
||||||
|
:P_APPLICATIONNAME, :P_USERID, :P_CURSOR
|
||||||
|
);
|
||||||
|
END;`,
|
||||||
|
{
|
||||||
|
P_APPLICATIONNAME: { val: body.P_APPLICATIONNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_CURSOR: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||||
|
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
|
},
|
||||||
|
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||||
|
);
|
||||||
|
|
||||||
|
await connection.commit();
|
||||||
|
|
||||||
|
const outBinds = result.outBinds;
|
||||||
|
if (!outBinds?.P_CURSOR) {
|
||||||
|
this.logger.error('One or more expected cursors are missing from stored procedure output.');
|
||||||
|
throw new InternalServerException("Incomplete data received from the database.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||||
|
|
||||||
|
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||||
|
this.logger.warn(fres[0].ERRORMESG);
|
||||||
|
throw new BadRequestException(fres[0].ERRORMESG)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fres.length > 0 ? fres[0] : {}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error, CarnetApplicationService.name)
|
||||||
|
} finally {
|
||||||
|
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async SaveHistory(body: SaveHistoryDTO) {
|
||||||
|
let connection;
|
||||||
|
try {
|
||||||
|
connection = await this.oracleDBService.getConnection();
|
||||||
|
|
||||||
|
const result = await connection.execute(
|
||||||
|
`BEGIN
|
||||||
|
Pay_SaveHistory(
|
||||||
|
:P_APPLICATIONNAME, :P_ORDERID, :P_PAYMENTAMOUNT, :P_STATUS, :P_USERID, :P_PAYMENTERROR, :P_CURSOR
|
||||||
|
);
|
||||||
|
END;`,
|
||||||
|
{
|
||||||
|
P_APPLICATIONNAME: { val: body.P_APPLICATIONNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_ORDERID: { val: body.P_ORDERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_PAYMENTAMOUNT: { val: body.P_PAYMENTAMOUNT, type: oracledb.DB_TYPE_NUMBER },
|
||||||
|
P_STATUS: { val: body.P_STATUS, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_PAYMENTERROR: { val: body.P_PAYMENTERROR, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_CURSOR: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||||
|
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
|
},
|
||||||
|
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||||
|
);
|
||||||
|
|
||||||
|
await connection.commit();
|
||||||
|
|
||||||
|
const outBinds = result.outBinds;
|
||||||
|
if (!outBinds?.P_CURSOR) {
|
||||||
|
this.logger.error('One or more expected cursors are missing from stored procedure output.');
|
||||||
|
throw new InternalServerException("Incomplete data received from the database.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||||
|
|
||||||
|
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||||
|
this.logger.warn(fres[0].ERRORMESG);
|
||||||
|
throw new BadRequestException(fres[0].ERRORMESG)
|
||||||
|
}
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Saved Successfully", ...fres[0] };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error, CarnetApplicationService.name)
|
||||||
|
} finally {
|
||||||
|
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,12 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('HomePage - Oracle')
|
@ApiTags('HomePage - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('ca', 'sa', 'ua')
|
@Roles('ca', 'sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class HomePageController {
|
export class HomePageController {
|
||||||
constructor(private readonly homePageService: HomePageService) { }
|
constructor(private readonly homePageService: HomePageService) { }
|
||||||
|
|
||||||
|
|
||||||
|
// NOT USED
|
||||||
@Get('GetHomePageData/:P_SPID')
|
@Get('GetHomePageData/:P_SPID')
|
||||||
GetHomePageData(@Param() params: SPID_DTO) {
|
GetHomePageData(@Param() params: SPID_DTO) {
|
||||||
return this.homePageService.GetHomePageData(params);
|
return this.homePageService.GetHomePageData(params);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ export class HomePageService {
|
|||||||
|
|
||||||
constructor(private readonly oracleDBService: OracleDBService) { }
|
constructor(private readonly oracleDBService: OracleDBService) { }
|
||||||
|
|
||||||
|
// NOT USED
|
||||||
async GetHomePageData(params: SPID_DTO) {
|
async GetHomePageData(params: SPID_DTO) {
|
||||||
let connection;
|
let connection;
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('Manage Clients - Oracle')
|
@ApiTags('Manage Clients - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa')
|
@Roles('sa')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class ManageClientsController {
|
export class ManageClientsController {
|
||||||
constructor(private readonly manageClientsService: ManageClientsService) { }
|
constructor(private readonly manageClientsService: ManageClientsService) { }
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,7 @@ export class ManageClientsService {
|
|||||||
P_ISSUINGREGION: null,
|
P_ISSUINGREGION: null,
|
||||||
P_REVENUELOCATION: null,
|
P_REVENUELOCATION: null,
|
||||||
P_USERID: null,
|
P_USERID: null,
|
||||||
|
P_INDUSTRYTYPE: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const reqBody = JSON.parse(JSON.stringify(body));
|
const reqBody = JSON.parse(JSON.stringify(body));
|
||||||
@ -58,6 +59,7 @@ export class ManageClientsService {
|
|||||||
:P_SPID, :P_CLIENTNAME, :P_LOOKUPCODE, :P_ADDRESS1,
|
:P_SPID, :P_CLIENTNAME, :P_LOOKUPCODE, :P_ADDRESS1,
|
||||||
:P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP,
|
:P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP,
|
||||||
:P_COUNTRY, :P_ISSUINGREGION, :P_REVENUELOCATION, :P_USERID,
|
:P_COUNTRY, :P_ISSUINGREGION, :P_REVENUELOCATION, :P_USERID,
|
||||||
|
:P_INDUSTRYTYPE,
|
||||||
:P_CLIENTCURSOR
|
:P_CLIENTCURSOR
|
||||||
);
|
);
|
||||||
END;`,
|
END;`,
|
||||||
@ -74,6 +76,7 @@ export class ManageClientsService {
|
|||||||
P_ISSUINGREGION: { val: finalBody.P_ISSUINGREGION, type: oracledb.DB_TYPE_NVARCHAR },
|
P_ISSUINGREGION: { val: finalBody.P_ISSUINGREGION, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_REVENUELOCATION: { val: finalBody.P_REVENUELOCATION, type: oracledb.DB_TYPE_NVARCHAR },
|
P_REVENUELOCATION: { val: finalBody.P_REVENUELOCATION, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_INDUSTRYTYPE: { val: finalBody.P_INDUSTRYTYPE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_CLIENTCURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
P_CLIENTCURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -118,6 +121,7 @@ export class ManageClientsService {
|
|||||||
P_COUNTRY: null,
|
P_COUNTRY: null,
|
||||||
P_REVENUELOCATION: null,
|
P_REVENUELOCATION: null,
|
||||||
P_USERID: null,
|
P_USERID: null,
|
||||||
|
P_INDUSTRYTYPE: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const reqBody = JSON.parse(JSON.stringify(body));
|
const reqBody = JSON.parse(JSON.stringify(body));
|
||||||
@ -135,7 +139,8 @@ export class ManageClientsService {
|
|||||||
MANAGEPREPARER_PKG.UpdateClient(
|
MANAGEPREPARER_PKG.UpdateClient(
|
||||||
:P_SPID, :P_CLIENTID, :P_PREPARERNAME, :P_ADDRESS1,
|
:P_SPID, :P_CLIENTID, :P_PREPARERNAME, :P_ADDRESS1,
|
||||||
:P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP,
|
:P_ADDRESS2, :P_CITY, :P_STATE, :P_ZIP,
|
||||||
:P_COUNTRY, :P_REVENUELOCATION, :P_USERID, :P_CURSOR
|
:P_COUNTRY, :P_REVENUELOCATION, :P_USERID, :P_INDUSTRYTYPE,
|
||||||
|
:P_CURSOR
|
||||||
);
|
);
|
||||||
END;`,
|
END;`,
|
||||||
{
|
{
|
||||||
@ -150,6 +155,7 @@ export class ManageClientsService {
|
|||||||
P_COUNTRY: { val: finalBody.P_COUNTRY, type: oracledb.DB_TYPE_NVARCHAR },
|
P_COUNTRY: { val: finalBody.P_COUNTRY, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_REVENUELOCATION: { val: finalBody.P_REVENUELOCATION, type: oracledb.DB_TYPE_NVARCHAR },
|
P_REVENUELOCATION: { val: finalBody.P_REVENUELOCATION, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_INDUSTRYTYPE: { val: finalBody.P_INDUSTRYTYPE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('Manage Fee - Oracle')
|
@ApiTags('Manage Fee - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa','ua')
|
@Roles('sa','ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class ManageFeeController {
|
export class ManageFeeController {
|
||||||
constructor(private readonly manageFeeService: ManageFeeService) { }
|
constructor(private readonly manageFeeService: ManageFeeService) { }
|
||||||
|
|
||||||
|
|||||||
@ -195,6 +195,7 @@ export class ManageFeeService {
|
|||||||
MANAGEFEE_SETUP_PKG.CREATEBONDRATE(
|
MANAGEFEE_SETUP_PKG.CREATEBONDRATE(
|
||||||
:P_SPID, :P_HOLDERTYPE, :P_USCIBMEMBERFLAG, :P_SPCLCOMMODITY,
|
:P_SPID, :P_HOLDERTYPE, :P_USCIBMEMBERFLAG, :P_SPCLCOMMODITY,
|
||||||
:P_SPCLCOUNTRY, :P_EFFDATE, :P_RATE, :P_USERID,
|
:P_SPCLCOUNTRY, :P_EFFDATE, :P_RATE, :P_USERID,
|
||||||
|
:P_PCT_VALUE,
|
||||||
:P_CURSOR
|
:P_CURSOR
|
||||||
);
|
);
|
||||||
END;`,
|
END;`,
|
||||||
@ -207,6 +208,7 @@ export class ManageFeeService {
|
|||||||
P_EFFDATE: { val: body.P_EFFDATE, type: oracledb.DB_TYPE_VARCHAR },
|
P_EFFDATE: { val: body.P_EFFDATE, type: oracledb.DB_TYPE_VARCHAR },
|
||||||
P_RATE: { val: body.P_RATE, type: oracledb.DB_TYPE_NUMBER },
|
P_RATE: { val: body.P_RATE, type: oracledb.DB_TYPE_NUMBER },
|
||||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_VARCHAR },
|
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_VARCHAR },
|
||||||
|
P_PCT_VALUE: { val: body.P_PCT_VALUE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -238,7 +240,7 @@ export class ManageFeeService {
|
|||||||
const result = await connection.execute(
|
const result = await connection.execute(
|
||||||
`BEGIN
|
`BEGIN
|
||||||
MANAGEFEE_SETUP_PKG.UPDATEBONDRATE(
|
MANAGEFEE_SETUP_PKG.UPDATEBONDRATE(
|
||||||
:P_BONDRATESETUPID, :P_RATE, :P_EFFDATE, :P_USERID,
|
:P_BONDRATESETUPID, :P_RATE, :P_EFFDATE, :P_USERID, :P_PCT_VALUE,
|
||||||
:P_CURSOR
|
:P_CURSOR
|
||||||
);
|
);
|
||||||
END;`,
|
END;`,
|
||||||
@ -247,6 +249,7 @@ export class ManageFeeService {
|
|||||||
P_RATE: { val: body.P_RATE, type: oracledb.DB_TYPE_NUMBER },
|
P_RATE: { val: body.P_RATE, type: oracledb.DB_TYPE_NUMBER },
|
||||||
P_EFFDATE: { val: body.P_EFFDATE, type: oracledb.DB_TYPE_NVARCHAR },
|
P_EFFDATE: { val: body.P_EFFDATE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
|
P_PCT_VALUE: { val: body.P_PCT_VALUE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
|||||||
@ApiTags('Manage Holders - Oracle')
|
@ApiTags('Manage Holders - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('ca', 'sa')
|
@Roles('ca', 'sa')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class ManageHoldersController {
|
export class ManageHoldersController {
|
||||||
constructor(private readonly manageHoldersService: ManageHoldersService) { }
|
constructor(private readonly manageHoldersService: ManageHoldersService) { }
|
||||||
|
|
||||||
|
|||||||
@ -10,11 +10,13 @@ import { UserMaintenanceModule } from './user-maintenance/user-maintenance.modul
|
|||||||
import { CarnetApplicationModule } from './carnet-application/carnet-application.module';
|
import { CarnetApplicationModule } from './carnet-application/carnet-application.module';
|
||||||
import { OracleService } from './oracle.service';
|
import { OracleService } from './oracle.service';
|
||||||
import { AuthModule } from 'src/auth/auth.module';
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
import { PaypalModule } from 'src/paypal/paypal.module';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
DbModule,
|
DbModule,
|
||||||
|
PaypalModule,
|
||||||
CarnetApplicationModule,
|
CarnetApplicationModule,
|
||||||
UserMaintenanceModule,
|
UserMaintenanceModule,
|
||||||
HomePageModule,
|
HomePageModule,
|
||||||
@ -28,4 +30,4 @@ import { AuthModule } from 'src/auth/auth.module';
|
|||||||
controllers: [],
|
controllers: [],
|
||||||
exports: [OracleService, UserMaintenanceModule],
|
exports: [OracleService, UserMaintenanceModule],
|
||||||
})
|
})
|
||||||
export class OracleModule {}
|
export class OracleModule { }
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('Param Table - Oracle')
|
@ApiTags('Param Table - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa', 'ua')
|
@Roles('sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class ParamTableController {
|
export class ParamTableController {
|
||||||
constructor(private readonly paramTableService: ParamTableService) { }
|
constructor(private readonly paramTableService: ParamTableService) { }
|
||||||
|
|
||||||
|
|||||||
@ -175,7 +175,7 @@ export class ParamTableService {
|
|||||||
throw new BadRequestException(fres[0].ERRORMESG)
|
throw new BadRequestException(fres[0].ERRORMESG)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { statusCode: 201, message: "Createdted Successfully", ...fres[0] };
|
return { statusCode: 201, message: "Created Successfully", ...fres[0] };
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, ParamTableService.name)
|
handleError(error, ParamTableService.name)
|
||||||
@ -230,7 +230,7 @@ export class ParamTableService {
|
|||||||
throw new BadRequestException(fres[0].ERRORMESG)
|
throw new BadRequestException(fres[0].ERRORMESG)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { statusCode: 201, message: "Createdted Successfully", ...fres[0] };
|
return { statusCode: 201, message: "Created Successfully", ...fres[0] };
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error, ParamTableService.name)
|
handleError(error, ParamTableService.name)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('Carnet Sequence - Oracle')
|
@ApiTags('Carnet Sequence - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa', 'ua')
|
@Roles('sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class CarnetSequenceController {
|
export class CarnetSequenceController {
|
||||||
constructor(private readonly carnetSequenceService: CarnetSequenceService) { }
|
constructor(private readonly carnetSequenceService: CarnetSequenceService) { }
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { RegionService } from './region.service';
|
import { RegionService } from './region.service';
|
||||||
|
|
||||||
import { Get, Post, Body, Controller, Patch, UseGuards } from '@nestjs/common';
|
import { Get, Post, Body, Controller, Patch, UseGuards, Param } from '@nestjs/common';
|
||||||
|
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Roles } from 'src/decorators/roles.decorator';
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
|
||||||
import { InsertRegionsDto, UpdateRegionDto } from 'src/dto/property.dto';
|
import { InsertRegionsDto, SPID_DTO, UpdateRegionDto } from 'src/dto/property.dto';
|
||||||
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
import { RolesGuard } from 'src/guards/roles.guard';
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
|
||||||
@ApiTags('Regions - Oracle')
|
@ApiTags('Regions - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa', 'ua')
|
@Roles('sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class RegionController {
|
export class RegionController {
|
||||||
constructor(private readonly regionService: RegionService) { }
|
constructor(private readonly regionService: RegionService) { }
|
||||||
|
|
||||||
@ -26,9 +26,9 @@ export class RegionController {
|
|||||||
return this.regionService.updateRegions(body);
|
return this.regionService.updateRegions(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('/GetRegions')
|
@Get('/GetRegions/:P_SPID')
|
||||||
getRegions() {
|
getRegions(@Param() param: SPID_DTO) {
|
||||||
return this.regionService.getRegions();
|
return this.regionService.getRegions(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
|||||||
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper';
|
import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper';
|
||||||
|
|
||||||
import { InsertRegionsDto, UpdateRegionDto } from 'src/dto/property.dto';
|
import { InsertRegionsDto, SPID_DTO, UpdateRegionDto } from 'src/dto/property.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RegionService {
|
export class RegionService {
|
||||||
@ -21,11 +21,12 @@ export class RegionService {
|
|||||||
|
|
||||||
const result = await connection.execute(
|
const result = await connection.execute(
|
||||||
`BEGIN
|
`BEGIN
|
||||||
USCIB_Managed_Pkg.InsertNewRegion(:P_REGION,:P_NAME,:P_CURSOR);
|
USCIB_Managed_Pkg.InsertNewRegion(:P_REGION, :P_NAME, :P_SPID, :P_CURSOR);
|
||||||
END;`,
|
END;`,
|
||||||
{
|
{
|
||||||
P_REGION: { val: body.P_REGION, type: oracledb.DB_TYPE_VARCHAR },
|
P_REGION: { val: body.P_REGION, type: oracledb.DB_TYPE_VARCHAR },
|
||||||
P_NAME: { val: body.P_NAME, type: oracledb.DB_TYPE_VARCHAR },
|
P_NAME: { val: body.P_NAME, type: oracledb.DB_TYPE_VARCHAR },
|
||||||
|
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
|
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
|
||||||
},
|
},
|
||||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||||
@ -95,16 +96,17 @@ export class RegionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRegions() {
|
async getRegions(body: SPID_DTO) {
|
||||||
let connection;
|
let connection;
|
||||||
try {
|
try {
|
||||||
connection = await this.oracleDBService.getConnection();
|
connection = await this.oracleDBService.getConnection();
|
||||||
|
|
||||||
const result = await connection.execute(
|
const result = await connection.execute(
|
||||||
`BEGIN
|
`BEGIN
|
||||||
USCIB_Managed_Pkg.GetRegions(:P_CURSOR);
|
USCIB_Managed_Pkg.GetRegions(:P_SPID, :P_CURSOR);
|
||||||
END;`,
|
END;`,
|
||||||
{
|
{
|
||||||
|
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
},
|
},
|
||||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('SPContacts - Oracle')
|
@ApiTags('SPContacts - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa', 'ua')
|
@Roles('sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class SpContactsController {
|
export class SpContactsController {
|
||||||
constructor(private readonly spContactsService: SpContactsService) { }
|
constructor(private readonly spContactsService: SpContactsService) { }
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
|||||||
@ApiTags('SP - Oracle')
|
@ApiTags('SP - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('sa', 'ua')
|
@Roles('sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class SpController {
|
export class SpController {
|
||||||
constructor(private readonly spService: SpService) { }
|
constructor(private readonly spService: SpService) { }
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Body, Controller, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
|
import { Body, Controller, Get, Param, Patch, Post, Query, Req, UseGuards } from '@nestjs/common';
|
||||||
import { UserMaintenanceService } from './user-maintenance.service';
|
import { UserMaintenanceService } from './user-maintenance.service';
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@ -10,11 +10,12 @@ import {
|
|||||||
import { Roles } from 'src/decorators/roles.decorator';
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
import { RolesGuard } from 'src/guards/roles.guard';
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { Request } from 'express';
|
||||||
|
|
||||||
@ApiTags('User Maintenance - Oracle')
|
@ApiTags('User Maintenance - Oracle')
|
||||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
@Roles('ca', 'sa', 'ua')
|
@Roles('ca', 'sa', 'ua')
|
||||||
@Controller('oracle')
|
@Controller('1')
|
||||||
export class UserMaintenanceController {
|
export class UserMaintenanceController {
|
||||||
constructor(private readonly userMaintenanceService: UserMaintenanceService) { }
|
constructor(private readonly userMaintenanceService: UserMaintenanceService) { }
|
||||||
|
|
||||||
@ -74,8 +75,8 @@ export class UserMaintenanceController {
|
|||||||
|
|
||||||
@Post('CreateClientLogins')
|
@Post('CreateClientLogins')
|
||||||
@Roles('sa')
|
@Roles('sa')
|
||||||
async CreateClientLogins(@Body() body: CreateClientLoginsDTO) {
|
async CreateClientLogins(@Body() body: CreateClientLoginsDTO, @Req() req: Request) {
|
||||||
return await this.userMaintenanceService.CreateClientLogins(body);
|
return await this.userMaintenanceService.CreateClientLogins(body, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate email
|
// validate email
|
||||||
|
|||||||
@ -7,6 +7,6 @@ import { AuthModule } from 'src/auth/auth.module';
|
|||||||
imports: [forwardRef(() => AuthModule)],
|
imports: [forwardRef(() => AuthModule)],
|
||||||
controllers: [UserMaintenanceController],
|
controllers: [UserMaintenanceController],
|
||||||
providers: [UserMaintenanceService],
|
providers: [UserMaintenanceService],
|
||||||
exports: [UserMaintenanceService, AuthModule]
|
exports: [UserMaintenanceService]
|
||||||
})
|
})
|
||||||
export class UserMaintenanceModule { }
|
export class UserMaintenanceModule { }
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
|||||||
import { OracleDBService } from 'src/db/db.service';
|
import { OracleDBService } from 'src/db/db.service';
|
||||||
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
import * as oracledb from 'oracledb';
|
import * as oracledb from 'oracledb';
|
||||||
import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper';
|
import { closeOracleDbConnection, extractSubdomain, fetchCursor, handleError } from 'src/utils/helper';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SPID_DTO,
|
SPID_DTO,
|
||||||
@ -12,6 +12,7 @@ import {
|
|||||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||||
import { AuthService } from 'src/auth/auth.service';
|
import { AuthService } from 'src/auth/auth.service';
|
||||||
import { MailTypeDTO } from 'src/auth/auth.dto';
|
import { MailTypeDTO } from 'src/auth/auth.dto';
|
||||||
|
import { Request } from 'express';
|
||||||
|
|
||||||
|
|
||||||
interface RoleDetail { [key: string]: any; }
|
interface RoleDetail { [key: string]: any; }
|
||||||
@ -356,7 +357,7 @@ export class UserMaintenanceService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async CreateClientLogins(body: CreateClientLoginsDTO) {
|
async CreateClientLogins(body: CreateClientLoginsDTO, req: Request) {
|
||||||
let connection;
|
let connection;
|
||||||
try {
|
try {
|
||||||
connection = await this.oracleDBService.getConnection();
|
connection = await this.oracleDBService.getConnection();
|
||||||
@ -392,10 +393,18 @@ export class UserMaintenanceService {
|
|||||||
throw new BadRequestException(fres[0].ERRORMESG)
|
throw new BadRequestException(fres[0].ERRORMESG)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_CLIENT })
|
let appDomain;
|
||||||
|
if (req.headers.origin) {
|
||||||
|
appDomain = extractSubdomain(req.headers.origin)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appDomain = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_CLIENT }, appDomain)
|
||||||
|
|
||||||
if (mailRes.statusCode !== 200) {
|
if (mailRes.statusCode !== 200) {
|
||||||
return new InternalServerException();
|
throw new InternalServerException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return { statusCode: 201, message: "Client registration initiated successfully", ...fres[0] };
|
return { statusCode: 201, message: "Client registration initiated successfully", ...fres[0] };
|
||||||
|
|||||||
4
src/paypal/paypal.controller.ts
Normal file
4
src/paypal/paypal.controller.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Controller } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Controller('paypal')
|
||||||
|
export class PaypalController {}
|
||||||
10
src/paypal/paypal.module.ts
Normal file
10
src/paypal/paypal.module.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Global, Module } from '@nestjs/common';
|
||||||
|
import { PaypalController } from './paypal.controller';
|
||||||
|
import { PaypalService } from './paypal.service';
|
||||||
|
|
||||||
|
@Global()
|
||||||
|
@Module({
|
||||||
|
providers: [PaypalService],
|
||||||
|
exports: [PaypalService]
|
||||||
|
})
|
||||||
|
export class PaypalModule { }
|
||||||
69
src/paypal/paypal.service.ts
Normal file
69
src/paypal/paypal.service.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// paypal.service.ts
|
||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PaypalService {
|
||||||
|
private accessToken: string | null = null;
|
||||||
|
private tokenExpiresAt: number = 0; // Unix timestamp in milliseconds
|
||||||
|
|
||||||
|
private readonly clientId = process.env.PAYPAL_CLIENT_ID;
|
||||||
|
private readonly clientSecret = process.env.PAYPAL_CLIENT_SECRET;
|
||||||
|
private readonly baseUrl = process.env.PAYPAL_BASE_URL; // or live URL
|
||||||
|
|
||||||
|
private readonly logger = new Logger(PaypalService.name);
|
||||||
|
|
||||||
|
async generateAccessToken(): Promise<any> {
|
||||||
|
|
||||||
|
// return process.env.PAYPAL_AT
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
// Check if token is still valid
|
||||||
|
if (this.accessToken && now < this.tokenExpiresAt - 60_000) {
|
||||||
|
return this.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch new token
|
||||||
|
const auth = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const tokenUrl = process.env.PAYPAL_BASE_URL + '/v1/oauth2/token';
|
||||||
|
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.append('grant_type', 'client_credentials');
|
||||||
|
|
||||||
|
const response = await axios.post(
|
||||||
|
tokenUrl,
|
||||||
|
params.toString(), // or use `params` directly
|
||||||
|
{
|
||||||
|
auth: {
|
||||||
|
username: process.env.PAYPAL_CLIENT_ID!,
|
||||||
|
password: process.env.PAYPAL_SECRET!,
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const { access_token, expires_in } = response.data;
|
||||||
|
|
||||||
|
this.accessToken = access_token;
|
||||||
|
this.tokenExpiresAt = now + expires_in * 1000; // convert seconds to ms
|
||||||
|
|
||||||
|
// this.logger.warn(`Fetched new PayPal access token, expires in ${access_token} seconds`);
|
||||||
|
// console.log(access_token);
|
||||||
|
|
||||||
|
|
||||||
|
if (this.accessToken) {
|
||||||
|
return this.accessToken;
|
||||||
|
}
|
||||||
|
throw new InternalServerException("Error while getting paypal access token")
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Failed to fetch PayPal access token', error);
|
||||||
|
throw new InternalServerException('PayPal token fetch failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
308
src/pg/carnet-application/carnet-application.controller.ts
Normal file
308
src/pg/carnet-application/carnet-application.controller.ts
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post, Put, Res, StreamableFile, UseGuards } from '@nestjs/common';
|
||||||
|
import { CarnetApplicationService } from './carnet-application.service';
|
||||||
|
|
||||||
|
import {
|
||||||
|
AddCountriesDTO,
|
||||||
|
AddGenerallistItemsDTO,
|
||||||
|
CA_UpdateHolderDTO,
|
||||||
|
CapturePaymentDTO,
|
||||||
|
CarnetProcessingCenterDTO, CarnetProcessingCenterDTO2, CopyCarnetDTO, CreateApplicationDTO, DeleteGenerallistItemsDTO, EditGenerallistItemsDTO, GetCarnetControlCenterDTO, GetCarnetDetailsbyCarnetStatusDTO, GetExtendedSectionDTO, GetOrderDetailsDTO, GetPaymentHistoryDTO, InitiatePaymentDTO, PrintCarnetDTO, PrintGLDTO, SaveCarnetApplicationDTO, SaveExtensionApplicationDTO, SaveHistoryDTO, TransmitApplicationtoProcessDTO,
|
||||||
|
UpdateExpGoodsAuthRepDTO,
|
||||||
|
UpdateShippingDetailsDTO
|
||||||
|
} from 'src/dto/property.dto';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { deleteFilesAsync, generateFinalPDF, replaceSlashWithDash } from 'src/utils/helper';
|
||||||
|
import { Response } from 'express';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||||
|
import { createReadStream } from 'fs';
|
||||||
|
import { BadRequestException as BR } from 'src/exceptions/badRequest.exception';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { ApiExcludeController, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
@ApiTags('Carnet Application - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
@Controller('2')
|
||||||
|
export class CarnetApplicationController {
|
||||||
|
constructor(private readonly carnetApplicationService: CarnetApplicationService) { }
|
||||||
|
|
||||||
|
// [ CARNETAPPLICATION_PKG ]
|
||||||
|
|
||||||
|
// not used
|
||||||
|
// @Post('SaveCarnetApplication')
|
||||||
|
// async CreateClientData(@Body() body: SaveCarnetApplicationDTO) {
|
||||||
|
// return this.carnetApplicationService.SaveCarnetApplication(body);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Post('TransmitApplicationtoProcess')
|
||||||
|
@Roles('pca')
|
||||||
|
TransmitApplicationtoProcess(@Body() body: TransmitApplicationtoProcessDTO) {
|
||||||
|
return this.carnetApplicationService.TransmitApplicationtoProcess(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateApplication')
|
||||||
|
@Roles('pca')
|
||||||
|
CreateApplication(@Body() body: CreateApplicationDTO) {
|
||||||
|
return this.carnetApplicationService.CreateApplication(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('update-holder')
|
||||||
|
UpdateHolder(@Body() body: CA_UpdateHolderDTO) {
|
||||||
|
return this.carnetApplicationService.UpdateHolder(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('UpdateExpGoodsAuthRep')
|
||||||
|
UpdateExpGoodsAuthRep(@Body() body: UpdateExpGoodsAuthRepDTO) {
|
||||||
|
return this.carnetApplicationService.UpdateExpGoodsAuthRep(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('AddGenerallistItems')
|
||||||
|
AddGenerallistItems(@Body() body: AddGenerallistItemsDTO) {
|
||||||
|
return this.carnetApplicationService.AddGenerallistItems(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('EditGenerallistItems')
|
||||||
|
EditGenerallistItems(@Body() body: EditGenerallistItemsDTO) {
|
||||||
|
return this.carnetApplicationService.EditGenerallistItems(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete('DeleteGenerallistItems')
|
||||||
|
DeleteGenerallistItems(@Body() body: DeleteGenerallistItemsDTO) {
|
||||||
|
return this.carnetApplicationService.DeleteGenerallistItems(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('AddCountries')
|
||||||
|
AddCountries(@Body() body: AddCountriesDTO) {
|
||||||
|
return this.carnetApplicationService.AddCountries(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('UpdateShippingDetails')
|
||||||
|
UpdateShippingDetails(@Body() body: UpdateShippingDetailsDTO) {
|
||||||
|
return this.carnetApplicationService.UpdateShippingDetails(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('EstimatedFees/:P_SPID/:P_USERID/:P_HEADERID')
|
||||||
|
EstimatedFees(@Param() body: GetCarnetControlCenterDTO) {
|
||||||
|
return this.carnetApplicationService.EstimatedFees(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// // processing [ PROCESSINGCENTER_PKG ]
|
||||||
|
|
||||||
|
@Patch('ProcessCarnet')
|
||||||
|
ProcessCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||||
|
return this.carnetApplicationService.ProcessCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('UpdatePrintCarnet')
|
||||||
|
UpdatePrintCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||||
|
return this.carnetApplicationService.UpdatePrintCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('VoidCarnet')
|
||||||
|
@Roles('psa')
|
||||||
|
VoidCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||||
|
return this.carnetApplicationService.VoidCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('CopyCarnet')
|
||||||
|
CopyCarnet(@Body() body: CopyCarnetDTO) {
|
||||||
|
return this.carnetApplicationService.CopyCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('DuplicateCarnet')
|
||||||
|
DuplicateCarnet(@Body() body: CarnetProcessingCenterDTO2) {
|
||||||
|
return this.carnetApplicationService.DuplicateCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('AddlSets')
|
||||||
|
AddlSets(@Body() body: CarnetProcessingCenterDTO2) {
|
||||||
|
return this.carnetApplicationService.AddlSets(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('ExtendCarnet')
|
||||||
|
ExtendCarnet(@Body() body: CarnetProcessingCenterDTO2) {
|
||||||
|
return this.carnetApplicationService.ExtendCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetExtendedSection/:P_SPID/:P_HEADERID')
|
||||||
|
GetExtendedSection(@Param() body: GetExtendedSectionDTO) {
|
||||||
|
return this.carnetApplicationService.GetExtendedSection(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('SaveExtensionApplication')
|
||||||
|
@HttpCode(200)
|
||||||
|
SaveExtensionApplication(@Body() body: SaveExtensionApplicationDTO) {
|
||||||
|
return this.carnetApplicationService.SaveExtensionApplication(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('CloseCarnet')
|
||||||
|
@Roles('psa')
|
||||||
|
CloseCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||||
|
return this.carnetApplicationService.CloseCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('ResetCarnet')
|
||||||
|
@Roles('psa')
|
||||||
|
ResetCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||||
|
return this.carnetApplicationService.ResetCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete('DeleteCarnet')
|
||||||
|
DeleteCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||||
|
return this.carnetApplicationService.DeleteCarnet(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [ CARNETCONTROLCENTER_PKG ]
|
||||||
|
|
||||||
|
@Get('GetHolderstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||||
|
GetHolderstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||||
|
return this.carnetApplicationService.GetHolderstoEdit(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetGoodsDetailstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||||
|
GetGoodsDetailstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||||
|
return this.carnetApplicationService.GetGoodsDetailstoEdit(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetGoodsItemstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||||
|
GetGoodsItemstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||||
|
return this.carnetApplicationService.GetGoodsItemstoEdit(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetCountryDetailstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||||
|
GetCountryDetailstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||||
|
return this.carnetApplicationService.GetCountryDetailstoEdit(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetShipPaymentDetailstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||||
|
GetShipPaymentDetailstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||||
|
return this.carnetApplicationService.GetShipPaymentDetailstoEdit(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetCarnetDetailsbyCarnetStatus/:P_SPID/:P_USERID/:P_CARNETSTATUS')
|
||||||
|
@Roles('pca', 'psa', 'pua')
|
||||||
|
GetCarnetDetailsbyCarnetStatus(@Param() params: GetCarnetDetailsbyCarnetStatusDTO) {
|
||||||
|
return this.carnetApplicationService.GetCarnetDetailsbyCarnetStatus(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [PRINT_PKG]
|
||||||
|
@Post('PrintCarnet')
|
||||||
|
@HttpCode(200)
|
||||||
|
async PrintCarnet(@Body() body: PrintCarnetDTO, @Res({ passthrough: true }) res: Response) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { finalArray, carnetData }: any = await this.carnetApplicationService.PrintCarnet(body);
|
||||||
|
// const filterCarnetData = finalArray.filter(item => item !== '2GeneralList.pdf')
|
||||||
|
|
||||||
|
let filesArray = [`${replaceSlashWithDash(carnetData.carnetNo)}p1.pdf`, `${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`];
|
||||||
|
// await generateFinalPDF([...filesArray, '2GeneralList.pdf', ...carnetData], 'carnet.pdf');
|
||||||
|
await generateFinalPDF([...filesArray, ...finalArray, '13LastSheetP3.pdf', '13LastSheetP4.pdf'], `${replaceSlashWithDash(carnetData.carnetNo)}carnet.pdf`);
|
||||||
|
|
||||||
|
const fileName = `${replaceSlashWithDash(carnetData.carnetNo)}carnet.pdf`;
|
||||||
|
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'application/pdf',
|
||||||
|
'Content-Disposition': `attachment; filename="${fileName}"`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const filePath = join(process.cwd(), 'dist/public/carnet-pdf', fileName); //server
|
||||||
|
// const filePath = join(process.cwd(), 'public/carnet-pdf', fileName); //local
|
||||||
|
|
||||||
|
console.log(filePath);
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(filePath);
|
||||||
|
|
||||||
|
const stream = createReadStream(filePath);
|
||||||
|
|
||||||
|
// Clean up files after response finishes streaming
|
||||||
|
res.on('finish', async () => {
|
||||||
|
await deleteFilesAsync([...filesArray, ...finalArray.filter(x => x !== `${replaceSlashWithDash(carnetData.carnetNo)}p2.pdf`), fileName]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return new StreamableFile(stream);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof BadRequestException || error instanceof BR) {
|
||||||
|
throw new BadRequestException("Download failed please check the details")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new InternalServerException("Error while downloading");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('PrintGL')
|
||||||
|
@HttpCode(200)
|
||||||
|
async PrintGL(@Body() body: PrintGLDTO, @Res({ passthrough: true }) res: Response) {
|
||||||
|
try {
|
||||||
|
const { finalArray, carnetData }: any = await this.carnetApplicationService.PrintGL(body);
|
||||||
|
|
||||||
|
let filesArray = [`${body.P_HEADERID}p2.pdf`];
|
||||||
|
// await generateFinalPDF([...filesArray, '2GeneralList.pdf', ...carnetData], 'carnet.pdf');
|
||||||
|
await generateFinalPDF([...filesArray, ...finalArray], `${body.P_HEADERID}-GL.pdf`);
|
||||||
|
|
||||||
|
const fileName = `${body.P_HEADERID}-GL.pdf`;
|
||||||
|
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'application/pdf',
|
||||||
|
'Content-Disposition': `attachment; filename="${fileName}"`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const filePath = join(process.cwd(), 'dist/public/carnet-pdf', fileName); //server
|
||||||
|
// const filePath = join(process.cwd(), 'public/carnet-pdf', fileName); //local
|
||||||
|
|
||||||
|
// console.log(filePath);
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(filePath);
|
||||||
|
|
||||||
|
const stream = createReadStream(filePath);
|
||||||
|
|
||||||
|
// Clean up files after response finishes streaming
|
||||||
|
res.on('finish', async () => {
|
||||||
|
await deleteFilesAsync([...filesArray, ...finalArray, fileName]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return new StreamableFile(stream);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof BadRequestException || error instanceof BR) {
|
||||||
|
throw new BadRequestException("Download failed please check the details")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new InternalServerException("Error while downloading");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//[payment]
|
||||||
|
|
||||||
|
@Post('InitiatePayment')
|
||||||
|
async InitiatePayment(@Body() body: InitiatePaymentDTO) {
|
||||||
|
return this.carnetApplicationService.InitiatePayment(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CompletePayment')
|
||||||
|
@HttpCode(200)
|
||||||
|
async CapturePayment(@Body() body: CapturePaymentDTO) {
|
||||||
|
return this.carnetApplicationService.CapturePayment(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Get('OrderDetails/:P_ORDERID')
|
||||||
|
async OrderDetails(@Param() body: GetOrderDetailsDTO) {
|
||||||
|
return this.carnetApplicationService.OrderDetails(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPaymentHistory/:P_APPLICATIONNAME/:P_USERID')
|
||||||
|
async GetPaymentHistory(@Param() body: GetPaymentHistoryDTO) {
|
||||||
|
return this.carnetApplicationService.GetPaymentHistory(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('SaveHistory')
|
||||||
|
@HttpCode(200)
|
||||||
|
async SaveHistory(@Body() body: SaveHistoryDTO) {
|
||||||
|
return this.carnetApplicationService.SaveHistory(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/carnet-application/carnet-application.module.ts
Normal file
11
src/pg/carnet-application/carnet-application.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { CarnetApplicationController } from './carnet-application.controller';
|
||||||
|
import { CarnetApplicationService } from './carnet-application.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [CarnetApplicationController],
|
||||||
|
providers: [CarnetApplicationService]
|
||||||
|
})
|
||||||
|
export class CarnetApplicationModule {}
|
||||||
1752
src/pg/carnet-application/carnet-application.service.ts
Normal file
1752
src/pg/carnet-application/carnet-application.service.ts
Normal file
File diff suppressed because it is too large
Load Diff
92
src/pg/manage-clients/manage-clients.controller.ts
Normal file
92
src/pg/manage-clients/manage-clients.controller.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
|
||||||
|
import { ClientContactControlsDTO, CreateClientContactsDTO, CreateClientDataDTO, CreateClientLocationsDTO, GetClientContactByLacationIdDTO, GetClientDTO, GetPreparersParamDTO, GetPreparersQueryDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO } from 'src/dto/property.dto';
|
||||||
|
import { ManageClientsService } from './manage-clients.service';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
|
||||||
|
@ApiTags('Manage Clients - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa')
|
||||||
|
@Controller('2')
|
||||||
|
export class ManageClientsController {
|
||||||
|
constructor(private readonly manageClientsService: ManageClientsService) { }
|
||||||
|
|
||||||
|
@Post('CreateNewClients')
|
||||||
|
async CreateClientData(@Body() body: CreateClientDataDTO) {
|
||||||
|
return this.manageClientsService.CreateClientData(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('UpdateClient')
|
||||||
|
async UpdateClient(@Body() body: UpdateClientDTO) {
|
||||||
|
return this.manageClientsService.UpdateClient(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('UpdateClientContacts')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
UpdateClientContacts(@Body() body: UpdateClientContactsDTO) {
|
||||||
|
return this.manageClientsService.UpdateClientContacts(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('UpdateClientLocations')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
UpdateClientLocations(@Body() body: UpdateClientLocationsDTO) {
|
||||||
|
return this.manageClientsService.UpdateClientLocations(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateClientContacts')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
CreateClientContact(@Body() body: CreateClientContactsDTO) {
|
||||||
|
return this.manageClientsService.CreateClientContact(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('SetDefaultClientContacts/:P_SPID/:P_CLIENTCONTACTID/:P_USERID')
|
||||||
|
SetDefaultClientContacts(@Param() param: ClientContactControlsDTO) {
|
||||||
|
return this.manageClientsService.SetDefaultClientContacts(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('InactivateClientContacts/:P_SPID/:P_CLIENTCONTACTID/:P_USERID')
|
||||||
|
InactivateClientContacts(@Param() param: ClientContactControlsDTO) {
|
||||||
|
return this.manageClientsService.InactivateClientContacts(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('ReactivateClientContacts/:P_SPID/:P_CLIENTCONTACTID/:P_USERID')
|
||||||
|
ReactivateClientContacts(@Param() param: ClientContactControlsDTO) {
|
||||||
|
return this.manageClientsService.ReactivateClientContacts(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateClientLocations')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
CreateClientLocation(@Body() body: CreateClientLocationsDTO) {
|
||||||
|
return this.manageClientsService.CreateClientLocation(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPreparers/:P_SPID/:P_STATUS')
|
||||||
|
async GetPreparers(@Param() param: GetPreparersParamDTO, @Query() query: GetPreparersQueryDTO) {
|
||||||
|
return await this.manageClientsService.GetPreparers({ ...param, ...query });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPreparerByClientid/:P_SPID/:P_CLIENTID')
|
||||||
|
GetPreparerByClientid(@Param() body: GetClientDTO) {
|
||||||
|
return this.manageClientsService.GetPreparerByClientid(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPreparerContactsByClientid/:P_SPID/:P_CLIENTID')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
GetPreparerContactsByClientid(@Param() body: GetClientDTO) {
|
||||||
|
return this.manageClientsService.GetPreparerContactsByClientid(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPreparerContactsbyClientLocationID/:P_SPID/:P_LOCATIONID')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
GetPreparerContactsbyClientLocationID(@Param() body: GetClientContactByLacationIdDTO) {
|
||||||
|
return this.manageClientsService.GetPreparerContactsbyClientLocationID(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetPreparerLocByClientid/:P_SPID/:P_CLIENTID')
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
GetPreparerLocByClientid(@Param() body: GetClientDTO) {
|
||||||
|
return this.manageClientsService.GetPreparerLocByClientid(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/manage-clients/manage-clients.module.ts
Normal file
11
src/pg/manage-clients/manage-clients.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { ManageClientsController } from './manage-clients.controller';
|
||||||
|
import { ManageClientsService } from './manage-clients.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [ManageClientsController],
|
||||||
|
providers: [ManageClientsService]
|
||||||
|
})
|
||||||
|
export class ManageClientsModule {}
|
||||||
642
src/pg/manage-clients/manage-clients.service.ts
Normal file
642
src/pg/manage-clients/manage-clients.service.ts
Normal file
@ -0,0 +1,642 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { ClientContactControlsDTO, CreateClientContactsDTO, CreateClientDataDTO, CreateClientLocationsDTO, GetClientContactByLacationIdDTO, GetClientDTO, GetPreparersDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO } from 'src/dto/property.dto';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ManageClientsService {
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
CreateClientData = async (body: CreateClientDataDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_createclientdata($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CLIENTNAME,
|
||||||
|
body.P_LOOKUPCODE,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_ISSUINGREGION,
|
||||||
|
body.P_REVENUELOCATION,
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_INDUSTRYTYPE,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateClient = async (body: UpdateClientDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_updateclient($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CLIENTID,
|
||||||
|
body.P_PREPARERNAME,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_REVENUELOCATION,
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_INDUSTRYTYPE,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateClientContacts = async (body: UpdateClientContactsDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_updateclientcontacts($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CLIENTCONTACTID,
|
||||||
|
body.P_FIRSTNAME,
|
||||||
|
body.P_LASTNAME,
|
||||||
|
body.P_MIDDLEINITIAL,
|
||||||
|
body.P_TITLE,
|
||||||
|
body.P_PHONENO,
|
||||||
|
body.P_FAXNO,
|
||||||
|
body.P_MOBILENO,
|
||||||
|
body.P_EMAILADDRESS,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateClientLocations = async (body: UpdateClientLocationsDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_updateclientlocations($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CLIENTLOCATIONID,
|
||||||
|
body.P_LOCATIONNAME,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async CreateClientContact(body: CreateClientContactsDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
// Helper to escape special characters for Postgres composite fields
|
||||||
|
function escapePostgresCompositeField(str: string): string {
|
||||||
|
if (str == null) return '';
|
||||||
|
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||||||
|
}
|
||||||
|
|
||||||
|
const contactLiterals = body.P_CONTACTSTABLE.map(c => {
|
||||||
|
const fields = [
|
||||||
|
c.P_FIRSTNAME || '',
|
||||||
|
c.P_LASTNAME || '',
|
||||||
|
c.P_MIDDLEINITIAL || '',
|
||||||
|
c.P_TITLE || '',
|
||||||
|
c.P_EMAILADDRESS || '',
|
||||||
|
c.P_PHONENO || '',
|
||||||
|
c.P_MOBILENO || '',
|
||||||
|
c.P_FAXNO || '',
|
||||||
|
].map(field => escapePostgresCompositeField(field)).join(',');
|
||||||
|
|
||||||
|
|
||||||
|
return `"(${fields})"`; // Composite literal wrapped in double quotes
|
||||||
|
});
|
||||||
|
|
||||||
|
const pgArrayLiteral = `{${contactLiterals.join(',')}}`;
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_createclientcontact($1, $2, $3::"CARNETSYS".contactstable[], $4, $5, $6)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_LOCATIONID,
|
||||||
|
pgArrayLiteral,
|
||||||
|
body.P_DEFCONTACTFLAG,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDefaultClientContacts = async (body: ClientContactControlsDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_setdefaultclientcontacts($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTCONTACTID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InactivateClientContacts = async (body: ClientContactControlsDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_inactivateclientcontacts($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTCONTACTID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.inActivate,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactivateClientContacts = async (body: ClientContactControlsDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_reactivateclientcontacts($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTCONTACTID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.reActivate,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateClientLocation = async (body: CreateClientLocationsDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
function escapePostgresCompositeField(str: string): string {
|
||||||
|
if (str == null) return '';
|
||||||
|
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||||||
|
}
|
||||||
|
|
||||||
|
const addressLiterals = body.P_CLIENTLOCADDRESSTABLE.map(c => {
|
||||||
|
const fields = [
|
||||||
|
c.P_NAMEOF || '',
|
||||||
|
c.P_ADDRESS1 || '',
|
||||||
|
c.P_ADDRESS2 || '',
|
||||||
|
c.P_CITY || '',
|
||||||
|
c.P_STATE || '',
|
||||||
|
c.P_ZIP || '',
|
||||||
|
c.P_COUNTRY || '',
|
||||||
|
].map(field => escapePostgresCompositeField(field)).join(',');
|
||||||
|
|
||||||
|
|
||||||
|
return `"(${fields})"`; // Composite literal wrapped in double quotes
|
||||||
|
});
|
||||||
|
|
||||||
|
const pgArrayLiteral = `{${addressLiterals.join(',')}}`;
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_createclientlocation($1, $2, $3::"CARNETSYS".addresstable[], $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CLIENTID,
|
||||||
|
pgArrayLiteral,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetPreparers = async (body: GetPreparersDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_getpreparers($1, $2, $3, $4, $5, $6, $7)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_NAME, body.P_LOOKUPCODE, body.P_CITY, body.P_STATE, body.P_STATUS, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetPreparerByClientid = async (body: GetClientDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_GetPreparerByClientid($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows)[0] ?? [];
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetPreparerContactsByClientid = async (body: GetClientDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_getpreparercontactsbyclientid($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetPreparerContactsbyClientLocationID = async (body: GetClientContactByLacationIdDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_getpreparercontactsbyclientlocationid($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_LOCATIONID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetPreparerLocByClientid = async (body: GetClientDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managepreparer_pkg_getpreparerlocbyclientid($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageClientsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
139
src/pg/manage-fee/manage-fee.controller.ts
Normal file
139
src/pg/manage-fee/manage-fee.controller.ts
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, UseGuards } from '@nestjs/common';
|
||||||
|
import { ManageFeeService } from './manage-fee.service';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { CreateBasicFeeDTO, CreateBondRateDTO, CreateCargoRateDTO, CreateCfFeeDTO, CreateCsFeeDTO, CreateEfFeeDTO, CreateFeeCommDTO, GetFeeGeneralDTO, UpdateBasicFeeDTO, UpdateBondRateDTO, UpdateCargoRateDTO, UpdateCfFeeDTO, UpdateCsFeeDTO, UpdateEfFeeDTO, UpdateFeeCommDTO } from 'src/dto/property.dto';
|
||||||
|
|
||||||
|
@ApiTags('Manage Fee - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class ManageFeeController {
|
||||||
|
|
||||||
|
constructor(private readonly manageFeeService: ManageFeeService) { }
|
||||||
|
|
||||||
|
@Get('/GetBasicFeeRates/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETBASICFEERATES(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETBASICFEERATES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateBasicFee')
|
||||||
|
CREATEBASICFEE(@Body() body: CreateBasicFeeDTO) {
|
||||||
|
return this.manageFeeService.CREATEBASICFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/UpdateBasicFee')
|
||||||
|
UPDATEBASICFEE(@Body() body: UpdateBasicFeeDTO) {
|
||||||
|
return this.manageFeeService.UPDATEBASICFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bond rate
|
||||||
|
|
||||||
|
@Get('/GetBondRates/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETBONDRATES(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETBONDRATES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateBondRate')
|
||||||
|
CREATEBONDRATE(@Body() body: CreateBondRateDTO) {
|
||||||
|
return this.manageFeeService.CREATEBONDRATE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Patch('/UpdateBondRate')
|
||||||
|
UPDATEBONDRATE(@Body() body: UpdateBondRateDTO) {
|
||||||
|
return this.manageFeeService.UPDATEBONDRATE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cargo rate
|
||||||
|
|
||||||
|
@Get('/GetCargoRates/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETCARGORATES(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETCARGORATES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Post('/CreateCargoRate')
|
||||||
|
CREATECARGORATE(@Body() body: CreateCargoRateDTO) {
|
||||||
|
return this.manageFeeService.CREATECARGORATE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Patch('/UpdateCargoRate')
|
||||||
|
UPDATECARGORATE(@Body() body: UpdateCargoRateDTO) {
|
||||||
|
return this.manageFeeService.UPDATECARGORATE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cf fee rate
|
||||||
|
|
||||||
|
@Get('/GetCfFeeRates/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETCFFEERATES(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETCFFEERATES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Post('/CreateCfFee')
|
||||||
|
CREATECFFEE(@Body() body: CreateCfFeeDTO) {
|
||||||
|
return this.manageFeeService.CREATECFFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/UpdateCfFee')
|
||||||
|
UPDATECFFEE(@Body() body: UpdateCfFeeDTO) {
|
||||||
|
return this.manageFeeService.UPDATECFFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cs fee rate
|
||||||
|
|
||||||
|
@Get('/GetCsFeeRates/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETCSFEERATES(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETCSFEERATES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateCsFee')
|
||||||
|
CREATECSFEE(@Body() body: CreateCsFeeDTO) {
|
||||||
|
return this.manageFeeService.CREATECSFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/UpdateCsFee')
|
||||||
|
UPDATECSFEE(@Body() body: UpdateCsFeeDTO) {
|
||||||
|
return this.manageFeeService.UPDATECSFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ef fee rate
|
||||||
|
|
||||||
|
@Get('/GetEfFeeRates/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETEFFEERATES(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETEFFEERATES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateEfFee')
|
||||||
|
CREATEEFFEE(@Body() body: CreateEfFeeDTO) {
|
||||||
|
return this.manageFeeService.CREATEEFFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/UpdateEfFee')
|
||||||
|
UPDATEEFFEE(@Body() body: UpdateEfFeeDTO) {
|
||||||
|
return this.manageFeeService.UPDATEEFFEE(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fee comm
|
||||||
|
|
||||||
|
@Get('/GetFeeComm/:P_SPID/:P_ACTIVE_INACTIVE')
|
||||||
|
GETFEECOMM(@Param() body: GetFeeGeneralDTO) {
|
||||||
|
return this.manageFeeService.GETFEECOMM(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Post('/CreateFeeComm')
|
||||||
|
CREATEFEECOMM(@Body() body: CreateFeeCommDTO) {
|
||||||
|
return this.manageFeeService.CREATEFEECOMM(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Patch('/UpdateFeeComm')
|
||||||
|
UPDATEFEECOMM(@Body() body: UpdateFeeCommDTO) {
|
||||||
|
return this.manageFeeService.UPDATEFEECOMM(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/manage-fee/manage-fee.module.ts
Normal file
11
src/pg/manage-fee/manage-fee.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { ManageFeeController } from './manage-fee.controller';
|
||||||
|
import { ManageFeeService } from './manage-fee.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [ManageFeeController],
|
||||||
|
providers: [ManageFeeService]
|
||||||
|
})
|
||||||
|
export class ManageFeeModule {}
|
||||||
947
src/pg/manage-fee/manage-fee.service.ts
Normal file
947
src/pg/manage-fee/manage-fee.service.ts
Normal file
@ -0,0 +1,947 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { CreateBasicFeeDTO, CreateBondRateDTO, CreateCargoRateDTO, CreateCfFeeDTO, CreateCsFeeDTO, CreateEfFeeDTO, CreateFeeCommDTO, GetFeeGeneralDTO, UpdateBasicFeeDTO, UpdateBondRateDTO, UpdateCargoRateDTO, UpdateCfFeeDTO, UpdateCsFeeDTO, UpdateEfFeeDTO, UpdateFeeCommDTO } from 'src/dto/property.dto';
|
||||||
|
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ManageFeeService {
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
async GETBASICFEERATES(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_getbasicfeerates($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATEBASICFEE(body: CreateBasicFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createbasicfee($1, $2, $3, $4, $5, $6, $7)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_STARTNUMBER,
|
||||||
|
body.P_ENDNUMBER,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_FEES,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATEBASICFEE(body: UpdateBasicFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updatebasicfee($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_BASICFEESETUPID,
|
||||||
|
body.P_FEES,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bond rate
|
||||||
|
|
||||||
|
async GETBONDRATES(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_getbondrates($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATEBONDRATE(body: CreateBondRateDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createbondrate($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_HOLDERTYPE,
|
||||||
|
body.P_USCIBMEMBERFLAG,
|
||||||
|
body.P_SPCLCOMMODITY,
|
||||||
|
body.P_SPCLCOUNTRY,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_PCT_VALUE,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATEBONDRATE(body: UpdateBondRateDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updatebondrate($1, $2, $3, $4, $5, $6)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_BONDRATESETUPID,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_PCT_VALUE,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// cargo rate
|
||||||
|
|
||||||
|
async GETCARGORATES(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_getcargorates($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATECARGORATE(body: CreateCargoRateDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createcargorate($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CARNETTYPE,
|
||||||
|
body.P_STARTSETS,
|
||||||
|
body.P_ENDSETS,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATECARGORATE(body: UpdateCargoRateDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updatecargorate($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_CARGORATESETUPID,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// counter foil
|
||||||
|
|
||||||
|
async GETCFFEERATES(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_getcffeerates($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATECFFEE(body: CreateCfFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createcffee($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_STARTSETS,
|
||||||
|
body.P_ENDSETS,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_CUSTOMERTYPE,
|
||||||
|
body.P_CARNETTYPE,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATECFFEE(body: UpdateCfFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updatecffee($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_CFFEESETUPID,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// continuation sheet
|
||||||
|
|
||||||
|
async GETCSFEERATES(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_getcsfeerates($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATECSFEE(body: CreateCsFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createcsfee($1, $2, $3, $4, $5, $6, $7)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CUSTOMERTYPE,
|
||||||
|
body.P_CARNETTYPE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATECSFEE(body: UpdateCsFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updatecsfee($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_CSFEESETUPID,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// expedited fee
|
||||||
|
|
||||||
|
async GETEFFEERATES(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_geteffeerates($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATEEFFEE(body: CreateEfFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createeffee($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CUSTOMERTYPE,
|
||||||
|
body.P_DELIVERYTYPE,
|
||||||
|
body.P_STARTTIME,
|
||||||
|
body.P_ENDTIME,
|
||||||
|
body.P_TIMEZONE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_FEES,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATEEFFEE(body: UpdateEfFeeDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updateeffee($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_EFFEESETUPID,
|
||||||
|
body.P_FEES,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fee comm
|
||||||
|
|
||||||
|
async GETFEECOMM(body: GetFeeGeneralDTO) {
|
||||||
|
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_getfeecomm($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_ACTIVE_INACTIVE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATEFEECOMM(body: CreateFeeCommDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_createfeecomm($1, $2, $3, $4, $5, $6)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_PARAMID,
|
||||||
|
body.P_COMMRATE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATEFEECOMM(body: UpdateFeeCommDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".managefee_setup_pkg_updatefeecomm($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_FEECOMMID,
|
||||||
|
body.P_RATE,
|
||||||
|
body.P_EFFDATE,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageFeeService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
109
src/pg/manage-holder/manage-holder.controller.ts
Normal file
109
src/pg/manage-holder/manage-holder.controller.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiQuery, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { CreateHolderContactsDTO, CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO, HolderContactActivateOrInactivateDTO, UpdateHolderContactDTO, UpdateHolderDTO } from 'src/dto/property.dto';
|
||||||
|
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||||
|
import { ManageHolderService } from './manage-holder.service';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
|
||||||
|
@ApiTags('Manage Holders - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('pca', 'psa')
|
||||||
|
@Controller('2')
|
||||||
|
export class ManageHolderController {
|
||||||
|
|
||||||
|
constructor(private readonly manageHoldersService: ManageHolderService) { }
|
||||||
|
|
||||||
|
@Get('SearchHolder/:P_SPID/:P_USERID')
|
||||||
|
@ApiQuery({ name: "P_HOLDERNAME", type: String, required: false, description: "Optional" })
|
||||||
|
@ApiQuery({ name: "P_HOLDERID", type: Number, required: false, description: "Optional" })
|
||||||
|
SearchHolder(
|
||||||
|
@Param('P_SPID') P_SPID: number,
|
||||||
|
@Param('P_USERID') P_USERID: string,
|
||||||
|
@Query('P_HOLDERID') P_HOLDERID?: number,
|
||||||
|
@Query('P_HOLDERNAME') P_HOLDERNAME?: string | null | undefined,
|
||||||
|
) {
|
||||||
|
if (!P_USERID) {
|
||||||
|
throw new BadRequestException('User ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitize holder name
|
||||||
|
let rawHolderName: string | null = null;
|
||||||
|
|
||||||
|
if (typeof P_HOLDERNAME === 'string') {
|
||||||
|
const trimmed = P_HOLDERNAME.trim().replace(/^['"]|['"]$/g, '');
|
||||||
|
rawHolderName = trimmed === '' || trimmed.toLowerCase() === 'null' ? null : trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate and coerce P_HOLDERID
|
||||||
|
let holderId: number | null = null;
|
||||||
|
|
||||||
|
if (P_HOLDERID !== undefined && P_HOLDERID !== null) {
|
||||||
|
const parsed = Number(P_HOLDERID);
|
||||||
|
if (isNaN(parsed)) {
|
||||||
|
throw new BadRequestException('Invalid holder ID');
|
||||||
|
}
|
||||||
|
holderId = parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
P_SPID,
|
||||||
|
P_USERID,
|
||||||
|
P_HOLDERID: holderId,
|
||||||
|
P_HOLDERNAME: rawHolderName,
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.manageHoldersService.SearchHolder(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateHolderData')
|
||||||
|
CreateHolders(@Body() body: CreateHoldersDTO) {
|
||||||
|
return this.manageHoldersService.CreateHolders(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateHoldercontact')
|
||||||
|
CreateHoldercontact(@Body() body: CreateHolderContactsDTO) {
|
||||||
|
return this.manageHoldersService.CreateHoldercontact(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('/UpdateHolder')
|
||||||
|
UpdateHolder(@Body() body: UpdateHolderDTO) {
|
||||||
|
return this.manageHoldersService.UpdateHolder(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetHolderRecord/:P_SPID/:P_HOLDERID')
|
||||||
|
GetHolderRecord(@Param() body: GetHolderDTO) {
|
||||||
|
return this.manageHoldersService.GetHolderRecord(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('/UpdateHolderContact')
|
||||||
|
UpdateHolderContact(@Body() body: UpdateHolderContactDTO) {
|
||||||
|
return this.manageHoldersService.UpdateHolderContact(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetHolderContacts/:P_SPID/:P_HOLDERID')
|
||||||
|
GetHolderContacts(@Param() body: GetHolderDTO) {
|
||||||
|
return this.manageHoldersService.GetHolderContacts(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/InactivateHolder/:P_SPID/:P_HOLDERID/:P_USERID')
|
||||||
|
InactivateHolder(@Param() body: HolderActivateOrInactivateDTO) {
|
||||||
|
return this.manageHoldersService.InactivateHolder(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/ReactivateHolder/:P_SPID/:P_HOLDERID/:P_USERID')
|
||||||
|
ReactivateHolder(@Param() body: HolderActivateOrInactivateDTO) {
|
||||||
|
return this.manageHoldersService.ReactivateHolder(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/InactivateHolderContact/:P_SPID/:P_HOLDERCONTACTID/:P_USERID')
|
||||||
|
InactivateHolderContact(@Param() body: HolderContactActivateOrInactivateDTO) {
|
||||||
|
return this.manageHoldersService.InactivateHolderContact(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/ReactivateHolderContact/:P_SPID/:P_HOLDERCONTACTID/:P_USERID')
|
||||||
|
ReactivateHolderContact(@Param() body: HolderContactActivateOrInactivateDTO) {
|
||||||
|
return this.manageHoldersService.ReactivateHolderContact(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/manage-holder/manage-holder.module.ts
Normal file
11
src/pg/manage-holder/manage-holder.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { ManageHolderController } from './manage-holder.controller';
|
||||||
|
import { ManageHolderService } from './manage-holder.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [ManageHolderController],
|
||||||
|
providers: [ManageHolderService]
|
||||||
|
})
|
||||||
|
export class ManageHolderModule {}
|
||||||
499
src/pg/manage-holder/manage-holder.service.ts
Normal file
499
src/pg/manage-holder/manage-holder.service.ts
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { CONTACTSTABLE_ROW_DTO, CreateHolderContactsDTO, CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO, HolderContactActivateOrInactivateDTO, UpdateHolderContactDTO, UpdateHolderDTO } from 'src/dto/property.dto';
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ManageHolderService {
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
SearchHolder = async (body: { P_SPID: number, P_USERID: string, P_HOLDERID: number | null, P_HOLDERNAME: string | null }) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_searchholder($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, body.P_HOLDERNAME, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateHolders(body: CreateHoldersDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_createholderdata($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_CLIENTLOCATIONID,
|
||||||
|
body.P_HOLDERNO,
|
||||||
|
body.P_HOLDERTYPE,
|
||||||
|
body.P_USCIBMEMBERFLAG,
|
||||||
|
body.P_GOVAGENCYFLAG,
|
||||||
|
body.P_HOLDERNAME,
|
||||||
|
body.P_NAMEQUALIFIER,
|
||||||
|
body.P_ADDLNAME,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateHoldercontact(body: CreateHolderContactsDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
// Helper to escape special characters for Postgres composite fields
|
||||||
|
function escapePostgresCompositeField(str: string): string {
|
||||||
|
if (str == null) return '';
|
||||||
|
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const contactLiterals = body.P_CONTACTSTABLE.map(c => {
|
||||||
|
const fields = [
|
||||||
|
c.P_FIRSTNAME || '',
|
||||||
|
c.P_LASTNAME || '',
|
||||||
|
c.P_MIDDLEINITIAL || '',
|
||||||
|
c.P_TITLE || '',
|
||||||
|
c.P_EMAILADDRESS || '',
|
||||||
|
c.P_PHONENO || '',
|
||||||
|
c.P_MOBILENO || '',
|
||||||
|
c.P_FAXNO || '',
|
||||||
|
].map(field => escapePostgresCompositeField(field)).join(',');
|
||||||
|
|
||||||
|
|
||||||
|
return `"(${fields})"`; // Composite literal wrapped in double quotes
|
||||||
|
});
|
||||||
|
|
||||||
|
const pgArrayLiteral = `{${contactLiterals.join(',')}}`;
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_createholdercontact($1, $2, $3::"CARNETSYS".contactstable[], $4, $5)
|
||||||
|
`;
|
||||||
|
|
||||||
|
await client.query(callProcQuery, [
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_HOLDERID,
|
||||||
|
pgArrayLiteral,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Fetch results from cursor (do NOT quote cursor name)
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// Close cursor
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name);
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateHolder = async (body: UpdateHolderDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_updateholder($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_HOLDERID,
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_LOCATIONID,
|
||||||
|
body.P_HOLDERNO,
|
||||||
|
body.P_HOLDERTYPE,
|
||||||
|
body.P_USCIBMEMBERFLAG,
|
||||||
|
body.P_GOVAGENCYFLAG,
|
||||||
|
body.P_HOLDERNAME,
|
||||||
|
body.P_NAMEQUALIFIER,
|
||||||
|
body.P_ADDLNAME,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetHolderRecord = async (body: GetHolderDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_getholdermaster($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows)[0]??[];
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateHolderContact = async (body: UpdateHolderContactDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_updateholdercontacts($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_HOLDERCONTACTID,
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_FIRSTNAME,
|
||||||
|
body.P_LASTNAME,
|
||||||
|
body.P_MIDDLEINITIAL,
|
||||||
|
body.P_TITLE,
|
||||||
|
body.P_PHONENO,
|
||||||
|
body.P_MOBILENO,
|
||||||
|
body.P_FAXNO,
|
||||||
|
body.P_EMAILADDRESS,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetHolderContacts = async (body: GetHolderDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_getholdercontacts($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InactivateHolder = async (body: HolderActivateOrInactivateDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_inactivateholder($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.inActivate,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactivateHolder = async (body: HolderActivateOrInactivateDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_reactivateholder($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.reActivate,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_inactivateholdercontact($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERCONTACTID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.inActivate,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageholder_pkg_reactivateholdercontact($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_HOLDERCONTACTID, body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.reActivate,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ManageHolderService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
86
src/pg/param-table/param-table.controller.ts
Normal file
86
src/pg/param-table/param-table.controller.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, Put, Query, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiQuery, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { ParamTableService } from './param-table.service';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ActivateOrInactivateParamRecordDTO, CreateParamRecordDTO, CreateTableRecordDTO,
|
||||||
|
getParamValuesDTO, SPID_DTO, UpdateParamRecordDTO
|
||||||
|
} from 'src/dto/property.dto';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
|
||||||
|
@ApiTags('Param Table - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class ParamTableController {
|
||||||
|
|
||||||
|
constructor(private readonly paramTableService: ParamTableService) { }
|
||||||
|
|
||||||
|
@Get('/GetParamValues')
|
||||||
|
@Roles('pca', 'psa', 'pua')
|
||||||
|
@ApiQuery({
|
||||||
|
name: 'P_SPID',
|
||||||
|
required: false,
|
||||||
|
type: Number,
|
||||||
|
description: 'The ID of the parameter',
|
||||||
|
})
|
||||||
|
@ApiQuery({
|
||||||
|
name: 'P_PARAMTYPE',
|
||||||
|
required: false,
|
||||||
|
type: String,
|
||||||
|
description: 'The type of the parameter',
|
||||||
|
})
|
||||||
|
GETPARAMVALUES(@Query() body: getParamValuesDTO) {
|
||||||
|
return this.paramTableService.GETPARAMVALUES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetAllParamValues')
|
||||||
|
@ApiQuery({
|
||||||
|
name: 'P_SPID',
|
||||||
|
required: false,
|
||||||
|
type: Number,
|
||||||
|
description: 'The ID of the parameter',
|
||||||
|
})
|
||||||
|
@ApiQuery({
|
||||||
|
name: 'P_PARAMTYPE',
|
||||||
|
required: false,
|
||||||
|
type: String,
|
||||||
|
description: 'The type of the parameter',
|
||||||
|
})
|
||||||
|
GETALLPARAMVALUES(@Query() body: getParamValuesDTO) {
|
||||||
|
return this.paramTableService.GETALLPARAMVALUES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetCountriesAndMessages/:P_SPID')
|
||||||
|
@Roles('pca', 'psa', 'pua')
|
||||||
|
GET_COUNTRIES_AND_MESSAGES(@Param() body: SPID_DTO) {
|
||||||
|
return this.paramTableService.GET_COUNTRIES_AND_MESSAGES(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateTableRecord')
|
||||||
|
CREATETABLERECORD(@Body() body: CreateTableRecordDTO) {
|
||||||
|
return this.paramTableService.CREATETABLERECORD(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/CreateParamRecord')
|
||||||
|
CREATEPARAMRECORD(@Body() body: CreateParamRecordDTO) {
|
||||||
|
return this.paramTableService.CREATEPARAMRECORD(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/UpdateParamRecord')
|
||||||
|
UPDATEPARAMRECORD(@Body() body: UpdateParamRecordDTO) {
|
||||||
|
return this.paramTableService.UPDATEPARAMRECORD(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/InActivateParamRecord')
|
||||||
|
INACTIVATEPARAMRECORD(@Body() body: ActivateOrInactivateParamRecordDTO) {
|
||||||
|
return this.paramTableService.INACTIVATEPARAMRECORD(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/ReActivateParamRecord')
|
||||||
|
REACTIVATEPARAMRECORD(@Body() body: ActivateOrInactivateParamRecordDTO) {
|
||||||
|
return this.paramTableService.REACTIVATEPARAMRECORD(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/param-table/param-table.module.ts
Normal file
11
src/pg/param-table/param-table.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { ParamTableController } from './param-table.controller';
|
||||||
|
import { ParamTableService } from './param-table.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [ParamTableController],
|
||||||
|
providers: [ParamTableService]
|
||||||
|
})
|
||||||
|
export class ParamTableModule { }
|
||||||
312
src/pg/param-table/param-table.service.ts
Normal file
312
src/pg/param-table/param-table.service.ts
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { ActivateOrInactivateParamRecordDTO, CreateParamRecordDTO, CreateTableRecordDTO, getParamValuesDTO, SPID_DTO, UpdateParamRecordDTO } from 'src/dto/property.dto';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ParamTableService {
|
||||||
|
private readonly logger = new Logger(ParamTableService.name);
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
async GETPARAMVALUES(body: getParamValuesDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_getparamvalues($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_PARAMTYPE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async GETALLPARAMVALUES(body: getParamValuesDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_getallparamvalues($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_PARAMTYPE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async GET_COUNTRIES_AND_MESSAGES(body: SPID_DTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_getcountriesandmessages($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATETABLERECORD(body: CreateTableRecordDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_createtablerecord($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_USERID, body.P_TABLEFULLDESC, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
let fr: any = toUpperCaseKeys(fetchResult?.rows)
|
||||||
|
|
||||||
|
// return fetchResult.rows;
|
||||||
|
return { statusCode: 201, message: ResponseStatus.created, ...fr[0] };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CREATEPARAMRECORD(body: CreateParamRecordDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
// Call the stored procedure
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_createparamrecord(
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
await client.query(callProcQuery, [
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_PARAMTYPE,
|
||||||
|
body.P_PARAMDESC,
|
||||||
|
body.P_PARAMVALUE,
|
||||||
|
body.P_ADDLPARAMVALUE1,
|
||||||
|
body.P_ADDLPARAMVALUE2,
|
||||||
|
body.P_ADDLPARAMVALUE3,
|
||||||
|
body.P_ADDLPARAMVALUE4,
|
||||||
|
body.P_ADDLPARAMVALUE5,
|
||||||
|
body.P_SORTSEQ,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// ✅ Correct: quote the cursor name when using it in SQL
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM "${cursorName}"`);
|
||||||
|
|
||||||
|
// ✅ Always close the cursor
|
||||||
|
await client.query(`CLOSE "${cursorName}"`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
let fr: any = toUpperCaseKeys(fetchResult?.rows)
|
||||||
|
|
||||||
|
// Return response
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...fr[0] || {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async UPDATEPARAMRECORD(body: UpdateParamRecordDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_updateparamrecord(
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
await client.query(callProcQuery, [
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_PARAMID,
|
||||||
|
body.P_PARAMDESC,
|
||||||
|
body.P_ADDLPARAMVALUE1,
|
||||||
|
body.P_ADDLPARAMVALUE2,
|
||||||
|
body.P_ADDLPARAMVALUE3,
|
||||||
|
body.P_ADDLPARAMVALUE4,
|
||||||
|
body.P_ADDLPARAMVALUE5,
|
||||||
|
body.P_SORTSEQ,
|
||||||
|
body.P_USERID,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// ✅ Correct: quote the cursor name when using it in SQL
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM "${cursorName}"`);
|
||||||
|
|
||||||
|
// ✅ Always close the cursor
|
||||||
|
await client.query(`CLOSE "${cursorName}"`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
// Return response
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async INACTIVATEPARAMRECORD(body: ActivateOrInactivateParamRecordDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_inactivateparamrecord($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_PARAMID, body.P_USERID]);
|
||||||
|
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.inActivate
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async REACTIVATEPARAMRECORD(body: ActivateOrInactivateParamRecordDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".manageparamtable_pkg_reactivateparamrecord($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_PARAMID, body.P_USERID]);
|
||||||
|
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.reActivate
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, ParamTableService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/pg/pg.module.ts
Normal file
17
src/pg/pg.module.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Global, Module } from '@nestjs/common';
|
||||||
|
import { ParamTableModule } from './param-table/param-table.module';
|
||||||
|
import { DbModule } from 'src/db/db.module';
|
||||||
|
import { UscibManagedSpModule } from './uscib-managed-sp/uscib-managed-sp.module';
|
||||||
|
import { UserMaintenanceModule } from './user-maintenance/user-maintenance.module';
|
||||||
|
import { ManageFeeModule } from './manage-fee/manage-fee.module';
|
||||||
|
import { ManageHolderModule } from './manage-holder/manage-holder.module';
|
||||||
|
import { ManageClientsModule } from './manage-clients/manage-clients.module';
|
||||||
|
import { CarnetApplicationModule } from './carnet-application/carnet-application.module';
|
||||||
|
|
||||||
|
@Global()
|
||||||
|
@Module({
|
||||||
|
imports: [DbModule, ParamTableModule, UscibManagedSpModule, UserMaintenanceModule, ManageFeeModule, ManageHolderModule, ManageClientsModule, CarnetApplicationModule],
|
||||||
|
providers: [],
|
||||||
|
exports: [UserMaintenanceModule]
|
||||||
|
})
|
||||||
|
export class PgModule { }
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { Body, Controller, Get, Param, Post, UseGuards } from '@nestjs/common';
|
||||||
|
import { CarnetSequenceService } from './carnet-sequence.service';
|
||||||
|
import { CreateCarnetSequenceDTO, SPID_DTO } from 'src/dto/property.dto';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
|
||||||
|
@ApiTags('Carnet Sequence - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class CarnetSequenceController {
|
||||||
|
constructor(private readonly carnetSequenceService: CarnetSequenceService) { }
|
||||||
|
|
||||||
|
@Post('/CreateCarnetSequence/')
|
||||||
|
createCarnetSequence(@Body() body: CreateCarnetSequenceDTO) {
|
||||||
|
return this.carnetSequenceService.createCarnetSequence(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetCarnetSequence/:P_SPID')
|
||||||
|
getCarnetSequence(@Param() params: SPID_DTO) {
|
||||||
|
return this.carnetSequenceService.getCarnetSequence(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { CarnetSequenceController } from './carnet-sequence.controller';
|
||||||
|
import { CarnetSequenceService } from './carnet-sequence.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [CarnetSequenceController],
|
||||||
|
providers: [CarnetSequenceService]
|
||||||
|
})
|
||||||
|
export class CarnetSequenceModule {}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { CreateCarnetSequenceDTO, SPID_DTO } from 'src/dto/property.dto';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CarnetSequenceService {
|
||||||
|
private readonly logger = new Logger(CarnetSequenceService.name);
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
async createCarnetSequence(body: CreateCarnetSequenceDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_createcarnetsequence($1, $2, $3, $4, $5, $6)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_REGIONID, body.P_STARTNUMBER, body.P_ENDNUMBER, body.P_CARNETTYPE, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return { statusCode: 201, message: ResponseStatus.created, ...toUpperCaseKeys(fetchResult?.rows)[0] };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, CarnetSequenceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCarnetSequence(body: SPID_DTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_getcarnetsequence($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, CarnetSequenceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/pg/uscib-managed-sp/region/region.controller.ts
Normal file
30
src/pg/uscib-managed-sp/region/region.controller.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { RegionService } from './region.service';
|
||||||
|
import { InsertRegionsDto, SPID_DTO, UpdateRegionDto } from 'src/dto/property.dto';
|
||||||
|
|
||||||
|
@ApiTags('Regions - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class RegionController {
|
||||||
|
constructor(private readonly regionService: RegionService) { }
|
||||||
|
|
||||||
|
@Post('/InsertRegions')
|
||||||
|
insertRegions(@Body() body: InsertRegionsDto) {
|
||||||
|
return this.regionService.insertRegions(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/UpdateRegion')
|
||||||
|
updateRegions(@Body() body: UpdateRegionDto) {
|
||||||
|
return this.regionService.updateRegions(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetRegions/:P_SPID')
|
||||||
|
getRegions(@Param() param: SPID_DTO) {
|
||||||
|
return this.regionService.getRegions(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/uscib-managed-sp/region/region.module.ts
Normal file
11
src/pg/uscib-managed-sp/region/region.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { RegionController } from './region.controller';
|
||||||
|
import { RegionService } from './region.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [RegionController],
|
||||||
|
providers: [RegionService]
|
||||||
|
})
|
||||||
|
export class RegionModule { }
|
||||||
120
src/pg/uscib-managed-sp/region/region.service.ts
Normal file
120
src/pg/uscib-managed-sp/region/region.service.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { InsertRegionsDto, SPID_DTO, UpdateRegionDto } from 'src/dto/property.dto';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RegionService {
|
||||||
|
private readonly logger = new Logger(RegionService.name);
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
async insertRegions(body: InsertRegionsDto) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_insertnewregion($1, $2, $3, $4)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_REGION, body.P_NAME, body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, RegionService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateRegions(body: UpdateRegionDto) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_updateregion($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_REGIONID, body.P_NAME, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return { statusCode: 200, message: ResponseStatus.updated, ...toUpperCaseKeys(fetchResult?.rows)[0] || {} };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, RegionService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRegions(body: SPID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_getregions($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, RegionService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, Put, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { SpContactsService } from './sp-contacts.service';
|
||||||
|
import { InsertSPContactsDTO, SP_CONTACTID_DTO, SPID_DTO, UpdateSPContactsDTO } from 'src/dto/property.dto';
|
||||||
|
|
||||||
|
@ApiTags('SPContacts - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class SpContactsController {
|
||||||
|
|
||||||
|
constructor(private readonly spContactsService: SpContactsService) { }
|
||||||
|
|
||||||
|
|
||||||
|
@Post('/InsertSPContacts')
|
||||||
|
insertSPContacts(@Body() body: InsertSPContactsDTO) {
|
||||||
|
return this.spContactsService.insertSPContacts(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/SetSPDefaultContact/:P_SPCONTACTID')
|
||||||
|
@Roles('pua')
|
||||||
|
setSPDefaultcontact(@Param() param: SP_CONTACTID_DTO) {
|
||||||
|
return this.spContactsService.setSPDefaultcontact(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('/UpdateSPContacts')
|
||||||
|
updateSPContacts(@Body() body: UpdateSPContactsDTO) {
|
||||||
|
return this.spContactsService.updateSPContacts(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch('/InactivateSPContact/:P_SPCONTACTID')
|
||||||
|
inactivateSPContact(@Param() param: SP_CONTACTID_DTO) {
|
||||||
|
return this.spContactsService.inactivateSPContact(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetSPDefaultContact/:P_SPID')
|
||||||
|
getSPDefaultcontacts(@Param() param: SPID_DTO) {
|
||||||
|
return this.spContactsService.getSPDefaultcontacts(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetSPAllContacts/:P_SPID')
|
||||||
|
getSPAllContacts(@Param() param: SPID_DTO) {
|
||||||
|
return this.spContactsService.getSPAllContacts(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/uscib-managed-sp/sp-contacts/sp-contacts.module.ts
Normal file
11
src/pg/uscib-managed-sp/sp-contacts/sp-contacts.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { SpContactsController } from './sp-contacts.controller';
|
||||||
|
import { SpContactsService } from './sp-contacts.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [SpContactsController],
|
||||||
|
providers: [SpContactsService]
|
||||||
|
})
|
||||||
|
export class SpContactsModule {}
|
||||||
240
src/pg/uscib-managed-sp/sp-contacts/sp-contacts.service.ts
Normal file
240
src/pg/uscib-managed-sp/sp-contacts/sp-contacts.service.ts
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InsertSPContactsDTO, SP_CONTACTID_DTO, SPID_DTO, UpdateSPContactsDTO } from 'src/dto/property.dto';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SpContactsService {
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
async insertSPContacts(body: InsertSPContactsDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_insertspcontacts($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_DEFCONTACTFLAG,
|
||||||
|
body.P_FIRSTNAME,
|
||||||
|
body.P_LASTNAME,
|
||||||
|
body.P_MIDDLEINITIAL,
|
||||||
|
body.P_TITLE,
|
||||||
|
body.P_PHONENO,
|
||||||
|
body.P_MOBILENO,
|
||||||
|
body.P_FAXNO,
|
||||||
|
body.P_EMAILADDRESS,
|
||||||
|
body.P_USER_ID,
|
||||||
|
cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpContactsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSPDefaultcontact(body: SP_CONTACTID_DTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_setdefaultcontact($1)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPCONTACTID]);
|
||||||
|
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return { statusCode: 200, message: ResponseStatus.defaultSpContactAdded };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpContactsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateSPContacts(body: UpdateSPContactsDTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_updatespcontacts($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPCONTACTID,
|
||||||
|
body.P_FIRSTNAME,
|
||||||
|
body.P_LASTNAME,
|
||||||
|
body.P_MIDDLEINITIAL,
|
||||||
|
body.P_TITLE,
|
||||||
|
body.P_PHONENO,
|
||||||
|
body.P_MOBILENO,
|
||||||
|
body.P_FAXNO,
|
||||||
|
body.P_EMAILADDRESS,
|
||||||
|
body.P_USER_ID,
|
||||||
|
cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: ResponseStatus.updated,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpContactsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async inactivateSPContact(body: SP_CONTACTID_DTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".USCIB_Managed_Pkg_InActivateSPContacts($1)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPCONTACTID]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return { statusCode: 200, message: ResponseStatus.inActivate };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpContactsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSPDefaultcontacts(body: SPID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_getspdefaultcontacts($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpContactsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSPAllContacts(body: SPID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_getspallcontacts($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpContactsService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/pg/uscib-managed-sp/sp/sp.controller.ts
Normal file
37
src/pg/uscib-managed-sp/sp/sp.controller.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { Body, Controller, Get, Param, Post, Put, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { SpService } from './sp.service';
|
||||||
|
import { InsertNewServiceProviderDTO, SPID_DTO, UpdateServiceProviderDTO } from 'src/dto/property.dto';
|
||||||
|
|
||||||
|
@ApiTags('SP - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class SpController {
|
||||||
|
constructor(private readonly spService: SpService) { }
|
||||||
|
|
||||||
|
@Post('/InsertNewServiceProvider')
|
||||||
|
@Roles('pua')
|
||||||
|
insertNewServiceProvider(@Body() body: InsertNewServiceProviderDTO) {
|
||||||
|
return this.spService.insertNewServiceProvider(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('/UpdateServiceProvider')
|
||||||
|
updateServiceProvider(@Body() body: UpdateServiceProviderDTO) {
|
||||||
|
return this.spService.updateServiceProvider(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetAllServiceproviders')
|
||||||
|
@Roles('pua')
|
||||||
|
getAllServiceproviders() {
|
||||||
|
return this.spService.getAllServiceproviders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('/GetSelectedServiceprovider/:P_SPID')
|
||||||
|
getServiceproviderByID(@Param() param: SPID_DTO) {
|
||||||
|
return this.spService.getServiceproviderByID(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/pg/uscib-managed-sp/sp/sp.module.ts
Normal file
11
src/pg/uscib-managed-sp/sp/sp.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { SpController } from './sp.controller';
|
||||||
|
import { SpService } from './sp.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [SpController],
|
||||||
|
providers: [SpService]
|
||||||
|
})
|
||||||
|
export class SpModule {}
|
||||||
205
src/pg/uscib-managed-sp/sp/sp.service.ts
Normal file
205
src/pg/uscib-managed-sp/sp/sp.service.ts
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { InsertNewServiceProviderDTO, SPID_DTO, UpdateServiceProviderDTO } from 'src/dto/property.dto';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { checkPgUserDefinedErrors, handlePgError, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SpService {
|
||||||
|
|
||||||
|
private readonly logger = new Logger(SpService.name);
|
||||||
|
|
||||||
|
constructor(private readonly pgDBService: PgDBService) { }
|
||||||
|
|
||||||
|
async insertNewServiceProvider(body: InsertNewServiceProviderDTO) {
|
||||||
|
|
||||||
|
console.log(" i got executed here ....");
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
console.log(" pg connection successfull ..... ");
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_insertnewsp($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_NAME,
|
||||||
|
body.P_LOOKUPCODE,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_ISSUINGREGION,
|
||||||
|
body.P_REPLACEMENTREGION,
|
||||||
|
body.P_BONDSURETY,
|
||||||
|
body.P_CARGOPOLICYNO,
|
||||||
|
body.P_CARGOSURETY,
|
||||||
|
body.P_USER_ID,
|
||||||
|
body.P_NOTES,
|
||||||
|
body.P_FILEIDS,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
console.log("Procedure called");
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
console.log("Fetch done", fetchResult?.rows);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
console.log("Cursor closed");
|
||||||
|
await client.query('COMMIT');
|
||||||
|
console.log("Transaction committed");
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return { statusCode: 201, message: ResponseStatus.created, ...toUpperCaseKeys(fetchResult?.rows)[0] || {} };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
console.log(" i went through here ... ");
|
||||||
|
|
||||||
|
handlePgError(error, SpService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateServiceProvider(body: UpdateServiceProviderDTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_updatesp($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_NAME,
|
||||||
|
body.P_LOOKUPCODE,
|
||||||
|
body.P_ADDRESS1,
|
||||||
|
body.P_ADDRESS2,
|
||||||
|
body.P_CITY,
|
||||||
|
body.P_STATE,
|
||||||
|
body.P_ZIP,
|
||||||
|
body.P_COUNTRY,
|
||||||
|
body.P_BONDSURETY,
|
||||||
|
body.P_CARGOPOLICYNO,
|
||||||
|
body.P_CARGOSURETY,
|
||||||
|
body.P_REPLACEMENTREGION,
|
||||||
|
body.P_ISSUINGREGION,
|
||||||
|
body.P_USER_ID,
|
||||||
|
body.P_NOTES,
|
||||||
|
body.P_FILEIDS,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return { statusCode: 200, message: ResponseStatus.updated, ...toUpperCaseKeys(fetchResult?.rows)[0] || {} };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAllServiceproviders() {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_getallsps($1)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async getServiceproviderByID(body: SPID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".uscib_managed_pkg_getspbyspid($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows)[0]??[];
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, SpService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/pg/uscib-managed-sp/uscib-managed-sp.module.ts
Normal file
10
src/pg/uscib-managed-sp/uscib-managed-sp.module.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { CarnetSequenceModule } from './carnet-sequence/carnet-sequence.module';
|
||||||
|
import { RegionModule } from './region/region.module';
|
||||||
|
import { SpModule } from './sp/sp.module';
|
||||||
|
import { SpContactsModule } from './sp-contacts/sp-contacts.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [CarnetSequenceModule, RegionModule, SpModule, SpContactsModule]
|
||||||
|
})
|
||||||
|
export class UscibManagedSpModule {}
|
||||||
95
src/pg/user-maintenance/user-maintenance.controller.ts
Normal file
95
src/pg/user-maintenance/user-maintenance.controller.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import { Body, Controller, Get, Param, Patch, Post, Req, UseGuards } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Roles } from 'src/decorators/roles.decorator';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||||
|
import { RolesGuard } from 'src/guards/roles.guard';
|
||||||
|
import { UserMaintenanceService } from './user-maintenance.service';
|
||||||
|
import { CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, EMAIL_DTO, GetCarnetDetailsbyCarnetStatusDTO, SPID_CLIENTID_DTO, SPID_DTO, SPID_EMAIL_DTO, USERID_DTO } from 'src/dto/property.dto';
|
||||||
|
import { Request } from 'express';
|
||||||
|
|
||||||
|
@ApiTags('User Maintenance - PG')
|
||||||
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||||
|
@Roles('pca', 'psa', 'pua')
|
||||||
|
@Controller('2')
|
||||||
|
export class UserMaintenanceController {
|
||||||
|
|
||||||
|
constructor(private readonly userMaintenanceService: UserMaintenanceService) { }
|
||||||
|
|
||||||
|
// SP_USER_DETAILS
|
||||||
|
|
||||||
|
// [spclientuser_pkg]
|
||||||
|
|
||||||
|
@Get('GetUserDetails/:P_USERID')
|
||||||
|
async GetSPUserDetails(@Param() params: USERID_DTO) {
|
||||||
|
return await this.userMaintenanceService.GetSPUserDetails(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [userlogin_pkg]
|
||||||
|
|
||||||
|
@Patch('LockUserAccount')
|
||||||
|
async LockUserAccount(@Body() body: SPID_EMAIL_DTO) {
|
||||||
|
return await this.userMaintenanceService.LockUserAccount(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// USCIB_LOGINS
|
||||||
|
|
||||||
|
@Get('GetUSCIBLogins')
|
||||||
|
@Roles('pua')
|
||||||
|
async GetUSCIBLogins() {
|
||||||
|
return await this.userMaintenanceService.GetUSCIBLogins();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateUSCIBLogins')
|
||||||
|
@Roles('pua')
|
||||||
|
async CreateUSCIBLogins(@Body() body: CreateUSCIBLoginsDTO, @Req() req: Request) {
|
||||||
|
return await this.userMaintenanceService.CreateUSCIBLogins(body, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SP LOGINS
|
||||||
|
|
||||||
|
@Get('GetSPLogins/:P_SPID')
|
||||||
|
@Roles('psa')
|
||||||
|
async GetSPLogins(@Param() params: SPID_DTO) {
|
||||||
|
return await this.userMaintenanceService.GetSPLogins(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateSPLogins')
|
||||||
|
@Roles('psa')
|
||||||
|
async CreateSPLogins(@Body() body: CreateSPLoginsDTO, @Req() req: Request) {
|
||||||
|
return await this.userMaintenanceService.CreateSPLogins(body, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLIENT LOGINS
|
||||||
|
|
||||||
|
@Get('GetClientloginsBySPID/:P_SPID')
|
||||||
|
@Roles('psa')
|
||||||
|
async GetClientloginsBySPID(@Param() params: SPID_DTO) {
|
||||||
|
return await this.userMaintenanceService.GetClientloginsBySPID(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('GetClientloginsByClientID/:P_SPID/:P_CLIENTID')
|
||||||
|
@Roles('psa')
|
||||||
|
async GetClientloginsByClientID(@Param() params: SPID_CLIENTID_DTO) {
|
||||||
|
return await this.userMaintenanceService.GetClientloginsByClientID(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('CreateClientLogins')
|
||||||
|
@Roles('psa')
|
||||||
|
async CreateClientLogins(@Body() body: CreateClientLoginsDTO, @Req() req: Request) {
|
||||||
|
return await this.userMaintenanceService.CreateClientLogins(body, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate email
|
||||||
|
|
||||||
|
@Get('ValidateEmail/:P_EMAILADDR')
|
||||||
|
async ValidateEmail(@Param() params: EMAIL_DTO) {
|
||||||
|
return await this.userMaintenanceService.ValidateEmail(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get carnet summary data
|
||||||
|
@Get('GetCarnetSummaryData/:P_USERID')
|
||||||
|
GetCarnetSummaryData(@Param() params: USERID_DTO) {
|
||||||
|
return this.userMaintenanceService.GetCarnetSummaryData(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
12
src/pg/user-maintenance/user-maintenance.module.ts
Normal file
12
src/pg/user-maintenance/user-maintenance.module.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { forwardRef, Module } from '@nestjs/common';
|
||||||
|
import { UserMaintenanceController } from './user-maintenance.controller';
|
||||||
|
import { UserMaintenanceService } from './user-maintenance.service';
|
||||||
|
import { AuthModule } from 'src/auth/auth.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [forwardRef(() => AuthModule)],
|
||||||
|
controllers: [UserMaintenanceController],
|
||||||
|
providers: [UserMaintenanceService],
|
||||||
|
exports: [UserMaintenanceService]
|
||||||
|
})
|
||||||
|
export class UserMaintenanceModule { }
|
||||||
590
src/pg/user-maintenance/user-maintenance.service.ts
Normal file
590
src/pg/user-maintenance/user-maintenance.service.ts
Normal file
@ -0,0 +1,590 @@
|
|||||||
|
import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, EMAIL_DTO, GetCarnetDetailsbyCarnetStatusDTO, SPID_CLIENTID_DTO, SPID_DTO, SPID_EMAIL_DTO, USERID_DTO } from 'src/dto/property.dto';
|
||||||
|
import { checkPgUserDefinedErrors, extractSubdomain, handlePgError, normalizeKeysToUpperCase, releasePgClient, ResponseStatus, toUpperCaseKeys } from 'src/utils/helper';
|
||||||
|
|
||||||
|
import { PoolClient } from 'pg';
|
||||||
|
import { PgDBService } from 'src/db/db.service';
|
||||||
|
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||||
|
import { AuthService } from 'src/auth/auth.service';
|
||||||
|
import { MailTypeDTO } from 'src/auth/auth.dto';
|
||||||
|
import { Request } from 'express';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserMaintenanceService {
|
||||||
|
|
||||||
|
private readonly logger = new Logger(UserMaintenanceService.name);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly pgDBService: PgDBService,
|
||||||
|
@Inject(forwardRef(() => AuthService))
|
||||||
|
private readonly authService: AuthService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
async GetSPUserDetails(body: USERID_DTO): Promise<any> {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
// Assign unique names to each cursor
|
||||||
|
const roleCursor = 'role_cursor';
|
||||||
|
const menuCursor = 'menu_cursor';
|
||||||
|
const menuPageCursor = 'menu_page_cursor';
|
||||||
|
const userDetailsCursor = 'user_details_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".spclientuser_pkg_getspuserdetails($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
|
||||||
|
await client.query(callProcQuery, [
|
||||||
|
body.P_USERID,
|
||||||
|
roleCursor,
|
||||||
|
menuCursor,
|
||||||
|
menuPageCursor,
|
||||||
|
userDetailsCursor
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Fetch all data from each cursor
|
||||||
|
const roleResult = await client.query(`FETCH ALL FROM ${roleCursor}`);
|
||||||
|
const menuResult = await client.query(`FETCH ALL FROM ${menuCursor}`);
|
||||||
|
const menuPageResult = await client.query(`FETCH ALL FROM ${menuPageCursor}`);
|
||||||
|
const userDetailsResult = await client.query(`FETCH ALL FROM ${userDetailsCursor}`);
|
||||||
|
|
||||||
|
// Close all cursors
|
||||||
|
await client.query(`CLOSE ${roleCursor}`);
|
||||||
|
await client.query(`CLOSE ${menuCursor}`);
|
||||||
|
await client.query(`CLOSE ${menuPageCursor}`);
|
||||||
|
await client.query(`CLOSE ${userDetailsCursor}`);
|
||||||
|
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
// no need for this api
|
||||||
|
// checkPgUserDefinedErrors(roleResult);
|
||||||
|
// checkPgUserDefinedErrors(menuResult);
|
||||||
|
// checkPgUserDefinedErrors(menuPageResult);
|
||||||
|
// checkPgUserDefinedErrors(userDetailsResult);
|
||||||
|
|
||||||
|
return {
|
||||||
|
roleDetails: toUpperCaseKeys(roleResult.rows).map(x => x.ROLENAME),
|
||||||
|
menuDetails: toUpperCaseKeys(menuResult.rows).map(x => x.MENUNAME),
|
||||||
|
menuPageDetails: toUpperCaseKeys(menuPageResult.rows),
|
||||||
|
userDetails: toUpperCaseKeys(userDetailsResult.rows)[0],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, 'getSpUserDetails');
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async LockUserAccount(body: SPID_EMAIL_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_lockuseraccount($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_EMAILADDR,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// statusCode: 201,
|
||||||
|
// message: ResponseStatus.lockedUserDone,
|
||||||
|
// ...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
// };
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult?.rows)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// USCIB_LOGINS
|
||||||
|
|
||||||
|
async GetUSCIBLogins() {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_getusciblogins($1)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateUSCIBLogins(body: CreateUSCIBLoginsDTO, req: Request) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_createusciblogins($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_EMAILADDR,
|
||||||
|
body.P_LOOKUPCODE,
|
||||||
|
body.P_ENABLEPASSWORDPOLICY,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
let appDomain;
|
||||||
|
if (req.headers.origin) {
|
||||||
|
appDomain = extractSubdomain(req.headers.origin)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appDomain = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_USCIB }, appDomain)
|
||||||
|
|
||||||
|
if (mailRes.statusCode !== 200) {
|
||||||
|
throw new InternalServerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SP LOGINS
|
||||||
|
|
||||||
|
async GetSPLogins(body: SPID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_getsplogins($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateSPLogins(body: CreateSPLoginsDTO, req: Request) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_createsplogins($1, $2, $3, $4, $5, $6, $7)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_DOMAIN,
|
||||||
|
body.P_EMAILADDR,
|
||||||
|
body.P_LOOKUPCODE,
|
||||||
|
body.P_ENABLEPASSWORDPOLICY,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
let appDomain;
|
||||||
|
if (req.headers.origin) {
|
||||||
|
appDomain = extractSubdomain(req.headers.origin)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appDomain = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_SP }, appDomain)
|
||||||
|
|
||||||
|
if (mailRes.statusCode !== 200) {
|
||||||
|
throw new InternalServerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.created,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLIENT LOGINS
|
||||||
|
|
||||||
|
async GetClientloginsBySPID(body: SPID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_getclientloginsbyspid($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetClientloginsByClientID(body: SPID_CLIENTID_DTO) {
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_getclientloginsbyclientid($1, $2, $3)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_SPID, body.P_CLIENTID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
return toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateClientLogins(body: CreateClientLoginsDTO, req: Request) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_createclientlogins($1, $2, $3, $4, $5)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery,
|
||||||
|
[
|
||||||
|
body.P_SPID,
|
||||||
|
body.P_USERID,
|
||||||
|
body.P_CLIENTCONTACTID,
|
||||||
|
body.P_ENABLEPASSWORDPOLICY,
|
||||||
|
cursorName
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
let appDomain;
|
||||||
|
if (req.headers.origin) {
|
||||||
|
appDomain = extractSubdomain(req.headers.origin)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appDomain = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_CLIENT }, appDomain)
|
||||||
|
|
||||||
|
if (mailRes.statusCode !== 200) {
|
||||||
|
throw new InternalServerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
message: ResponseStatus.clientRegistrationDone,
|
||||||
|
...toUpperCaseKeys(fetchResult?.rows)[0]
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate email
|
||||||
|
|
||||||
|
async ValidateEmail(body: EMAIL_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_validateemail($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_EMAILADDR, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
if (fetchResult?.rows.length > 0) {
|
||||||
|
return toUpperCaseKeys(fetchResult.rows)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//carnet summary data
|
||||||
|
async GetCarnetSummaryData(body: USERID_DTO) {
|
||||||
|
|
||||||
|
let client: PoolClient | null = null;
|
||||||
|
|
||||||
|
const cursorName = 'p_cursor';
|
||||||
|
|
||||||
|
try {
|
||||||
|
client = await this.pgDBService.getConnection();
|
||||||
|
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
const callProcQuery = `
|
||||||
|
CALL "CARNETSYS".userlogin_pkg_getcarnetsummarydata($1, $2)
|
||||||
|
`;
|
||||||
|
await client.query(callProcQuery, [body.P_USERID, cursorName]);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in FETCH
|
||||||
|
const fetchResult = await client.query(`FETCH ALL FROM ${cursorName}`);
|
||||||
|
|
||||||
|
// 🚫 DON'T quote the cursor name in CLOSE
|
||||||
|
await client.query(`CLOSE ${cursorName}`);
|
||||||
|
await client.query('COMMIT');
|
||||||
|
|
||||||
|
checkPgUserDefinedErrors(fetchResult);
|
||||||
|
|
||||||
|
const fres: any = toUpperCaseKeys(fetchResult.rows);
|
||||||
|
|
||||||
|
// Step 1: Replace spaces in keys
|
||||||
|
const mappedRows = fres.map((obj) => {
|
||||||
|
const newObj = {};
|
||||||
|
for (const key in obj) {
|
||||||
|
const newKey = key.replace(/ /g, '_');
|
||||||
|
newObj[newKey] = obj[key];
|
||||||
|
}
|
||||||
|
return newObj;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 2: Group and aggregate
|
||||||
|
const reducedRows = mappedRows.reduce((acc, curr) => {
|
||||||
|
let existing;
|
||||||
|
|
||||||
|
if (curr.SERVICE_PROVIDER_NAME && curr.SPID) {
|
||||||
|
existing = acc.find(
|
||||||
|
(item) =>
|
||||||
|
item.Service_Provider_Name === curr.SERVICE_PROVIDER_NAME &&
|
||||||
|
item.SPID === curr.SPID
|
||||||
|
);
|
||||||
|
} else if (curr.PREPARER_NAME && curr.CLIENTID) {
|
||||||
|
existing = acc.find(
|
||||||
|
(item) =>
|
||||||
|
item.Preparer_Name === curr.PREPARER_NAME &&
|
||||||
|
item.CLIENTID === curr.CLIENTID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
existing.CARNETSTATUS.push(curr.CARNETSTATUS);
|
||||||
|
existing.Carnet_Count.push(curr.CARNET_COUNT);
|
||||||
|
} else {
|
||||||
|
const newItem = {
|
||||||
|
CARNETSTATUS: [curr.CARNETSTATUS],
|
||||||
|
Carnet_Count: [curr.CARNET_COUNT],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (curr.SERVICE_PROVIDER_NAME && curr.SPID) {
|
||||||
|
newItem['Service_Provider_Name'] = curr.SERVICE_PROVIDER_NAME;
|
||||||
|
newItem['SPID'] = curr.SPID;
|
||||||
|
} else if (curr.PREPARER_NAME && curr.CLIENTID) {
|
||||||
|
newItem['Preparer_Name'] = curr.PREPARER_NAME;
|
||||||
|
newItem['CLIENTID'] = curr.CLIENTID;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.push(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return reducedRows;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (client) await client.query('ROLLBACK');
|
||||||
|
handlePgError(error, UserMaintenanceService.name)
|
||||||
|
} finally {
|
||||||
|
releasePgClient(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -17,6 +17,89 @@ import { PrintCarnetDTO, PrintGLDTO } from 'src/dto/property.dto';
|
|||||||
|
|
||||||
const logger = new Logger('Helper');
|
const logger = new Logger('Helper');
|
||||||
|
|
||||||
|
export enum ResponseStatus {
|
||||||
|
created = 'Created Successfully',
|
||||||
|
updated = 'Updated Successfully',
|
||||||
|
defaultSpContactAdded = "Default contact was added successfully for SP",
|
||||||
|
inActivate = 'Inactivated Successfully',
|
||||||
|
reActivate = 'Reactivated Successfully',
|
||||||
|
clientRegistrationDone = 'Client registration initiated successfully',
|
||||||
|
lockedUserDone = 'Locked Successfully',
|
||||||
|
transmitted = 'Transmitted Successfully',
|
||||||
|
added = 'Added Successfully',
|
||||||
|
deleted = 'Deleted Successfully',
|
||||||
|
processed = 'Processed Successfully',
|
||||||
|
voided = 'Voided Successfully',
|
||||||
|
copied = 'Coppied Successfully',
|
||||||
|
duplicated = 'Duplicated Successfully',
|
||||||
|
addl_completed = 'Additional sets completed',
|
||||||
|
extended = 'Extended Successfully',
|
||||||
|
saved = 'Saved Successfully',
|
||||||
|
closed = 'Closed Successfully',
|
||||||
|
reset_successfull = 'Reset Successfull'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractSubdomain(domain: string): string | null {
|
||||||
|
try {
|
||||||
|
const url = new URL(domain);
|
||||||
|
const hostname = url.hostname; // e.g., "der.asd.com", "localhost", "121.1.21.123"
|
||||||
|
|
||||||
|
// Return the full hostname if it's an IP address or 'localhost'
|
||||||
|
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) || hostname === 'localhost') {
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = hostname.split('.');
|
||||||
|
|
||||||
|
if (parts.length < 3) {
|
||||||
|
// Not enough parts to have a subdomain (e.g., "asd.com")
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the subdomain (leftmost part)
|
||||||
|
return parts[0];
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Invalid domain:', domain, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parsePGNumericFields(row) {
|
||||||
|
const keysToConvert = [
|
||||||
|
'BASICFEE', 'CFFEE', 'CSFEE', 'EFFEE', 'SHIPFEE',
|
||||||
|
'SECURITYAMOUNT', 'BONDPREMIUM', 'INSUREDVALUE',
|
||||||
|
'CARGOPREMIUM', 'LDIPREMIUM'
|
||||||
|
];
|
||||||
|
|
||||||
|
const parsed = { ...row };
|
||||||
|
for (const key of keysToConvert) {
|
||||||
|
if (parsed[key] !== null && parsed[key] !== undefined) {
|
||||||
|
parsed[key] = Number(parsed[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeKeysToUpperCase(obj) {
|
||||||
|
return Object.keys(obj).reduce((acc, key) => {
|
||||||
|
acc[key.toUpperCase()] = obj[key];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toUpperCaseKeys(rows: Record<string, any>[]): Record<string, any>[] {
|
||||||
|
return rows.map(row => {
|
||||||
|
const transformedRow: Record<string, any> = {};
|
||||||
|
for (const key in row) {
|
||||||
|
transformedRow[key.toUpperCase()] = row[key];
|
||||||
|
}
|
||||||
|
return transformedRow;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const handleError = (error: any, context: string = 'UnknownService'): never => {
|
export const handleError = (error: any, context: string = 'UnknownService'): never => {
|
||||||
if (error instanceof BadRequestException || error instanceof BR) {
|
if (error instanceof BadRequestException || error instanceof BR) {
|
||||||
logger.warn(`[${context}] ${error.message}`);
|
logger.warn(`[${context}] ${error.message}`);
|
||||||
@ -37,6 +120,32 @@ export const handleError = (error: any, context: string = 'UnknownService'): nev
|
|||||||
throw new InternalServerErrorException(error.message || 'Internal error');
|
throw new InternalServerErrorException(error.message || 'Internal error');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const handlePgError = (error: any, context: string = 'UnknownService'): never => {
|
||||||
|
if (error instanceof BadRequestException || error instanceof BR) {
|
||||||
|
logger.warn(`[${context}] ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
logger.error(`[${context}] Unexpected error:`, error.message);
|
||||||
|
throw new InternalServerErrorException(error.message || 'Internal error');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function releasePgClient(client: any) {
|
||||||
|
if (client && typeof client.release === 'function') {
|
||||||
|
try {
|
||||||
|
client.release();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error releasing client:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const checkPgUserDefinedErrors = (fetchResult: any) => {
|
||||||
|
if (fetchResult?.rows?.[0]?.errormesg) {
|
||||||
|
throw new BadRequestException(fetchResult?.rows?.[0]?.errormesg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const closeOracleDbConnection = async (connection: any, context: string = 'UnknownService'): Promise<void> => {
|
export const closeOracleDbConnection = async (connection: any, context: string = 'UnknownService'): Promise<void> => {
|
||||||
if (connection) {
|
if (connection) {
|
||||||
try {
|
try {
|
||||||
@ -1201,8 +1310,8 @@ export async function processGlDataInBatches(
|
|||||||
|
|
||||||
let totalItemValue = 0;
|
let totalItemValue = 0;
|
||||||
for (const item of glDataArray) {
|
for (const item of glDataArray) {
|
||||||
if (typeof item.itemValue === 'number') {
|
if (typeof Number(item.itemValue) === 'number') {
|
||||||
totalItemValue += item.itemValue;
|
totalItemValue += Number(item.itemValue);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Non-numeric itemValue encountered for itemNo: ${item.itemNo}. Skipping value.`);
|
console.warn(`Non-numeric itemValue encountered for itemNo: ${item.itemNo}. Skipping value.`);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user