brief-07-back/src/trade/trade.service.ts
2024-06-09 01:02:27 +02:00

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;
}
}