mirror of
https://github.com/Kevsl/crypto-exchange-api.git
synced 2025-07-09 06:00:12 +02:00
173 lines
3.8 KiB
TypeScript
173 lines
3.8 KiB
TypeScript
import { ForbiddenException, Injectable } from '@nestjs/common';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
import { checkUserHasAccount, checkuserIsAdmin } from 'src/utils/checkUser';
|
|
import { TradeDto } from './dto';
|
|
@Injectable()
|
|
export class TradeService {
|
|
constructor(private prisma: PrismaService) {}
|
|
|
|
async getTrades(userId: string) {
|
|
await checkuserIsAdmin(userId);
|
|
|
|
return this.prisma.trade.findMany({
|
|
orderBy: {
|
|
created_at: 'desc',
|
|
},
|
|
// include: {
|
|
// Giver: true,
|
|
// Receiver: true,
|
|
// Crypto: true,
|
|
// },
|
|
|
|
select: {
|
|
Giver: {
|
|
select: {
|
|
firstName: true,
|
|
lastName: true,
|
|
pseudo: true,
|
|
},
|
|
},
|
|
Receiver: {
|
|
select: {
|
|
firstName: true,
|
|
lastName: true,
|
|
pseudo: true,
|
|
dollarAvailables: true,
|
|
},
|
|
},
|
|
Crypto: true,
|
|
},
|
|
});
|
|
}
|
|
async getLastTrades() {
|
|
return this.prisma.trade.findMany({
|
|
orderBy: {
|
|
created_at: 'desc',
|
|
},
|
|
select: {
|
|
amount_traded: true,
|
|
Crypto: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
async createTrade(userId: string, dto: TradeDto) {
|
|
await checkUserHasAccount(userId);
|
|
|
|
const offer = await this.prisma.offer.findUnique({
|
|
where: {
|
|
id: dto.id_offer,
|
|
},
|
|
});
|
|
const crypto = await this.prisma.crypto.findFirst({
|
|
where: {
|
|
id: offer.id_crypto,
|
|
},
|
|
});
|
|
|
|
const buyer = await this.prisma.user.findFirst({
|
|
where: {
|
|
id: offer.id_user,
|
|
},
|
|
});
|
|
|
|
const price = crypto.value * offer.amount;
|
|
if (buyer.dollarAvailables < price) {
|
|
throw new ForbiddenException(
|
|
`Acqueror ${buyer.pseudo} doesnt have enough money to make this trade`,
|
|
);
|
|
}
|
|
|
|
const asset = await this.prisma.userHasCrypto.findFirst({
|
|
where: {
|
|
id_crypto: offer.id_crypto,
|
|
id_user: offer.id_user,
|
|
},
|
|
});
|
|
|
|
if (!asset || asset.amount < offer.amount) {
|
|
throw new ForbiddenException(`Seller doesnt have enough ${crypto.name} `);
|
|
}
|
|
|
|
const trade = await this.prisma.trade.create({
|
|
data: {
|
|
id_giver: offer.id_user,
|
|
id_receiver: userId,
|
|
id_crypto: offer.id_crypto,
|
|
amount_traded: offer.amount,
|
|
},
|
|
});
|
|
|
|
const newBalanceGiver = (asset.amount -= offer.amount);
|
|
await this.prisma.userHasCrypto.update({
|
|
where: {
|
|
id: asset.id,
|
|
},
|
|
data: {
|
|
amount: newBalanceGiver,
|
|
},
|
|
});
|
|
|
|
const receiverAssets = await this.prisma.userHasCrypto.findFirst({
|
|
where: {
|
|
id_user: userId,
|
|
id_crypto: offer.id_crypto,
|
|
},
|
|
});
|
|
if (!receiverAssets) {
|
|
await this.prisma.userHasCrypto.create({
|
|
data: {
|
|
id_user: userId,
|
|
id_crypto: offer.id_crypto,
|
|
amount: offer.amount,
|
|
createdAt: new Date(),
|
|
},
|
|
});
|
|
} else {
|
|
const newBalanceReceiver = receiverAssets.amount + offer.amount;
|
|
await this.prisma.userHasCrypto.update({
|
|
where: {
|
|
id: receiverAssets.id,
|
|
},
|
|
data: {
|
|
amount: newBalanceReceiver,
|
|
},
|
|
});
|
|
}
|
|
|
|
const newValue = crypto.value * 1.1;
|
|
await this.prisma.cryptoHistory.create({
|
|
data: {
|
|
id_crypto: crypto.id,
|
|
value: newValue,
|
|
},
|
|
});
|
|
|
|
await this.prisma.crypto.update({
|
|
where: {
|
|
id: crypto.id,
|
|
},
|
|
data: {
|
|
value: newValue,
|
|
},
|
|
});
|
|
|
|
const prevAmount = buyer.dollarAvailables;
|
|
|
|
await this.prisma.user.update({
|
|
where: {
|
|
id: userId,
|
|
},
|
|
data: {
|
|
dollarAvailables: prevAmount - price,
|
|
},
|
|
});
|
|
await this.prisma.offer.delete({
|
|
where: {
|
|
id: offer.id,
|
|
},
|
|
});
|
|
return trade;
|
|
}
|
|
}
|