🚚 one file per credit transaction type
This commit is contained in:
parent
cf3f3449e8
commit
976e8e7fdc
13 changed files with 335 additions and 409 deletions
|
@ -5,7 +5,7 @@ import {
|
|||
|
||||
import deferReply from "../../../../handlers/deferReply";
|
||||
import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds";
|
||||
import { transfer as CreditsTransfer } from "../../../../helpers/credits";
|
||||
import creditsTransfer from "../../../../helpers/credits/transfer";
|
||||
|
||||
// 1. Export a builder function.
|
||||
export const builder = (command: SlashCommandSubcommandBuilder) => {
|
||||
|
@ -55,7 +55,7 @@ export const execute = async (interaction: ChatInputCommandInteraction) => {
|
|||
const EmbedSuccess = await BaseEmbedSuccess(guild, "[:dollar:] Gift");
|
||||
|
||||
// 5. Start an transaction of the credits.
|
||||
await CreditsTransfer(guild, user, target, credits);
|
||||
await creditsTransfer(guild, user, target, credits);
|
||||
|
||||
// 6. Tell the target that they have been gifted credits.
|
||||
await target.send({
|
||||
|
|
|
@ -6,7 +6,7 @@ import { command as CooldownCommand } from "../../../../handlers/cooldown";
|
|||
import prisma from "../../../../handlers/database";
|
||||
import deferReply from "../../../../handlers/deferReply";
|
||||
import { success as BaseEmbedSuccess } from "../../../../helpers/baseEmbeds";
|
||||
import { give as CreditsGive } from "../../../../helpers/credits";
|
||||
import creditsGive from "../../../../helpers/credits/give";
|
||||
import logger from "../../../../middlewares/logger";
|
||||
|
||||
// 1. Export a builder function.
|
||||
|
@ -52,7 +52,7 @@ export const execute = async (interaction: CommandInteraction) => {
|
|||
max: createGuild.creditsWorkRate,
|
||||
});
|
||||
|
||||
const upsertGuildMember = await CreditsGive(guild, user, creditsEarned);
|
||||
const upsertGuildMember = await creditsGive(guild, user, creditsEarned);
|
||||
|
||||
// 8. Send embed.
|
||||
await interaction.editReply({
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ChatInputCommandInteraction, PermissionsBitField } from "discord.js";
|
|||
import deferReply from "../../../../../../handlers/deferReply";
|
||||
import { success as baseEmbedSuccess } from "../../../../../../helpers/baseEmbeds";
|
||||
import checkPermission from "../../../../../../helpers/checkPermission";
|
||||
import { give as CreditsGive } from "../../../../../../helpers/credits";
|
||||
import creditsGive from "../../../../../../helpers/credits/give";
|
||||
import pluralize from "../../../../../../helpers/pluralize";
|
||||
|
||||
export default {
|
||||
|
@ -51,7 +51,7 @@ export default {
|
|||
const embedSuccess = await baseEmbedSuccess(guild, "[:toolbox:] Give");
|
||||
|
||||
// 6. Give the credits.
|
||||
await CreditsGive(guild, discordReceiver, creditsAmount);
|
||||
await creditsGive(guild, discordReceiver, creditsAmount);
|
||||
|
||||
// 7. Send embed.
|
||||
return await interaction.editReply({
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
// Dependencies
|
||||
// Helpers
|
||||
// Models
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import {
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
PermissionsBitField,
|
||||
SlashCommandSubcommandBuilder,
|
||||
} from "discord.js";
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedData";
|
||||
// Handlers
|
||||
import prisma from "../../../../../../handlers/database";
|
||||
import deferReply from "../../../../../../handlers/deferReply";
|
||||
import checkPermission from "../../../../../../helpers/checkPermission";
|
||||
import logger from "../../../../../../middlewares/logger";
|
||||
|
||||
// Function
|
||||
import deferReply from "../../../../../../handlers/deferReply";
|
||||
import { success as baseEmbedSuccess } from "../../../../../../helpers/baseEmbeds";
|
||||
import checkPermission from "../../../../../../helpers/checkPermission";
|
||||
import creditsSet from "../../../../../../helpers/credits/set";
|
||||
|
||||
export default {
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
|
@ -35,107 +28,35 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: ChatInputCommandInteraction) => {
|
||||
// 1. Defer reply as ephemeral.
|
||||
await deferReply(interaction, true);
|
||||
|
||||
// 2. Check if the user has the permission to manage the guild.
|
||||
checkPermission(interaction, PermissionsBitField.Flags.ManageGuild);
|
||||
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild);
|
||||
// 3. Destructure interaction object.
|
||||
const { options, guild } = interaction;
|
||||
if (!guild) throw new Error(`We could not find this guild.`);
|
||||
if (!options) throw new Error(`We could not find the options.`);
|
||||
|
||||
// 4. Get the user and amount from the options.
|
||||
const discordUser = options.getUser("user");
|
||||
const creditAmount = options.getInteger("amount");
|
||||
if (typeof creditAmount !== "number") throw new Error("Amount is not set.");
|
||||
if (!discordUser) throw new Error("User is not specified");
|
||||
|
||||
// If amount is null
|
||||
if (creditAmount === null) {
|
||||
logger?.silly(`Amount is null`);
|
||||
// 5. Set the credits.
|
||||
await creditsSet(guild, discordUser, creditAmount);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(`You must provide an amount.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
// 6. Create base embeds.
|
||||
const embedSuccess = await baseEmbedSuccess(guild, "[:toolbox:] Set");
|
||||
|
||||
if (discordUser === null) {
|
||||
logger?.silly(`User is null`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(`You must provide a user.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (guild === null) {
|
||||
logger?.silly(`Guild is null`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(`You must provide a guild.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const createGuildMember = await prisma.guildMember.upsert({
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: discordUser.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
update: { creditsEarned: creditAmount },
|
||||
create: {
|
||||
creditsEarned: creditAmount,
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: discordUser.id,
|
||||
},
|
||||
where: {
|
||||
id: discordUser.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
logger.silly(createGuildMember);
|
||||
|
||||
return interaction?.editReply({
|
||||
// 7. Send embed.
|
||||
return await interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Set)")
|
||||
.setDescription(
|
||||
`Set **${discordUser}**'s credits to **${creditAmount}**.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embedSuccess.setDescription(
|
||||
`Set **${discordUser}**'s credits to **${creditAmount}**.`
|
||||
),
|
||||
],
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
// Dependencies
|
||||
// Models
|
||||
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
|
||||
import {
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
PermissionsBitField,
|
||||
SlashCommandSubcommandBuilder,
|
||||
} from "discord.js";
|
||||
// Configurations
|
||||
import getEmbedConfig from "../../../../../../helpers/getEmbedData";
|
||||
// Helpers../../../../../../../helpers/userData
|
||||
import pluralize from "../../../../../../helpers/pluralize";
|
||||
// Handlers
|
||||
import prisma from "../../../../../../handlers/database";
|
||||
import deferReply from "../../../../../../handlers/deferReply";
|
||||
import checkPermission from "../../../../../../helpers/checkPermission";
|
||||
import logger from "../../../../../../middlewares/logger";
|
||||
|
||||
// Function
|
||||
import deferReply from "../../../../../../handlers/deferReply";
|
||||
import { success as baseEmbedSuccess } from "../../../../../../helpers/baseEmbeds";
|
||||
import checkPermission from "../../../../../../helpers/checkPermission";
|
||||
import creditsTake from "../../../../../../helpers/credits/take";
|
||||
import pluralize from "../../../../../../helpers/pluralize";
|
||||
|
||||
export default {
|
||||
builder: (command: SlashCommandSubcommandBuilder) => {
|
||||
return command
|
||||
|
@ -36,127 +29,36 @@ export default {
|
|||
);
|
||||
},
|
||||
execute: async (interaction: ChatInputCommandInteraction) => {
|
||||
// 1. Defer reply as ephemeral.
|
||||
await deferReply(interaction, true);
|
||||
|
||||
// 2. Check if the user has the MANAGE_GUILD permission.
|
||||
checkPermission(interaction, PermissionsBitField.Flags.ManageGuild);
|
||||
|
||||
const { errorColor, successColor, footerText, footerIcon } =
|
||||
await getEmbedConfig(interaction.guild); // Destructure
|
||||
// 3. Destructure interaction object.
|
||||
const { guild, options } = interaction;
|
||||
if (!guild) throw new Error("Invalid guild.");
|
||||
if (!options) throw new Error("Invalid options.");
|
||||
|
||||
// User option
|
||||
const discordReceiver = options?.getUser("user");
|
||||
// 4. Get the user and amount from the options.
|
||||
const discordReceiver = options.getUser("user");
|
||||
const optionAmount = options.getInteger("amount");
|
||||
if (typeof optionAmount !== "number") throw new Error("Invalid amount.");
|
||||
if (!discordReceiver) throw new Error("Invalid user.");
|
||||
|
||||
// Amount option
|
||||
const optionAmount = options?.getInteger("amount");
|
||||
// 5. Create base embeds.
|
||||
const embedSuccess = await baseEmbedSuccess(guild, "[:toolbox:] Take");
|
||||
|
||||
// If amount is null
|
||||
if (optionAmount === null) {
|
||||
logger?.silly(`Amount is null`);
|
||||
// 6. Take the credits.
|
||||
await creditsTake(guild, discordReceiver, optionAmount);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`You must provide an amount.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If amount is zero or below
|
||||
if (optionAmount <= 0) {
|
||||
logger?.silly(`Amount is zero or below`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`You must provide an amount greater than zero.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (discordReceiver === null) {
|
||||
logger?.silly(`Discord receiver is null`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`You must provide a user.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
if (guild === null) {
|
||||
logger?.silly(`Guild is null`);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(`You must be in a guild.`)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(errorColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
const createGuildMember = await prisma.guildMember.upsert({
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: discordReceiver.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
update: { creditsEarned: { decrement: optionAmount } },
|
||||
create: {
|
||||
creditsEarned: -optionAmount,
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: discordReceiver.id,
|
||||
},
|
||||
where: {
|
||||
id: discordReceiver.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
logger.silly(createGuildMember);
|
||||
await interaction?.editReply({
|
||||
// 7. Send embed.
|
||||
return await interaction.editReply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("[:toolbox:] Manage - Credits (Take)")
|
||||
.setDescription(
|
||||
`Took ${pluralize(optionAmount, "credit")} from ${discordReceiver}.`
|
||||
)
|
||||
.setTimestamp(new Date())
|
||||
.setColor(successColor)
|
||||
.setFooter({ text: footerText, iconURL: footerIcon }),
|
||||
embedSuccess.setDescription(
|
||||
`Took ${pluralize(optionAmount, "credit")} from ${discordReceiver}.`
|
||||
),
|
||||
],
|
||||
});
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
EmbedBuilder,
|
||||
PermissionsBitField,
|
||||
} from "discord.js";
|
||||
import { transfer as CreditsTransfer } from "../../../../../../helpers/credits";
|
||||
import creditsTransfer from "../../../../../../helpers/credits/transfer";
|
||||
// Configurations
|
||||
import deferReply from "../../../../../../handlers/deferReply";
|
||||
import checkPermission from "../../../../../../helpers/checkPermission";
|
||||
|
@ -65,7 +65,7 @@ export default {
|
|||
if (!optionToUser)
|
||||
throw new Error("You must provide a user to transfer to.");
|
||||
|
||||
await CreditsTransfer(guild, optionFromUser, optionToUser, optionAmount);
|
||||
await creditsTransfer(guild, optionFromUser, optionToUser, optionAmount);
|
||||
|
||||
return interaction?.editReply({
|
||||
embeds: [
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ChannelType, Message } from "discord.js";
|
||||
import { message as CooldownMessage } from "../../../../handlers/cooldown";
|
||||
import prisma from "../../../../handlers/database";
|
||||
import { give as CreditsGive } from "../../../../helpers/credits";
|
||||
import creditsGive from "../../../../helpers/credits/give";
|
||||
import logger from "../../../../middlewares/logger";
|
||||
|
||||
export default {
|
||||
|
@ -59,6 +59,6 @@ export default {
|
|||
);
|
||||
if (isOnCooldown) return;
|
||||
|
||||
await CreditsGive(guild, author, createGuildMember.guild.creditsRate);
|
||||
await creditsGive(guild, author, createGuildMember.guild.creditsRate);
|
||||
},
|
||||
};
|
||||
|
|
54
src/helpers/credits/give.ts
Normal file
54
src/helpers/credits/give.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
import prisma from "../../handlers/database";
|
||||
import transactionRules from "./transactionRules";
|
||||
|
||||
export default async (guild: Guild, user: User, amount: number) => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// 1. Check if the transaction is valid.
|
||||
await transactionRules(guild, user, amount);
|
||||
|
||||
// 2. Make the transaction.
|
||||
const recipient = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
increment: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: user.id,
|
||||
},
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 3. Verify that the recipient actually is created.
|
||||
if (!recipient) throw new Error("No recipient available");
|
||||
|
||||
// 4. Return the recipient.
|
||||
return recipient;
|
||||
});
|
||||
};
|
|
@ -1,173 +0,0 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
import prisma from "../../handlers/database";
|
||||
|
||||
// Start an transaction between two users in a guild.
|
||||
export const transfer = async (
|
||||
guild: Guild,
|
||||
from: User,
|
||||
to: User,
|
||||
amount: number
|
||||
) => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// 1. Decrement amount from the sender.
|
||||
const sender = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
decrement: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: from.id,
|
||||
},
|
||||
where: {
|
||||
id: from.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: -amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: from.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 2. Verify that the sender actually is created.
|
||||
if (!sender) throw new Error("No sender available");
|
||||
|
||||
// 3. Verify that the sender's balance exists.
|
||||
if (!sender.creditsEarned) throw new Error("No credits available");
|
||||
|
||||
// 4. Verify that the sender's balance didn't go below zero.
|
||||
if (sender.creditsEarned < 0) {
|
||||
throw new Error(`${from} doesn't have enough to send ${amount}`);
|
||||
}
|
||||
|
||||
// 5. Verify that the sender is not trying to send less that one credits.
|
||||
if (amount <= 0) {
|
||||
throw new Error("You can't transfer below one credit.");
|
||||
}
|
||||
|
||||
// 6. Verify that the sender is not trying to send more than 100.000.000 credits.
|
||||
if (amount > 100000000) {
|
||||
throw new Error("You can't transfer more than 100.000.000 credits.");
|
||||
}
|
||||
|
||||
// 7. Verify that recipient are not an bot.
|
||||
if (to.bot) throw new Error("You can't transfer to an bot.");
|
||||
|
||||
// 8. Verify that sender and recipient are not the same user.
|
||||
if (from.id === to.id) throw new Error("You can't transfer to yourself.");
|
||||
|
||||
// 9. Increment the recipient's balance by amount.
|
||||
const recipient = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
increment: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: to.id,
|
||||
},
|
||||
where: {
|
||||
id: to.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: to.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return recipient;
|
||||
});
|
||||
};
|
||||
|
||||
// Give to guildMember
|
||||
export const give = async (guild: Guild, user: User, amount: number) => {
|
||||
// 1. Verify that the amount is not above 100.000.000 credits.
|
||||
if (amount > 100000000) {
|
||||
throw new Error("You can't give more than 1.000.000 credits.");
|
||||
}
|
||||
|
||||
// 2. Verify that the amount is not below 1 credits.
|
||||
if (amount <= 0) {
|
||||
throw new Error("You can't give below one credit.");
|
||||
}
|
||||
|
||||
// 3. Verify that the user is not an bot.
|
||||
if (user.bot) {
|
||||
throw new Error("You can't give to an bot.");
|
||||
}
|
||||
|
||||
// 4. Increment the user's balance by amount.
|
||||
return await prisma.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
increment: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: user.id,
|
||||
},
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
52
src/helpers/credits/set.ts
Normal file
52
src/helpers/credits/set.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
import prisma from "../../handlers/database";
|
||||
import transactionRules from "./transactionRules";
|
||||
|
||||
export default async (guild: Guild, user: User, amount: number) => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// 1. Check if the transaction is valid.
|
||||
await transactionRules(guild, user, amount);
|
||||
|
||||
// 2. Make the transaction.
|
||||
const recipient = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: amount,
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: user.id,
|
||||
},
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 3. Verify that the recipient actually is created.
|
||||
if (!recipient) throw new Error("No recipient available");
|
||||
|
||||
// 4. Return the recipient.
|
||||
return recipient;
|
||||
});
|
||||
};
|
55
src/helpers/credits/take.ts
Normal file
55
src/helpers/credits/take.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
import prisma from "../../handlers/database";
|
||||
import transactionRules from "./transactionRules";
|
||||
|
||||
export default async (guild: Guild, user: User, amount: number) => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// 1. Check if the transaction is valid.
|
||||
await transactionRules(guild, user, amount);
|
||||
|
||||
// 2. Make the transaction.
|
||||
const recipient = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
decrement: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: user.id,
|
||||
},
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: -amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: user.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 3. Verify that the recipient credits are not below zero.
|
||||
if (recipient.creditsEarned < -100)
|
||||
throw new Error("User do not have enough credits");
|
||||
|
||||
// 4. Return the recipient.
|
||||
return recipient;
|
||||
});
|
||||
};
|
18
src/helpers/credits/transactionRules.ts
Normal file
18
src/helpers/credits/transactionRules.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
|
||||
export default async (guild: Guild, user: User, amount: number) => {
|
||||
// 1. Verify that the amount is not above 100.000.000 credits.
|
||||
if (amount > 100000000) {
|
||||
throw new Error("You can't give more than 1.000.000 credits.");
|
||||
}
|
||||
|
||||
// 2. Verify that the amount is not below 1 credits.
|
||||
if (amount <= 0) {
|
||||
throw new Error("You can't give below one credit.");
|
||||
}
|
||||
|
||||
// 3. Verify that the user is not an bot.
|
||||
if (user.bot) {
|
||||
throw new Error("You can't give to an bot.");
|
||||
}
|
||||
};
|
97
src/helpers/credits/transfer.ts
Normal file
97
src/helpers/credits/transfer.ts
Normal file
|
@ -0,0 +1,97 @@
|
|||
import { Guild, User } from "discord.js";
|
||||
import prisma from "../../handlers/database";
|
||||
import transactionRules from "./transactionRules";
|
||||
|
||||
export default async (guild: Guild, from: User, to: User, amount: number) => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// 1. Decrement amount from the sender.
|
||||
const sender = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
decrement: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: from.id,
|
||||
},
|
||||
where: {
|
||||
id: from.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: -amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: from.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 4. Verify that the sender's balance didn't go below zero.
|
||||
if (sender.creditsEarned < 0) {
|
||||
throw new Error(`${from} doesn't have enough to send ${amount}`);
|
||||
}
|
||||
|
||||
// 5. Check if the transactions is valid.
|
||||
await transactionRules(guild, from, amount);
|
||||
await transactionRules(guild, to, amount);
|
||||
|
||||
// 6. Verify that sender and recipient are not the same user.
|
||||
if (from.id === to.id) throw new Error("You can't transfer to yourself.");
|
||||
|
||||
// 7. Increment the recipient's balance by amount.
|
||||
const recipient = await tx.guildMember.upsert({
|
||||
update: {
|
||||
creditsEarned: {
|
||||
increment: amount,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
user: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: to.id,
|
||||
},
|
||||
where: {
|
||||
id: to.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
guild: {
|
||||
connectOrCreate: {
|
||||
create: {
|
||||
id: guild.id,
|
||||
},
|
||||
where: {
|
||||
id: guild.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
creditsEarned: amount,
|
||||
},
|
||||
where: {
|
||||
userId_guildId: {
|
||||
userId: to.id,
|
||||
guildId: guild.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return recipient;
|
||||
});
|
||||
};
|
Loading…
Add table
Reference in a new issue