From feda138732d39734df0ad9939cf9803ae28c3a20 Mon Sep 17 00:00:00 2001 From: ilham Date: Mon, 16 May 2022 14:12:08 +0700 Subject: [PATCH 1/5] fixing: ppob --- src/transaction/dto/order-transaction.dto.ts | 3 + .../entities/check-bill-history.entity.ts | 42 +++++++ src/transaction/ppob_callback.controller.ts | 4 +- src/transaction/transaction.module.ts | 8 +- src/transaction/transaction.service.ts | 107 +++++++++++++++--- src/users/entities/partner.entity.ts | 5 + src/users/users.service.ts | 25 ++++ 7 files changed, 178 insertions(+), 16 deletions(-) create mode 100644 src/transaction/entities/check-bill-history.entity.ts diff --git a/src/transaction/dto/order-transaction.dto.ts b/src/transaction/dto/order-transaction.dto.ts index ff3d293..8dc3d30 100644 --- a/src/transaction/dto/order-transaction.dto.ts +++ b/src/transaction/dto/order-transaction.dto.ts @@ -9,4 +9,7 @@ export class OrderTransactionDto { @IsOptional() trx_id: string; + + @IsOptional() + bill_trx_id: string; } diff --git a/src/transaction/entities/check-bill-history.entity.ts b/src/transaction/entities/check-bill-history.entity.ts new file mode 100644 index 0000000..bb9799a --- /dev/null +++ b/src/transaction/entities/check-bill-history.entity.ts @@ -0,0 +1,42 @@ +import { Column, Entity, ManyToOne, OneToMany } from 'typeorm'; +import { BaseModel } from '../../config/basemodel.entity'; +import { statusTransaction, typeTransaction } from '../../helper/enum-list'; +import { ProductHistoryPrice } from '../../product/entities/product-history-price.entity'; +import { UserDetail } from '../../users/entities/user_detail.entity'; +import { TransactionJournal } from './transaction-journal.entity'; + +@Entity() +export class CheckBillHistory extends BaseModel { + @Column() + trx_id: string; + + @Column() + partner_trx_id: string; + + @Column() + amount: number; + + @Column({ + type: 'uuid', + nullable: true, + }) + user: string; + + @Column({ + nullable: true, + }) + destination: string; + + @Column({ + nullable: true, + }) + request_json: string; + + @Column({ + nullable: true, + }) + callback_json: string; + + @Column() + product_code: string; +} diff --git a/src/transaction/ppob_callback.controller.ts b/src/transaction/ppob_callback.controller.ts index fb36659..d43199d 100644 --- a/src/transaction/ppob_callback.controller.ts +++ b/src/transaction/ppob_callback.controller.ts @@ -51,9 +51,9 @@ export class PpobCallbackController { async getMetro(@Req() request: FastifyRequest) { const response = request.query; - console.log(response, "INI DIA") + console.log(typeof response['message'], "INI DIA") - if (response['message'].include('CEK TAGIHAN')) { + if (response['message'].includes('CEK TAGIHAN')) { console.log("messagenya tuh",response['message']) } else { if (response['status'] != 20) { diff --git a/src/transaction/transaction.module.ts b/src/transaction/transaction.module.ts index 13bae9e..a384646 100644 --- a/src/transaction/transaction.module.ts +++ b/src/transaction/transaction.module.ts @@ -10,10 +10,16 @@ import { CoaService } from './coa.service'; import { ProductModule } from '../product/product.module'; import { UsersModule } from 'src/users/users.module'; import { ConfigurableModule } from '../configurable/configurable.module'; +import { CheckBillHistory } from './entities/check-bill-history.entity'; @Module({ imports: [ - TypeOrmModule.forFeature([COA, TransactionJournal, Transactions]), + TypeOrmModule.forFeature([ + COA, + TransactionJournal, + Transactions, + CheckBillHistory, + ]), ProductModule, ConfigurableModule, forwardRef(() => UsersModule), diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 5bd7db9..0fb35cf 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -27,6 +27,8 @@ import { DepositReturnDto } from './dto/deposit_return.dto'; import { UserDetail } from '../users/entities/user_detail.entity'; import { doTransaction } from '../helper/irs-api'; import { ProductHistoryPrice } from '../product/entities/product-history-price.entity'; +import axios from 'axios'; +import { CheckBillHistory } from './entities/check-bill-history.entity'; @Injectable() export class TransactionService { @@ -39,6 +41,8 @@ export class TransactionService { private transactionJournalRepository: Repository, @InjectRepository(COA) private coaRepository: Repository, + @InjectRepository(CheckBillHistory) + private checkBillHistoryRepository: Repository, private coaService: CoaService, private productService: ProductService, private productHistoryPriceService: ProductHistoryPriceService, @@ -477,6 +481,8 @@ export class TransactionService { `${coaType[coaType.SALES]}-SYSTEM`, ); + + if (coaAccount.amount < product_price.mark_up_price + product_price.price) { throw new HttpException( { @@ -814,21 +820,52 @@ export class TransactionService { }) .join(''); - let hitSupplier = await doTransaction( - 'CEK' + orderTransactionDto.productCode.slice(3), - orderTransactionDto.destination, - trxId, - supplier, - ); + let status; - // let hitSupplier = await doTransaction( - // 'CEKXL1', - // orderTransactionDto.destination, - // trxId, - // supplier, - // ); + try { + let hitSupplier = await doTransaction( + 'CEK' + orderTransactionDto.productCode.slice(3), + orderTransactionDto.destination, + trxId, + supplier, + ); + const parsingResponse = hitSupplier.split(' '); + hitSupplier = { + success: hitSupplier.include('diproses'), + msg: hitSupplier, + }; - return hitSupplier; + if (!hitSupplier.success) { + status = statusTransaction[statusTransaction.FAILED]; + throw new HttpException( + { + statusCode: HttpStatus.INTERNAL_SERVER_ERROR, + error: hitSupplier.msg, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } else { + status = statusTransaction[statusTransaction.SUCCESS]; + + await this.checkBillHistoryRepository.insert({ + trx_id: trxId, + user: userData.id, + callback_json: JSON.stringify(hitSupplier), + destination: orderTransactionDto.destination, + product_code: orderTransactionDto.productCode, + partner_trx_id: orderTransactionDto.trx_id, + }); + } + } catch (e) { + throw e; + } + + return { + trx_id: trxId, + client_trx_id: orderTransactionDto.trx_id, + product: orderTransactionDto.productCode, + status: status, + }; } async createDepositReturn(currentUser, depositReturnDto: DepositReturnDto) { @@ -1060,6 +1097,20 @@ export class TransactionService { } catch (e) { throw e; } + + if (userData.partner) { + const message = `Transaksi ${product.code} dengan tujuan ${dataTransaction.destination} telah gagal.`; + this.callbackToPartner( + userData.id, + message, + dataTransaction.partner_trx_id, + dataTransaction.amount, + product.code, + dataTransaction.destination, + '-', + 'gagal', + ); + } } async callbackOrderSuccess(supplier_trx_id: string, callback: any) { @@ -1131,6 +1182,36 @@ export class TransactionService { } catch (e) { throw e; } + + if (userData.partner) { + const message = `Transaksi ${product.code} dengan tujuan ${dataTransaction.destination} telah berhasil.`; + this.callbackToPartner( + userData.id, + message, + dataTransaction.partner_trx_id, + dataTransaction.amount, + product.code, + dataTransaction.destination, + dataTransaction.seri_number, + 'berhasil', + ); + } + } + + async callbackToPartner( + partnerId: string, + message: string, + trxId: string, + harga: number, + productCode: string, + destination: string, + seriNumber: string, + status: string, + ) { + const partnerData = await this.userService.findPartner(partnerId); + const res = await axios.get( + `${partnerData.callback_url}?status=${status}&memberID=${partnerData.code}&trxid=${trxId}&harga=${harga}&product=${productCode}&dest=${destination}&seriNumber=${seriNumber}&message=${message}`, + ); } async withdrawBenefit(user) { diff --git a/src/users/entities/partner.entity.ts b/src/users/entities/partner.entity.ts index 6d53f95..57098af 100644 --- a/src/users/entities/partner.entity.ts +++ b/src/users/entities/partner.entity.ts @@ -27,4 +27,9 @@ export class Partner extends BaseModel { @Column({ default: true }) status: boolean; + + @Column({ + default: '', + }) + callback_url: string; } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index cc89d11..b1f8d81 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -20,12 +20,15 @@ import * as uuid from 'uuid'; import { UserDetail } from './entities/user_detail.entity'; import { COA } from '../transaction/entities/coa.entity'; import { mapSeries } from 'bluebird'; +import { Partner } from './entities/partner.entity'; @Injectable() export class UsersService { constructor( @InjectRepository(User) private usersRepository: Repository, + @InjectRepository(Partner) + private partnerRepository: Repository, @InjectRepository(UserDetail) private userDetailRepository: Repository, @Inject( @@ -676,4 +679,26 @@ export class UsersService { } } } + + async findPartner(partnerId: string) { + try { + return this.partnerRepository.findOneOrFail({ + where: { + id: partnerId, + }, + }); + } catch (e) { + if (e instanceof EntityNotFoundError) { + throw new HttpException( + { + statusCode: HttpStatus.NOT_FOUND, + error: 'Partner not found', + }, + HttpStatus.NOT_FOUND, + ); + } else { + throw e; + } + } + } } From 6bc9c72df8514e71a313b02b37c43f2925fe0af2 Mon Sep 17 00:00:00 2001 From: rahman Date: Mon, 16 May 2022 15:05:03 +0700 Subject: [PATCH 2/5] feat: add column check bill --- .../entities/transactions.entity.ts | 5 ++++ src/transaction/transaction.service.ts | 25 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/transaction/entities/transactions.entity.ts b/src/transaction/entities/transactions.entity.ts index 4c146b7..fb1aed7 100644 --- a/src/transaction/entities/transactions.entity.ts +++ b/src/transaction/entities/transactions.entity.ts @@ -16,6 +16,11 @@ export class Transactions extends BaseModel { @Column() type: typeTransaction; + @Column({ + nullable: true, + }) + check_bill: string; + @Column({ type: 'uuid', nullable: true, diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 0fb35cf..63b34fd 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -50,7 +50,7 @@ export class TransactionService { private commissionService: CommissionService, private supplierService: SupplierService, private connection: Connection, - ) {} + ) { } async addSupplierSaldo(addSaldoSupplier: AddSaldoSupplier, currentUser: any) { const supplier = await this.supplierService.findByCode( @@ -481,7 +481,29 @@ export class TransactionService { `${coaType[coaType.SALES]}-SYSTEM`, ); + if (orderTransactionDto.bill_trx_id !== null) { + try { + const billId = await this.checkBillHistoryRepository.findOneOrFail({ + where: { + id: orderTransactionDto.bill_trx_id + }, + }); + product_price.price = billId.amount + } catch (e) { + if (e instanceof EntityNotFoundError) { + throw new HttpException( + { + statusCode: HttpStatus.NOT_FOUND, + error: 'Build not found', + }, + HttpStatus.NOT_FOUND, + ); + } else { + throw e; + } + } + } if (coaAccount.amount < product_price.mark_up_price + product_price.price) { throw new HttpException( @@ -570,6 +592,7 @@ export class TransactionService { transactionData.destination = orderTransactionDto.destination; transactionData.partner_trx_id = orderTransactionDto.trx_id; transactionData.supplier_trx_id = trxId; + transactionData.check_bill = orderTransactionDto.bill_trx_id; if (!hitSupplier.success) { transactionData.status = statusTransaction.FAILED; From 0f0d80f11852e1b8be9bf89afb0632f64a9f9367 Mon Sep 17 00:00:00 2001 From: rahman Date: Mon, 16 May 2022 15:06:23 +0700 Subject: [PATCH 3/5] feat: add column check bill --- src/transaction/transaction.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 63b34fd..8d0b789 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -494,7 +494,7 @@ export class TransactionService { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, - error: 'Build not found', + error: 'Bill not found', }, HttpStatus.NOT_FOUND, ); From 9ee5b65dfc776051495d8de2fd79ce6b0f528df8 Mon Sep 17 00:00:00 2001 From: ilham Date: Tue, 17 May 2022 12:26:25 +0700 Subject: [PATCH 4/5] fixing: check bill --- .../entities/check-bill-history.entity.ts | 5 +++- src/transaction/ppob_callback.controller.ts | 26 ++++++++++++++++++- src/transaction/transaction.service.ts | 21 ++++++++++++--- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/transaction/entities/check-bill-history.entity.ts b/src/transaction/entities/check-bill-history.entity.ts index bb9799a..3c0f2fd 100644 --- a/src/transaction/entities/check-bill-history.entity.ts +++ b/src/transaction/entities/check-bill-history.entity.ts @@ -13,9 +13,12 @@ export class CheckBillHistory extends BaseModel { @Column() partner_trx_id: string; - @Column() + @Column({ nullable: true }) amount: number; + @Column({ nullable: true }) + admin_price: number; + @Column({ type: 'uuid', nullable: true, diff --git a/src/transaction/ppob_callback.controller.ts b/src/transaction/ppob_callback.controller.ts index d43199d..eb7f9d8 100644 --- a/src/transaction/ppob_callback.controller.ts +++ b/src/transaction/ppob_callback.controller.ts @@ -54,7 +54,31 @@ export class PpobCallbackController { console.log(typeof response['message'], "INI DIA") if (response['message'].includes('CEK TAGIHAN')) { - console.log("messagenya tuh",response['message']) + + if (response['status'] != 20) { + //TODO: UPDATE GAGAL + const updateTransaction = + await this.transactionService.callbackOrderFailed( + response['refid'], + response, + ); + + return { + updateTransaction, + statusCode: HttpStatus.BAD_REQUEST, + message: 'failed to proccess', + }; + } + + const splitMessage = response['message'].split('","'); + console.log("masuk sini") + //TODO: UPDATE BERHASIL + await this.transactionService.updateBill( + response['refid'], + splitMessage[3].replace(/^\D+/g, ''), + splitMessage[4].replace(/^\D+/g, ''), + ); + // } else { if (response['status'] != 20) { //TODO: UPDATE GAGAL diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 8d0b789..3bfbaf3 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -488,7 +488,7 @@ export class TransactionService { id: orderTransactionDto.bill_trx_id }, }); - product_price.price = billId.amount + product_price.price = billId.amount; } catch (e) { if (e instanceof EntityNotFoundError) { throw new HttpException( @@ -533,7 +533,7 @@ export class TransactionService { if (supplier.code != 'IRS') { const parsingResponse = hitSupplier.split(' '); hitSupplier = { - success: hitSupplier.include('diproses'), + success: hitSupplier.includes('diproses'), harga: parseInt( parsingResponse[parsingResponse.length - 2].replaceAll('.', ''), ), @@ -723,7 +723,7 @@ export class TransactionService { if (supplier.code != 'IRS') { const parsingResponse = hitSupplier.split(' '); hitSupplier = { - success: hitSupplier.include('diproses'), + success: hitSupplier.includes('diproses'), harga: parseInt( parsingResponse[parsingResponse.length - 2].replaceAll('.', ''), ), @@ -853,8 +853,9 @@ export class TransactionService { supplier, ); const parsingResponse = hitSupplier.split(' '); + console.log(hitSupplier,"ini dia") hitSupplier = { - success: hitSupplier.include('diproses'), + success: hitSupplier.includes('diproses'), msg: hitSupplier, }; @@ -1779,4 +1780,16 @@ export class TransactionService { return transaction; } + + async updateBill(trxId: string, amount: number, admin: number) { + await this.checkBillHistoryRepository.update( + { + trx_id: trxId, + }, + { + amount: amount, + admin_price: admin, + }, + ); + } } From f449299bbf0aee9610b51222207c86a2978f3b3f Mon Sep 17 00:00:00 2001 From: ilham Date: Tue, 17 May 2022 12:52:02 +0700 Subject: [PATCH 5/5] fixing: check bill --- src/transaction/ppob_callback.controller.ts | 23 ++++------ src/transaction/transaction.service.ts | 49 ++++++++++++++++++++- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/transaction/ppob_callback.controller.ts b/src/transaction/ppob_callback.controller.ts index eb7f9d8..0a38f3f 100644 --- a/src/transaction/ppob_callback.controller.ts +++ b/src/transaction/ppob_callback.controller.ts @@ -51,32 +51,25 @@ export class PpobCallbackController { async getMetro(@Req() request: FastifyRequest) { const response = request.query; - console.log(typeof response['message'], "INI DIA") - if (response['message'].includes('CEK TAGIHAN')) { - if (response['status'] != 20) { //TODO: UPDATE GAGAL - const updateTransaction = - await this.transactionService.callbackOrderFailed( - response['refid'], - response, - ); - - return { - updateTransaction, - statusCode: HttpStatus.BAD_REQUEST, - message: 'failed to proccess', - }; + await this.transactionService.updateBill( + response['refid'], + null, + null, + false, + ); } const splitMessage = response['message'].split('","'); - console.log("masuk sini") + //TODO: UPDATE BERHASIL await this.transactionService.updateBill( response['refid'], splitMessage[3].replace(/^\D+/g, ''), splitMessage[4].replace(/^\D+/g, ''), + true ); // } else { diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 3bfbaf3..38687de 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -1781,7 +1781,14 @@ export class TransactionService { return transaction; } - async updateBill(trxId: string, amount: number, admin: number) { + async updateBill( + trxId: string, + amount: number, + admin: number, + status: boolean, + ) { + const billData = await this.findOneBillById(trxId); + await this.checkBillHistoryRepository.update( { trx_id: trxId, @@ -1791,5 +1798,45 @@ export class TransactionService { admin_price: admin, }, ); + const userData = await this.userService.findExist(billData.user); + + if (userData.partner) { + const message = status + ? `Bill dari ${billData.destination} adalah ${amount}.` + : ''; + const statusResponse = status ? 'berhasil' : 'gagal'; + this.callbackToPartner( + userData.id, + message, + billData.partner_trx_id, + amount, + billData.product_code, + billData.destination, + '-', + statusResponse, + ); + } + } + + async findOneBillById(trxId: string) { + try { + return await this.checkBillHistoryRepository.findOneOrFail({ + where:{ + trx_id: trxId, + }, + }); + } catch (e) { + if (e instanceof EntityNotFoundError) { + throw new HttpException( + { + statusCode: HttpStatus.NOT_FOUND, + error: 'Bill not found', + }, + HttpStatus.NOT_FOUND, + ); + } else { + throw e; + } + } } }