Merge branch 'development' into 'devops-staging'

Development

See merge request empatnusabangsa/ppob/ppob-backend!161
This commit is contained in:
ilham dwi pratama 2022-05-17 07:29:02 +00:00
commit a10f471326
8 changed files with 290 additions and 20 deletions

View File

@ -9,4 +9,7 @@ export class OrderTransactionDto {
@IsOptional() @IsOptional()
trx_id: string; trx_id: string;
@IsOptional()
bill_trx_id: string;
} }

View 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;
}

View File

@ -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,

View File

@ -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

View File

@ -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),

View File

@ -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 hitSupplier = await doTransaction( let status;
'CEK' + orderTransactionDto.productCode.slice(3),
orderTransactionDto.destination,
trxId,
supplier,
);
// let hitSupplier = await doTransaction( try {
// 'CEKXL1', let hitSupplier = await doTransaction(
// orderTransactionDto.destination, 'CEK' + orderTransactionDto.productCode.slice(3),
// trxId, orderTransactionDto.destination,
// supplier, trxId,
// ); supplier,
);
const parsingResponse = hitSupplier.split(' ');
console.log(hitSupplier,"ini dia")
hitSupplier = {
success: hitSupplier.includes('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) { 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;
}
}
}
} }

View File

@ -27,4 +27,9 @@ export class Partner extends BaseModel {
@Column({ default: true }) @Column({ default: true })
status: boolean; status: boolean;
@Column({
default: '',
})
callback_url: string;
} }

View File

@ -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;
}
}
}
} }