diff --git a/ormconfig.ts b/ormconfig.ts index 1095c53..e69de29 100644 --- a/ormconfig.ts +++ b/ormconfig.ts @@ -1,48 +0,0 @@ -import { DataSourceOptions } from 'typeorm'; - -export const OracleConfig: any = { - - user: 'Carnetsys', - password: 'Carnet1234', - connectString: '172.31.18.76/xe', - - // user: 'C##carnetsys', - // password: 'root', - // connectString: '192.168.1.96/xe', - - }; - - export const MssqlConfig: any = { - // type: 'mssql', - - // server: 'localhost', - // user: 'mssql1433', - // password: 'root', - // database: 'CarnetDB', - - server: '172.31.18.76', - port: 1433, - user: 'Carnetsys', - password: 'Carnet1234', - database: 'CarnetDB', - - // entities: [__dirname + '/**/*.entity{.ts,.js}'], - // synchronize: true, - - options: { - enableArithAbort: true, - trustServerCertificate: true, - encrypt:true - }, - }; - - export const MysqlConfig: DataSourceOptions = { - type: 'mysql', - host: 'localhost', - port: 3306, - username: 'root', - password: 'root', - database: 'demo', - // entities: [__dirname + '/**/*.entity{.ts,.js}'], - synchronize: true, - }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0f08080..1947fb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "UNLICENSED", "dependencies": { "@nestjs/common": "^11.0.1", + "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", "@nestjs/swagger": "^11.0.6", @@ -2613,6 +2614,21 @@ } } }, + "node_modules/@nestjs/config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", + "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", + "license": "MIT", + "dependencies": { + "dotenv": "16.4.7", + "dotenv-expand": "12.0.1", + "lodash": "4.17.21" + }, + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "rxjs": "^7.1.0" + } + }, "node_modules/@nestjs/core": { "version": "11.0.10", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.0.10.tgz", @@ -5947,6 +5963,21 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-expand": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz", + "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==", + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index 7614dbf..00b775a 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ }, "dependencies": { "@nestjs/common": "^11.0.1", + "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", "@nestjs/swagger": "^11.0.6", diff --git a/src/app.module.ts b/src/app.module.ts index 5504f39..cd36973 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -5,9 +5,13 @@ import { AuthModule } from './auth/auth.module'; import { MssqlModule } from './mssql/mssql.module'; import { OriginCheckMiddleware } from './middleware/OriginCheck.middleware'; import { ReqBodyKeysToUppercaseMiddleware } from './middleware/reqBodyKeysToUppercase.middleware'; +import { ConfigModule } from '@nestjs/config'; @Module({ - imports: [AuthModule, DbModule, OracleModule], + imports: [ + ConfigModule.forRoot({ isGlobal: true }), + AuthModule, DbModule, OracleModule + ], controllers: [], providers: [], }) @@ -21,13 +25,13 @@ export class AppModule { .apply(ReqBodyKeysToUppercaseMiddleware) .forRoutes('*'); // Apply to all routes - // .forRoutes('users'); // Applies to all methods on /users + // .forRoutes('users'); // Applies to all methods on /users - // .forRoutes(UsersController); // Applies to all routes in this controller - - // .forRoutes( - // { path: 'users', method: RequestMethod.GET }, - // { path: 'auth/login', method: RequestMethod.POST }, - // ); + // .forRoutes(UsersController); // Applies to all routes in this controller + + // .forRoutes( + // { path: 'users', method: RequestMethod.GET }, + // { path: 'auth/login', method: RequestMethod.POST }, + // ); } } diff --git a/src/db/db.config.ts b/src/db/db.config.ts new file mode 100644 index 0000000..378412a --- /dev/null +++ b/src/db/db.config.ts @@ -0,0 +1,20 @@ +import { ConfigService } from '@nestjs/config'; + +export const getOracleConfig = (configService: ConfigService) => ({ + user: configService.get('ORACLE_USER'), + password: configService.get('ORACLE_PASSWORD'), + connectString: configService.get('ORACLE_CONNECT_STRING'), +}); + +export const getMssqlConfig = (configService: ConfigService) => ({ + server: configService.get('MSSQL_SERVER'), + port: configService.get('MSSQL_PORT'), + user: configService.get('MSSQL_USER'), + password: configService.get('MSSQL_PASSWORD'), + database: configService.get('MSSQL_DATABASE'), + options: { + enableArithAbort: true, + trustServerCertificate: true, + encrypt: true + }, +}); \ No newline at end of file diff --git a/src/db/db.service.ts b/src/db/db.service.ts index 3eee641..a902828 100644 --- a/src/db/db.service.ts +++ b/src/db/db.service.ts @@ -1,8 +1,10 @@ -import { MssqlConfig, OracleConfig } from 'ormconfig'; +// import { MssqlConfig, OracleConfig } from 'ormconfig'; import { createPool, Pool, Connection as cob } from 'oracledb'; import { Connection, ConnectionPool } from 'mssql'; import { Injectable, Logger } from '@nestjs/common'; import { InternalServerException } from 'src/exceptions/internalServerError.exception'; +import { ConfigService } from '@nestjs/config'; +import { getMssqlConfig, getOracleConfig } from './db.config'; // @Injectable() // export class OracleDBService { @@ -30,77 +32,76 @@ import { InternalServerException } from 'src/exceptions/internalServerError.exce @Injectable() export class OracleDBService { private pool: Pool | null = null; - private readonly logger = new Logger(OracleDBService.name); - constructor() { + constructor(private readonly configService: ConfigService) { this.initializePool().catch(err => { - Logger.error('Error initializing Oracle DB pool', err); - // You might want to rethrow or handle accordingly depending on app behavior + this.logger.error('Error initializing Oracle DB pool', err); throw new InternalServerException(); }); } private async initializePool(): Promise { try { + const config = getOracleConfig(this.configService); + this.pool = await createPool({ - ...OracleConfig, + ...config, poolMin: 1, poolMax: 10, poolIncrement: 1, }); - Logger.log('Oracle connection pool created successfully'); - } catch (error) { - Logger.error('Failed to create Oracle DB pool:', error); - throw error; // Optional: rethrow to allow external handling - } - } - async getConnection(): Promise { - if (!this.pool) { - Logger.error('Attempted to get a connection before pool was initialized'); - throw new InternalServerException('Database connection pool not initialized'); - } - - try { - const connection = await this.pool.getConnection(); - return connection; + this.logger.log('Oracle connection pool created successfully'); } catch (error) { - Logger.error('Failed to get Oracle DB connection:', error); + this.logger.error('Failed to create Oracle DB pool:', error); + throw error; + } + } + + async getConnection(): Promise { + if (!this.pool) { + this.logger.error('Attempted to get a connection before pool was initialized'); + throw new InternalServerException('Database connection pool not initialized'); + } + + try { + return await this.pool.getConnection(); + } catch (error) { + this.logger.error('Failed to get Oracle DB connection:', error); throw error; } } - // Optionally add a close method to gracefully shut down the pool async closePool(): Promise { if (this.pool) { try { - await this.pool.close(10); // 10-second timeout - Logger.log('Oracle DB pool closed successfully'); + await this.pool.close(10); + this.logger.log('Oracle DB pool closed successfully'); } catch (error) { - Logger.error('Error closing Oracle DB pool:', error); - throw new InternalServerException() + this.logger.error('Error closing Oracle DB pool:', error); + throw new InternalServerException(); } } } } + @Injectable() export class MssqlDBService { private pool: ConnectionPool; - private poolConnected: boolean = false; + private poolConnected = false; - private readonly config = { - ...MssqlConfig, - pool: { - max: 10, - min: 0, - idleTimeoutMillis: 30000, - }, - }; - - constructor() { - this.pool = new ConnectionPool(this.config); + constructor(private readonly configService: ConfigService) { + const config: any = getMssqlConfig(configService); + this.pool = new ConnectionPool({ + ...config, + pool: { + max: 10, + min: 0, + idleTimeoutMillis: 30000, + }, + }); } async getConnection(): Promise { @@ -122,3 +123,4 @@ export class MssqlDBService { } } } + diff --git a/src/dto/carnet-application/carnet-application-property.dto.ts b/src/dto/carnet-application/carnet-application-property.dto.ts index 0224a8b..d80fa7b 100644 --- a/src/dto/carnet-application/carnet-application-property.dto.ts +++ b/src/dto/carnet-application/carnet-application-property.dto.ts @@ -41,6 +41,13 @@ export class APPLICATIONNAME_DTO { P_APPLICATIONNAME: string; } +export class ORDERTYPE_DTO { + @ApiProperty({ required: true }) + @IsString({ message: 'Property P_ORDERTYPE must be a string' }) + @IsDefined({ message: 'Property P_ORDERTYPE is required' }) + P_ORDERTYPE: string; +} + export class COMMERCIAL_SAMPLE_FLAG_DTO { @ApiProperty({ required: true, enum: YON }) @Transform(({ value }) => typeof value === 'string' ? value.trim().toUpperCase() : value) diff --git a/src/dto/carnet-application/carnet-application.dto.ts b/src/dto/carnet-application/carnet-application.dto.ts index a18af2b..bffe18f 100644 --- a/src/dto/carnet-application/carnet-application.dto.ts +++ b/src/dto/carnet-application/carnet-application.dto.ts @@ -4,7 +4,7 @@ import { APPLICATIONNAME_DTO, AUTHREP_DTO, AUTO_FLAG_DTO, COMMERCIAL_SAMPLE_FLAG_DTO, COUNTRYTABLE_DTO, CUSTCOURIERNO_DTO, DELIVERYMETHOD_DTO, DELIVERYTYPE_DTO, EXIBITIONS_FAIR_FLAG_DTO, FORMOFSECURITY_DTO, GLTABLE_DTO, HEADERID_DTO, - HORSE_FLAG_DTO, INSPROTECTION_DTO, LDIPROTECTION_DTO, PAYMENTMETHOD_DTO, + HORSE_FLAG_DTO, INSPROTECTION_DTO, LDIPROTECTION_DTO, ORDERTYPE_DTO, PAYMENTMETHOD_DTO, PROF_EQUIPMENT_FLAG_DTO, REFNO_DTO, SHIPADDRID_DTO, SHIPTOTYPE_DTO, USSETS_DTO } from "./carnet-application-property.dto"; @@ -53,3 +53,32 @@ export class TransmitApplicationtoProcessDTO extends IntersectionType( export class CarnetProcessingCenterDTO extends (IntersectionType(USERID_DTO, HEADERID_DTO)) { } +export class CreateApplicationDTO extends IntersectionType( + SPID_DTO, CLIENTID_DTO, LOCATIONID_DTO, USERID_DTO, APPLICATIONNAME_DTO, + ORDERTYPE_DTO +) { } + +export class CA_UpdateHolderDTO extends IntersectionType( + HEADERID_DTO, HOLDERID_DTO +) { } + +export class UpdateExpGoodsAuthRepDTO extends IntersectionType( + HEADERID_DTO, COMMERCIAL_SAMPLE_FLAG_DTO, PROF_EQUIPMENT_FLAG_DTO, + EXIBITIONS_FAIR_FLAG_DTO, AUTO_FLAG_DTO, HORSE_FLAG_DTO, + AUTHREP_DTO +) { } + +export class AddGenerallistItemsDTO extends IntersectionType( + HEADERID_DTO, GLTABLE_DTO, USERID_DTO +) { } + +export class AddCountriesDTO extends IntersectionType( + HEADERID_DTO, USSETS_DTO, COUNTRYTABLE_DTO, USERID_DTO +) { } + +export class UpdateShippingDetailsDTO extends IntersectionType( + HEADERID_DTO, SHIPTOTYPE_DTO, SHIPADDRID_DTO, FORMOFSECURITY_DTO, + INSPROTECTION_DTO, LDIPROTECTION_DTO, DELIVERYTYPE_DTO, DELIVERYMETHOD_DTO, + PAYMENTMETHOD_DTO, CUSTCOURIERNO_DTO, REFNO_DTO, NOTES_DTO, USERID_DTO +) { } + diff --git a/src/main.ts b/src/main.ts index 90b5ef3..fc84f5d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -87,6 +87,11 @@ async function bootstrap() { const documentFactory = () => SwaggerModule.createDocument(app, config, options); SwaggerModule.setup('api', app, documentFactory); + app.use('/api-json', (req, res) => { + res.setHeader('Content-Type', 'application/json'); + res.send(document); + }); + await app.listen(process.env.PORT ?? 3000); } bootstrap(); diff --git a/src/oracle/carnet-application/carnet-application.controller.ts b/src/oracle/carnet-application/carnet-application.controller.ts index 62de76e..fe07602 100644 --- a/src/oracle/carnet-application/carnet-application.controller.ts +++ b/src/oracle/carnet-application/carnet-application.controller.ts @@ -1,10 +1,15 @@ -import { Body, Controller, Patch, Post } from '@nestjs/common'; +import { Body, Controller, Patch, Post, Put } from '@nestjs/common'; import { CarnetApplicationService } from './carnet-application.service'; import { ApiTags } from '@nestjs/swagger'; import { - CarnetProcessingCenterDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO + AddCountriesDTO, + AddGenerallistItemsDTO, + CA_UpdateHolderDTO, + CarnetProcessingCenterDTO, CreateApplicationDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO, + UpdateExpGoodsAuthRepDTO, + UpdateShippingDetailsDTO } from 'src/dto/property.dto'; @@ -14,6 +19,8 @@ export class CarnetApplicationController { constructor(private readonly carnetApplicationService: CarnetApplicationService) { } + // [ CARNETAPPLICATION_PKG ] + @Post('SaveCarnetApplication') async CreateClientData(@Body() body: SaveCarnetApplicationDTO) { return this.carnetApplicationService.SaveCarnetApplication(body); @@ -24,6 +31,38 @@ export class CarnetApplicationController { return this.carnetApplicationService.TransmitApplicationtoProcess(body); } + @Post('CreateApplication') + 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); + } + + @Post('AddCountries') + AddCountries(@Body() body: AddCountriesDTO) { + return this.carnetApplicationService.AddCountries(body); + } + + @Patch('UpdateShippingDetails') + UpdateShippingDetails(@Body() body: UpdateShippingDetailsDTO) { + return this.carnetApplicationService.UpdateShippingDetails(body); + } + + // processing [ PROCESSINGCENTER_PKG ] + @Patch('ProcessOriginalCarnet') ProcessOriginalCarnet(@Body() body: CarnetProcessingCenterDTO) { return this.carnetApplicationService.ProcessOriginalCarnet(body); diff --git a/src/oracle/carnet-application/carnet-application.service.ts b/src/oracle/carnet-application/carnet-application.service.ts index 22f3f87..0c7cb3a 100644 --- a/src/oracle/carnet-application/carnet-application.service.ts +++ b/src/oracle/carnet-application/carnet-application.service.ts @@ -6,23 +6,35 @@ import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/hel import { COUNTRYTABLE_DTO, COUNTRYTABLE_ROW_DTO, GLTABLE_DTO, GLTABLE_ROW_DTO, - CarnetProcessingCenterDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO + CarnetProcessingCenterDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO, + CreateApplicationDTO, + UpdateExpGoodsAuthRepDTO, + AddGenerallistItemsDTO, + AddCountriesDTO, + UpdateShippingDetailsDTO, + CA_UpdateHolderDTO } from 'src/dto/property.dto'; +import { OracleService } from '../oracle.service'; @Injectable() export class CarnetApplicationService { private readonly logger = new Logger(CarnetApplicationService.name); - constructor(private readonly oracleDBService: OracleDBService) { } + constructor( + private readonly oracleDBService: OracleDBService, + private readonly oracleService: OracleService + ) { } + + // [ CARNETAPPLICATION_PKG ] async SaveCarnetApplication(body: SaveCarnetApplicationDTO) { const newBody = { - p_spid: null, // + P_SPID: null, // P_CLIENTID: null, P_LOCATIONID: null, - p_userid: null, // + P_USERID: null, // P_HEADERID: null, P_APPLICATIONNAME: null, P_HOLDERID: null, @@ -72,94 +84,96 @@ export class CarnetApplicationService { // return res; - const GLTABLE = await connection.getDbObjectClass('CARNETSYS.GLTABLE'); + // const GLTABLE = await connection.getDbObjectClass('CARNETSYS.GLTABLE'); - if (typeof GLTABLE !== 'function') { - throw new InternalServerException('GLTABLE is not a constructor'); - } + // if (typeof GLTABLE !== 'function') { + // throw new InternalServerException('GLTABLE is not a constructor'); + // } - async function createGLArrayInstance( - ITEMNO, - ITEMDESCRIPTION, - ITEMVALUE, - NOOFPIECES, - ITEMWEIGHT, - ITEMWEIGHTUOM, - GOODSORIGINCOUNTRY, - ) { - const result = await connection.execute( - `SELECT CARNETSYS.GLARRAY(:ITEMNO, :ITEMDESCRIPTION, :ITEMVALUE, :NOOFPIECES, :ITEMWEIGHT, :ITEMWEIGHTUOM, :GOODSORIGINCOUNTRY) FROM dual`, - { - ITEMNO, - ITEMDESCRIPTION, - ITEMVALUE, - NOOFPIECES, - ITEMWEIGHT, - ITEMWEIGHTUOM, - GOODSORIGINCOUNTRY, - }, - ); - console.log(result.rows); + // async function createGLArrayInstance( + // ITEMNO, + // ITEMDESCRIPTION, + // ITEMVALUE, + // NOOFPIECES, + // ITEMWEIGHT, + // ITEMWEIGHTUOM, + // GOODSORIGINCOUNTRY, + // ) { + // const result = await connection.execute( + // `SELECT CARNETSYS.GLARRAY(:ITEMNO, :ITEMDESCRIPTION, :ITEMVALUE, :NOOFPIECES, :ITEMWEIGHT, :ITEMWEIGHTUOM, :GOODSORIGINCOUNTRY) FROM dual`, + // { + // ITEMNO, + // ITEMDESCRIPTION, + // ITEMVALUE, + // NOOFPIECES, + // ITEMWEIGHT, + // ITEMWEIGHTUOM, + // GOODSORIGINCOUNTRY, + // }, + // ); + // console.log(result.rows); - return result.rows[0][0]; - } + // return result.rows[0][0]; + // } - const GLTABLE_ARRAY: GLTABLE_DTO = { - P_GLTABLE: await Promise.all( - (finalBody.P_GLTABLE ?? []).map(async (x: GLTABLE_ROW_DTO) => { - return await createGLArrayInstance( - x.ITEMNO, - x.ITEMDESCRIPTION, - x.ITEMVALUE, - x.NOOFPIECES, - x.ITEMWEIGHT, - x.ITEMWEIGHTUOM, - x.GOODSORIGINCOUNTRY, - ); - }) - ) - }; + // const GLTABLE_ARRAY: GLTABLE_DTO = { + // P_GLTABLE: await Promise.all( + // (finalBody.P_GLTABLE ?? []).map(async (x: GLTABLE_ROW_DTO) => { + // return await createGLArrayInstance( + // x.ITEMNO, + // x.ITEMDESCRIPTION, + // x.ITEMVALUE, + // x.NOOFPIECES, + // x.ITEMWEIGHT, + // x.ITEMWEIGHTUOM, + // x.GOODSORIGINCOUNTRY, + // ); + // }) + // ) + // }; + + // const GLTABLE_INSTANCE = new GLTABLE(GLTABLE_ARRAY.P_GLTABLE ?? []); + const GLTABLE_INSTANCE = await this.oracleService.get_GL_TABLE_INSTANCE(finalBody); + + // const COUNTRYTABLE = await connection.getDbObjectClass('CARNETSYS.CARNETCOUNTRYTABLE'); + + // if (typeof COUNTRYTABLE !== 'function') { + // throw new Error('COUNTRYTABLE is not a constructor'); + // } + + // async function createCarnetCountryArrayInstance( + // P_VISISTTRANSITIND, + // COUNTRYCODE, + // NOOFTIMESENTLEAVE, + // ) { + // const result = await connection.execute( + // `SELECT CARNETSYS.CARNETCOUNTRYARRAY(:P_VISISTTRANSITIND, :COUNTRYCODE, :NOOFTIMESENTLEAVE) FROM dual`, + // { + // P_VISISTTRANSITIND, + // COUNTRYCODE, + // NOOFTIMESENTLEAVE, + // }, + // ); + // console.log(result.rows); + // return result.rows[0][0]; + // } + + // const COUNTRYTABLE_ARRAY: COUNTRYTABLE_DTO = { + // P_COUNTRYTABLE: await Promise.all( + // (finalBody.P_COUNTRYTABLE ?? []).map(async (x: COUNTRYTABLE_ROW_DTO) => { + // return await createCarnetCountryArrayInstance( + // x.P_VISISTTRANSITIND, + // x.COUNTRYCODE, + // x.NOOFTIMESENTLEAVE, + // ); + // }) + // ) + // }; - const GLTABLE_INSTANCE = new GLTABLE(GLTABLE_ARRAY.P_GLTABLE ?? []); + // const COUNTRYTABLE_INSTANCE = new COUNTRYTABLE(COUNTRYTABLE_ARRAY.P_COUNTRYTABLE ?? []); - const COUNTRYTABLE = await connection.getDbObjectClass('CARNETSYS.CARNETCOUNTRYTABLE'); - - if (typeof COUNTRYTABLE !== 'function') { - throw new Error('COUNTRYTABLE is not a constructor'); - } - - async function createCarnetCountryArrayInstance( - P_VISISTTRANSITIND, - COUNTRYCODE, - NOOFTIMESENTLEAVE, - ) { - const result = await connection.execute( - `SELECT CARNETSYS.CARNETCOUNTRYARRAY(:P_VISISTTRANSITIND, :COUNTRYCODE, :NOOFTIMESENTLEAVE) FROM dual`, - { - P_VISISTTRANSITIND, - COUNTRYCODE, - NOOFTIMESENTLEAVE, - }, - ); - console.log(result.rows); - return result.rows[0][0]; - } - - const COUNTRYTABLE_ARRAY: COUNTRYTABLE_DTO = { - P_COUNTRYTABLE: await Promise.all( - (finalBody.P_COUNTRYTABLE ?? []).map(async (x: COUNTRYTABLE_ROW_DTO) => { - return await createCarnetCountryArrayInstance( - x.P_VISISTTRANSITIND, - x.COUNTRYCODE, - x.NOOFTIMESENTLEAVE, - ); - }) - ) - }; - - - const COUNTRYTABLE_INSTANCE = new COUNTRYTABLE(COUNTRYTABLE_ARRAY.P_COUNTRYTABLE ?? []); + const COUNTRYTABLE_INSTANCE = await this.oracleService.get_COUNTRY_TABLE_INSTANCE(finalBody); // return { aa:GLTABLE_ARRAY, ab:COUNTRYTABLE_ARRAY, a: GLTABLE_INSTANCE, b: COUNTRYTABLE_INSTANCE } @@ -259,6 +273,257 @@ export class CarnetApplicationService { } } + async CreateApplication(body: CreateApplicationDTO) { + let connection; + try { + connection = await this.oracleDBService.getConnection(); + + const result = await connection.execute( + `BEGIN + CARNETAPPLICATION_PKG.CreateApplication( + :P_SPID, :P_CLIENTID, :P_LOCATIONID, :P_USERID, + :P_APPLICATIONNAME, :P_ORDERTYPE, :P_ERRORMESG + ); + END;`, + { + P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, + P_CLIENTID: { val: body.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER }, + P_LOCATIONID: { val: body.P_LOCATIONID, type: oracledb.DB_TYPE_NUMBER }, + P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, + P_APPLICATIONNAME: { val: body.P_APPLICATIONNAME, type: oracledb.DB_TYPE_NVARCHAR }, + P_ORDERTYPE: { val: body.P_ORDERTYPE, type: oracledb.DB_TYPE_NVARCHAR }, + P_ERRORMESG: { 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_ERRORMESG) { + 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_ERRORMESG, CarnetApplicationService.name); + } catch (error) { + handleError(error, CarnetApplicationService.name) + } finally { + await closeOracleDbConnection(connection, CarnetApplicationService.name) + } + } + + async UpdateHolder(body: CA_UpdateHolderDTO) { + let connection; + try { + connection = await this.oracleDBService.getConnection(); + + const result = await connection.execute( + `BEGIN + CARNETAPPLICATION_PKG.UpdateHolder( + :P_HEADERID, :P_HOLDERID, :P_ERRORMESG + ); + END;`, + { + P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER }, + P_HOLDERID: { val: body.P_HOLDERID, type: oracledb.DB_TYPE_NUMBER }, + P_ERRORMESG: { 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_ERRORMESG) { + 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_ERRORMESG, CarnetApplicationService.name); + } catch (error) { + handleError(error, CarnetApplicationService.name) + } finally { + await closeOracleDbConnection(connection, CarnetApplicationService.name) + } + } + + async UpdateExpGoodsAuthRep(body: UpdateExpGoodsAuthRepDTO) { + let connection; + try { + connection = await this.oracleDBService.getConnection(); + + const result = await connection.execute( + `BEGIN + CARNETAPPLICATION_PKG.UpdateExpGoodsAuthRep( + :P_HEADERID, :P_COMMERCIALSAMPLEFLAG, :P_PROFEQUIPMENTFLAG, + :P_EXHIBITIONSFAIRFLAG, :P_AUTOFLAG, :P_HORSEFLAG, :P_AUTHREP, + :P_ERRORMESG + ); + END;`, + { + P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER }, + P_COMMERCIALSAMPLEFLAG: { val: body.P_COMMERCIALSAMPLEFLAG, type: oracledb.DB_TYPE_NVARCHAR }, + P_PROFEQUIPMENTFLAG: { val: body.P_PROFEQUIPMENTFLAG, type: oracledb.DB_TYPE_NVARCHAR }, + P_EXHIBITIONSFAIRFLAG: { val: body.P_EXHIBITIONSFAIRFLAG, type: oracledb.DB_TYPE_NVARCHAR }, + P_AUTOFLAG: { val: body.P_AUTOFLAG, type: oracledb.DB_TYPE_NVARCHAR }, + P_HORSEFLAG: { val: body.P_HORSEFLAG, type: oracledb.DB_TYPE_NVARCHAR }, + P_AUTHREP: { val: body.P_AUTHREP, type: oracledb.DB_TYPE_NVARCHAR }, + P_ERRORMESG: { 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_ERRORMESG) { + 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_ERRORMESG, CarnetApplicationService.name); + } catch (error) { + handleError(error, CarnetApplicationService.name) + } finally { + await closeOracleDbConnection(connection, CarnetApplicationService.name) + } + } + + async AddGenerallistItems(body: AddGenerallistItemsDTO) { + let connection; + try { + connection = await this.oracleDBService.getConnection(); + + const GLTABLE_INSTANCE = await this.oracleService.get_GL_TABLE_INSTANCE(body); + + const result = await connection.execute( + `BEGIN + CARNETAPPLICATION_PKG.AddGenerallistItems( + :P_HEADERID, :P_GLTABLE, :P_USERID, :P_ERRORMESG + ); + END;`, + { + P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER }, + P_GLTABLE: { val: GLTABLE_INSTANCE, type: 'CARNETSYS.GLTABLE' }, + // P_GLTABLE: { val: GLTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT }, + P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, + P_ERRORMESG: { 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_ERRORMESG) { + 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_ERRORMESG, CarnetApplicationService.name); + } catch (error) { + handleError(error, CarnetApplicationService.name) + } finally { + await closeOracleDbConnection(connection, CarnetApplicationService.name) + } + } + + async AddCountries(body: AddCountriesDTO) { + let connection; + try { + connection = await this.oracleDBService.getConnection(); + + const COUNTRYTABLE_INSTANCE = await this.oracleService.get_COUNTRY_TABLE_INSTANCE(body); + + const result = await connection.execute( + `BEGIN + CARNETAPPLICATION_PKG.AddCountries( + :P_HEADERID, :P_USSETS, :P_COUNTRYTABLE, :P_USERID, :P_ERRORMESG + ); + END;`, + { + P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER }, + P_USSETS: { val: body.P_USSETS, type: oracledb.DB_TYPE_NUMBER }, + P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT, typeName: 'CARNETCOUNTRYTABLE' }, + // P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: 'CARNETSYS.GLTABLE' }, + // P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT }, + P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, + P_ERRORMESG: { 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_ERRORMESG) { + 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_ERRORMESG, CarnetApplicationService.name); + } catch (error) { + handleError(error, CarnetApplicationService.name) + } finally { + await closeOracleDbConnection(connection, CarnetApplicationService.name) + } + } + + async UpdateShippingDetails(body: UpdateShippingDetailsDTO) { + let connection; + try { + connection = await this.oracleDBService.getConnection(); + + const result = await connection.execute( + `BEGIN + CARNETAPPLICATION_PKG.UpdateHolder( + :P_HEADERID, :P_SHIPTOTYPE, :P_SHIPADDRID, :P_FORMOFSECURITY, :P_INSPROTECTION, + :P_LDIPROTECTION, :P_DELIVERYTYPE, :P_DELIVERYMETHOD, :P_PAYMENTMETHOD, + :P_CUSTCOURIERNO, :P_REFNO, :P_NOTES, :P_USERID, :P_ERRORMESG + ); + END;`, + { + P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER }, + P_SHIPTOTYPE: { val: body.P_SHIPTOTYPE, type: oracledb.DB_TYPE_NVARCHAR }, + P_SHIPADDRID: { val: body.P_SHIPADDRID, type: oracledb.DB_TYPE_NUMBER }, + P_FORMOFSECURITY: { val: body.P_FORMOFSECURITY, type: oracledb.DB_TYPE_NVARCHAR }, + P_INSPROTECTION: { val: body.P_INSPROTECTION, type: oracledb.DB_TYPE_NVARCHAR }, + P_LDIPROTECTION: { val: body.P_LDIPROTECTION, type: oracledb.DB_TYPE_NVARCHAR }, + P_DELIVERYTYPE: { val: body.P_DELIVERYTYPE, type: oracledb.DB_TYPE_NVARCHAR }, + P_DELIVERYMETHOD: { val: body.P_DELIVERYMETHOD, type: oracledb.DB_TYPE_NVARCHAR }, + P_PAYMENTMETHOD: { val: body.P_PAYMENTMETHOD, type: oracledb.DB_TYPE_NVARCHAR }, + P_CUSTCOURIERNO: { val: body.P_CUSTCOURIERNO, type: oracledb.DB_TYPE_NVARCHAR }, + P_REFNO: { val: body.P_REFNO, type: oracledb.DB_TYPE_NVARCHAR }, + P_NOTES: { val: body.P_NOTES, type: oracledb.DB_TYPE_NVARCHAR }, + P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, + P_ERRORMESG: { 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_ERRORMESG) { + 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_ERRORMESG, CarnetApplicationService.name); + } catch (error) { + handleError(error, CarnetApplicationService.name) + } finally { + await closeOracleDbConnection(connection, CarnetApplicationService.name) + } + } + // processing [ PROCESSINGCENTER_PKG ] async ProcessOriginalCarnet(body: CarnetProcessingCenterDTO) { diff --git a/src/oracle/home-page/home-page.controller.ts b/src/oracle/home-page/home-page.controller.ts index 9c9e3b2..413a6fa 100644 --- a/src/oracle/home-page/home-page.controller.ts +++ b/src/oracle/home-page/home-page.controller.ts @@ -10,7 +10,8 @@ import { ApiTags } from '@nestjs/swagger'; import { EMAIL_DTO, GetCarnetDetailsbyCarnetStatusDTO, - SPID_DTO + SPID_DTO, + USERID_DTO } from 'src/dto/property.dto'; @ApiTags('HomePage - Oracle') @@ -24,8 +25,8 @@ export class HomePageController { return this.homePageService.GetHomePageData(params); } - @Get('GetCarnetSummaryData/:P_EMAILADDR') - GetCarnetSummaryData(@Param() params: EMAIL_DTO) { + @Get('GetCarnetSummaryData/:P_USERID') + GetCarnetSummaryData(@Param() params: USERID_DTO) { return this.homePageService.GetCarnetSummaryData(params); } diff --git a/src/oracle/home-page/home-page.service.ts b/src/oracle/home-page/home-page.service.ts index 0077a71..f19f785 100644 --- a/src/oracle/home-page/home-page.service.ts +++ b/src/oracle/home-page/home-page.service.ts @@ -6,7 +6,8 @@ import * as oracledb from 'oracledb'; import { EMAIL_DTO, GetCarnetDetailsbyCarnetStatusDTO, - SPID_DTO + SPID_DTO, + USERID_DTO } from 'src/dto/property.dto'; @Injectable() @@ -293,7 +294,7 @@ export class HomePageService { } } - async GetCarnetSummaryData(body: EMAIL_DTO) { + async GetCarnetSummaryData(body: USERID_DTO) { let connection; let rows: any = []; try { @@ -304,11 +305,11 @@ export class HomePageService { const result = await connection.execute( `BEGIN - USERLOGIN_PKG.GetCarnetSummaryData(:P_EMAILADDR,:P_CURSOR); + USERLOGIN_PKG.GetCarnetSummaryData(:P_USERID,:P_CURSOR); END;`, { - P_EMAILADDR: { - val: body.P_EMAILADDR, + P_USERID: { + val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR, }, P_CURSOR: { diff --git a/src/oracle/manage-holders/manage-holders.service.ts b/src/oracle/manage-holders/manage-holders.service.ts index f22b059..cf5372a 100644 --- a/src/oracle/manage-holders/manage-holders.service.ts +++ b/src/oracle/manage-holders/manage-holders.service.ts @@ -330,7 +330,7 @@ export class ManageHoldersService { const finalBody: CreateHoldersDTO = { ...newBody, ...reqBody }; - let connection: Connection | undefined = undefined; + let connection; try { diff --git a/src/oracle/oracle.module.ts b/src/oracle/oracle.module.ts index fedf6a9..ae2f3cc 100644 --- a/src/oracle/oracle.module.ts +++ b/src/oracle/oracle.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Global, Module } from '@nestjs/common'; import { DbModule } from 'src/db/db.module'; import { ManageHoldersModule } from './manage-holders/manage-holders.module'; import { HomePageModule } from './home-page/home-page.module'; @@ -8,7 +8,9 @@ import { ManageFeeModule } from './manage-fee/manage-fee.module'; import { ManageClientsModule } from './manage-clients/manage-clients.module'; import { UserMaintenanceModule } from './user-maintenance/user-maintenance.module'; import { CarnetApplicationModule } from './carnet-application/carnet-application.module'; +import { OracleService } from './oracle.service'; +@Global() @Module({ imports: [ DbModule, @@ -21,8 +23,8 @@ import { CarnetApplicationModule } from './carnet-application/carnet-application ManageHoldersModule, ManageClientsModule, ], - providers: [], + providers: [OracleService], controllers: [], - exports: [], + exports: [OracleService], }) export class OracleModule {} diff --git a/src/oracle/oracle.service.ts b/src/oracle/oracle.service.ts new file mode 100644 index 0000000..3876f52 --- /dev/null +++ b/src/oracle/oracle.service.ts @@ -0,0 +1,121 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { OracleDBService } from "src/db/db.service"; +import { COUNTRYTABLE_DTO, COUNTRYTABLE_ROW_DTO, GLTABLE_DTO, GLTABLE_ROW_DTO } from "src/dto/property.dto"; +import { InternalServerException } from "src/exceptions/internalServerError.exception"; +import { closeOracleDbConnection, handleError } from "src/utils/helper"; + +@Injectable() +export class OracleService { + private readonly logger = new Logger(OracleService.name); + + constructor(private readonly oracleDBService: OracleDBService) { } + + async get_GL_TABLE_INSTANCE(finalBody: any) { + + // P_GLTABLE: { val: GLTABLE_INSTANCE, type: 'CARNETSYS.GLTABLE' } + // P_GLTABLE: { val: GLTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT } + + let connection; + + try { + connection = await this.oracleDBService.getConnection(); + + const GLTABLE = await connection.getDbObjectClass('CARNETSYS.GLTABLE'); + + if (typeof GLTABLE !== 'function') { + throw new InternalServerException('GLTABLE is not a constructor'); + } + + async function createGLArrayInstance( + ITEMNO, ITEMDESCRIPTION, ITEMVALUE, NOOFPIECES, + ITEMWEIGHT, ITEMWEIGHTUOM, GOODSORIGINCOUNTRY, + ) { + const result = await connection.execute( + `SELECT CARNETSYS.GLARRAY( + :ITEMNO, :ITEMDESCRIPTION, :ITEMVALUE, :NOOFPIECES, + :ITEMWEIGHT, :ITEMWEIGHTUOM, :GOODSORIGINCOUNTRY + ) FROM dual`, + { + ITEMNO, ITEMDESCRIPTION, ITEMVALUE, NOOFPIECES, + ITEMWEIGHT, ITEMWEIGHTUOM, GOODSORIGINCOUNTRY, + } + ); + console.log(result.rows); + + return result.rows[0][0]; + } + + const GLTABLE_ARRAY: GLTABLE_DTO = { + P_GLTABLE: await Promise.all( + (finalBody.P_GLTABLE ?? []).map(async (x: GLTABLE_ROW_DTO) => { + return await createGLArrayInstance( + x.ITEMNO, x.ITEMDESCRIPTION, x.ITEMVALUE, x.NOOFPIECES, + x.ITEMWEIGHT, x.ITEMWEIGHTUOM, x.GOODSORIGINCOUNTRY, + ); + }) + ) + }; + + const GLTABLE_INSTANCE = new GLTABLE(GLTABLE_ARRAY.P_GLTABLE ?? []); + + return GLTABLE_INSTANCE; + + } catch (error) { + throw new Error("Error occured completing this process") + } finally { + await closeOracleDbConnection(connection, OracleService.name) + } + } + + async get_COUNTRY_TABLE_INSTANCE(finalBody: any) { + + // P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: 'CARNETSYS.CARNETCOUNTRYTABLE' } + // P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT } + + let connection; + + try { + connection = await this.oracleDBService.getConnection(); + + const COUNTRYTABLE = await connection.getDbObjectClass('CARNETSYS.CARNETCOUNTRYTABLE'); + + if (typeof COUNTRYTABLE !== 'function') { + throw new Error('COUNTRYTABLE is not a constructor'); + } + + async function createCarnetCountryArrayInstance( + P_VISISTTRANSITIND, COUNTRYCODE, NOOFTIMESENTLEAVE, + ) { + const result = await connection.execute( + `SELECT CARNETSYS.CARNETCOUNTRYARRAY( + :P_VISISTTRANSITIND, :COUNTRYCODE, :NOOFTIMESENTLEAVE + ) FROM dual`, + { + P_VISISTTRANSITIND, COUNTRYCODE, NOOFTIMESENTLEAVE, + }, + ); + console.log(result.rows); + return result.rows[0][0]; + } + + const COUNTRYTABLE_ARRAY: COUNTRYTABLE_DTO = { + P_COUNTRYTABLE: await Promise.all( + (finalBody.P_COUNTRYTABLE ?? []).map(async (x: COUNTRYTABLE_ROW_DTO) => { + return await createCarnetCountryArrayInstance( + x.P_VISISTTRANSITIND, x.COUNTRYCODE, x.NOOFTIMESENTLEAVE, + ); + }) + ) + }; + + const COUNTRYTABLE_INSTANCE = new COUNTRYTABLE(COUNTRYTABLE_ARRAY.P_COUNTRYTABLE ?? []); + + return COUNTRYTABLE_INSTANCE; + + } catch (error) { + throw new Error("Error occured completing this process") + } finally { + await closeOracleDbConnection(connection, OracleService.name) + } + } +} \ No newline at end of file