Merge branch 'development' into 'devops-staging'
Development See merge request empatnusabangsa/ppob/ppob-backend!161
This commit is contained in:
commit
a10f471326
|
@ -9,4 +9,7 @@ export class OrderTransactionDto {
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
trx_id: string;
|
trx_id: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
bill_trx_id: string;
|
||||||
}
|
}
|
||||||
|
|
45
src/transaction/entities/check-bill-history.entity.ts
Normal file
45
src/transaction/entities/check-bill-history.entity.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
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({ nullable: true })
|
||||||
|
amount: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
admin_price: 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;
|
||||||
|
}
|
|
@ -16,6 +16,11 @@ export class Transactions extends BaseModel {
|
||||||
@Column()
|
@Column()
|
||||||
type: typeTransaction;
|
type: typeTransaction;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
check_bill: string;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
type: 'uuid',
|
type: 'uuid',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -51,10 +51,27 @@ export class PpobCallbackController {
|
||||||
async getMetro(@Req() request: FastifyRequest) {
|
async getMetro(@Req() request: FastifyRequest) {
|
||||||
const response = request.query;
|
const response = request.query;
|
||||||
|
|
||||||
console.log(response, "INI DIA")
|
if (response['message'].includes('CEK TAGIHAN')) {
|
||||||
|
if (response['status'] != 20) {
|
||||||
|
//TODO: UPDATE GAGAL
|
||||||
|
await this.transactionService.updateBill(
|
||||||
|
response['refid'],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (response['message'].include('CEK TAGIHAN')) {
|
const splitMessage = response['message'].split('","');
|
||||||
console.log("messagenya tuh",response['message'])
|
|
||||||
|
//TODO: UPDATE BERHASIL
|
||||||
|
await this.transactionService.updateBill(
|
||||||
|
response['refid'],
|
||||||
|
splitMessage[3].replace(/^\D+/g, ''),
|
||||||
|
splitMessage[4].replace(/^\D+/g, ''),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
//
|
||||||
} else {
|
} else {
|
||||||
if (response['status'] != 20) {
|
if (response['status'] != 20) {
|
||||||
//TODO: UPDATE GAGAL
|
//TODO: UPDATE GAGAL
|
||||||
|
|
|
@ -10,10 +10,16 @@ import { CoaService } from './coa.service';
|
||||||
import { ProductModule } from '../product/product.module';
|
import { ProductModule } from '../product/product.module';
|
||||||
import { UsersModule } from 'src/users/users.module';
|
import { UsersModule } from 'src/users/users.module';
|
||||||
import { ConfigurableModule } from '../configurable/configurable.module';
|
import { ConfigurableModule } from '../configurable/configurable.module';
|
||||||
|
import { CheckBillHistory } from './entities/check-bill-history.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([COA, TransactionJournal, Transactions]),
|
TypeOrmModule.forFeature([
|
||||||
|
COA,
|
||||||
|
TransactionJournal,
|
||||||
|
Transactions,
|
||||||
|
CheckBillHistory,
|
||||||
|
]),
|
||||||
ProductModule,
|
ProductModule,
|
||||||
ConfigurableModule,
|
ConfigurableModule,
|
||||||
forwardRef(() => UsersModule),
|
forwardRef(() => UsersModule),
|
||||||
|
|
|
@ -27,6 +27,8 @@ import { DepositReturnDto } from './dto/deposit_return.dto';
|
||||||
import { UserDetail } from '../users/entities/user_detail.entity';
|
import { UserDetail } from '../users/entities/user_detail.entity';
|
||||||
import { doTransaction } from '../helper/irs-api';
|
import { doTransaction } from '../helper/irs-api';
|
||||||
import { ProductHistoryPrice } from '../product/entities/product-history-price.entity';
|
import { ProductHistoryPrice } from '../product/entities/product-history-price.entity';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { CheckBillHistory } from './entities/check-bill-history.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TransactionService {
|
export class TransactionService {
|
||||||
|
@ -39,6 +41,8 @@ export class TransactionService {
|
||||||
private transactionJournalRepository: Repository<TransactionJournal>,
|
private transactionJournalRepository: Repository<TransactionJournal>,
|
||||||
@InjectRepository(COA)
|
@InjectRepository(COA)
|
||||||
private coaRepository: Repository<COA>,
|
private coaRepository: Repository<COA>,
|
||||||
|
@InjectRepository(CheckBillHistory)
|
||||||
|
private checkBillHistoryRepository: Repository<CheckBillHistory>,
|
||||||
private coaService: CoaService,
|
private coaService: CoaService,
|
||||||
private productService: ProductService,
|
private productService: ProductService,
|
||||||
private productHistoryPriceService: ProductHistoryPriceService,
|
private productHistoryPriceService: ProductHistoryPriceService,
|
||||||
|
@ -46,7 +50,7 @@ export class TransactionService {
|
||||||
private commissionService: CommissionService,
|
private commissionService: CommissionService,
|
||||||
private supplierService: SupplierService,
|
private supplierService: SupplierService,
|
||||||
private connection: Connection,
|
private connection: Connection,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async addSupplierSaldo(addSaldoSupplier: AddSaldoSupplier, currentUser: any) {
|
async addSupplierSaldo(addSaldoSupplier: AddSaldoSupplier, currentUser: any) {
|
||||||
const supplier = await this.supplierService.findByCode(
|
const supplier = await this.supplierService.findByCode(
|
||||||
|
@ -477,6 +481,30 @@ export class TransactionService {
|
||||||
`${coaType[coaType.SALES]}-SYSTEM`,
|
`${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: 'Bill not found',
|
||||||
|
},
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (coaAccount.amount < product_price.mark_up_price + product_price.price) {
|
if (coaAccount.amount < product_price.mark_up_price + product_price.price) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
{
|
{
|
||||||
|
@ -505,7 +533,7 @@ export class TransactionService {
|
||||||
if (supplier.code != 'IRS') {
|
if (supplier.code != 'IRS') {
|
||||||
const parsingResponse = hitSupplier.split(' ');
|
const parsingResponse = hitSupplier.split(' ');
|
||||||
hitSupplier = {
|
hitSupplier = {
|
||||||
success: hitSupplier.include('diproses'),
|
success: hitSupplier.includes('diproses'),
|
||||||
harga: parseInt(
|
harga: parseInt(
|
||||||
parsingResponse[parsingResponse.length - 2].replaceAll('.', ''),
|
parsingResponse[parsingResponse.length - 2].replaceAll('.', ''),
|
||||||
),
|
),
|
||||||
|
@ -564,6 +592,7 @@ export class TransactionService {
|
||||||
transactionData.destination = orderTransactionDto.destination;
|
transactionData.destination = orderTransactionDto.destination;
|
||||||
transactionData.partner_trx_id = orderTransactionDto.trx_id;
|
transactionData.partner_trx_id = orderTransactionDto.trx_id;
|
||||||
transactionData.supplier_trx_id = trxId;
|
transactionData.supplier_trx_id = trxId;
|
||||||
|
transactionData.check_bill = orderTransactionDto.bill_trx_id;
|
||||||
|
|
||||||
if (!hitSupplier.success) {
|
if (!hitSupplier.success) {
|
||||||
transactionData.status = statusTransaction.FAILED;
|
transactionData.status = statusTransaction.FAILED;
|
||||||
|
@ -694,7 +723,7 @@ export class TransactionService {
|
||||||
if (supplier.code != 'IRS') {
|
if (supplier.code != 'IRS') {
|
||||||
const parsingResponse = hitSupplier.split(' ');
|
const parsingResponse = hitSupplier.split(' ');
|
||||||
hitSupplier = {
|
hitSupplier = {
|
||||||
success: hitSupplier.include('diproses'),
|
success: hitSupplier.includes('diproses'),
|
||||||
harga: parseInt(
|
harga: parseInt(
|
||||||
parsingResponse[parsingResponse.length - 2].replaceAll('.', ''),
|
parsingResponse[parsingResponse.length - 2].replaceAll('.', ''),
|
||||||
),
|
),
|
||||||
|
@ -814,21 +843,53 @@ export class TransactionService {
|
||||||
})
|
})
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
|
let status;
|
||||||
|
|
||||||
|
try {
|
||||||
let hitSupplier = await doTransaction(
|
let hitSupplier = await doTransaction(
|
||||||
'CEK' + orderTransactionDto.productCode.slice(3),
|
'CEK' + orderTransactionDto.productCode.slice(3),
|
||||||
orderTransactionDto.destination,
|
orderTransactionDto.destination,
|
||||||
trxId,
|
trxId,
|
||||||
supplier,
|
supplier,
|
||||||
);
|
);
|
||||||
|
const parsingResponse = hitSupplier.split(' ');
|
||||||
|
console.log(hitSupplier,"ini dia")
|
||||||
|
hitSupplier = {
|
||||||
|
success: hitSupplier.includes('diproses'),
|
||||||
|
msg: hitSupplier,
|
||||||
|
};
|
||||||
|
|
||||||
// let hitSupplier = await doTransaction(
|
if (!hitSupplier.success) {
|
||||||
// 'CEKXL1',
|
status = statusTransaction[statusTransaction.FAILED];
|
||||||
// orderTransactionDto.destination,
|
throw new HttpException(
|
||||||
// trxId,
|
{
|
||||||
// supplier,
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
// );
|
error: hitSupplier.msg,
|
||||||
|
},
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
status = statusTransaction[statusTransaction.SUCCESS];
|
||||||
|
|
||||||
return hitSupplier;
|
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) {
|
async createDepositReturn(currentUser, depositReturnDto: DepositReturnDto) {
|
||||||
|
@ -1060,6 +1121,20 @@ export class TransactionService {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw 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) {
|
async callbackOrderSuccess(supplier_trx_id: string, callback: any) {
|
||||||
|
@ -1131,6 +1206,36 @@ export class TransactionService {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw 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) {
|
async withdrawBenefit(user) {
|
||||||
|
@ -1675,4 +1780,63 @@ export class TransactionService {
|
||||||
|
|
||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateBill(
|
||||||
|
trxId: string,
|
||||||
|
amount: number,
|
||||||
|
admin: number,
|
||||||
|
status: boolean,
|
||||||
|
) {
|
||||||
|
const billData = await this.findOneBillById(trxId);
|
||||||
|
|
||||||
|
await this.checkBillHistoryRepository.update(
|
||||||
|
{
|
||||||
|
trx_id: trxId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: amount,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,4 +27,9 @@ export class Partner extends BaseModel {
|
||||||
|
|
||||||
@Column({ default: true })
|
@Column({ default: true })
|
||||||
status: boolean;
|
status: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
callback_url: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,15 @@ import * as uuid from 'uuid';
|
||||||
import { UserDetail } from './entities/user_detail.entity';
|
import { UserDetail } from './entities/user_detail.entity';
|
||||||
import { COA } from '../transaction/entities/coa.entity';
|
import { COA } from '../transaction/entities/coa.entity';
|
||||||
import { mapSeries } from 'bluebird';
|
import { mapSeries } from 'bluebird';
|
||||||
|
import { Partner } from './entities/partner.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(User)
|
@InjectRepository(User)
|
||||||
private usersRepository: Repository<User>,
|
private usersRepository: Repository<User>,
|
||||||
|
@InjectRepository(Partner)
|
||||||
|
private partnerRepository: Repository<Partner>,
|
||||||
@InjectRepository(UserDetail)
|
@InjectRepository(UserDetail)
|
||||||
private userDetailRepository: Repository<UserDetail>,
|
private userDetailRepository: Repository<UserDetail>,
|
||||||
@Inject(
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user