add: callback transaction
This commit is contained in:
@@ -3,4 +3,7 @@ import { IsNotEmpty, IsUUID } from 'class-validator';
|
||||
export class OrderTransactionDto {
|
||||
@IsNotEmpty()
|
||||
productCode: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
phoneNumber: string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { Partner } from '../../users/entities/partner.entity';
|
||||
import { ProductHistoryPrice } from '../../product/entities/product-history-price.entity';
|
||||
import { User } from '../../users/entities/user.entity';
|
||||
import { UserDetail } from '../../users/entities/user_detail.entity';
|
||||
import { TransactionJournal } from './transaction-journal.entity';
|
||||
|
||||
@Entity()
|
||||
export class Transactions extends BaseModel {
|
||||
@@ -47,7 +48,19 @@ export class Transactions extends BaseModel {
|
||||
})
|
||||
image_prove: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
})
|
||||
supplier_trx_id: string;
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
})
|
||||
phone_number: string;
|
||||
|
||||
mark_up_price: number;
|
||||
|
||||
userData: UserDetail;
|
||||
|
||||
transactionJournal: TransactionJournal;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,20 @@ export class PpobCallbackController {
|
||||
constructor(private readonly transactionService: TransactionService) {}
|
||||
|
||||
@Get()
|
||||
get(@Req() request: FastifyRequest) {
|
||||
async get(@Req() request: FastifyRequest) {
|
||||
const response = request.query;
|
||||
|
||||
if (response['statuscode'] == 2) {
|
||||
//TODO: UPDATE GAGAL
|
||||
const updateTransaction =
|
||||
await this.transactionService.callbackOrderFailed(response['clientid']);
|
||||
} else {
|
||||
//TODO: UPDATE BERHASIL
|
||||
const updateTransaction =
|
||||
await this.transactionService.callbackOrderSuccess(
|
||||
response['clientid'],
|
||||
);
|
||||
}
|
||||
this.logger.log({
|
||||
requestQuery: request.query,
|
||||
});
|
||||
|
||||
@@ -83,6 +83,21 @@ export class TransactionController {
|
||||
};
|
||||
}
|
||||
|
||||
@Post('order-prod')
|
||||
async orderTransactionProd(
|
||||
@Body() orderTransactionDto: OrderTransactionDto,
|
||||
@Request() req,
|
||||
) {
|
||||
return {
|
||||
data: await this.transactionService.orderTransactionProd(
|
||||
orderTransactionDto,
|
||||
req.user,
|
||||
),
|
||||
statusCode: HttpStatus.CREATED,
|
||||
message: 'success',
|
||||
};
|
||||
}
|
||||
|
||||
@Post('deposit-return')
|
||||
async depositReturn(
|
||||
@Body() depositReturnDto: DepositReturnDto,
|
||||
@@ -159,6 +174,17 @@ export class TransactionController {
|
||||
};
|
||||
}
|
||||
|
||||
@Get('total-order')
|
||||
async findTotalOrder(@Request() req) {
|
||||
const data = await this.transactionService.getTotalSell();
|
||||
|
||||
return {
|
||||
data,
|
||||
statusCode: HttpStatus.OK,
|
||||
message: 'success',
|
||||
};
|
||||
}
|
||||
|
||||
@Get('deposit-return/confirmation')
|
||||
async findDepositReturnConfirmation(
|
||||
@Query('page') page: number,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
|
||||
import { DistributeTransactionDto } from './dto/distribute-transaction.dto';
|
||||
import { OrderTransactionDto } from './dto/order-transaction.dto';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
@@ -25,6 +25,8 @@ import { ProductHistoryPriceService } from '../product/history-price/history-pri
|
||||
import { CommissionService } from '../configurable/commission.service';
|
||||
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';
|
||||
|
||||
interface JournalEntry {
|
||||
coa_id: string;
|
||||
@@ -34,6 +36,8 @@ interface JournalEntry {
|
||||
|
||||
@Injectable()
|
||||
export class TransactionService {
|
||||
private readonly logger = new Logger(TransactionService.name);
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Transactions)
|
||||
private transactionRepository: Repository<Transactions>,
|
||||
@@ -371,11 +375,13 @@ export class TransactionService {
|
||||
const transactionData = new Transactions();
|
||||
|
||||
transactionData.id = uuid.v4();
|
||||
transactionData.amount = product_price.mark_up_price;
|
||||
transactionData.amount =
|
||||
product_price.mark_up_price + product_price.price;
|
||||
transactionData.user = userData.id;
|
||||
transactionData.status = statusTransaction.SUCCESS;
|
||||
transactionData.type = typeTransaction.ORDER;
|
||||
transactionData.product_price = product_price;
|
||||
transactionData.phone_number = orderTransactionDto.phoneNumber;
|
||||
await manager.insert(Transactions, transactionData);
|
||||
|
||||
await this.accountingTransaction({
|
||||
@@ -414,6 +420,82 @@ export class TransactionService {
|
||||
return true;
|
||||
}
|
||||
|
||||
async orderTransactionProd(
|
||||
orderTransactionDto: OrderTransactionDto,
|
||||
currentUser: any,
|
||||
) {
|
||||
//TODO GET USER DATA
|
||||
const userData = await this.userService.findByUsername(
|
||||
currentUser.username,
|
||||
);
|
||||
|
||||
//TODO GET PRODUCT AND PRICE
|
||||
const product = await this.productService.findOne(
|
||||
orderTransactionDto.productCode,
|
||||
);
|
||||
|
||||
const product_price = await this.productHistoryPriceService.findOne(
|
||||
product.id,
|
||||
userData.partner?.id,
|
||||
);
|
||||
|
||||
//TODO HIT API SUPPLIER
|
||||
const trxId = Array(6)
|
||||
.fill(null)
|
||||
.map(() => Math.round(Math.random() * 16).toString(16))
|
||||
.join('');
|
||||
|
||||
const hitSupplier = await doTransaction(
|
||||
orderTransactionDto.productCode,
|
||||
orderTransactionDto.phoneNumber,
|
||||
trxId,
|
||||
);
|
||||
|
||||
this.logger.log({
|
||||
responseAPISupplier: hitSupplier,
|
||||
});
|
||||
|
||||
//TODO TRANSACTION DAT
|
||||
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.phone_number = orderTransactionDto.phoneNumber;
|
||||
transactionData.supplier_trx_id = trxId;
|
||||
|
||||
if (!hitSupplier.success) {
|
||||
transactionData.status = statusTransaction.FAILED;
|
||||
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;
|
||||
await this.transactionRepository.insert(transactionData);
|
||||
}
|
||||
|
||||
if (hitSupplier.harga > product_price.price) {
|
||||
product_price.endDate = new Date();
|
||||
|
||||
let newProductPrice = new ProductHistoryPrice();
|
||||
newProductPrice = product_price;
|
||||
newProductPrice.id = uuid.v4();
|
||||
newProductPrice.price = hitSupplier.harga;
|
||||
|
||||
await this.productHistoryPriceService.create(product_price);
|
||||
await this.productHistoryPriceService.create(newProductPrice);
|
||||
}
|
||||
|
||||
return hitSupplier;
|
||||
}
|
||||
|
||||
async createDepositReturn(currentUser, depositReturnDto: DepositReturnDto) {
|
||||
const userData = await this.userService.findByUsername(
|
||||
currentUser.username,
|
||||
@@ -563,6 +645,115 @@ export class TransactionService {
|
||||
return transactionData;
|
||||
}
|
||||
|
||||
async callbackOrderFailed(supplier_trx_id: string) {
|
||||
const dataTransaction = await this.transactionRepository.findOne({
|
||||
where: {
|
||||
supplier_trx_id: supplier_trx_id,
|
||||
},
|
||||
});
|
||||
dataTransaction.status = statusTransaction.FAILED;
|
||||
|
||||
await this.transactionRepository.save(dataTransaction);
|
||||
}
|
||||
|
||||
async callbackOrderSuccess(supplier_trx_id: string) {
|
||||
const dataTransaction = await this.transactionRepository.findOne({
|
||||
where: {
|
||||
supplier_trx_id: supplier_trx_id,
|
||||
},
|
||||
});
|
||||
dataTransaction.status = statusTransaction.FAILED;
|
||||
|
||||
const userData = await this.userService.findExist(dataTransaction.user);
|
||||
|
||||
let supervisorData = [];
|
||||
|
||||
const product_price = await this.productHistoryPriceService.findById(
|
||||
dataTransaction.product_price.id,
|
||||
);
|
||||
|
||||
const product = await this.productService.findOneById(
|
||||
product_price.product.id,
|
||||
);
|
||||
|
||||
let profit = product_price.mark_up_price;
|
||||
|
||||
if (!userData.partner) {
|
||||
//GET SALES
|
||||
supervisorData = await this.calculateCommission(
|
||||
supervisorData,
|
||||
profit,
|
||||
userData,
|
||||
);
|
||||
profit = supervisorData
|
||||
.map((item) => {
|
||||
return item.credit;
|
||||
})
|
||||
.reduce((prev, curr) => {
|
||||
return prev + curr;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
//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`,
|
||||
);
|
||||
|
||||
const coaExpense = await this.coaService.findByName(
|
||||
`${coaType[coaType.EXPENSE]}-SYSTEM`,
|
||||
);
|
||||
|
||||
try {
|
||||
await this.connection.transaction(async (manager) => {
|
||||
await manager.save(dataTransaction);
|
||||
|
||||
await this.accountingTransaction({
|
||||
createTransaction: false,
|
||||
transactionalEntityManager: manager,
|
||||
transaction: dataTransaction,
|
||||
amount: dataTransaction.amount,
|
||||
journals: [
|
||||
{
|
||||
coa_id: coaInventory.id,
|
||||
credit: product_price.price,
|
||||
},
|
||||
{
|
||||
coa_id: coaCostOfSales.id,
|
||||
debit: product_price.price,
|
||||
},
|
||||
{
|
||||
coa_id: coaAccount.id,
|
||||
debit: product_price.mark_up_price + product_price.price,
|
||||
},
|
||||
{
|
||||
coa_id: coaSales.id,
|
||||
credit: product_price.mark_up_price + product_price.price,
|
||||
},
|
||||
{
|
||||
coa_id: coaExpense.id,
|
||||
debit: userData.partner ? 0 : profit,
|
||||
},
|
||||
].concat(supervisorData),
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async transactionHistoryByUser(
|
||||
page: number,
|
||||
user: string,
|
||||
@@ -763,6 +954,24 @@ export class TransactionService {
|
||||
}
|
||||
}
|
||||
|
||||
async getTotalSell() {
|
||||
const { total_amount } = await this.transactionRepository
|
||||
.createQueryBuilder('transactions')
|
||||
.select('SUM(transactions.amount) as total_amount')
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(total_amount);
|
||||
}
|
||||
|
||||
async getTotalProfit() {
|
||||
const { total_amount } = await this.transactionRepository
|
||||
.createQueryBuilder('transactions')
|
||||
.select('SUM(transactions.amount) as total_amount')
|
||||
.getRawOne();
|
||||
|
||||
return parseInt(total_amount);
|
||||
}
|
||||
|
||||
async calculateCommission(data, totalPrice, userData) {
|
||||
const supervisorData = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user