mirror of
https://github.com/Kevsl/crypto-exchange-api.git
synced 2025-07-09 14:00:12 +02:00
277 lines
6.5 KiB
TypeScript
277 lines
6.5 KiB
TypeScript
import { ForbiddenException, Injectable } from '@nestjs/common';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
import { checkUserHasAccount, checkuserIsAdmin } from 'src/utils/checkUser';
|
|
import { CryptoDto } from './dto';
|
|
import { BuyCryptoDto } from './dto/buy.crypto.dto';
|
|
@Injectable()
|
|
export class CryptoService {
|
|
constructor(private prisma: PrismaService) {}
|
|
|
|
async getCryptos(userId: string) {
|
|
await checkUserHasAccount(userId);
|
|
|
|
return this.prisma.crypto.findMany({
|
|
orderBy: {
|
|
name: 'asc',
|
|
},
|
|
});
|
|
}
|
|
async searchCryptos(userId: string, cryptoName: string) {
|
|
await checkUserHasAccount(userId);
|
|
|
|
return this.prisma.crypto.findMany({
|
|
where: {
|
|
name: {
|
|
contains: cryptoName,
|
|
mode: 'insensitive',
|
|
},
|
|
},
|
|
orderBy: {
|
|
name: 'asc',
|
|
},
|
|
});
|
|
}
|
|
|
|
async getCryptoHistory(userId: string, cryptoId: string) {
|
|
await checkUserHasAccount(userId);
|
|
|
|
if (cryptoId) {
|
|
return this.prisma.cryptoHistory.findMany({
|
|
where: {
|
|
id_crypto: cryptoId,
|
|
},
|
|
|
|
orderBy: {
|
|
created_at: 'desc',
|
|
},
|
|
take: 50,
|
|
});
|
|
} else {
|
|
throw new ForbiddenException('Crypto UUID required');
|
|
}
|
|
}
|
|
|
|
async sellCryto(userId: string, dto: BuyCryptoDto) {
|
|
await checkUserHasAccount(userId);
|
|
|
|
const crypto = await this.prisma.crypto.findFirst({
|
|
where: {
|
|
id: dto.id_crypto,
|
|
},
|
|
});
|
|
|
|
const user = await this.prisma.user.findFirst({
|
|
where: { id: userId },
|
|
});
|
|
|
|
if (!crypto || !crypto.id) {
|
|
throw new ForbiddenException('Crypto doesnt exist');
|
|
}
|
|
|
|
const userAsset = await this.prisma.userHasCrypto.findFirst({
|
|
where: {
|
|
id_user: userId,
|
|
id_crypto: dto.id_crypto,
|
|
},
|
|
});
|
|
const newCryptoValue = crypto.value * 0.9;
|
|
if (!userAsset || userAsset.amount < dto.amount) {
|
|
throw new ForbiddenException(`Seller dont have enough asset`);
|
|
} else {
|
|
await this.prisma.crypto.update({
|
|
where: {
|
|
id: crypto.id,
|
|
},
|
|
data: {
|
|
value: newCryptoValue,
|
|
},
|
|
});
|
|
|
|
const price = crypto.value * dto.amount;
|
|
const newBalanceSeller = user.dollarAvailables + price;
|
|
|
|
await this.prisma.user.update({
|
|
where: {
|
|
id: userId,
|
|
},
|
|
data: {
|
|
dollarAvailables: newBalanceSeller,
|
|
},
|
|
});
|
|
await this.prisma.cryptoHistory.create({
|
|
data: {
|
|
id_crypto: crypto.id,
|
|
value: newCryptoValue,
|
|
},
|
|
});
|
|
const newBalance = userAsset.amount - dto.amount;
|
|
await this.prisma.crypto.update({
|
|
where: {
|
|
id: dto.id_crypto,
|
|
},
|
|
data: {
|
|
quantity: crypto.quantity + dto.amount,
|
|
},
|
|
});
|
|
if (newBalance > 0) {
|
|
return this.prisma.userHasCrypto.update({
|
|
where: {
|
|
id: userAsset.id,
|
|
},
|
|
data: {
|
|
amount: newBalance,
|
|
},
|
|
});
|
|
} else {
|
|
return this.prisma.userHasCrypto.delete({
|
|
where: {
|
|
id: userAsset.id,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
async createCrypto(userId: string, dto: CryptoDto) {
|
|
await checkuserIsAdmin(userId);
|
|
|
|
const existingCryptosWithSameName = await this.prisma.crypto.findMany({
|
|
where: {
|
|
name: dto.name,
|
|
},
|
|
});
|
|
if (existingCryptosWithSameName.length > 0) {
|
|
throw new ForbiddenException('Name already taken');
|
|
}
|
|
const crypto = await this.prisma.crypto.create({
|
|
data: {
|
|
name: dto.name,
|
|
image: dto.image,
|
|
value: dto.value,
|
|
quantity: dto.quantity,
|
|
},
|
|
});
|
|
|
|
return crypto;
|
|
}
|
|
|
|
async buyCrypto(userId: string, dto: BuyCryptoDto) {
|
|
const crypto = await this.prisma.crypto.findFirst({
|
|
where: {
|
|
id: dto.id_crypto,
|
|
},
|
|
});
|
|
|
|
const user = await this.prisma.user.findFirst({
|
|
where: {
|
|
id: userId,
|
|
},
|
|
});
|
|
if (crypto.quantity < dto.amount) {
|
|
throw new ForbiddenException('No more tokens available');
|
|
}
|
|
const necessaryAmount = crypto.value * dto.amount;
|
|
console.log(necessaryAmount, user.dollarAvailables);
|
|
|
|
if (necessaryAmount > user.dollarAvailables) {
|
|
throw new ForbiddenException('Make money first :) ');
|
|
} else {
|
|
const userAsset = await this.prisma.userHasCrypto.findFirst({
|
|
where: {
|
|
id_crypto: dto.id_crypto,
|
|
id_user: userId,
|
|
},
|
|
});
|
|
const newBalance = user.dollarAvailables - necessaryAmount;
|
|
console.log(newBalance);
|
|
|
|
await this.prisma.user.update({
|
|
where: {
|
|
id: user.id,
|
|
},
|
|
data: {
|
|
dollarAvailables: newBalance,
|
|
},
|
|
});
|
|
if (userAsset) {
|
|
const newBalance = userAsset.amount + dto.amount;
|
|
await this.prisma.userHasCrypto.update({
|
|
where: {
|
|
id: userAsset.id,
|
|
},
|
|
data: {
|
|
amount: newBalance,
|
|
},
|
|
});
|
|
} else {
|
|
await this.prisma.userHasCrypto.create({
|
|
data: {
|
|
id_crypto: dto.id_crypto,
|
|
id_user: userId,
|
|
amount: dto.amount,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
const newCryptoValue = crypto.value * 1.1;
|
|
|
|
await this.prisma.cryptoHistory.create({
|
|
data: {
|
|
id_crypto: crypto.id,
|
|
value: newCryptoValue,
|
|
},
|
|
});
|
|
const newQuantity = (crypto.quantity -= dto.amount);
|
|
return this.prisma.crypto.update({
|
|
where: {
|
|
id: dto.id_crypto,
|
|
},
|
|
data: {
|
|
value: newCryptoValue,
|
|
quantity: newQuantity,
|
|
},
|
|
});
|
|
}
|
|
|
|
async editCryptoById(userId: string, cryptoId: string, dto: CryptoDto) {
|
|
await checkuserIsAdmin(userId);
|
|
|
|
const crypto = await this.prisma.crypto.findUnique({
|
|
where: {
|
|
id: cryptoId,
|
|
},
|
|
});
|
|
|
|
if (!crypto || crypto.id !== cryptoId)
|
|
throw new ForbiddenException('Access to resources denied');
|
|
|
|
return this.prisma.crypto.update({
|
|
where: {
|
|
id: crypto.id,
|
|
},
|
|
data: {
|
|
...dto,
|
|
},
|
|
});
|
|
}
|
|
|
|
async deleteCryptoById(userId: string, id: string) {
|
|
await checkuserIsAdmin(userId);
|
|
|
|
const crypto = await this.prisma.crypto.findUnique({
|
|
where: {
|
|
id: id,
|
|
},
|
|
});
|
|
|
|
if (!crypto || crypto.id !== id)
|
|
throw new ForbiddenException('Access to resources denied');
|
|
|
|
await this.prisma.crypto.delete({
|
|
where: {
|
|
id: crypto.id,
|
|
},
|
|
});
|
|
}
|
|
}
|