add: transaction distribution and order
This commit is contained in:
parent
37352567f1
commit
426c2ccec8
|
@ -29,6 +29,7 @@
|
||||||
"@nestjs/platform-express": "^8.0.0",
|
"@nestjs/platform-express": "^8.0.0",
|
||||||
"@nestjs/platform-fastify": "^8.0.8",
|
"@nestjs/platform-fastify": "^8.0.8",
|
||||||
"@nestjs/typeorm": "^8.0.2",
|
"@nestjs/typeorm": "^8.0.2",
|
||||||
|
"axios": "^0.24.0",
|
||||||
"class-transformer": "^0.4.0",
|
"class-transformer": "^0.4.0",
|
||||||
"class-validator": "^0.13.1",
|
"class-validator": "^0.13.1",
|
||||||
"crypto": "^1.0.1",
|
"crypto": "^1.0.1",
|
||||||
|
|
25
src/helper/irs-service.ts
Normal file
25
src/helper/irs-service.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import * as axios from 'axios';
|
||||||
|
|
||||||
|
export const createTransaction = async (kode, tujuan) => {
|
||||||
|
const codeTransaksi = generateRequestId();
|
||||||
|
|
||||||
|
return axios.default
|
||||||
|
.get(
|
||||||
|
`http://h2h.elangpangarep.com/api/h2h?id=PT0005&pin=04JFGC&user=D10BD0&pass=6251F3&kodeproduk=${kode}&tujuan=${tujuan}&counter=1&idtrx=${codeTransaksi}`,
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const generateRequestId = () => {
|
||||||
|
return `${new Date()
|
||||||
|
.toLocaleString('en-us', {
|
||||||
|
year: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
})
|
||||||
|
.replace(/(\d+)\/(\d+)\/(\d+)/, '$3$1$2')}${Math.random()
|
||||||
|
.toPrecision(3)
|
||||||
|
.replace('0.', '')}`;
|
||||||
|
};
|
|
@ -2,6 +2,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { EntityNotFoundError, Repository } from 'typeorm';
|
import { EntityNotFoundError, Repository } from 'typeorm';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { COA } from './entities/coa.entity';
|
import { COA } from './entities/coa.entity';
|
||||||
|
import { coaType } from '../helper/enum-list';
|
||||||
|
|
||||||
export class CoaService {
|
export class CoaService {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -9,9 +10,9 @@ export class CoaService {
|
||||||
private coaRepository: Repository<COA>,
|
private coaRepository: Repository<COA>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async findByUser(id: string) {
|
async findByUser(id: string, type: coaType) {
|
||||||
try {
|
try {
|
||||||
return await this.coaRepository.findOneOrFail({ user: id });
|
return await this.coaRepository.findOneOrFail({ user: id, type: type });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof EntityNotFoundError) {
|
if (e instanceof EntityNotFoundError) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
|
|
|
@ -3,4 +3,7 @@ import { IsNotEmpty, IsUUID } from 'class-validator';
|
||||||
export class OrderTransactionDto {
|
export class OrderTransactionDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
productCode: string;
|
productCode: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
destination: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { UpdateTransactionDto } from './dto/update-transaction.dto';
|
||||||
export class TransactionController {
|
export class TransactionController {
|
||||||
constructor(private readonly transactionService: TransactionService) {}
|
constructor(private readonly transactionService: TransactionService) {}
|
||||||
|
|
||||||
@Post()
|
@Post('distribute')
|
||||||
create(@Body() createTransactionDto: DistributeTransactionDto) {
|
create(@Body() createTransactionDto: DistributeTransactionDto) {
|
||||||
return this.transactionService.distributeDeposit(createTransactionDto);
|
return this.transactionService.distributeDeposit(createTransactionDto);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ import { TransactionType } from './entities/transaction-type.entity';
|
||||||
import { TransactionJournal } from './entities/transaction-journal.entity';
|
import { TransactionJournal } from './entities/transaction-journal.entity';
|
||||||
import { Transactions } from './entities/transactions.entity';
|
import { Transactions } from './entities/transactions.entity';
|
||||||
import { CoaService } from './coa.service';
|
import { CoaService } from './coa.service';
|
||||||
import { ProductService } from '../product/product.service';
|
|
||||||
import { ProductSubCategoriesService } from '../product/product-sub-categories.service';
|
|
||||||
import { ProductModule } from '../product/product.module';
|
import { ProductModule } from '../product/product.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { DistributeTransactionDto } from './dto/distribute-transaction.dto';
|
import { DistributeTransactionDto } from './dto/distribute-transaction.dto';
|
||||||
import { OrderTransactionDto } from './dto/order-transaction.dto';
|
import { OrderTransactionDto } from './dto/order-transaction.dto';
|
||||||
import { UpdateTransactionDto } from './dto/update-transaction.dto';
|
import { UpdateTransactionDto } from './dto/update-transaction.dto';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Transactions } from './entities/transactions.entity';
|
import { Transactions } from './entities/transactions.entity';
|
||||||
import { Connection, Repository } from 'typeorm';
|
import { Connection, EntityNotFoundError, Repository } from 'typeorm';
|
||||||
import { COA } from './entities/coa.entity';
|
import { COA } from './entities/coa.entity';
|
||||||
import { TransactionType } from './entities/transaction-type.entity';
|
import { TransactionType } from './entities/transaction-type.entity';
|
||||||
import { TransactionJournal } from './entities/transaction-journal.entity';
|
import { TransactionJournal } from './entities/transaction-journal.entity';
|
||||||
import { CoaService } from './coa.service';
|
import { CoaService } from './coa.service';
|
||||||
import { statusTransaction } from '../helper/enum-list';
|
import { statusTransaction } from '../helper/enum-list';
|
||||||
import { ProductService } from '../product/product.service';
|
import { ProductService } from '../product/product.service';
|
||||||
|
import * as irsService from '../helper/irs-service';
|
||||||
|
import { balanceType, typeTransaction } from '../helper/enum-list';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TransactionService {
|
export class TransactionService {
|
||||||
|
@ -24,6 +26,7 @@ export class TransactionService {
|
||||||
@InjectRepository(COA)
|
@InjectRepository(COA)
|
||||||
private coaRepository: Repository<COA>,
|
private coaRepository: Repository<COA>,
|
||||||
private coaService: CoaService,
|
private coaService: CoaService,
|
||||||
|
private productService: ProductService,
|
||||||
private connection: Connection,
|
private connection: Connection,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -32,8 +35,6 @@ export class TransactionService {
|
||||||
const coaSender = await this.coaService.findByUser('id_user');
|
const coaSender = await this.coaService.findByUser('id_user');
|
||||||
const coaReciever = await this.coaService.findByUser('id_user');
|
const coaReciever = await this.coaService.findByUser('id_user');
|
||||||
|
|
||||||
// GET TYPE TRANSAKSI
|
|
||||||
|
|
||||||
await this.connection.transaction(async (manager) => {
|
await this.connection.transaction(async (manager) => {
|
||||||
//INSERT TRANSACTION
|
//INSERT TRANSACTION
|
||||||
const transactionSaved = await manager.insert(Transactions, {
|
const transactionSaved = await manager.insert(Transactions, {
|
||||||
|
@ -41,6 +42,7 @@ export class TransactionService {
|
||||||
user: 'id_user',
|
user: 'id_user',
|
||||||
userDestination: distributeTransactionDto.destination,
|
userDestination: distributeTransactionDto.destination,
|
||||||
status: statusTransaction.SUCCESS,
|
status: statusTransaction.SUCCESS,
|
||||||
|
type: typeTransaction.DISTRIBUTION,
|
||||||
});
|
});
|
||||||
|
|
||||||
//INSERT TRANSACTION JOURNAL FOR SENDER
|
//INSERT TRANSACTION JOURNAL FOR SENDER
|
||||||
|
@ -48,6 +50,7 @@ export class TransactionService {
|
||||||
amount: distributeTransactionDto.amount,
|
amount: distributeTransactionDto.amount,
|
||||||
transaction: transactionSaved.identifiers[0],
|
transaction: transactionSaved.identifiers[0],
|
||||||
coa: coaSender,
|
coa: coaSender,
|
||||||
|
type: balanceType.CREDIT,
|
||||||
});
|
});
|
||||||
|
|
||||||
//INSERT TRANSACTION JOURNAL FOR RECEIVER
|
//INSERT TRANSACTION JOURNAL FOR RECEIVER
|
||||||
|
@ -55,6 +58,7 @@ export class TransactionService {
|
||||||
amount: distributeTransactionDto.amount,
|
amount: distributeTransactionDto.amount,
|
||||||
transaction: transactionSaved.identifiers[0],
|
transaction: transactionSaved.identifiers[0],
|
||||||
coa: coaReciever,
|
coa: coaReciever,
|
||||||
|
type: balanceType.DEBIT,
|
||||||
});
|
});
|
||||||
|
|
||||||
//UPDATE AMOUNT COA SENDER
|
//UPDATE AMOUNT COA SENDER
|
||||||
|
@ -69,22 +73,65 @@ export class TransactionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async orderTransaction(orderTransactionDto: OrderTransactionDto) {
|
async orderTransaction(orderTransactionDto: OrderTransactionDto) {
|
||||||
// const product = await this.productService.findOne(
|
const coaAccount = await this.coaService.findByUser('id_user');
|
||||||
// orderTransactionDto.productCode,
|
|
||||||
// );
|
//GET PRODUCT
|
||||||
|
const product = await this.productService.findOne(
|
||||||
|
orderTransactionDto.productCode,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (coaAccount.amount <= product.price) {
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
error: `Transaction Failed because saldo not enough`,
|
||||||
|
},
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const orderIRS = await irsService.createTransaction(
|
||||||
|
orderTransactionDto.productCode,
|
||||||
|
orderTransactionDto.destination,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (orderIRS.success) {
|
||||||
|
await this.connection.transaction(async (manager) => {
|
||||||
|
//INSERT TRANSACTION
|
||||||
|
const transactionSaved = await manager.insert(Transactions, {
|
||||||
|
amount: product.price,
|
||||||
|
user: 'id_user',
|
||||||
|
status: statusTransaction.SUCCESS,
|
||||||
|
type: typeTransaction.ORDER,
|
||||||
|
});
|
||||||
|
|
||||||
|
//INSERT TRANSACTION JOURNAL
|
||||||
|
const journalSender = await manager.insert(TransactionJournal, {
|
||||||
|
amount: product.price,
|
||||||
|
transaction: transactionSaved.identifiers[0],
|
||||||
|
coa: coaAccount,
|
||||||
|
type: balanceType.CREDIT,
|
||||||
|
});
|
||||||
|
|
||||||
|
//UPDATE AMOUNT COA
|
||||||
|
coaAccount.amount = coaAccount.amount - product.price;
|
||||||
|
await manager.save(coaAccount);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new HttpException(
|
||||||
|
{
|
||||||
|
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
error: `Transaction Failed because ${orderIRS.msg}`,
|
||||||
|
},
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
findOne(id: number) {
|
|
||||||
return `This action returns a #${id} transaction`;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(id: number, updateTransactionDto: UpdateTransactionDto) {
|
|
||||||
return `This action updates a #${id} transaction`;
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(id: number) {
|
|
||||||
return `This action removes a #${id} transaction`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user