Merge branch 'master' into 'devops-production'
Master See merge request empatnusabangsa/ppob/ppob-backend!182
This commit is contained in:
commit
234ae2918f
7633
package-lock.json
generated
Normal file
7633
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -6,13 +6,24 @@ const irs_pin = '04JFGC';
|
||||||
const irs_user = 'D10BD0';
|
const irs_user = 'D10BD0';
|
||||||
const irs_pass = '6251F3';
|
const irs_pass = '6251F3';
|
||||||
|
|
||||||
export const doTransaction = async (productCode, destination, idtrx) => {
|
export const doTransaction = async (
|
||||||
|
productCode,
|
||||||
|
destination,
|
||||||
|
idtrx,
|
||||||
|
supplier,
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(
|
if(supplier.code == 'IRS'){
|
||||||
`${irs_url}?id=${irs_id}&pin=${irs_pin}&user=${irs_user}&pass=${irs_pass}&kodeproduk=${productCode}&tujuan=${destination}&counter=1&idtrx=${idtrx}`,
|
const res = await axios.get(
|
||||||
);
|
`${irs_url}?id=${irs_id}&pin=${irs_pin}&user=${irs_user}&pass=${irs_pass}&kodeproduk=${productCode}&tujuan=${destination}&counter=1&idtrx=${idtrx}`,
|
||||||
|
);
|
||||||
return res.data;
|
return res.data;
|
||||||
|
} else {
|
||||||
|
const res = await axios.get(
|
||||||
|
`${supplier.url}?memberID=${supplier.irs_id}&pin=${supplier.irs_pin}&password=${supplier.irs_pass}&product=${productCode}&dest=${destination}&counter=1&refID=${idtrx}`,
|
||||||
|
);
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@ export class UpdatePriceProductDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
type: productType;
|
type: productType;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
productType: string;
|
||||||
|
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
|
|
||||||
endDate: Date;
|
endDate: Date;
|
||||||
|
|
|
@ -32,4 +32,14 @@ export class ProductHistoryPrice extends BaseModel {
|
||||||
|
|
||||||
@Column('text')
|
@Column('text')
|
||||||
type: productType;
|
type: productType;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
admin_price: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
partner_fee: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,11 @@ export class Product extends BaseModel {
|
||||||
})
|
})
|
||||||
basePrice: number;
|
basePrice: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
default: 'prepaid',
|
||||||
|
})
|
||||||
|
type: string;
|
||||||
|
|
||||||
@ManyToOne(
|
@ManyToOne(
|
||||||
() => {
|
() => {
|
||||||
return ProductSubCategories;
|
return ProductSubCategories;
|
||||||
|
|
|
@ -55,6 +55,7 @@ export class ProductService {
|
||||||
const supplierData = await this.supplierService.findByCode(supplierCode);
|
const supplierData = await this.supplierService.findByCode(supplierCode);
|
||||||
|
|
||||||
const data = await parsingFile(uploadFile);
|
const data = await parsingFile(uploadFile);
|
||||||
|
|
||||||
data.shift();
|
data.shift();
|
||||||
await mapSeries(data, async (it) => {
|
await mapSeries(data, async (it) => {
|
||||||
let dataHistoryPrice;
|
let dataHistoryPrice;
|
||||||
|
@ -71,6 +72,7 @@ export class ProductService {
|
||||||
code: it[0],
|
code: it[0],
|
||||||
supplier: supplierData,
|
supplier: supplierData,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (productData) {
|
if (productData) {
|
||||||
//TODO : Handle Update Product
|
//TODO : Handle Update Product
|
||||||
productData.name = it[1];
|
productData.name = it[1];
|
||||||
|
@ -108,18 +110,23 @@ export class ProductService {
|
||||||
type: productType.NORMAL,
|
type: productType.NORMAL,
|
||||||
startDate: new Date(),
|
startDate: new Date(),
|
||||||
partner: it[6] != '-' ? partnerData : null,
|
partner: it[6] != '-' ? partnerData : null,
|
||||||
|
admin_price: it[8],
|
||||||
|
partner_fee: it[9],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let partnerData;
|
let partnerData;
|
||||||
|
|
||||||
if (it[6] != '-' && it[6] != '') {
|
if (it[6] != '-' && it[6] != '') {
|
||||||
partnerData = await this.partnerService.findOne(it[6]);
|
partnerData = await this.partnerService.findOne(it[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const savedProduct = await this.productRepository.insert({
|
const savedProduct = await this.productRepository.insert({
|
||||||
name: it[1],
|
name: it[1],
|
||||||
code: it[0],
|
code: it[0],
|
||||||
status: it[5] == 'active' ? 'ACTIVE' : 'NOT ACTIVE',
|
status: it[5] == 'active' ? 'ACTIVE' : 'NOT ACTIVE',
|
||||||
sub_categories: subCategories,
|
sub_categories: subCategories,
|
||||||
supplier: supplierData,
|
supplier: supplierData,
|
||||||
|
type: it[7] == 'postpaid' ? 'postpaid' : 'prepaid',
|
||||||
});
|
});
|
||||||
|
|
||||||
return await this.productHistoryPrice.insert({
|
return await this.productHistoryPrice.insert({
|
||||||
|
@ -130,6 +137,8 @@ export class ProductService {
|
||||||
startDate: new Date(),
|
startDate: new Date(),
|
||||||
endDate: null,
|
endDate: null,
|
||||||
partner: partnerData,
|
partner: partnerData,
|
||||||
|
admin_price: it[8],
|
||||||
|
partner_fee: it[9],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -167,7 +176,7 @@ export class ProductService {
|
||||||
'product.currentPrice',
|
'product.currentPrice',
|
||||||
'product.priceHistory',
|
'product.priceHistory',
|
||||||
'current_price',
|
'current_price',
|
||||||
'current_price.partner_id is null and current_price.end_date is NULL',
|
'current_price.end_date is NULL',
|
||||||
)
|
)
|
||||||
.select(['product.id'])
|
.select(['product.id'])
|
||||||
.addSelect([
|
.addSelect([
|
||||||
|
@ -178,7 +187,9 @@ export class ProductService {
|
||||||
'category.name',
|
'category.name',
|
||||||
'product.status',
|
'product.status',
|
||||||
])
|
])
|
||||||
.addSelect('current_price.price')
|
.addSelect('current_price.price', 'price')
|
||||||
|
.addSelect('current_price.partner_fee', 'partner_fee')
|
||||||
|
.addSelect('current_price.admin_price', 'admin_price')
|
||||||
.addSelect(
|
.addSelect(
|
||||||
'(current_price.price + current_price.mark_up_price) as mark_up_price',
|
'(current_price.price + current_price.mark_up_price) as mark_up_price',
|
||||||
)
|
)
|
||||||
|
@ -291,18 +302,34 @@ export class ProductService {
|
||||||
subCategories: string,
|
subCategories: string,
|
||||||
username: string,
|
username: string,
|
||||||
) {
|
) {
|
||||||
|
let filterSubCategories;
|
||||||
const user = await this.usersService.findOneByUsername(username);
|
const user = await this.usersService.findOneByUsername(username);
|
||||||
const supplier = await this.supplierService.findByActive();
|
|
||||||
|
|
||||||
const baseQuery = this.productRepository
|
if (subCategories) {
|
||||||
|
filterSubCategories = subCategories.split(',').map((data) => {
|
||||||
|
return data.trim();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.partner === null) {
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
|
error: 'Partner id not found',
|
||||||
|
},
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseQuery = await this.productRepository
|
||||||
.createQueryBuilder('product')
|
.createQueryBuilder('product')
|
||||||
.leftJoin('product.sub_categories', 'sub_categories')
|
.leftJoin('product.sub_categories', 'sub_categories')
|
||||||
.where(
|
.leftJoinAndSelect(
|
||||||
`product.supplier_id = :supplier_id and product.status = 'ACTIVE'`,
|
'product.supplier',
|
||||||
{
|
'supplier',
|
||||||
supplier_id: supplier.id,
|
'supplier.status = true',
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
.where(`product.status = 'ACTIVE'`)
|
||||||
.innerJoinAndMapOne(
|
.innerJoinAndMapOne(
|
||||||
'product.currentPrice',
|
'product.currentPrice',
|
||||||
'product.priceHistory',
|
'product.priceHistory',
|
||||||
|
@ -313,26 +340,64 @@ export class ProductService {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.select(['product.id'])
|
.select(['product.id'])
|
||||||
.addSelect(['product.name', 'product.code', 'sub_categories.name'])
|
.addSelect([
|
||||||
.addSelect(
|
'product.name',
|
||||||
'(current_price.price + current_price.mark_up_price) as price',
|
'product.code',
|
||||||
);
|
'product.type',
|
||||||
|
'product.status',
|
||||||
|
'sub_categories.name',
|
||||||
|
'current_price.admin_price as admin_price',
|
||||||
|
'current_price.mark_up_price as markup_price',
|
||||||
|
'current_price.partner_fee as partner_fee',
|
||||||
|
'current_price.price as price',
|
||||||
|
])
|
||||||
|
// .addSelect(
|
||||||
|
// '(current_price.price + current_price.mark_up_price) as price',
|
||||||
|
// );
|
||||||
|
|
||||||
if (
|
// if (
|
||||||
subCategories != 'null' &&
|
// subCategories != 'null' &&
|
||||||
subCategories &&
|
// subCategories &&
|
||||||
subCategories != 'undefined'
|
// subCategories != 'undefined'
|
||||||
) {
|
// ) {
|
||||||
baseQuery.where('product.sub_categories_id = :id', {
|
// baseQuery.where('product.sub_categories_id = :id', {
|
||||||
id: subCategories,
|
// id: subCategories,
|
||||||
});
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
if (subCategories && filterSubCategories.length > 0) {
|
||||||
|
baseQuery.where('product.sub_categories_id IN (:...subCategoryId)', {
|
||||||
|
subCategoryId: filterSubCategories,
|
||||||
|
}).andWhere(`product.status = 'ACTIVE'`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const newData = []
|
||||||
|
|
||||||
const data = await baseQuery
|
const data = await baseQuery
|
||||||
.offset(page * pageSize)
|
.offset(page * pageSize)
|
||||||
.limit(pageSize)
|
.limit(pageSize)
|
||||||
.getRawMany();
|
.getRawMany();
|
||||||
|
|
||||||
|
data.map((dataa) => {
|
||||||
|
let actualPrice = 0
|
||||||
|
|
||||||
|
if (dataa.product_type === 'prepaid') {
|
||||||
|
actualPrice = Number(dataa['price']) + Number(dataa['markup_price'])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataa.product_type === 'postpaid') {
|
||||||
|
actualPrice = Number(dataa['admin_price'])- (Number(dataa['partner_fee']) + Number(dataa['markup_price']))
|
||||||
|
}
|
||||||
|
|
||||||
|
dataa.price = actualPrice
|
||||||
|
|
||||||
|
newData.push({
|
||||||
|
...dataa
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
const totalData = await baseQuery.getCount();
|
const totalData = await baseQuery.getCount();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -341,7 +406,7 @@ export class ProductService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(code: string) {
|
async findOne(code: string, type: string) {
|
||||||
try {
|
try {
|
||||||
return await this.productRepository.findOneOrFail({
|
return await this.productRepository.findOneOrFail({
|
||||||
relations: ['supplier'],
|
relations: ['supplier'],
|
||||||
|
@ -422,7 +487,7 @@ export class ProductService {
|
||||||
code: string,
|
code: string,
|
||||||
updatePriceProductDto: UpdatePriceProductDto,
|
updatePriceProductDto: UpdatePriceProductDto,
|
||||||
) {
|
) {
|
||||||
const product = await this.findOne(code);
|
const product = await this.findOne(code, updatePriceProductDto.productType);
|
||||||
|
|
||||||
await this.productHistoryPrice.insert({
|
await this.productHistoryPrice.insert({
|
||||||
product: product,
|
product: product,
|
||||||
|
|
|
@ -9,4 +9,7 @@ export class OrderTransactionDto {
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
trx_id: string;
|
trx_id: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
bill_trx_id: string;
|
||||||
}
|
}
|
||||||
|
|
51
src/transaction/entities/check-bill-history.entity.ts
Normal file
51
src/transaction/entities/check-bill-history.entity.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
status: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => ProductHistoryPrice, (product) => product.id)
|
||||||
|
product_price: ProductHistoryPrice;
|
||||||
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -24,14 +24,84 @@ export class PpobCallbackController {
|
||||||
response['clientid'],
|
response['clientid'],
|
||||||
response,
|
response,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateTransaction,
|
||||||
|
statusCode: HttpStatus.BAD_REQUEST,
|
||||||
|
message: 'failed to proccess',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: UPDATE BERHASIL
|
||||||
|
const updateTransaction =
|
||||||
|
await this.transactionService.callbackOrderSuccess(
|
||||||
|
response['clientid'],
|
||||||
|
response,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateTransaction,
|
||||||
|
statusCode: HttpStatus.OK,
|
||||||
|
message: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Public()
|
||||||
|
@Get('/metro')
|
||||||
|
async getMetro(@Req() request: FastifyRequest) {
|
||||||
|
const response = request.query;
|
||||||
|
|
||||||
|
if (response['message'].toLowerCase().includes('cek tagihan')) {
|
||||||
|
if (response['status'] != 20) {
|
||||||
|
//TODO: UPDATE GAGAL
|
||||||
|
await this.transactionService.updateBill(
|
||||||
|
response['refid'],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
response['message'],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: HttpStatus.OK,
|
||||||
|
message: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const splitMessage = response['message'].split('"');
|
||||||
|
//TODO: UPDATE BERHASIL
|
||||||
|
await this.transactionService.updateBill(
|
||||||
|
response['refid'],
|
||||||
|
Number(splitMessage[21].replace(/^\D+/g, '')),
|
||||||
|
Number(splitMessage[17].replace(/^\D+/g, '')),
|
||||||
|
true,
|
||||||
|
response['message'],
|
||||||
|
);
|
||||||
|
//
|
||||||
} else {
|
} else {
|
||||||
|
if (response['status'].toString() != '20') {
|
||||||
|
//TODO: UPDATE GAGAL
|
||||||
|
const updateTransaction =
|
||||||
|
await this.transactionService.callbackOrderFailed(
|
||||||
|
response['refid'],
|
||||||
|
response,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateTransaction,
|
||||||
|
statusCode: HttpStatus.BAD_REQUEST,
|
||||||
|
message: 'failed to proccess',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: UPDATE BERHASIL
|
//TODO: UPDATE BERHASIL
|
||||||
const updateTransaction =
|
const updateTransaction =
|
||||||
await this.transactionService.callbackOrderSuccess(
|
await this.transactionService.callbackOrderSuccess(
|
||||||
response['clientid'],
|
response['refid'],
|
||||||
response,
|
response,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.log({
|
this.logger.log({
|
||||||
requestQuery: request.query,
|
requestQuery: request.query,
|
||||||
});
|
});
|
||||||
|
|
|
@ -87,6 +87,36 @@ export class TransactionController {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('order-bill-prod')
|
||||||
|
async orderTransactioBillnProd(
|
||||||
|
@Body() orderTransactionDto: OrderTransactionDto,
|
||||||
|
@Request() req,
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
data: await this.transactionService.orderTransactionBillProd(
|
||||||
|
orderTransactionDto,
|
||||||
|
req.user,
|
||||||
|
),
|
||||||
|
statusCode: HttpStatus.CREATED,
|
||||||
|
message: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('check-bill')
|
||||||
|
async checkBill(
|
||||||
|
@Body() orderTransactionDto: OrderTransactionDto,
|
||||||
|
@Request() req,
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
data: await this.transactionService.checkBill(
|
||||||
|
orderTransactionDto,
|
||||||
|
req.user,
|
||||||
|
),
|
||||||
|
statusCode: HttpStatus.CREATED,
|
||||||
|
message: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Post('deposit-return')
|
@Post('deposit-return')
|
||||||
async depositReturn(
|
async depositReturn(
|
||||||
@Body() depositReturnDto: DepositReturnDto,
|
@Body() depositReturnDto: DepositReturnDto,
|
||||||
|
@ -125,6 +155,27 @@ export class TransactionController {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('check-bill-history')
|
||||||
|
async getCheckBillHistory(
|
||||||
|
@Param('id') id: string,
|
||||||
|
@Query('page') page: number,
|
||||||
|
@Query('pageSize') pageSize: number,
|
||||||
|
@Request() req,
|
||||||
|
) {
|
||||||
|
const [data, count] = await this.transactionService.findAll(
|
||||||
|
req.user.userId,
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
count,
|
||||||
|
statusCode: HttpStatus.OK,
|
||||||
|
message: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Get('history-user/:id')
|
@Get('history-user/:id')
|
||||||
async getHistoryTransactionUserByParam(
|
async getHistoryTransactionUserByParam(
|
||||||
@Query('page') page: number,
|
@Query('page') page: number,
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -312,6 +316,7 @@ export class TransactionService {
|
||||||
//GET PRODUCT
|
//GET PRODUCT
|
||||||
const product = await this.productService.findOne(
|
const product = await this.productService.findOne(
|
||||||
orderTransactionDto.productCode,
|
orderTransactionDto.productCode,
|
||||||
|
'prepaid'
|
||||||
);
|
);
|
||||||
|
|
||||||
const product_price = await this.productHistoryPriceService.findOne(
|
const product_price = await this.productHistoryPriceService.findOne(
|
||||||
|
@ -446,6 +451,230 @@ export class TransactionService {
|
||||||
//GET PRODUCT AND PRICE
|
//GET PRODUCT AND PRICE
|
||||||
const product = await this.productService.findOne(
|
const product = await this.productService.findOne(
|
||||||
orderTransactionDto.productCode,
|
orderTransactionDto.productCode,
|
||||||
|
'prepaid',
|
||||||
|
);
|
||||||
|
|
||||||
|
const supplier = await this.supplierService.findByCode(
|
||||||
|
product.supplier.code,
|
||||||
|
);
|
||||||
|
|
||||||
|
let product_price = await this.productHistoryPriceService.findOne(
|
||||||
|
product.id,
|
||||||
|
userData.partner?.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
//GET COA
|
||||||
|
const coaAccount = await this.coaService.findByUser(
|
||||||
|
userData.id,
|
||||||
|
coaType.WALLET,
|
||||||
|
);
|
||||||
|
|
||||||
|
const coaInventory = await this.coaService.findByName(
|
||||||
|
`${coaType[coaType.INVENTORY]}-${product.supplier.code}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const coaCostOfSales = await this.coaService.findByName(
|
||||||
|
`${coaType[coaType.COST_OF_SALES]}-${product.supplier.code}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const coaSales = await this.coaService.findByName(
|
||||||
|
`${coaType[coaType.SALES]}-SYSTEM`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (orderTransactionDto.bill_trx_id) {
|
||||||
|
try {
|
||||||
|
const billId = await this.checkBillHistoryRepository.findOneOrFail({
|
||||||
|
where: {
|
||||||
|
trx_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) {
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
error: `Transaction Failed because saldo not enough`,
|
||||||
|
},
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//HIT API SUPPLIER
|
||||||
|
const trxId = Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map(() => {
|
||||||
|
return Math.round(Math.random() * 16).toString(16);
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
let hitSupplier = await doTransaction(
|
||||||
|
orderTransactionDto.productCode,
|
||||||
|
orderTransactionDto.destination,
|
||||||
|
trxId,
|
||||||
|
supplier,
|
||||||
|
);
|
||||||
|
// let hitSupplier;
|
||||||
|
|
||||||
|
if (supplier.code != 'IRS') {
|
||||||
|
const parsingResponse = hitSupplier.split(' ');
|
||||||
|
console.log
|
||||||
|
const newHitSupplier = {
|
||||||
|
success: hitSupplier.includes('diproses'),
|
||||||
|
harga: parseInt(
|
||||||
|
parsingResponse[parsingResponse.length - 2].replace(/\./g,' '),
|
||||||
|
),
|
||||||
|
msg: hitSupplier,
|
||||||
|
};
|
||||||
|
hitSupplier = newHitSupplier;
|
||||||
|
if(orderTransactionDto.bill_trx_id !== null){
|
||||||
|
hitSupplier.harga = product_price.price;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// const hitSupplier = {
|
||||||
|
// harga: 2000,
|
||||||
|
// success: true,
|
||||||
|
// msg: 'Berhasil',
|
||||||
|
// };
|
||||||
|
|
||||||
|
this.logger.log({
|
||||||
|
responseAPISupplier: hitSupplier,
|
||||||
|
});
|
||||||
|
|
||||||
|
let costInventory = product_price.price;
|
||||||
|
|
||||||
|
if (hitSupplier.harga != product_price.price) {
|
||||||
|
product_price.endDate = new Date();
|
||||||
|
costInventory = hitSupplier.harga;
|
||||||
|
const listActivePrice =
|
||||||
|
await this.productHistoryPriceService.getAllActivePriceByProduct(
|
||||||
|
product.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.productHistoryPriceService.updateEndDate(product.id);
|
||||||
|
|
||||||
|
listActivePrice.map(async (x) => {
|
||||||
|
const newProductPrice = new ProductHistoryPrice();
|
||||||
|
|
||||||
|
newProductPrice.id = uuid.v4();
|
||||||
|
newProductPrice.type = x.type;
|
||||||
|
newProductPrice.price = hitSupplier.harga;
|
||||||
|
newProductPrice.mark_up_price = x.mark_up_price;
|
||||||
|
newProductPrice.startDate = new Date();
|
||||||
|
newProductPrice.product = product;
|
||||||
|
newProductPrice.partner = x.partner;
|
||||||
|
await this.productHistoryPriceService.create(newProductPrice);
|
||||||
|
|
||||||
|
product_price = newProductPrice;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//TRANSACTION DATA
|
||||||
|
await this.connection.transaction(async (manager) => {
|
||||||
|
const transactionData = new Transactions();
|
||||||
|
|
||||||
|
transactionData.id = uuid.v4();
|
||||||
|
transactionData.amount =
|
||||||
|
product_price.mark_up_price + product_price.price;
|
||||||
|
transactionData.user = userData.id;
|
||||||
|
transactionData.type = typeTransaction.ORDER;
|
||||||
|
transactionData.product_price = product_price;
|
||||||
|
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;
|
||||||
|
status = statusTransaction[transactionData.status];
|
||||||
|
await this.transactionRepository.insert(transactionData);
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
error: hitSupplier.msg,
|
||||||
|
},
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
transactionData.status = statusTransaction.PENDING;
|
||||||
|
status = statusTransaction[transactionData.status];
|
||||||
|
}
|
||||||
|
|
||||||
|
await manager.insert(Transactions, transactionData);
|
||||||
|
|
||||||
|
await this.accountingTransaction({
|
||||||
|
createTransaction: false,
|
||||||
|
transactionalEntityManager: manager,
|
||||||
|
transaction: transactionData,
|
||||||
|
amount: transactionData.amount,
|
||||||
|
journals: [
|
||||||
|
{
|
||||||
|
coa_id: coaInventory.id,
|
||||||
|
credit: costInventory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
coa_id: coaCostOfSales.id,
|
||||||
|
debit: costInventory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
coa_id: coaAccount.id,
|
||||||
|
debit: product_price.mark_up_price + costInventory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
coa_id: coaSales.id,
|
||||||
|
credit: product_price.mark_up_price + costInventory,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
trx_id: trxId,
|
||||||
|
client_trx_id: orderTransactionDto.trx_id,
|
||||||
|
product: orderTransactionDto.productCode,
|
||||||
|
amount: product_price.mark_up_price + product_price.price,
|
||||||
|
status: status,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async orderTransactionBillProd(
|
||||||
|
orderTransactionDto: OrderTransactionDto,
|
||||||
|
currentUser: any,
|
||||||
|
) {
|
||||||
|
let status;
|
||||||
|
const amount = 0;
|
||||||
|
//GET USER DATA
|
||||||
|
const userData = await this.userService.findByUsername(
|
||||||
|
currentUser.username,
|
||||||
|
);
|
||||||
|
|
||||||
|
//GET PRODUCT AND PRICE
|
||||||
|
const product = await this.productService.findOne(
|
||||||
|
orderTransactionDto.productCode,
|
||||||
|
'postpaid',
|
||||||
|
);
|
||||||
|
|
||||||
|
const supplier = await this.supplierService.findByCode(
|
||||||
|
product.supplier.code,
|
||||||
);
|
);
|
||||||
|
|
||||||
let product_price = await this.productHistoryPriceService.findOne(
|
let product_price = await this.productHistoryPriceService.findOne(
|
||||||
|
@ -489,12 +718,23 @@ export class TransactionService {
|
||||||
})
|
})
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
const hitSupplier = await doTransaction(
|
let hitSupplier = await doTransaction(
|
||||||
orderTransactionDto.productCode,
|
orderTransactionDto.productCode,
|
||||||
orderTransactionDto.destination,
|
orderTransactionDto.destination,
|
||||||
trxId,
|
trxId,
|
||||||
|
supplier,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (supplier.code != 'IRS') {
|
||||||
|
const parsingResponse = hitSupplier.split(' ');
|
||||||
|
hitSupplier = {
|
||||||
|
success: hitSupplier.includes('diproses'),
|
||||||
|
harga: parseInt(
|
||||||
|
parsingResponse[parsingResponse.length - 2].replaceAll('.', ''),
|
||||||
|
),
|
||||||
|
msg: hitSupplier,
|
||||||
|
};
|
||||||
|
}
|
||||||
// const hitSupplier = {
|
// const hitSupplier = {
|
||||||
// harga: 2000,
|
// harga: 2000,
|
||||||
// success: true,
|
// success: true,
|
||||||
|
@ -510,27 +750,6 @@ export class TransactionService {
|
||||||
if (hitSupplier.harga != product_price.price) {
|
if (hitSupplier.harga != product_price.price) {
|
||||||
product_price.endDate = new Date();
|
product_price.endDate = new Date();
|
||||||
costInventory = hitSupplier.harga;
|
costInventory = hitSupplier.harga;
|
||||||
const listActivePrice =
|
|
||||||
await this.productHistoryPriceService.getAllActivePriceByProduct(
|
|
||||||
product.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.productHistoryPriceService.updateEndDate(product.id);
|
|
||||||
|
|
||||||
listActivePrice.map(async (x) => {
|
|
||||||
const newProductPrice = new ProductHistoryPrice();
|
|
||||||
|
|
||||||
newProductPrice.id = uuid.v4();
|
|
||||||
newProductPrice.type = x.type;
|
|
||||||
newProductPrice.price = hitSupplier.harga;
|
|
||||||
newProductPrice.mark_up_price = x.mark_up_price;
|
|
||||||
newProductPrice.startDate = new Date();
|
|
||||||
newProductPrice.product = product;
|
|
||||||
newProductPrice.partner = x.partner;
|
|
||||||
await this.productHistoryPriceService.create(newProductPrice);
|
|
||||||
|
|
||||||
product_price = newProductPrice;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -605,6 +824,84 @@ export class TransactionService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkBill(orderTransactionDto: OrderTransactionDto, currentUser: any) {
|
||||||
|
//GET USER DATA
|
||||||
|
const userData = await this.userService.findByUsername(
|
||||||
|
currentUser.username,
|
||||||
|
);
|
||||||
|
|
||||||
|
//GET PRODUCT AND PRICE
|
||||||
|
const product = await this.productService.findOne(
|
||||||
|
orderTransactionDto.productCode,
|
||||||
|
'postpaid',
|
||||||
|
);
|
||||||
|
|
||||||
|
const supplier = await this.supplierService.findByCode(
|
||||||
|
product.supplier.code,
|
||||||
|
);
|
||||||
|
|
||||||
|
let product_price = await this.productHistoryPriceService.findOne(
|
||||||
|
product.id,
|
||||||
|
userData.partner?.id,
|
||||||
|
);
|
||||||
|
//HIT API SUPPLIER
|
||||||
|
const trxId = Array(6)
|
||||||
|
.fill(null)
|
||||||
|
.map(() => {
|
||||||
|
return Math.round(Math.random() * 16).toString(16);
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
let status;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let hitSupplier = await doTransaction(
|
||||||
|
'CEK' + orderTransactionDto.productCode.slice(3),
|
||||||
|
orderTransactionDto.destination,
|
||||||
|
trxId,
|
||||||
|
supplier,
|
||||||
|
);
|
||||||
|
const parsingResponse = hitSupplier.split(' ');
|
||||||
|
hitSupplier = {
|
||||||
|
success: hitSupplier.includes('diproses'),
|
||||||
|
msg: 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,
|
||||||
|
product_price: product_price,
|
||||||
|
status: 'PENDING',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} 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) {
|
||||||
const userData = await this.userService.findByUsername(
|
const userData = await this.userService.findByUsername(
|
||||||
currentUser.username,
|
currentUser.username,
|
||||||
|
@ -834,6 +1131,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) {
|
||||||
|
@ -866,8 +1177,7 @@ export class TransactionService {
|
||||||
const coaExpense = await this.coaService.findByName(
|
const coaExpense = await this.coaService.findByName(
|
||||||
`${coaType[coaType.EXPENSE]}-SYSTEM`,
|
`${coaType[coaType.EXPENSE]}-SYSTEM`,
|
||||||
);
|
);
|
||||||
|
if (userData.partner != null) {
|
||||||
if (!userData.partner) {
|
|
||||||
//GET SALES
|
//GET SALES
|
||||||
supervisorData = await this.calculateCommission(
|
supervisorData = await this.calculateCommission(
|
||||||
supervisorData,
|
supervisorData,
|
||||||
|
@ -905,6 +1215,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) {
|
||||||
|
@ -1041,6 +1381,58 @@ export class TransactionService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findOne(user: string, id: string) {
|
||||||
|
try {
|
||||||
|
return this.checkBillHistoryRepository.findOneOrFail({
|
||||||
|
where: {
|
||||||
|
trx_id: id,
|
||||||
|
user: user,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
|
error: 'Billing not found',
|
||||||
|
},
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(user: string, page, pageSize?) {
|
||||||
|
try {
|
||||||
|
return await this.checkBillHistoryRepository.findAndCount({
|
||||||
|
where: {
|
||||||
|
user: user,
|
||||||
|
},
|
||||||
|
select: [
|
||||||
|
'amount',
|
||||||
|
'admin_price',
|
||||||
|
'product_code',
|
||||||
|
'destination',
|
||||||
|
'trx_id',
|
||||||
|
'partner_trx_id',
|
||||||
|
'status',
|
||||||
|
'createdAt',
|
||||||
|
],
|
||||||
|
skip: page * (pageSize || 10),
|
||||||
|
take: pageSize || 10,
|
||||||
|
order: {
|
||||||
|
createdAt: 'DESC',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
|
error: 'Billing not found',
|
||||||
|
},
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async topUpHistoryByUser(
|
async topUpHistoryByUser(
|
||||||
page: number,
|
page: number,
|
||||||
user: string,
|
user: string,
|
||||||
|
@ -1449,4 +1841,79 @@ export class TransactionService {
|
||||||
|
|
||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateBill(
|
||||||
|
trxId: string,
|
||||||
|
amount: number,
|
||||||
|
admin: number,
|
||||||
|
status: boolean,
|
||||||
|
message: string,
|
||||||
|
) {
|
||||||
|
const billData = await this.findOneBillById(trxId);
|
||||||
|
console.log(billData,"ini dia")
|
||||||
|
const userData = await this.userService.findExist(billData.user);
|
||||||
|
|
||||||
|
const product_price = await this.productHistoryPriceService.findById(
|
||||||
|
billData.product_price.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.checkBillHistoryRepository.update(
|
||||||
|
{
|
||||||
|
trx_id: trxId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: status
|
||||||
|
? amount -
|
||||||
|
admin +
|
||||||
|
product_price.partner_fee +
|
||||||
|
product_price.mark_up_price
|
||||||
|
: 0,
|
||||||
|
admin_price: admin,
|
||||||
|
status: status ? 'SUCCESS' : 'FAILED',
|
||||||
|
callback_json: JSON.stringify(message),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userData.partner) {
|
||||||
|
const message = status
|
||||||
|
? `Bill dari ${billData.destination} adalah ${
|
||||||
|
amount + product_price.partner_fee + product_price.mark_up_price
|
||||||
|
}.`
|
||||||
|
: '';
|
||||||
|
const statusResponse = status ? 'berhasil' : 'gagal';
|
||||||
|
this.callbackToPartner(
|
||||||
|
userData.id,
|
||||||
|
message,
|
||||||
|
billData.partner_trx_id,
|
||||||
|
amount + product_price.partner_fee + product_price.mark_up_price,
|
||||||
|
billData.product_code,
|
||||||
|
billData.destination,
|
||||||
|
'-',
|
||||||
|
statusResponse,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOneBillById(trxId: string) {
|
||||||
|
try {
|
||||||
|
return await this.checkBillHistoryRepository.findOneOrFail({
|
||||||
|
relations: ['product_price'],
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,19 @@ export class CreateSupplierDto {
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
code: string;
|
code: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
url: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
irs_id: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
irs_pin: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
irs_user: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
irs_pass: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,4 +27,9 @@ export class Partner extends BaseModel {
|
||||||
|
|
||||||
@Column({ default: true })
|
@Column({ default: true })
|
||||||
status: boolean;
|
status: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
default: '',
|
||||||
|
})
|
||||||
|
callback_url: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,31 @@ export class Supplier extends BaseModel {
|
||||||
@Column()
|
@Column()
|
||||||
status: boolean;
|
status: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
url: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
irs_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
irs_pin: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
irs_user: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true
|
||||||
|
})
|
||||||
|
irs_pass: string;
|
||||||
|
|
||||||
coa: COA;
|
coa: COA;
|
||||||
|
|
||||||
coa_undistribute: COA;
|
coa_undistribute: COA;
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class SupplierService {
|
||||||
)
|
)
|
||||||
private coaService: CoaService,
|
private coaService: CoaService,
|
||||||
private connection: Connection,
|
private connection: Connection,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
async create(createSupplierDto: CreateSupplierDto) {
|
async create(createSupplierDto: CreateSupplierDto) {
|
||||||
const check = await this.supplierRepository.findOne({
|
const check = await this.supplierRepository.findOne({
|
||||||
|
@ -43,6 +43,11 @@ export class SupplierService {
|
||||||
supplierData.id = uuid.v4();
|
supplierData.id = uuid.v4();
|
||||||
supplierData.name = createSupplierDto.name;
|
supplierData.name = createSupplierDto.name;
|
||||||
supplierData.code = createSupplierDto.code;
|
supplierData.code = createSupplierDto.code;
|
||||||
|
supplierData.url = createSupplierDto.url;
|
||||||
|
supplierData.irs_id = createSupplierDto.irs_id;
|
||||||
|
supplierData.irs_pin = createSupplierDto.irs_pin;
|
||||||
|
supplierData.irs_user = createSupplierDto.irs_user;
|
||||||
|
supplierData.irs_pass = createSupplierDto.irs_pass;
|
||||||
supplierData.status = false;
|
supplierData.status = false;
|
||||||
|
|
||||||
await this.connection.transaction(async (manager) => {
|
await this.connection.transaction(async (manager) => {
|
||||||
|
@ -99,6 +104,11 @@ export class SupplierService {
|
||||||
const supplierData = new Supplier();
|
const supplierData = new Supplier();
|
||||||
|
|
||||||
supplierData.name = updateSupplierDto.name;
|
supplierData.name = updateSupplierDto.name;
|
||||||
|
supplierData.url = updateSupplierDto.url;
|
||||||
|
supplierData.irs_id = updateSupplierDto.irs_id;
|
||||||
|
supplierData.irs_pin = updateSupplierDto.irs_pin;
|
||||||
|
supplierData.irs_user = updateSupplierDto.irs_user;
|
||||||
|
supplierData.irs_pass = updateSupplierDto.irs_pass;
|
||||||
supplierData.status = true;
|
supplierData.status = true;
|
||||||
|
|
||||||
await this.connection.transaction(async (manager) => {
|
await this.connection.transaction(async (manager) => {
|
||||||
|
|
|
@ -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(
|
||||||
|
@ -410,6 +413,7 @@ export class UsersService {
|
||||||
.leftJoinAndSelect('users.roles', 'roles')
|
.leftJoinAndSelect('users.roles', 'roles')
|
||||||
.leftJoinAndSelect('users.superior', 'superior')
|
.leftJoinAndSelect('users.superior', 'superior')
|
||||||
.leftJoinAndSelect('users.userDetail', 'userDetail')
|
.leftJoinAndSelect('users.userDetail', 'userDetail')
|
||||||
|
.leftJoinAndSelect('users.partner', 'partner')
|
||||||
.where('users.id = :id', {
|
.where('users.id = :id', {
|
||||||
id: id,
|
id: id,
|
||||||
})
|
})
|
||||||
|
@ -429,6 +433,14 @@ export class UsersService {
|
||||||
'userDetail.identity_number',
|
'userDetail.identity_number',
|
||||||
'userDetail.image_identity',
|
'userDetail.image_identity',
|
||||||
'userDetail.image_store',
|
'userDetail.image_store',
|
||||||
|
'partner.id',
|
||||||
|
'partner.name',
|
||||||
|
'partner.code',
|
||||||
|
'partner.npwp',
|
||||||
|
'partner.address',
|
||||||
|
'partner.phone_number',
|
||||||
|
'partner.callback_url'
|
||||||
|
|
||||||
])
|
])
|
||||||
.getOne();
|
.getOne();
|
||||||
const coa = await this.coaService.findByUser(id, coaType.WALLET);
|
const coa = await this.coaService.findByUser(id, coaType.WALLET);
|
||||||
|
@ -676,4 +688,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