use decimal.js

This commit is contained in:
2026-04-23 11:16:36 +03:30
parent f3ad487760
commit 8017484f54
6 changed files with 48 additions and 39 deletions
+7
View File
@@ -44,6 +44,7 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
"dayjs": "^1.11.19",
"decimal.js": "^10.6.0",
"fastify": "^5.6.1",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
@@ -8480,6 +8481,12 @@
}
}
},
"node_modules/decimal.js": {
"version": "10.6.0",
"resolved": "https://mirror-npm.runflare.com/decimal.js/-/decimal.js-10.6.0.tgz",
"integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"license": "MIT"
},
"node_modules/dedent": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz",
+1
View File
@@ -68,6 +68,7 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
"dayjs": "^1.11.19",
"decimal.js": "^10.6.0",
"fastify": "^5.6.1",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
@@ -52,7 +52,7 @@ export class Invoice extends BaseEntity {
type: 'int',
unique: true
})
invoiceNumber: number;
invoiceNumber!: number | Opt;
@Property({ type: 'int' })
+26 -26
View File
@@ -51,7 +51,7 @@ export class InvoiceService {
? new Date(dto.approvalDeadline)
: undefined;
const discount = dto.items.reduce((acc, item) => acc + (item.discount ?? 0), 0);
// const discount = dto.items.reduce((acc, item) => acc + (item.discount ?? 0), 0);
const invoice = await this.em.transactional(async (em) => {
const invoice = em.create(Invoice, {
@@ -59,12 +59,12 @@ export class InvoiceService {
...(request && { request }),
enableTax,
approvalDeadline,
discount,
// discount,
paidAmount: 0,
// balance: 0,
attachments: [],
paymentMethod: dto.paymentMethod,
invoiceNumber: 20,
invoiceNumber: 20, // TODO : invoice number
description: dto.description
});
em.persist(invoice);
@@ -75,7 +75,7 @@ export class InvoiceService {
const product = await this.productService.findOneOrFail(item.productId);
const unitPrice = item.unitPrice;
const itemDiscount = item.discount ?? 0;
const itemTotal = Math.max(0, unitPrice * item.quantity - itemDiscount);
// const itemTotal = Math.max(0, unitPrice * item.quantity - itemDiscount);
// subTotal += itemTotal;
const invoiceItem = em.create(InvoiceItem, {
@@ -114,7 +114,7 @@ export class InvoiceService {
await em.flush();
return invoice;
});
// TODO : maybe it is needed to get a fresh instance.
this.eventEmitter.emit(
InvoiceCreatedEvent.name,
new InvoiceCreatedEvent(
@@ -231,13 +231,13 @@ export class InvoiceService {
);
}
const product = await this.productService.findOneOrFail(item.productId);
const itemDiscount = item.discount ?? 0;
// const itemDiscount = item.discount ?? 0;
const invoiceItem = this.em.create(InvoiceItem, {
invoice,
product,
quantity: item.quantity,
unitPrice: item.unitPrice,
discount: itemDiscount || undefined,
// discount: itemDiscount || undefined,`
description: item.description,
});
invoice.items.add(invoiceItem);
@@ -245,25 +245,25 @@ export class InvoiceService {
}
const allItems = invoice.items.getItems();
let subTotal = 0;
let discount = 0;
for (const item of allItems) {
const itemTotal = Math.max(
0,
item.unitPrice * item.quantity - (item.discount ?? 0),
);
subTotal += itemTotal;
discount += item.discount ?? 0;
}
invoice.discount = discount;
const taxAmount = invoice.enableTax
? Math.round((subTotal - discount) * TAX_RATE)
: 0;
const total = Math.max(0, subTotal - discount + taxAmount);
invoice.subTotal = subTotal;
invoice.taxAmount = taxAmount;
invoice.total = total;
invoice.balance = total - invoice.paidAmount;
// let subTotal = 0;
// let discount = 0;
// for (const item of allItems) {
// const itemTotal = Math.max(
// 0,
// item.unitPrice * item.quantity - (item.discount ?? 0),
// );
// subTotal += itemTotal;
// discount += item.discount ?? 0;
// }
// invoice.discount = discount;
// const taxAmount = invoice.enableTax
// ? Math.round((subTotal - discount) * TAX_RATE)
// : 0;
// const total = Math.max(0, subTotal - discount + taxAmount);
// invoice.subTotal = subTotal;
// invoice.taxAmount = taxAmount;
// invoice.total = total;
// invoice.balance = total - invoice.paidAmount;
}
await this.em.flush();
return invoice;
@@ -7,7 +7,6 @@ import { OrderPaymentContext } from '../interface/payment';
import { PaymentMessage, OrderMessage } from 'src/common/enums/message.enum';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { onlinePaymentSucceedEvent, newCashPaymentEvent } from '../events/payment.events';
import { OrderService } from 'src/modules/order/providers/order.service';
import { PayOrderDto } from '../dto/pay-order.dto';
import { PaymentRepository } from '../repositories/payment.repository';
import { CreditRepository } from 'src/modules/user/repositories/credit.repository';
@@ -20,6 +19,7 @@ import { AdminRepository } from 'src/modules/admin/repositories/admin.repository
import { CreditTransaction } from 'src/modules/user/entities/credit-transaction.entity';
import { InvoiceService } from 'src/modules/invoice/invoice.service';
import { ConfigService } from '@nestjs/config';
import { Decimal } from 'decimal.js'
@@ -41,7 +41,7 @@ export class PaymentService {
private readonly adminRepository: AdminRepository,
private readonly invoiceService: InvoiceService,
private readonly configService: ConfigService,
) {
) {
this.frontUrl = this.configService.get<string>('FRONT_URL') || 'https://negareh-console.dev.danakcorp.com/'
}
@@ -84,11 +84,11 @@ export class PaymentService {
}
}
if (amount <= 0) {
if (new Decimal(amount).lte(0)) {
throw new BadRequestException(PaymentMessage.AMOUNT_MUST_BE_GREATER_THAN_ZERO);
}
if (amount > invoice.balance) {
if (new Decimal(amount).gte(invoice.balance)) {
throw new BadRequestException(`You cant pay more than ${invoice.balance}`);
}
@@ -125,13 +125,13 @@ export class PaymentService {
await this.em.transactional(async em => {
// 1. get User remained Credit
const remainedCredit = await this.creditService.getCurrentCredit(user.id)
const remainedCredit = new Decimal(await this.creditService.getCurrentCredit(user.id))
if (remainedCredit < amount) {
if (remainedCredit.lt(amount)) {
throw new BadRequestException("You Dont have enough Credit")
}
const newBalance = remainedCredit - amount;
const newBalance = remainedCredit.minus(amount)
// 2. Create payment record
const payment = em.create(Payment, {
creator: admin,
@@ -147,7 +147,7 @@ export class PaymentService {
user: invoice.user,
amount,
type: CreditTransactionType.WITHDRAW,
balance: newBalance,
balance: newBalance.toNumber(),
invoiceId: invoice.id,
});
+5 -4
View File
@@ -6,6 +6,7 @@ import { FindWalletTransactionsDto } from '../dto/find-wallet-transactions.dto';
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
import { CreditTransaction } from '../entities/credit-transaction.entity';
import { UserRepository } from '../repositories/user.repository';
import Decimal from 'decimal.js';
@Injectable()
@@ -24,7 +25,7 @@ export class CreditService {
throw new BadRequestException("User not found")
}
const maxCredit = user.maxCredit
const maxCredit = new Decimal(user.maxCredit)
const latestTransaction = await this.creditRepository.findOne(
{
@@ -32,11 +33,11 @@ export class CreditService {
},
{ orderBy: { createdAt: 'desc' } },
);
const balance = latestTransaction?.balance || 0
const balance = new Decimal(latestTransaction?.balance || 0)
const remained = maxCredit - balance
const remained = maxCredit.minus(balance)
return remained
return remained.toNumber()
}
// async getUserWalletTransactions(
// userId: string,