22-05-2025 added remaining user-maintenance api with oracle methed optimized with util and dto

This commit is contained in:
Kallesh B S 2025-05-22 17:25:38 +05:30
parent 2c7c088adf
commit e0e2b540cb
31 changed files with 907 additions and 822 deletions

View File

@ -1,4 +1,4 @@
GET http://localhost:3000/mssql/GetParamValues?P_PARAMTYPE=000&P_SPID=asdf
GET http://localhost:3000/user-maintenance/GetSPUserDetails?P_USERID=a@s.com
###

View File

@ -0,0 +1,6 @@
import { IntersectionType } from '@nestjs/swagger';
import { CARNET_TYPE_DTO, END_NUMBER_DTO, REGIONID_DTO, SPID_DTO, START_NUMBER_DTO } from 'src/dto/property.dto';
export class CreateCarnetSequenceDTO extends IntersectionType(
SPID_DTO, REGIONID_DTO, START_NUMBER_DTO, END_NUMBER_DTO, CARNET_TYPE_DTO
) { }

326
src/dto/property.dto.ts Normal file
View File

@ -0,0 +1,326 @@
import { ApiProperty } from "@nestjs/swagger";
import { Transform, Type } from "class-transformer";
import { IsDefined, IsEmail, IsEnum, IsInt, IsNumber, IsOptional, IsString, Length, Max, Min } from "class-validator";
// General
export class USERID_DTO {
@ApiProperty({ required: true })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_userid: string;
}
export class USER_ID_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_user_id must be a string' })
@IsDefined({ message: 'Property p_user_id is required' })
p_user_id: string;
}
export class EMAIL_DTO {
@ApiProperty({ required: true })
@IsEmail({}, { message: "Invalid p_emailaddr property" })
@Length(0, 50, {
message: 'Property p_emailaddr must be between 0 to 50 characters',
})
@IsString({ message: 'p_emailaddr p_userid must be string' })
@IsDefined({ message: 'p_emailaddr p_userid is required' })
p_emailaddr: string;
}
export class LOOKUP_CODE_DTO {
@ApiProperty({ required: true })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_lookupCode: string;
}
export class PASSWORD_DTO {
@ApiProperty({ required: true })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_password: string;
}
export enum YON {
YES = "Y",
NO = "N",
}
export class Name_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_name must be a string' })
@IsDefined({ message: 'Property p_name is required' })
P_NAME: string;
}
export class ADDRESS1_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_address1 must be a string' })
@IsDefined({ message: 'Property p_address1 is required' })
p_address1: string;
}
export class ADDRESS2_DTO {
@ApiProperty({ required: false })
@IsString({ message: 'Property p_address2 must be a string' })
@IsOptional()
p_address2?: string;
}
export class CITY_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_city must be a string' })
@IsDefined({ message: 'Property p_city is required' })
p_city: string;
}
export class STATE_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_state must be a string' })
@IsDefined({ message: 'Property p_state is required' })
p_state: string;
}
export class COUNTRY_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_country must be a string' })
@IsDefined({ message: 'Property p_country is required' })
p_country: string;
}
export class ZIP_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_zip must be a string' })
@IsDefined({ message: 'Property p_zip is required' })
p_zip: string;
}
export class ISSUING_REGION_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_issuingregion must be a string' })
@IsDefined({ message: 'Property p_issuingregion is required' })
p_issuingregion: string;
}
export class REPLACEMENT_REGION_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_replacementregion must be a string' })
@IsDefined({ message: 'Property p_replacementregion is required' })
p_replacementregion: string;
}
export class BOND_SURETY_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_bondsurety must be a string' })
@IsDefined({ message: 'Property p_bondsurety is required' })
p_bondsurety: string;
}
export class CARGO_POLICY_NO_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_cargopolicyno must be a string' })
@IsDefined({ message: 'Property p_cargopolicyno is required' })
p_cargopolicyno: string;
}
export class CARGO_SURETY_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_cargosurety must be a string' })
@IsDefined({ message: 'Property p_cargosurety is required' })
p_cargosurety: string;
}
export class NOTES_DTO {
@ApiProperty({ required: false })
@IsString({ message: 'Property P_NOTES must be a string' })
@IsOptional()
P_NOTES?: string;
}
export class FILE_ID_DTO {
@ApiProperty({ required: false })
@IsString({ message: 'Property P_FILEIDS must be a string' })
@IsOptional()
P_FILEIDS?: string;
}
// user maintenance
export class ENABLE_PASSWORD_POLICY_DTO {
@ApiProperty({ required: true, enum: YON })
@Transform(({ value }) => typeof value === 'string' ? value.trim().toUpperCase() : value)
@IsEnum(YON, { message: 'P_EnablePasswordPolicy must be either "Y" or "N"' })
@Length(1, 1, { message: 'P_EnablePasswordPolicy must be between 5 and 6 characters' })
@IsString()
@IsDefined({ message: "Invalid Request" })
P_EnablePasswordPolicy: YON;
}
export class DOMAIN_DTO {
@ApiProperty({ required: true })
@Length(0, 50, {
message: 'Property p_domain must be between 0 to 50 characters',
})
@IsString({ message: 'Property p_domain must be a string' })
@IsDefined({ message: 'Property p_domain is required' })
p_domain: string;
}
// SP
export class SPID_DTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_spid must be at least 0' })
@IsInt({ message: 'Property p_spid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_spid must be a number' })
@IsDefined({ message: 'Property p_spid is required' })
p_spid: number;
}
export class SP_ID_DTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_SPid must be at least 0' })
@IsInt({ message: 'Property p_SPid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_SPid must be a number' })
@IsDefined({ message: 'Property p_SPid is required' })
p_SPid: number;
}
// client
export class CLIENTID_DTO {
@ApiProperty({ required: true })
@Min(0, { message: 'p_clientid must be greater than or equal to 0' })
@IsInt({ message: "p_clientid must be whole number" })
@IsDefined({ message: 'Invalid Request' })
@Type(() => Number)
p_clientid: number;
}
export class CLIENT_CONTACTID_DTO {
@ApiProperty({ required: true })
@Max(999999999, {
message: 'Property p_clientcontactid must not exceed 999999999',
})
@Min(0, { message: 'Property p_clientcontactid must be at least 0 or more' })
@IsInt({ message: 'Property p_clientcontactid allows only whole numbers' })
@IsNumber({}, { message: 'Property p_clientcontactid must be a number' })
@IsDefined({ message: 'Property p_clientcontactid is required' })
p_clientcontactid: number;
}
// Region
export class REGION_CODE_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_region must be a string' })
@IsDefined({ message: 'Property p_region is required' })
P_REGION: string;
}
export class REGIONID_DTO {
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_regionID must be a number' })
@IsDefined({ message: 'Property p_regionID is required' })
P_REGIONID: number;
}
// CONTACT
export class SP_CONTACTID_DTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_spcontactid must be at least 0' })
@IsInt({ message: 'Property p_SPid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_spcontactid must be a number' })
@IsDefined({ message: 'Property p_spcontactid is required' })
p_spcontactid: number;
}
export class DEFAULT_CONTACT_FLAG_DTO {
@ApiProperty({ required: true, enum: YON })
@Transform(({ value }) => typeof value === 'string' ? value.trim().toUpperCase() : value)
@IsEnum(YON, { message: 'P_EnablePasswordPolicy must be either "Y" or "N"' })
@Length(1, 1, { message: 'P_EnablePasswordPolicy must be between 5 and 6 characters' })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_defcontactflag: YON;
}
export class FIRSTNAME_DTO {
@ApiProperty({ required: true })
@IsString()
p_firstname: string;
}
export class LASTNAME_DTO {
@ApiProperty({ required: true })
@IsString()
p_lastname: string;
}
export class MIDDLE_INITIAL_DTO {
@ApiProperty({ required: false })
@IsString()
P_MIDDLEINITIAL: string;
}
export class TITLE_DTO {
@ApiProperty({ required: true })
@IsString()
p_title: string;
}
export class PHONE_NO_DTO {
@ApiProperty({ required: true })
@IsString()
p_phoneno: string;
}
export class MOBILE_NO_DTO {
@ApiProperty({ required: true })
@IsString()
p_mobileno: string;
}
export class FAX_NO_DTO {
@ApiProperty({ required: true })
@IsString()
p_faxno: string;
}
export class EMAIL_ADDRESS_DTO {
@ApiProperty({ required: true })
@IsEmail()
p_emailaddress: string;
}
// carnet
export class START_NUMBER_DTO {
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_startnumber must be a number' })
@IsDefined({ message: 'Property p_startnumber is required' })
@Min(0, { message: 'Property p_startnumber must be at least 0' })
p_startnumber: number;
}
export class END_NUMBER_DTO {
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_endnumber must be a number' })
@IsDefined({ message: 'Property p_endnumber is required' })
@Min(0, { message: 'Property p_endnumber must be at least 0' })
p_endnumber: number;
}
export class CARNET_TYPE_DTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_carnettype must be a string' })
@IsDefined({ message: 'Property p_carnettype is required' })
p_carnettype: string;
}

6
src/dto/region.dto.ts Normal file
View File

@ -0,0 +1,6 @@
import { IntersectionType } from '@nestjs/swagger';
import { Name_DTO, REGION_CODE_DTO, REGIONID_DTO } from 'src/dto/property.dto';
export class InsertRegionsDto extends IntersectionType(REGION_CODE_DTO, Name_DTO) { }
export class UpdateRegionDto extends IntersectionType(REGIONID_DTO, Name_DTO) { }

View File

@ -0,0 +1,14 @@
import { IntersectionType } from '@nestjs/swagger';
import { DEFAULT_CONTACT_FLAG_DTO, EMAIL_ADDRESS_DTO, FAX_NO_DTO, FIRSTNAME_DTO, LASTNAME_DTO, MIDDLE_INITIAL_DTO, MOBILE_NO_DTO, PHONE_NO_DTO, SP_CONTACTID_DTO, SPID_DTO, TITLE_DTO, USER_ID_DTO } from 'src/dto/property.dto';
export class InsertSPContactsDTO extends IntersectionType(
SPID_DTO, DEFAULT_CONTACT_FLAG_DTO, FIRSTNAME_DTO, LASTNAME_DTO, MIDDLE_INITIAL_DTO, TITLE_DTO,
PHONE_NO_DTO, MOBILE_NO_DTO, FAX_NO_DTO, EMAIL_ADDRESS_DTO, USER_ID_DTO
) { }
export class UpdateSPContactsDTO extends IntersectionType(
SP_CONTACTID_DTO, FIRSTNAME_DTO, LASTNAME_DTO, MIDDLE_INITIAL_DTO, TITLE_DTO, PHONE_NO_DTO,
MOBILE_NO_DTO, FAX_NO_DTO, EMAIL_ADDRESS_DTO, USER_ID_DTO
) { }

15
src/dto/sp.dto.ts Normal file
View File

@ -0,0 +1,15 @@
import { IntersectionType } from '@nestjs/swagger';
import { ADDRESS1_DTO, ADDRESS2_DTO, BOND_SURETY_DTO, CARGO_POLICY_NO_DTO, CARGO_SURETY_DTO, CITY_DTO, COUNTRY_DTO, FILE_ID_DTO, ISSUING_REGION_DTO, LOOKUP_CODE_DTO, Name_DTO, NOTES_DTO, REPLACEMENT_REGION_DTO, SPID_DTO, STATE_DTO, USER_ID_DTO, ZIP_DTO } from 'src/dto/property.dto';
export class InsertNewServiceProviderDTO extends IntersectionType(
Name_DTO, LOOKUP_CODE_DTO, ADDRESS1_DTO, ADDRESS2_DTO, CITY_DTO, STATE_DTO, COUNTRY_DTO, ZIP_DTO,
ISSUING_REGION_DTO, REPLACEMENT_REGION_DTO, BOND_SURETY_DTO, CARGO_POLICY_NO_DTO, CARGO_SURETY_DTO,
USER_ID_DTO, NOTES_DTO, FILE_ID_DTO
) { }
export class UpdateServiceProviderDTO extends IntersectionType(
SPID_DTO, Name_DTO, LOOKUP_CODE_DTO, ADDRESS1_DTO, ADDRESS2_DTO, CITY_DTO, STATE_DTO, COUNTRY_DTO,
ISSUING_REGION_DTO, REPLACEMENT_REGION_DTO, BOND_SURETY_DTO, CARGO_POLICY_NO_DTO, CARGO_SURETY_DTO,
ZIP_DTO, USER_ID_DTO, NOTES_DTO, FILE_ID_DTO
) { }

View File

@ -0,0 +1,18 @@
import { IntersectionType } from "@nestjs/swagger";
import { CLIENT_CONTACTID_DTO, CLIENTID_DTO, DOMAIN_DTO, EMAIL_DTO, ENABLE_PASSWORD_POLICY_DTO, LOOKUP_CODE_DTO, PASSWORD_DTO, SPID_DTO, USERID_DTO } from "src/dto/property.dto";
export class SPID_CLIENTID_DTO extends IntersectionType(SPID_DTO, CLIENTID_DTO) { }
export class SPID_EMAIL_DTO extends IntersectionType(SPID_DTO, EMAIL_DTO) { }
export class CreateUSCIBLoginsDTO extends IntersectionType(
USERID_DTO, EMAIL_DTO, LOOKUP_CODE_DTO, PASSWORD_DTO, ENABLE_PASSWORD_POLICY_DTO
) { }
export class CreateClientLoginsDTO extends IntersectionType(
SPID_DTO, USERID_DTO, CLIENT_CONTACTID_DTO, PASSWORD_DTO, ENABLE_PASSWORD_POLICY_DTO
) { }
export class CreateSPLoginsDTO extends IntersectionType(
SPID_DTO, USERID_DTO, DOMAIN_DTO, EMAIL_DTO, LOOKUP_CODE_DTO, PASSWORD_DTO, ENABLE_PASSWORD_POLICY_DTO
) { }

View File

@ -1,7 +1,8 @@
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { CarnetSequenceService } from './carnet-sequence.service';
import { ApiTags } from '@nestjs/swagger';
import { CreateCarnetSequenceDTO, GetCarnetSequenceDTO } from 'src/oracle/uscib-managed-sp/carnet-sequence/carnet-sequence.dto';
import { CreateCarnetSequenceDTO } from 'src/dto/carnet-sequence.dto';
import { SPID_DTO } from 'src/dto/property.dto';
@Controller('mssql')
export class CarnetSequenceController {
@ -10,8 +11,8 @@ export class CarnetSequenceController {
@ApiTags('Carnet Sequence - Mssql')
@Get('/GetCarnetSequence')
getCarnetSequence(@Query() body: GetCarnetSequenceDTO) {
return this.carnetSequenceService.getCarnetSequence(body);
getCarnetSequence(@Query() body: SPID_DTO) {
return this.carnetSequenceService.getCarnetSequence(body);
}
@ApiTags('Carnet Sequence - Mssql')

View File

@ -2,14 +2,15 @@ import { Injectable } from '@nestjs/common';
import { Connection, Request } from 'mssql';
import { MssqlDBService } from 'src/db/db.service';
import * as mssql from 'mssql'
import { CreateCarnetSequenceDTO, GetCarnetSequenceDTO } from 'src/oracle/uscib-managed-sp/carnet-sequence/carnet-sequence.dto';
import { CreateCarnetSequenceDTO } from 'src/dto/carnet-sequence.dto';
import { SPID_DTO } from 'src/dto/property.dto';
@Injectable()
export class CarnetSequenceService {
constructor(private readonly mssqlDBService: MssqlDBService) { }
async getCarnetSequence(body: GetCarnetSequenceDTO) {
async getCarnetSequence(body: SPID_DTO) {
let connection: Connection;
try {
@ -30,7 +31,7 @@ export class CarnetSequenceService {
connection = await this.mssqlDBService.getConnection();
const request = new Request(connection);
request.input('P_SPID', mssql.Int, body.p_spid);
request.input('P_REGIONID', mssql.Float, body.p_regionid);
request.input('P_REGIONID', mssql.Float, body.P_REGIONID);
request.input('P_STARTNUMBER', mssql.Int, body.p_startnumber);
request.input('P_ENDNUMBER', mssql.Int, body.p_endnumber);
request.input('P_CARNETTYPE', mssql.VarChar(4000), body.p_carnettype);

View File

@ -1,7 +1,7 @@
import { Body, Controller, Get, Patch, Post } from '@nestjs/common';
import { ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { RegionService } from './region.service';
import { InsertRegionsDto, RegionDto, UpdateRegionDto } from 'src/oracle/uscib-managed-sp/region/region.dto';
import { InsertRegionsDto, UpdateRegionDto } from 'src/dto/region.dto';
@Controller('mssql')
export class RegionController {
@ -10,10 +10,6 @@ export class RegionController {
@ApiTags('Regions - Mssql')
@ApiOperation({ summary: 'Get all regions for issuing and replacement.' })
@ApiOkResponse({
description: 'User retrieved successfully',
type: RegionDto,
})
@ApiInternalServerErrorResponse({ description: 'Server error' })
@Get('/GetRegions')
getRegions() {

View File

@ -1,7 +1,7 @@
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { Connection, Request } from 'mssql';
import { MssqlDBService } from 'src/db/db.service';
import { InsertRegionsDto, UpdateRegionDto } from 'src/oracle/uscib-managed-sp/region/region.dto';
import { InsertRegionsDto, UpdateRegionDto } from 'src/dto/region.dto';
import * as mssql from 'mssql';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
@ -28,13 +28,13 @@ export class RegionService {
try {
connection = await this.mssqlDBService.getConnection();
const request = new Request(connection);
request.input('P_REGION', mssql.VarChar(mssql.MAX), body.p_region);
request.input('P_NAME', mssql.VarChar(mssql.MAX), body.p_name);
request.input('P_REGION', mssql.VarChar(mssql.MAX), body.P_REGION);
request.input('P_NAME', mssql.VarChar(mssql.MAX), body.P_NAME);
const result = await request.execute('carnetsys.INSERTNEWREGION');
return { statusCode: 201, message: "Created Successfully", ...result.recordset[0] };
} catch (error) {
throw new InternalServerException();
} catch (error) {
throw new InternalServerException();
}
}
@ -43,8 +43,8 @@ export class RegionService {
try {
connection = await this.mssqlDBService.getConnection();
const request = new Request(connection);
request.input('p_regionID', mssql.Int, body.p_regionID);
request.input('P_NAME', mssql.VarChar(mssql.MAX), body.p_name);
request.input('p_regionID', mssql.Int, body.P_REGIONID);
request.input('P_NAME', mssql.VarChar(mssql.MAX), body.P_NAME);
const result = await request.execute('carnetsys.UpdateRegion');
return { statusCode: 200, message: "Updated Successfully", ...result.recordset[0] };

View File

@ -1,7 +1,8 @@
import { Body, Controller, Get, Post, Put, Query } from '@nestjs/common';
import { SpContactsService } from './sp-contacts.service';
import { ApiTags } from '@nestjs/swagger';
import { getSPAllContactsDTO, getSPDefaultcontactDTO, inactivateSPContactDTO, InsertSPContactsDTO, setSPDefaultcontactDTO, UpdateSPContactsDTO } from 'src/oracle/uscib-managed-sp/sp-contacts/sp-contacts.dto';
import { InsertSPContactsDTO, UpdateSPContactsDTO } from 'src/dto/sp-contacts.dto';
import { SP_CONTACTID_DTO, SP_ID_DTO } from 'src/dto/property.dto';
@Controller('mssql')
export class SpContactsController {
@ -11,19 +12,19 @@ export class SpContactsController {
@ApiTags('SPContacts - Mssql')
@Post('/InactivateSPContact')
inactivateSPContact(@Query() body: inactivateSPContactDTO) {
inactivateSPContact(@Query() body: SP_CONTACTID_DTO) {
return this.spContactsService.inactivateSPContact(body);
}
@ApiTags('SPContacts - Mssql')
@Get('/GetSPDefaultContact')
getSPDefaultcontact(@Query() body: getSPDefaultcontactDTO) {
getSPDefaultcontact(@Query() body: SP_ID_DTO) {
return this.spContactsService.getSPDefaultcontacts(body);
}
@ApiTags('SPContacts - Mssql')
@Get('/GetSPAllContacts')
getSPAllContacts(@Query() body: getSPAllContactsDTO) {
getSPAllContacts(@Query() body: SP_ID_DTO) {
return this.spContactsService.getSpAllContacts(body);
}
@ -35,7 +36,7 @@ export class SpContactsController {
@ApiTags('SPContacts - Mssql')
@Post('/SetSPDefaultContact')
setSPDefaultcontact(@Query() body: setSPDefaultcontactDTO) {
setSPDefaultcontact(@Query() body: SP_CONTACTID_DTO) {
return this.spContactsService.setSPDefaultcontact(body);
}

View File

@ -2,14 +2,15 @@ import { Injectable } from '@nestjs/common';
import { MssqlDBService } from 'src/db/db.service';
import * as mssql from 'mssql'
import { Connection, Request } from 'mssql';
import { getSPAllContactsDTO, getSPDefaultcontactDTO, inactivateSPContactDTO, InsertSPContactsDTO, setSPDefaultcontactDTO, UpdateSPContactsDTO } from 'src/oracle/uscib-managed-sp/sp-contacts/sp-contacts.dto';
import { InsertSPContactsDTO, UpdateSPContactsDTO } from 'src/dto/sp-contacts.dto';
import { SP_CONTACTID_DTO, SP_ID_DTO } from 'src/dto/property.dto';
@Injectable()
export class SpContactsService {
constructor(private readonly mssqlDBService: MssqlDBService) { }
async getSpAllContacts(body: getSPAllContactsDTO) {
async getSpAllContacts(body: SP_ID_DTO) {
let connection: Connection;
try {
@ -24,7 +25,7 @@ export class SpContactsService {
}
}
async getSPDefaultcontacts(body: getSPDefaultcontactDTO) {
async getSPDefaultcontacts(body: SP_ID_DTO) {
let connection: Connection;
try {
@ -39,7 +40,7 @@ export class SpContactsService {
}
}
async inactivateSPContact(body: inactivateSPContactDTO) {
async inactivateSPContact(body: SP_CONTACTID_DTO) {
let connection: Connection;
try {
@ -78,7 +79,7 @@ export class SpContactsService {
}
}
async setSPDefaultcontact(body: setSPDefaultcontactDTO) {
async setSPDefaultcontact(body: SP_CONTACTID_DTO) {
let connection: Connection;
try {
connection = await this.mssqlDBService.getConnection();

View File

@ -1,7 +1,8 @@
import { Body, Controller, Get, Post, Put, Query } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { SpService } from './sp.service';
import { getSelectedServiceproviderDTO, InsertNewServiceProviderDTO, UpdateServiceProviderDTO } from 'src/oracle/uscib-managed-sp/sp/sp.dto';
import { InsertNewServiceProviderDTO, UpdateServiceProviderDTO } from 'src/dto/sp.dto';
import { SPID_DTO } from 'src/dto/property.dto';
@Controller('mssql')
export class SpController {
@ -16,7 +17,7 @@ export class SpController {
@ApiTags('SP - Mssql')
@Get('/GetSelectedServiceprovider')
getSelectedServiceprovider(@Query() body: getSelectedServiceproviderDTO) {
getSelectedServiceprovider(@Query() body: SPID_DTO) {
return this.spService.getSpBySpid(body);
}

View File

@ -1,8 +1,9 @@
import { Injectable } from '@nestjs/common';
import { Connection, Request } from 'mssql';
import { MssqlDBService } from 'src/db/db.service';
import { getSelectedServiceproviderDTO, InsertNewServiceProviderDTO, UpdateServiceProviderDTO } from 'src/oracle/uscib-managed-sp/sp/sp.dto';
import { InsertNewServiceProviderDTO, UpdateServiceProviderDTO } from 'src/dto/sp.dto';
import * as mssql from 'mssql'
import { SPID_DTO } from 'src/dto/property.dto';
@Injectable()
export class SpService {
@ -23,7 +24,7 @@ export class SpService {
}
}
async getSpBySpid(body: getSelectedServiceproviderDTO) {
async getSpBySpid(body: SPID_DTO) {
let connection: Connection;
try {
@ -43,8 +44,8 @@ export class SpService {
try {
connection = await this.mssqlDBService.getConnection();
const request = new Request(connection);
request.input('P_NAME', mssql.VarChar(4000), body.p_name);
request.input('P_LOOKUPCODE', mssql.VarChar(4000), body.p_lookupcode);
request.input('P_NAME', mssql.VarChar(4000), body.P_NAME);
request.input('P_LOOKUPCODE', mssql.VarChar(4000), body.p_lookupCode);
request.input('P_ADDRESS1', mssql.VarChar(4000), body.p_address1);
request.input('P_ADDRESS2', mssql.VarChar(4000), body.p_address2);
request.input('P_CITY', mssql.VarChar(4000), body.p_city);
@ -73,8 +74,8 @@ export class SpService {
connection = await this.mssqlDBService.getConnection();
const request = new Request(connection);
request.input('P_SPID', mssql.Int, body.p_spid);
request.input('P_NAME', mssql.VarChar(4000), body.p_name);
request.input('P_LOOKUPCODE', mssql.VarChar(4000), body.p_lookupcode);
request.input('P_NAME', mssql.VarChar(4000), body.P_NAME);
request.input('P_LOOKUPCODE', mssql.VarChar(4000), body.p_lookupCode);
request.input('P_ADDRESS1', mssql.VarChar(4000), body.p_address1);
request.input('P_ADDRESS2', mssql.VarChar(4000), body.p_address2);
request.input('P_CITY', mssql.VarChar(4000), body.p_city);

View File

@ -1,10 +1,10 @@
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import {
CreateCarnetSequenceDTO,
GetCarnetSequenceDTO,
} from './carnet-sequence.dto';
CreateCarnetSequenceDTO
} from '../../../dto/carnet-sequence.dto';
import { ApiTags } from '@nestjs/swagger';
import { CarnetSequenceService } from './carnet-sequence.service';
import { SPID_DTO } from 'src/dto/property.dto';
@Controller('oracle')
export class CarnetSequenceController {
@ -18,7 +18,7 @@ export class CarnetSequenceController {
@ApiTags('Carnet Sequence - Oracle')
@Get('/GetCarnetSequence')
getCarnetSequence(@Query() body: GetCarnetSequenceDTO) {
getCarnetSequence(@Query() body: SPID_DTO) {
return this.carnetSequenceService.getCarnetSequence(body);
}
}

View File

@ -1,42 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsDefined, IsInt, IsNumber, IsString, Min } from 'class-validator';
export class CreateCarnetSequenceDTO {
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_spid must be a number' })
@IsDefined({ message: 'Property p_spid is required' })
p_spid: number;
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_regionid must be a number' })
@IsDefined({ message: 'Property p_regionid is required' })
p_regionid: number;
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_startnumber must be a number' })
@IsDefined({ message: 'Property p_startnumber is required' })
@Min(0, { message: 'Property p_startnumber must be at least 0' })
p_startnumber: number;
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_endnumber must be a number' })
@IsDefined({ message: 'Property p_endnumber is required' })
@Min(0, { message: 'Property p_endnumber must be at least 0' })
p_endnumber: number;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_carnettype must be a string' })
@IsDefined({ message: 'Property p_carnettype is required' })
p_carnettype: string;
}
export class GetCarnetSequenceDTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_spid must be at least 0' })
@IsInt({ message: 'Property p_SPid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_spid must be a number' })
@IsDefined({ message: 'Property p_spid is required' })
p_spid: number;
}

View File

@ -3,11 +3,11 @@ import * as oracledb from 'oracledb';
import { OracleDBService } from 'src/db/db.service';
import {
CreateCarnetSequenceDTO,
GetCarnetSequenceDTO,
} from './carnet-sequence.dto';
} from '../../../dto/carnet-sequence.dto';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import { SPID_DTO } from 'src/dto/property.dto';
@Injectable()
export class CarnetSequenceService {
@ -39,7 +39,7 @@ export class CarnetSequenceService {
type: oracledb.DB_TYPE_NUMBER,
},
p_regionid: {
val: body.p_regionid,
val: body.P_REGIONID,
type: oracledb.DB_TYPE_NUMBER,
},
p_startnumber: {
@ -94,7 +94,7 @@ export class CarnetSequenceService {
}
}
async getCarnetSequence(body: GetCarnetSequenceDTO) {
async getCarnetSequence(body: SPID_DTO) {
let connection;
let rows = [];
try {

View File

@ -3,33 +3,26 @@ import { RegionService } from './region.service';
import { Get, Post, Body, Controller, Patch } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { InsertRegionsDto, UpdateRegionDto } from './region.dto';
import { InsertRegionsDto, UpdateRegionDto } from '../../../dto/region.dto';
@ApiTags('Regions - Oracle')
@Controller('oracle')
export class RegionController {
constructor(private readonly regionService: RegionService) {}
constructor(private readonly regionService: RegionService) { }
@ApiTags('Regions - Oracle')
@Post('/InsertRegions')
insertRegions(@Body() body: InsertRegionsDto) {
return this.regionService.insertRegions(body);
}
@ApiTags('Regions - Oracle')
@Patch('/UpdateRegion')
updateRegions(@Body() body: UpdateRegionDto) {
return this.regionService.updateRegions(body);
}
@ApiTags('Regions - Oracle')
@Get('/GetRegions')
getRegions() {
return this.regionService.getRegions();
}
// @ApiTags('Regions - Oracle')
// @Get('/getDetails')
selectAll() {
return this.regionService.selectSP();
}
}

View File

@ -1,45 +0,0 @@
import { IsDefined, IsInt, IsNumber, IsOptional, IsString } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
export class InsertRegionsDto {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_region must be a string' })
@IsDefined({ message: 'Property p_region is required' })
p_region: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_name must be a string' })
@IsDefined({ message: 'Property p_name is required' })
p_name: string;
}
export class UpdateRegionDto {
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_regionID must be a number' })
@IsDefined({ message: 'Property p_regionID is required' })
p_regionID: number;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_name must be a string' })
@IsDefined({ message: 'Property p_name is required' })
p_name: string;
}
export class RegionDto {
@ApiProperty({ example: 1, description: 'Unique identifier for the region' })
@IsInt()
REGIONID: number;
@ApiProperty({ example: '01', description: 'Region code' })
@IsString()
REGION: string;
@ApiProperty({ example: 'uk', description: 'Human-readable region name' })
@IsString()
REGIONNAME: string;
@ApiPropertyOptional({ example: null, description: 'Error message if applicable' })
@IsOptional()
@IsString()
ERRORMESG?: string | null;
}

View File

@ -1,9 +1,10 @@
import { Injectable, Logger } from '@nestjs/common';
import { OracleDBService } from 'src/db/db.service';
import * as oracledb from 'oracledb';
import { InsertRegionsDto, UpdateRegionDto } from './region.dto';
import { InsertRegionsDto, UpdateRegionDto } from '../../../dto/region.dto';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper';
@Injectable()
export class RegionService {
@ -11,90 +12,7 @@ export class RegionService {
constructor(private readonly oracleDBService: OracleDBService) { }
async selectAll() {
let connection: oracledb.Connection | undefined;
try {
connection = await this.oracleDBService.getConnection();
if (!connection) {
throw new InternalServerException();
}
const result = await connection.execute(
`SELECT * FROM BasicFeeSetup`,
[],
{
outFormat: oracledb.OUT_FORMAT_OBJECT,
}
);
return result.rows;
} catch (error) {
this.logger.error('selectAll failed', error.stack || error);
throw new InternalServerException();
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
}
}
async selectSP() {
let connection: oracledb.Connection | undefined;
try {
connection = await this.oracleDBService.getConnection();
if (!connection) {
throw new InternalServerException();
}
// const result = await connection.execute(
// `
// SELECT text
// FROM all_source
// WHERE name = 'MANAGEPREPARER_PKG' AND type = 'PACKAGE BODY'
// ORDER BY line
// `,
// [],
// {
// outFormat: oracledb.OUT_FORMAT_OBJECT,
// }
// );
const result: any = await connection.execute(
`SELECT text
FROM all_source
WHERE name = :pkgName AND type = 'PACKAGE BODY'
ORDER BY line`,
{ pkgName: 'USCIB_MANAGED_PKG' }, // bind variable
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
console.log(result);
const sourceCode = result.rows.map(row => row.TEXT).join('');
console.log(sourceCode);
return sourceCode;
} catch (error) {
this.logger.error('selectAll failed', error.stack || error);
throw new InternalServerException();
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
}
}
async insertRegions(body: InsertRegionsDto) {
async insertRegionsX(body: InsertRegionsDto) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
@ -104,15 +22,15 @@ export class RegionService {
const result = await connection.execute(
`BEGIN
USCIB_Managed_Pkg.InsertNewRegion(:p_region,:p_name,:p_cursor);
USCIB_Managed_Pkg.InsertNewRegion(:p_region,:P_NAME,:p_cursor);
END;`,
{
p_region: {
val: body.p_region,
val: body.P_REGION,
type: oracledb.DB_TYPE_VARCHAR,
},
p_name: {
val: body.p_name,
P_NAME: {
val: body.P_NAME,
type: oracledb.DB_TYPE_VARCHAR,
},
p_cursor: {
@ -129,7 +47,7 @@ export class RegionService {
const fres = await result.outBinds.p_cursor.getRows();
if (fres.length>0 && fres[0].ERRORMESG) {
if (fres.length > 0 && fres[0].ERRORMESG) {
this.logger.warn(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
@ -153,7 +71,48 @@ export class RegionService {
}
}
async updateRegions(body: UpdateRegionDto) {
async insertRegions(body: InsertRegionsDto) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
USCIB_Managed_Pkg.InsertNewRegion(:p_region,:P_NAME,:p_cursor);
END;`,
{
p_region: { val: body.P_REGION, type: oracledb.DB_TYPE_VARCHAR },
P_NAME: { val: body.P_NAME, type: oracledb.DB_TYPE_VARCHAR },
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, RegionService.name);
if (fres.length > 0 && fres[0].ERRORMESG) {
this.logger.warn(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
return { statusCode: 201, message: "Createdted Successfully", ...fres[0] };
} catch (error) {
handleError(error, RegionService.name)
} finally {
await closeOracleDbConnection(connection, RegionService.name)
}
}
async updateRegionsX(body: UpdateRegionDto) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
@ -163,15 +122,15 @@ export class RegionService {
const result = await connection.execute(
`BEGIN
USCIB_Managed_Pkg.UpdateRegion(:p_regionID,:p_name,:p_cursor);
USCIB_Managed_Pkg.UpdateRegion(:p_regionID,:P_NAME,:p_cursor);
END;`,
{
p_regionID: {
val: body.p_regionID,
val: body.P_REGIONID,
type: oracledb.DB_TYPE_NUMBER,
},
p_name: {
val: body.p_name,
P_NAME: {
val: body.P_NAME,
type: oracledb.DB_TYPE_VARCHAR,
},
p_cursor: {
@ -188,7 +147,7 @@ export class RegionService {
const fres = await result.outBinds.p_cursor.getRows();
if (fres.length>0 && fres[0].ERRORMESG) {
if (fres.length > 0 && fres[0].ERRORMESG) {
this.logger.warn(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
@ -212,7 +171,47 @@ export class RegionService {
}
}
async getRegions() {
async updateRegions(body: UpdateRegionDto) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
USCIB_Managed_Pkg.UpdateRegion(:p_regionID,:P_NAME,:p_cursor);
END;`,
{
p_regionID: { val: body.P_REGIONID, type: oracledb.DB_TYPE_NUMBER },
P_NAME: { val: body.P_NAME, type: oracledb.DB_TYPE_VARCHAR },
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, RegionService.name);
if (fres.length > 0 && fres[0].ERRORMESG) {
this.logger.warn(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
} catch (error) {
handleError(error, RegionService.name)
} finally {
await closeOracleDbConnection(connection, RegionService.name)
}
}
async getRegionsX() {
let connection;
let rows = [];
try {
@ -273,4 +272,33 @@ export class RegionService {
}
}
}
async getRegions() {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
USCIB_Managed_Pkg.GetRegions(:p_cursor);
END;`,
{
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await fetchCursor(outBinds.p_cursor, RegionService.name);
} catch (error) {
handleError(error, RegionService.name)
} finally {
await closeOracleDbConnection(connection, RegionService.name)
}
}
}

View File

@ -1,18 +1,15 @@
import { SpContactsService } from './sp-contacts.service';
import { Body, Controller, Get, Patch, Post, Put, Query } from '@nestjs/common';
import {
getSPAllContactsDTO,
getSPDefaultcontactDTO,
inactivateSPContactDTO,
InsertSPContactsDTO,
setSPDefaultcontactDTO,
UpdateSPContactsDTO,
} from './sp-contacts.dto';
} from '../../../dto/sp-contacts.dto';
import { ApiTags } from '@nestjs/swagger';
import { SP_CONTACTID_DTO, SP_ID_DTO } from 'src/dto/property.dto';
@Controller('oracle')
export class SpContactsController {
constructor(private readonly spContactsService: SpContactsService) {}
constructor(private readonly spContactsService: SpContactsService) { }
@ApiTags('SPContacts - Oracle')
@Post('/InsertSPContacts')
@ -22,7 +19,7 @@ export class SpContactsController {
@ApiTags('SPContacts - Oracle')
@Patch('/SetSPDefaultContact')
setSPDefaultcontact(@Query() body: setSPDefaultcontactDTO) {
setSPDefaultcontact(@Query() body: SP_CONTACTID_DTO) {
return this.spContactsService.setSPDefaultcontact(body);
}
@ -34,19 +31,19 @@ export class SpContactsController {
@ApiTags('SPContacts - Oracle')
@Patch('/InactivateSPContact')
inactivateSPContact(@Query() body: inactivateSPContactDTO) {
inactivateSPContact(@Query() body: SP_CONTACTID_DTO) {
return this.spContactsService.inactivateSPContact(body);
}
@ApiTags('SPContacts - Oracle')
@Get('/GetSPDefaultContact')
getSPDefaultcontact(@Query() body: getSPDefaultcontactDTO) {
getSPDefaultcontact(@Query() body: SP_ID_DTO) {
return this.spContactsService.getSPDefaultcontacts(body);
}
@ApiTags('SPContacts - Oracle')
@Get('/GetSPAllContacts')
getSPAllContacts(@Query() body: getSPAllContactsDTO) {
return this.spContactsService.getSPAllContacts(body);
getSPAllContacts(@Query() body: SP_ID_DTO) {
return this.spContactsService.getSPAllContacts(body);
}
}

View File

@ -1,121 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import {
IsDefined,
IsEmail,
IsInt,
IsNumber,
IsString,
Min,
} from 'class-validator';
export class InsertSPContactsDTO {
@ApiProperty({ required: true })
@IsNumber()
p_spid: number;
@ApiProperty({ required: true })
@IsString()
p_defcontactflag: string;
@ApiProperty({ required: true })
@IsString()
p_firstname: string;
@ApiProperty({ required: true })
@IsString()
p_lastname: string;
@ApiProperty({ required: false })
@IsString()
P_MIDDLEINITIAL: string;
@ApiProperty({ required: true })
@IsString()
p_title: string;
@ApiProperty({ required: true })
@IsString()
p_phoneno: string;
@ApiProperty({ required: true })
@IsString()
p_mobileno: string;
@ApiProperty({ required: true })
@IsString()
p_faxno: string;
@ApiProperty({ required: true })
@IsEmail()
p_emailaddress: string;
@ApiProperty({ required: true })
@IsString()
p_user_id: string;
}
export class UpdateSPContactsDTO {
@ApiProperty({ required: true })
@IsNumber()
p_spcontactid: number;
@ApiProperty({ required: true })
@IsString()
p_firstname: string;
@ApiProperty({ required: true })
@IsString()
p_lastname: string;
@ApiProperty({ required: false })
@IsString()
P_MIDDLEINITIAL: string;
@ApiProperty({ required: true })
@IsString()
p_title: string;
@ApiProperty({ required: true })
@IsString()
p_phoneno: string;
@ApiProperty({ required: true })
@IsString()
p_mobileno: string;
@ApiProperty({ required: true })
@IsString()
p_faxno: string;
@ApiProperty({ required: true })
@IsEmail()
p_emailaddress: string;
@ApiProperty({ required: true })
@IsString()
p_user_id: string;
}
export class setSPDefaultcontactDTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_spcontactid must be at least 0' })
@IsInt({ message: 'Property p_SPid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_spcontactid must be a number' })
@IsDefined({ message: 'Property p_spcontactid is required' })
p_spcontactid: number;
}
export class inactivateSPContactDTO extends setSPDefaultcontactDTO {}
export class getSPDefaultcontactDTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_SPid must be at least 0' })
@IsInt({ message: 'Property p_SPid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_SPid must be a number' })
@IsDefined({ message: 'Property p_SPid is required' })
p_SPid: number;
}
export class getSPAllContactsDTO extends getSPDefaultcontactDTO{}

View File

@ -2,15 +2,12 @@ import { Injectable, Logger } from '@nestjs/common';
import { OracleDBService } from 'src/db/db.service';
import * as oracledb from 'oracledb';
import {
getSPAllContactsDTO,
getSPDefaultcontactDTO,
inactivateSPContactDTO,
InsertSPContactsDTO,
setSPDefaultcontactDTO,
UpdateSPContactsDTO,
} from './sp-contacts.dto';
} from '../../../dto/sp-contacts.dto';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import { SP_CONTACTID_DTO, SP_ID_DTO } from 'src/dto/property.dto';
@Injectable()
export class SpContactsService {
@ -101,7 +98,7 @@ export class SpContactsService {
const fres = await result.outBinds.p_cursor.getRows();
if (fres.length>0 && fres[0].ERRORMESG) {
if (fres.length > 0 && fres[0].ERRORMESG) {
this.logger.warn(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
@ -124,7 +121,7 @@ export class SpContactsService {
}
}
async setSPDefaultcontact(body: setSPDefaultcontactDTO) {
async setSPDefaultcontact(body: SP_CONTACTID_DTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
@ -239,7 +236,7 @@ export class SpContactsService {
const fres = await result.outBinds.p_cursor.getRows();
if (fres.length>0 && fres[0].ERRORMESG) {
if (fres.length > 0 && fres[0].ERRORMESG) {
this.logger.warn(fres[0].ERRORMESG);
throw new BadRequestException(fres[0].ERRORMESG)
}
@ -263,7 +260,7 @@ export class SpContactsService {
}
}
async inactivateSPContact(body: inactivateSPContactDTO) {
async inactivateSPContact(body: SP_CONTACTID_DTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
@ -300,7 +297,7 @@ export class SpContactsService {
}
}
async getSPDefaultcontacts(body: getSPDefaultcontactDTO) {
async getSPDefaultcontacts(body: SP_ID_DTO) {
let connection;
let rows = [];
try {
@ -357,7 +354,7 @@ export class SpContactsService {
}
}
async getSPAllContacts(body: getSPAllContactsDTO) {
async getSPAllContacts(body: SP_ID_DTO) {
let connection;
let rows = [];

View File

@ -2,14 +2,14 @@ import { Body, Controller, Get, Post, Put, Query } from '@nestjs/common';
import { SpService } from './sp.service';
import { ApiTags } from '@nestjs/swagger';
import {
getSelectedServiceproviderDTO,
InsertNewServiceProviderDTO,
UpdateServiceProviderDTO,
} from './sp.dto';
} from '../../../dto/sp.dto';
import { SPID_DTO } from 'src/dto/property.dto';
@Controller('oracle')
export class SpController {
constructor(private readonly spService: SpService) {}
constructor(private readonly spService: SpService) { }
@ApiTags('SP - Oracle')
@Post('/InsertNewServiceProvider')
@ -31,7 +31,7 @@ export class SpController {
@ApiTags('SP - Oracle')
@Get('/GetSelectedServiceprovider')
getSelectedServiceprovider(@Query() body: getSelectedServiceproviderDTO) {
getSelectedServiceprovider(@Query() body: SPID_DTO) {
return this.spService.getServiceproviderByID(body);
}
}

View File

@ -1,190 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import {
IsDefined,
IsInt,
IsNumber,
IsOptional,
IsString,
Min,
} from 'class-validator';
export class InsertNewServiceProviderDTO {
@ApiProperty({ required: true })
@IsString({ message: 'Property p_name must be a string' })
@IsDefined({ message: 'Property p_name is required' })
p_name: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_lookupcode must be a string' })
@IsDefined({ message: 'Property p_lookupcode is required' })
p_lookupcode: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_address1 must be a string' })
@IsDefined({ message: 'Property p_address1 is required' })
p_address1: string;
@ApiProperty({ required: false })
@IsString({ message: 'Property p_address2 must be a string' })
@IsOptional()
p_address2?: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_city must be a string' })
@IsDefined({ message: 'Property p_city is required' })
p_city: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_state must be a string' })
@IsDefined({ message: 'Property p_state is required' })
p_state: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_country must be a string' })
@IsDefined({ message: 'Property p_country is required' })
p_country: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_zip must be a string' })
@IsDefined({ message: 'Property p_zip is required' })
p_zip: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_issuingregion must be a string' })
@IsDefined({ message: 'Property p_issuingregion is required' })
p_issuingregion: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_replacementregion must be a string' })
@IsDefined({ message: 'Property p_replacementregion is required' })
p_replacementregion: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_bondsurety must be a string' })
@IsDefined({ message: 'Property p_bondsurety is required' })
p_bondsurety: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_cargopolicyno must be a string' })
@IsDefined({ message: 'Property p_cargopolicyno is required' })
p_cargopolicyno: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_cargosurety must be a string' })
@IsDefined({ message: 'Property p_cargosurety is required' })
p_cargosurety: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_user_id must be a string' })
@IsDefined({ message: 'Property p_user_id is required' })
p_user_id: string;
@ApiProperty({ required: false })
@IsString({ message: 'Property P_NOTES must be a string' })
@IsOptional()
P_NOTES?: string;
@ApiProperty({ required: false })
@IsString({ message: 'Property P_FILEIDS must be a string' })
@IsOptional()
P_FILEIDS?: string;
}
export class UpdateServiceProviderDTO {
@ApiProperty({ required: true })
@IsNumber({}, { message: 'Property p_spid must be a number' })
@IsDefined({ message: 'Property p_spid is required' })
p_spid: number;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_name must be a string' })
@IsDefined({ message: 'Property p_name is required' })
p_name: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_lookupcode must be a string' })
@IsDefined({ message: 'Property p_lookupcode is required' })
p_lookupcode: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_address1 must be a string' })
@IsDefined({ message: 'Property p_address1 is required' })
p_address1: string;
@ApiProperty({ required: false })
@IsString({ message: 'Property p_address2 must be a string' })
@IsOptional()
p_address2?: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_city must be a string' })
@IsDefined({ message: 'Property p_city is required' })
p_city: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_state must be a string' })
@IsDefined({ message: 'Property p_state is required' })
p_state: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_country must be a string' })
@IsDefined({ message: 'Property p_country is required' })
p_country: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_issuingregion must be a string' })
@IsDefined({ message: 'Property p_issuingregion is required' })
p_issuingregion: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_replacementregion must be a string' })
@IsDefined({ message: 'Property p_replacementregion is required' })
p_replacementregion: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_bondsurety must be a string' })
@IsDefined({ message: 'Property p_bondsurety is required' })
p_bondsurety: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_cargopolicyno must be a string' })
@IsDefined({ message: 'Property p_cargopolicyno is required' })
p_cargopolicyno: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_cargosurety must be a string' })
@IsDefined({ message: 'Property p_cargosurety is required' })
p_cargosurety: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_zip must be a string' })
@IsDefined({ message: 'Property p_zip is required' })
p_zip: string;
@ApiProperty({ required: true })
@IsString({ message: 'Property p_user_id must be a string' })
@IsDefined({ message: 'Property p_user_id is required' })
p_user_id: string;
@ApiProperty({ required: false })
@IsString({ message: 'Property P_NOTES must be a string' })
@IsOptional()
P_NOTES?: string;
@ApiProperty({ required: false })
@IsString({ message: 'Property P_FILEIDS must be a string' })
@IsOptional()
P_FILEIDS?: string;
}
export class getSelectedServiceproviderDTO {
@ApiProperty({ required: true })
@Min(0, { message: 'Property p_spid must be at least 0' })
@IsInt({ message: 'Property p_SPid must be a whole number' })
@Transform(({ value }) => Number(value))
@IsNumber({}, { message: 'Property p_spid must be a number' })
@IsDefined({ message: 'Property p_spid is required' })
p_spid: number;
}

View File

@ -2,12 +2,12 @@ import { Injectable, Logger } from '@nestjs/common';
import { OracleDBService } from 'src/db/db.service';
import * as oracledb from 'oracledb';
import {
getSelectedServiceproviderDTO,
InsertNewServiceProviderDTO,
UpdateServiceProviderDTO,
} from './sp.dto';
} from '../../../dto/sp.dto';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import { SPID_DTO } from 'src/dto/property.dto';
@Injectable()
export class SpService {
@ -27,7 +27,7 @@ export class SpService {
const result = await connection.execute(
`BEGIN
USCIB_Managed_Pkg.InsertNewSP(
:p_name,
:P_NAME,
:p_lookupcode,
:p_address1,
:p_address2,
@ -46,12 +46,12 @@ export class SpService {
:p_cursor);
END;`,
{
p_name: {
val: body.p_name,
P_NAME: {
val: body.P_NAME,
type: oracledb.DB_TYPE_VARCHAR,
},
p_lookupcode: {
val: body.p_lookupcode,
val: body.p_lookupCode,
type: oracledb.DB_TYPE_VARCHAR,
},
p_address1: {
@ -196,7 +196,7 @@ export class SpService {
`BEGIN
USCIB_Managed_Pkg.UpdateSP(
:p_spid,
:p_name,
:P_NAME,
:p_lookupcode,
:p_address1,
:p_address2,
@ -219,12 +219,12 @@ export class SpService {
val: finalBody.p_spid,
type: oracledb.DB_TYPE_NUMBER,
},
p_name: {
val: finalBody.p_name,
P_NAME: {
val: finalBody.P_NAME,
type: oracledb.DB_TYPE_VARCHAR,
},
p_lookupcode: {
val: finalBody.p_lookupcode,
val: finalBody.p_lookupCode,
type: oracledb.DB_TYPE_VARCHAR,
},
p_address1: {
@ -382,7 +382,7 @@ export class SpService {
}
}
async getServiceproviderByID(body: getSelectedServiceproviderDTO) {
async getServiceproviderByID(body: SPID_DTO) {
let connection;
let rows: any = [];
try {

View File

@ -1,41 +1,64 @@
import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import { Body, Controller, Get, Param, Patch, Post, Query } from '@nestjs/common';
import { UserMaintenanceService } from './user-maintenance.service';
import { ApiTags } from '@nestjs/swagger';
import { CreateUSCIBLoginsDTO, GetSPUserDetailsDTO, UseSPIDDTO } from './user-maintenance.dto';
import { CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, SPID_CLIENTID_DTO, SPID_EMAIL_DTO } from '../../dto/user-maintenance.dto';
import { SPID_DTO, USERID_DTO } from 'src/dto/property.dto';
@ApiTags('User Maintenance - Oracle')
@Controller('oracle')
export class UserMaintenanceController {
constructor(private readonly userMaintenanceService: UserMaintenanceService) { }
// SP_USER_DETAILS
@Get('GetSPUserDetails/:p_userid')
async GetPreparers(@Param() params: GetSPUserDetailsDTO) {
@Get('GetUserDetails/:p_userid')
async GetPreparers(@Param() params: USERID_DTO) {
return await this.userMaintenanceService.GetSPUserDetails(params);
}
// @ApiTags('User Maintenance - Oracle')
// @Get('GetSPUserDetailsv1')
// async GetPreparersv1(@Query() query: GetSPUserDetailsDTO) {
// return await this.userMaintenanceService.GetSPUserDetailsv1(query);
// }
// @ApiTags('User Maintenance - Oracle')
@Post('CreateUSCIBLogins')
async CreateUSCIBLogins(@Body() body: CreateUSCIBLoginsDTO) {
return await this.userMaintenanceService.CreateUSCIBLogins(body);
@Patch('LockUserAccount')
async LockUserAccount(@Body() body: SPID_EMAIL_DTO) {
return await this.userMaintenanceService.LockUserAccount(body);
}
// @ApiTags('User Maintenance - Oracle')
// USCIB_LOGINS
@Get('GetUSCIBLogins')
async GetUSCIBLogins() {
return await this.userMaintenanceService.GetUSCIBLogins();
}
@Post('CreateUSCIBLogins')
async CreateUSCIBLogins(@Body() body: CreateUSCIBLoginsDTO) {
return await this.userMaintenanceService.CreateUSCIBLogins(body);
}
// SP LOGINS
@Get('GetSPLogins/:p_spid')
async GetSPLogins(@Param() params: UseSPIDDTO) {
async GetSPLogins(@Param() params: SPID_DTO) {
return await this.userMaintenanceService.GetSPLogins(params);
}
@Post('CreateSPLogins')
async CreateSPLogins(@Body() body: CreateSPLoginsDTO) {
return await this.userMaintenanceService.CreateSPLogins(body);
}
// CLIENT LOGINS
@Get('GetClientloginsBySPID/:p_spid')
async GetClientloginsBySPID(@Param() params: SPID_DTO) {
return await this.userMaintenanceService.GetSPLogins(params);
}
@Get('GetClientloginsByClientID/:p_spid/:p_clientid')
async GetClientloginsByClientID(@Param() params: SPID_CLIENTID_DTO) {
return await this.userMaintenanceService.GetSPLogins(params);
}
@Post('CreateClientLogins')
async CreateClientLogins(@Body() body: CreateClientLoginsDTO) {
return await this.userMaintenanceService.CreateClientLogins(body);
}
}

View File

@ -1,57 +0,0 @@
import { ApiProperty } from "@nestjs/swagger";
import { Transform, Type } from "class-transformer";
import { IsDefined, IsEmail, IsEnum, IsInt, IsPositive, IsString, Length, Min } from "class-validator";
export enum YON {
YES = "Y",
NO = "N",
}
export class GetSPUserDetailsDTO {
@ApiProperty({ required: true })
// @IsEmail({},{message:"Invalid P_USERID property"})
@IsString()
@IsDefined({ message: "Invalid Request" })
p_userid: string;
}
export class CreateUSCIBLoginsDTO {
@ApiProperty({ required: true })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_userid: string;
@ApiProperty({ required: true })
@IsEmail({}, { message: "Invalid p_emailaddr property" })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_emailaddr: string;
@ApiProperty({ required: true })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_lookupCode: string;
@ApiProperty({ required: true })
@IsString()
@IsDefined({ message: "Invalid Request" })
p_password: string;
@ApiProperty({ required: true, enum: YON })
@Transform(({ value }) => typeof value === 'string' ? value.trim().toUpperCase() : value)
@IsEnum(YON, { message: 'P_EnablePasswordPolicy must be either "Y" or "N"' })
@Length(1, 1, { message: 'P_EnablePasswordPolicy must be between 5 and 6 characters' })
@IsString()
@IsDefined({ message: "Invalid Request" })
P_EnablePasswordPolicy: YON;
}
export class UseSPIDDTO {
@ApiProperty({ required: true })
@Min(0, { message: 'p_spid must be greater than or equal to 0' })
@IsInt({ message: "p_spid must be whole number" })
@IsDefined({ message: 'Invalid Request' })
@Type(() => Number)
p_spid: number;
}

View File

@ -1,9 +1,11 @@
import { Injectable, Logger } from '@nestjs/common';
import { OracleDBService } from 'src/db/db.service';
import { CreateUSCIBLoginsDTO, GetSPUserDetailsDTO, UseSPIDDTO } from './user-maintenance.dto';
import { CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, SPID_CLIENTID_DTO, SPID_EMAIL_DTO } from '../../dto/user-maintenance.dto';
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
import * as oracledb from 'oracledb';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
import { SPID_DTO, USERID_DTO } from 'src/dto/property.dto';
import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper';
interface RoleDetail { [key: string]: any; }
@ -25,18 +27,20 @@ export class UserMaintenanceService {
constructor(private readonly oracleDBService: OracleDBService) { }
private async fetchCursor<T>(cursor: oracledb.ResultSet<T>): Promise<T[]> {
try {
const rows = await cursor.getRows(); // or getRows(1000) if needed
await cursor.close();
return rows;
} catch (err) {
this.logger.error('Failed to fetch from cursor', err.stack || err);
throw new InternalServerException("Error reading data from database.");
}
}
// private async fetchCursor<T>(cursor: oracledb.ResultSet<T>): Promise<T[]> {
// try {
// const rows = await cursor.getRows(); // or getRows(1000) if needed
// await cursor.close();
// return rows;
// } catch (err) {
// this.logger.error('Failed to fetch from cursor', err.stack || err);
// throw new InternalServerException("Error reading data from database.");
// }
// }
async GetSPUserDetails(body: GetSPUserDetailsDTO): Promise<any> {
// SP_USER_DETAILS
async GetSPUserDetails(body: USERID_DTO): Promise<any> {
let connection;
try {
@ -63,38 +67,59 @@ export class UserMaintenanceService {
this.logger.error('One or more expected cursors are missing from stored procedure output.');
throw new InternalServerException("Incomplete data received from the database.");
}
let userdetailsTemp: any = await this.fetchCursor(outBinds.P_USERDETAILS);
let roleDetailsTemp: { "ROLENAME": "" }[] = await fetchCursor(outBinds.P_ROLECUR, UserMaintenanceService.name);
let menuDetailsTemp: { "MENUNAME": "" }[] = await fetchCursor(outBinds.P_MENUCUR, UserMaintenanceService.name);
let userdetailsTemp: any = await fetchCursor(outBinds.P_USERDETAILS, UserMaintenanceService.name);
return {
roleDetails: await this.fetchCursor(outBinds.P_ROLECUR),
menuDetails: await this.fetchCursor(outBinds.P_MENUCUR),
menuPageDetails: await this.fetchCursor(outBinds.P_MENUPAGECUR),
roleDetails: roleDetailsTemp.map(x => x.ROLENAME),
menuDetails: menuDetailsTemp.map(x => x.MENUNAME),
menuPageDetails: await fetchCursor(outBinds.P_MENUPAGECUR, UserMaintenanceService.name),
userDetails: userdetailsTemp[0]
};
} catch (error) {
if (error instanceof BadRequestException) {
this.logger.warn(error.message);
throw error;
} else if (error.message.includes("NJS-107")) {
this.logger.warn("Invalid cursor encountered: " + error.message);
throw new BadRequestException("Invalid database response.");
} else if (error.message.includes("ORA-")) {
this.logger.error("Oracle error occurred: " + error.message);
throw new InternalServerException(error.message);
}
this.logger.error('GetSPUserDetails failed', error.stack || error);
throw new InternalServerException(error.message);
handleError(error, UserMaintenanceService.name)
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
async GetSPUserDetailsv1(body: GetSPUserDetailsDTO): Promise<GetUserDetailsResult> {
async LockUserAccount(body: SPID_EMAIL_DTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
Userlogin_pkg.LockUserAccount(
:p_spid, :p_emailaddr, :p_cursor
);
END;`,
{
p_spid: { val: body.p_spid, type: oracledb.DB_TYPE_NUMBER },
p_emailaddr: { val: body.p_emailaddr, type: oracledb.DB_TYPE_NVARCHAR },
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
handleError(error, UserMaintenanceService.name)
} finally {
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
// USCIB_LOGINS
async GetUSCIBLogins() {
let connection;
try {
@ -102,54 +127,29 @@ export class UserMaintenanceService {
const result = await connection.execute(
`BEGIN
SPCLIENTUSER_PKG.GetSPUserDetails(
:p_userid , :p_rolecur , :p_menucur , :p_menuPageCur , :p_userdetails
);
END;`,
Userlogin_pkg.GetUSCIBLogins(
:p_cursor
);
END;`,
{
p_userid: { val: body.p_userid, type: oracledb.DB_TYPE_NVARCHAR },
p_rolecur: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
p_menucur: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
p_menuPageCur: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
p_userdetails: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
const outBinds = result.outBinds;
if (!outBinds?.p_rolecur || !outBinds?.p_menucur || !outBinds?.p_menuPageCur || !outBinds?.p_userdetails) {
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.");
}
return {
roleDetails: await this.fetchCursor(outBinds.p_rolecur),
menuDetails: await this.fetchCursor(outBinds.p_menucur),
menuPageDetails: await this.fetchCursor(outBinds.p_menuPageCur),
userDetails: await this.fetchCursor(outBinds.p_userdetails),
};
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
if (error instanceof BadRequestException) {
this.logger.warn(error.message);
throw error;
} else if (error.message.includes("NJS-107")) {
this.logger.warn("Invalid cursor encountered: " + error.message);
throw new BadRequestException("Invalid database response.");
} else if (error.message.includes("ORA-")) {
this.logger.error("Oracle error occurred: " + error.message);
throw new InternalServerException(error.message);
}
this.logger.error('GetSPUserDetails failed', error.stack || error);
throw new InternalServerException(error.message);
handleError(error, UserMaintenanceService.name)
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
async CreateUSCIBLogins(body: CreateUSCIBLoginsDTO) {
@ -183,85 +183,19 @@ export class UserMaintenanceService {
}
return {
data: await this.fetchCursor(outBinds.p_cursor),
data: await fetchCursor(outBinds.p_cursor),
};
} catch (error) {
if (error instanceof BadRequestException) {
this.logger.warn(error.message);
throw error;
} else if (error.message.includes("NJS-107")) {
this.logger.warn("Invalid cursor encountered: " + error.message);
throw new BadRequestException("Invalid database response.");
} else if (error.message.includes("ORA-")) {
this.logger.error("Oracle error occurred: " + error.message);
throw new InternalServerException(error.message);
}
this.logger.error('GetSPUserDetails failed', error.stack || error);
throw new InternalServerException(error.message);
handleError(error, UserMaintenanceService.name)
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
async GetUSCIBLogins() {
// SP LOGINS
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
Userlogin_pkg.GetUSCIBLogins(
:p_cursor
);
END;`,
{
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await this.fetchCursor(outBinds.p_cursor);
} catch (error) {
if (error instanceof BadRequestException) {
this.logger.warn(error.message);
throw error;
} else if (error.message.includes("NJS-107")) {
this.logger.warn("Invalid cursor encountered: " + error.message);
throw new BadRequestException("Invalid database response.");
} else if (error.message.includes("ORA-")) {
this.logger.error("Oracle error occurred: " + error.message);
throw new InternalServerException(error.message);
}
this.logger.error('GetSPUserDetails failed', error.stack || error);
throw new InternalServerException(error.message);
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
}
}
async GetSPLogins(body: UseSPIDDTO) {
async GetSPLogins(body: SPID_DTO) {
let connection;
@ -287,30 +221,162 @@ export class UserMaintenanceService {
throw new InternalServerException("Incomplete data received from the database.");
}
return await this.fetchCursor(outBinds.p_cursor);
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
if (error instanceof BadRequestException) {
this.logger.warn(error.message);
throw error;
} else if (error.message.includes("NJS-107")) {
this.logger.warn("Invalid cursor encountered: " + error.message);
throw new BadRequestException("Invalid database response.");
} else if (error.message.includes("ORA-")) {
this.logger.error("Oracle error occurred: " + error.message);
throw new InternalServerException(error.message);
}
this.logger.error('GetSPUserDetails failed', error.stack || error);
throw new InternalServerException(error.message);
handleError(error, UserMaintenanceService.name)
} finally {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
this.logger.error('Failed to close DB connection', closeErr);
}
}
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
async CreateSPLogins(body: CreateSPLoginsDTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
Userlogin_pkg.CreateSPLogins(
:p_spid, :p_userid, :p_domain, :p_emailaddr, :p_lookupCode, :p_password, :P_EnablePasswordPolicy, :p_cursor
);
END;`,
{
p_spid: { val: body.p_spid, type: oracledb.DB_TYPE_NUMBER },
p_userid: { val: body.p_userid, type: oracledb.DB_TYPE_NVARCHAR },
p_domain: { val: body.p_domain, type: oracledb.DB_TYPE_NVARCHAR },
p_emailaddr: { val: body.p_emailaddr, type: oracledb.DB_TYPE_NVARCHAR },
p_lookupCode: { val: body.p_lookupCode, type: oracledb.DB_TYPE_NVARCHAR },
p_password: { val: body.p_password, type: oracledb.DB_TYPE_NVARCHAR },
P_EnablePasswordPolicy: { val: body.P_EnablePasswordPolicy, type: oracledb.DB_TYPE_NVARCHAR },
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
handleError(error, UserMaintenanceService.name)
} finally {
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
// CLIENT LOGINS
async GetClientloginsBySPID(body: SPID_DTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
Userlogin_pkg.GetClientloginsBySPID(
:p_spid , :p_cursor
);
END;`,
{
p_spid: { val: body.p_spid, type: oracledb.DB_TYPE_NUMBER },
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
handleError(error, UserMaintenanceService.name)
} finally {
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
async GetClientloginsByClientID(body: SPID_CLIENTID_DTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
Userlogin_pkg.GetClientloginsByClientID(
:p_spid, :p_clientid , :p_cursor
);
END;`,
{
p_spid: { val: body.p_spid, type: oracledb.DB_TYPE_NUMBER },
p_clientid: { val: body.p_clientid, type: oracledb.DB_TYPE_NUMBER },
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
handleError(error, UserMaintenanceService.name)
} finally {
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
async CreateClientLogins(body: CreateClientLoginsDTO) {
let connection;
try {
connection = await this.oracleDBService.getConnection();
const result = await connection.execute(
`BEGIN
Userlogin_pkg.CreateClientLogins(
:p_spid, :p_userid, :p_clientcontactid, :p_password, :P_EnablePasswordPolicy, :p_cursor
);
END;`,
{
p_spid: { val: body.p_spid, type: oracledb.DB_TYPE_NUMBER },
p_userid: { val: body.p_userid, type: oracledb.DB_TYPE_NVARCHAR },
p_clientcontactid: { val: body.p_clientcontactid, type: oracledb.DB_TYPE_NUMBER },
p_password: { val: body.p_password, type: oracledb.DB_TYPE_NVARCHAR },
P_EnablePasswordPolicy: { val: body.P_EnablePasswordPolicy, type: oracledb.DB_TYPE_NVARCHAR },
p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
},
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
);
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.");
}
return await fetchCursor(outBinds.p_cursor, UserMaintenanceService.name);
} catch (error) {
handleError(error, UserMaintenanceService.name)
} finally {
await closeOracleDbConnection(connection, UserMaintenanceService.name)
}
}
}

49
src/utils/helper.ts Normal file
View File

@ -0,0 +1,49 @@
import {
BadRequestException,
InternalServerErrorException,
Logger,
} from '@nestjs/common';
import * as oracledb from 'oracledb';
const logger = new Logger('Helper');
export const handleError = (error: any, context: string = 'UnknownService'): never => {
if (error instanceof BadRequestException) {
logger.warn(`[${context}] ${error.message}`);
throw error;
}
if (error.message?.includes('NJS-107')) {
logger.warn(`[${context}] Invalid cursor encountered: ${error.message}`);
throw new BadRequestException('Invalid database response.');
}
if (error.message?.includes('ORA-')) {
logger.error(`[${context}] Oracle error occurred: ${error.message}`);
throw new InternalServerErrorException(error.message);
}
logger.error(`[${context}] Unexpected error:`, error.stack || error);
throw new InternalServerErrorException(error.message || 'Internal error');
};
export const closeOracleDbConnection = async (connection: any, context: string = 'UnknownService'): Promise<void> => {
if (connection) {
try {
await connection.close();
} catch (closeErr) {
logger.error(`[${context}] Failed to close DB connection`, closeErr.stack || closeErr);
}
}
};
export const fetchCursor = async <T>(cursor: oracledb.ResultSet<T>, context: string = 'UnknownService'): Promise<T[]> => {
try {
const rows = await cursor.getRows();
await cursor.close();
return rows;
} catch (err) {
logger.error(`[${context}] Failed to fetch from cursor`, err.stack || err);
throw new InternalServerErrorException('Error reading data from database.');
}
};