diff --git a/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/emotes/Emotes.kt b/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/emotes/Emotes.kt index 9d1f72a312..bd1e211445 100644 --- a/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/emotes/Emotes.kt +++ b/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/emotes/Emotes.kt @@ -31,6 +31,7 @@ object Emotes { val loriAmeno = DiscordEmote(673868465433477126, "lori_ameno", false) val LoriStonks = DiscordEmote(788434890927505448L, "lori_stonks", false) val LoriBanHammer = DiscordEmote(741058240455901254L, "lori_ban_hammer", false) + val LoriKiss = DiscordEmote(950112551541289010L, "lori_kiss", false) val PantufaGaming = DiscordEmote(853048446922784819L, "pantufa_gaming", false) @@ -82,6 +83,8 @@ object Emotes { val Gift = UnicodeEmote("\uD83C\uDF81") val MoneyWithWings = UnicodeEmote("\uD83D\uDCB8") val DollarBill = UnicodeEmote("\uD83D\uDCB5") + val Rooster = UnicodeEmote("\uD83D\uDC13") + val Star = UnicodeEmote("⭐") val Discord = DiscordEmote(314003252830011395, "discord", false) val Undertale = DiscordEmote(412576128340066304L, "undertale_heart", false) diff --git a/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/DivineInterventionTransactionEntryAction.kt b/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/DivineInterventionTransactionEntryAction.kt new file mode 100644 index 0000000000..171592bd5f --- /dev/null +++ b/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/DivineInterventionTransactionEntryAction.kt @@ -0,0 +1,6 @@ +package net.perfectdreams.loritta.cinnamon.common.utils + +enum class DivineInterventionTransactionEntryAction { + ADDED_SONHOS, + REMOVED_SONHOS +} \ No newline at end of file diff --git a/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/TransactionType.kt b/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/TransactionType.kt index 9171ca7eca..41c9b46118 100644 --- a/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/TransactionType.kt +++ b/common/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/common/utils/TransactionType.kt @@ -10,11 +10,26 @@ enum class TransactionType( val description: StringI18nData, val emote: Emote ) { + PAYMENT( + I18nKeysData.Commands.Command.Transactions.Types.Payment.Title, + I18nKeysData.Commands.Command.Transactions.Types.Payment.Description, + Emotes.Star + ), + COINFLIP_BET( + I18nKeysData.Commands.Command.Transactions.Types.CoinFlipBet.Title, + I18nKeysData.Commands.Command.Transactions.Types.CoinFlipBet.Description, + Emotes.CoinHeads + ), COINFLIP_BET_GLOBAL( I18nKeysData.Commands.Command.Transactions.Types.CoinFlipBetGlobal.Title, I18nKeysData.Commands.Command.Transactions.Types.CoinFlipBetGlobal.Description, Emotes.CoinTails ), + EMOJI_FIGHT_BET( + I18nKeysData.Commands.Command.Transactions.Types.EmojiFightBet.Title, + I18nKeysData.Commands.Command.Transactions.Types.EmojiFightBet.Description, + Emotes.Rooster + ), HOME_BROKER( I18nKeysData.Commands.Command.Transactions.Types.HomeBroker.Title, I18nKeysData.Commands.Command.Transactions.Types.HomeBroker.Description, @@ -25,9 +40,19 @@ enum class TransactionType( I18nKeysData.Commands.Command.Transactions.Types.SparklyPowerLsx.Description, Emotes.PantufaGaming, ), + SONHOS_BUNDLE_PURCHASE( + I18nKeysData.Commands.Command.Transactions.Types.SonhosBundlePurchase.Title, + I18nKeysData.Commands.Command.Transactions.Types.SonhosBundlePurchase.Description, + Emotes.LoriRich, + ), INACTIVE_DAILY_TAX( I18nKeysData.Commands.Command.Transactions.Types.InactiveDailyTax.Title, I18nKeysData.Commands.Command.Transactions.Types.InactiveDailyTax.Description, Emotes.LoriSob, + ), + DIVINE_INTERVENTION( + I18nKeysData.Commands.Command.Transactions.Types.DivineIntervention.Title, + I18nKeysData.Commands.Command.Transactions.Types.DivineIntervention.Description, + Emotes.Jesus, ) } \ No newline at end of file diff --git a/discord/commands/src/jvmMain/kotlin/net/perfectdreams/loritta/cinnamon/platform/commands/economy/TransactionsExecutor.kt b/discord/commands/src/jvmMain/kotlin/net/perfectdreams/loritta/cinnamon/platform/commands/economy/TransactionsExecutor.kt index 1531400e6b..e4309fb947 100644 --- a/discord/commands/src/jvmMain/kotlin/net/perfectdreams/loritta/cinnamon/platform/commands/economy/TransactionsExecutor.kt +++ b/discord/commands/src/jvmMain/kotlin/net/perfectdreams/loritta/cinnamon/platform/commands/economy/TransactionsExecutor.kt @@ -8,6 +8,7 @@ import net.perfectdreams.discordinteraktions.common.builder.message.embed import net.perfectdreams.discordinteraktions.common.utils.footer import net.perfectdreams.i18nhelper.core.I18nContext import net.perfectdreams.loritta.cinnamon.common.emotes.Emotes +import net.perfectdreams.loritta.cinnamon.common.utils.DivineInterventionTransactionEntryAction import net.perfectdreams.loritta.cinnamon.common.utils.LorittaBovespaBrokerUtils.BrokerSonhosTransactionsEntryAction.BOUGHT_SHARES import net.perfectdreams.loritta.cinnamon.common.utils.LorittaBovespaBrokerUtils.BrokerSonhosTransactionsEntryAction.SOLD_SHARES import net.perfectdreams.loritta.cinnamon.common.utils.LorittaColors @@ -28,7 +29,12 @@ import net.perfectdreams.loritta.cinnamon.platform.utils.toKordColor import net.perfectdreams.loritta.cinnamon.pudding.data.BrokerSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.CachedUserInfo import net.perfectdreams.loritta.cinnamon.pudding.data.CoinFlipBetGlobalSonhosTransaction +import net.perfectdreams.loritta.cinnamon.pudding.data.CoinFlipBetSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.DailyTaxSonhosTransaction +import net.perfectdreams.loritta.cinnamon.pudding.data.DivineInterventionSonhosTransaction +import net.perfectdreams.loritta.cinnamon.pudding.data.EmojiFightBetSonhosTransaction +import net.perfectdreams.loritta.cinnamon.pudding.data.PaymentSonhosTransaction +import net.perfectdreams.loritta.cinnamon.pudding.data.SonhosBundlePurchaseSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.SonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.SparklyPowerLSXSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.UnknownSonhosTransaction @@ -70,9 +76,7 @@ class TransactionsExecutor : SlashCommandExecutor() { val isSelf = data.viewingTransactionsOfUserId.value == data.userId.value - val cachedUserInfo = if (!isSelf) - loritta.getCachedUserInfo(data.viewingTransactionsOfUserId) - else null + val cachedUserInfo = loritta.getCachedUserInfo(data.viewingTransactionsOfUserId) ?: error("Missing cached user info!") content = i18nContext.get(TransactionsCommand.I18N_PREFIX.NotAllTransactionsAreHere) @@ -98,7 +102,7 @@ class TransactionsExecutor : SlashCommandExecutor() { transactions, totalTransactions ) - } else if (totalPages == 0L) { + } else { // ===[ NO MATCHING TRANSACTIONS VIEW ]=== apply( createNoMatchingTransactionsEmbed( @@ -205,17 +209,19 @@ class TransactionsExecutor : SlashCommandExecutor() { i18nContext: I18nContext, data: TransactionListData, isSelf: Boolean, - cachedUserInfo: CachedUserInfo?, + cachedUserInfo: CachedUserInfo, transactions: List, totalTransactions: Long ) { // ===[ NORMAL TRANSACTION VIEW ]=== - val cachedUserInfos = mutableMapOf() + val cachedUserInfos = mutableMapOf( + cachedUserInfo.id to cachedUserInfo + ) title = buildString { if (isSelf) append(i18nContext.get(TransactionsCommand.I18N_PREFIX.YourTransactions)) - else append(i18nContext.get(TransactionsCommand.I18N_PREFIX.UserTransactions("${cachedUserInfo?.name}#${cachedUserInfo?.discriminator}"))) + else append(i18nContext.get(TransactionsCommand.I18N_PREFIX.UserTransactions("${cachedUserInfo.name.replace("`", "")}#${cachedUserInfo?.discriminator}"))) append(" — ") @@ -229,6 +235,30 @@ class TransactionsExecutor : SlashCommandExecutor() { append("[ | ]") append(" ") when (transaction) { + // ===[ PAYMENTS ]=== + is PaymentSonhosTransaction -> { + val receivedTheSonhos = transaction.user == transaction.receivedBy + val receiverUserInfo = cachedUserInfos.getOrPut(transaction.receivedBy) { loritta.getCachedUserInfo(transaction.receivedBy) } + val giverUserInfo = cachedUserInfos.getOrPut(transaction.givenBy) { loritta.getCachedUserInfo(transaction.givenBy) } + + if (receivedTheSonhos) { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.Payment.Received(transaction.sonhos, "${giverUserInfo?.name?.replace("`", "")}#${giverUserInfo?.discriminator}", transaction.givenBy.value) + ) + ) + } else { + appendMoneyLostEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.Payment.Sent(transaction.sonhos, "${receiverUserInfo?.name?.replace("`", "")}#${receiverUserInfo?.discriminator}", transaction.receivedBy.value) + ) + ) + } + } + + // ===[ BROKER ]=== is BrokerSonhosTransaction -> { when (transaction.action) { BOUGHT_SHARES -> { @@ -257,6 +287,68 @@ class TransactionsExecutor : SlashCommandExecutor() { } } } + + // ===[ COIN FLIP BET ]=== + is CoinFlipBetSonhosTransaction -> { + val wonTheBet = transaction.user == transaction.winner + val winnerUserInfo = cachedUserInfos.getOrPut(transaction.winner) { loritta.getCachedUserInfo(transaction.winner) } + val loserUserInfo = cachedUserInfos.getOrPut(transaction.loser) { loritta.getCachedUserInfo(transaction.loser) } + + if (transaction.tax != null && transaction.taxPercentage != null) { + // Taxed earning + if (wonTheBet) { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.CoinFlipBet.WonTaxed( + quantity = transaction.quantity, + quantityAfterTax = transaction.quantityAfterTax, + loserTag = "${loserUserInfo?.name?.replace("`", "")}#${loserUserInfo?.discriminator}", + loserId = transaction.loser.value + ) + ) + ) + } else { + appendMoneyLostEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.CoinFlipBet.LostTaxed( + quantity = transaction.quantity, + quantityAfterTax = transaction.quantityAfterTax, + winnerTag = "${winnerUserInfo?.name?.replace("`", "")}#${winnerUserInfo?.discriminator}", + winnerId = transaction.winner.value + ) + ) + ) + } + } else { + if (wonTheBet) { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.CoinFlipBet.Won( + quantityAfterTax = transaction.quantity, + loserTag = "${loserUserInfo?.name?.replace("`", "")}#${loserUserInfo?.discriminator}", + loserId = transaction.loser.value + ) + ) + ) + } else { + appendMoneyLostEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.CoinFlipBet.Lost( + quantity = transaction.quantity, + winnerTag = "${winnerUserInfo?.name?.replace("`", "")}#${winnerUserInfo?.discriminator}", + winnerId = transaction.winner.value + ) + ) + ) + } + } + } + + // ===[ COIN FLIP BET GLOBAL ]=== is CoinFlipBetGlobalSonhosTransaction -> { val wonTheBet = transaction.user == transaction.winner val winnerUserInfo = cachedUserInfos.getOrPut(transaction.winner) { loritta.getCachedUserInfo(transaction.winner) } @@ -271,7 +363,7 @@ class TransactionsExecutor : SlashCommandExecutor() { TransactionsCommand.I18N_PREFIX.Types.CoinFlipBetGlobal.WonTaxed( quantity = transaction.quantity, quantityAfterTax = transaction.quantityAfterTax, - loserTag = "${loserUserInfo?.name}#${loserUserInfo?.discriminator}", + loserTag = "${loserUserInfo?.name?.replace("`", "")}#${loserUserInfo?.discriminator}", loserId = transaction.loser.value ) ) @@ -283,7 +375,7 @@ class TransactionsExecutor : SlashCommandExecutor() { TransactionsCommand.I18N_PREFIX.Types.CoinFlipBetGlobal.LostTaxed( quantity = transaction.quantity, quantityAfterTax = transaction.quantityAfterTax, - winnerTag = "${winnerUserInfo?.name}#${winnerUserInfo?.discriminator}", + winnerTag = "${winnerUserInfo?.name?.replace("`", "")}#${winnerUserInfo?.discriminator}", winnerId = transaction.winner.value ) ) @@ -296,7 +388,7 @@ class TransactionsExecutor : SlashCommandExecutor() { i18nContext.get( TransactionsCommand.I18N_PREFIX.Types.CoinFlipBetGlobal.Won( quantityAfterTax = transaction.quantity, - loserTag = "${loserUserInfo?.name}#${loserUserInfo?.discriminator}", + loserTag = "${loserUserInfo?.name?.replace("`", "")}#${loserUserInfo?.discriminator}", loserId = transaction.loser.value ) ) @@ -307,7 +399,7 @@ class TransactionsExecutor : SlashCommandExecutor() { i18nContext.get( TransactionsCommand.I18N_PREFIX.Types.CoinFlipBetGlobal.Lost( quantity = transaction.quantity, - winnerTag = "${winnerUserInfo?.name}#${winnerUserInfo?.discriminator}", + winnerTag = "${winnerUserInfo?.name?.replace("`", "")}#${winnerUserInfo?.discriminator}", winnerId = transaction.winner.value ) ) @@ -315,6 +407,73 @@ class TransactionsExecutor : SlashCommandExecutor() { } } } + + // ===[ EMOJI FIGHT BET ]=== + is EmojiFightBetSonhosTransaction -> { + val wonTheBet = transaction.user == transaction.winner + val winnerUserInfo = cachedUserInfos.getOrPut(transaction.winner) { loritta.getCachedUserInfo(transaction.winner) } + // We don't store the loser because there may be multiple losers, so we only check that if the user isn't the "winner", then they are the loser + val loserUserInfo = cachedUserInfo.id + + val userCountExcludingTheWinner = transaction.usersInMatch - 1 + + if (transaction.tax != null && transaction.taxPercentage != null) { + // Taxed earning + if (wonTheBet) { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.EmojiFightBet.WonTaxed( + quantity = transaction.entryPrice * userCountExcludingTheWinner, + quantityAfterTax = transaction.entryPriceAfterTax * userCountExcludingTheWinner, + userInEmojiFight = userCountExcludingTheWinner, + emojiFightEmoji = transaction.emoji + ) + ) + ) + } else { + appendMoneyLostEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.EmojiFightBet.LostTaxed( + quantity = transaction.entryPrice * userCountExcludingTheWinner, + quantityAfterTax = transaction.entryPriceAfterTax * userCountExcludingTheWinner, + winnerTag = "${winnerUserInfo?.name?.replace("`", "")}#${winnerUserInfo?.discriminator}", + winnerId = transaction.winner.value, + emojiFightEmoji = transaction.emoji + ) + ) + ) + } + } else { + if (wonTheBet) { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.EmojiFightBet.Won( + quantityAfterTax = transaction.entryPriceAfterTax * userCountExcludingTheWinner, + userInEmojiFight = userCountExcludingTheWinner, + emojiFightEmoji = transaction.emoji + ) + ) + ) + } else { + appendMoneyLostEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.EmojiFightBet.Lost( + quantity = transaction.entryPrice * userCountExcludingTheWinner, + winnerTag = "${winnerUserInfo?.name?.replace("`", "")}#${winnerUserInfo?.discriminator}", + winnerId = transaction.winner.value, + emojiFightEmoji = transaction.emoji + ) + ) + ) + } + } + } + + // ===[ SPARKLYPOWER LSX ]=== is SparklyPowerLSXSonhosTransaction -> { when (transaction.action) { SparklyPowerLSXTransactionEntryAction.EXCHANGED_TO_SPARKLYPOWER -> { @@ -346,6 +505,20 @@ class TransactionsExecutor : SlashCommandExecutor() { } } + // ===[ SONHOS BUNDLES ]=== + is SonhosBundlePurchaseSonhosTransaction -> { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.SonhosBundlePurchase.PurchasedSonhos( + transaction.sonhos, + Emotes.LoriKiss + ) + ) + ) + } + + // ===[ DAILY TAX ]=== is DailyTaxSonhosTransaction -> { appendMoneyLostEmoji() append( @@ -359,9 +532,31 @@ class TransactionsExecutor : SlashCommandExecutor() { ) } + // ===[ DIVINE INTERVENTION ]=== + is DivineInterventionSonhosTransaction -> { + when (transaction.action) { + DivineInterventionTransactionEntryAction.ADDED_SONHOS -> { + appendMoneyEarnedEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.DivineIntervention.Received(transaction.sonhos) + ) + ) + } + DivineInterventionTransactionEntryAction.REMOVED_SONHOS -> { + appendMoneyLostEmoji() + append( + i18nContext.get( + TransactionsCommand.I18N_PREFIX.Types.DivineIntervention.Lost(transaction.sonhos) + ) + ) + } + } + } + // This should never happen because we do a left join with a "isNotNull" check is UnknownSonhosTransaction -> { - append("${Emotes.LoriShrug} Transação Desconhecida (Bug?)") + append("${Emotes.LoriShrug} Unknown Transaction (Bug?)") } } append("\n") @@ -380,7 +575,7 @@ class TransactionsExecutor : SlashCommandExecutor() { title = buildString { if (isSelf) append(i18nContext.get(TransactionsCommand.I18N_PREFIX.YourTransactions)) - else append(i18nContext.get(TransactionsCommand.I18N_PREFIX.UserTransactions("${cachedUserInfo?.name}#${cachedUserInfo?.discriminator}"))) + else append(i18nContext.get(TransactionsCommand.I18N_PREFIX.UserTransactions("${cachedUserInfo?.name?.replace("`", "")}#${cachedUserInfo?.discriminator}"))) } color = LorittaColors.LorittaRed.toKordColor() diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/Pudding.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/Pudding.kt index 5e7486fdc9..0cd84468e7 100644 --- a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/Pudding.kt +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/Pudding.kt @@ -9,6 +9,7 @@ import net.perfectdreams.loritta.cinnamon.common.achievements.AchievementType import net.perfectdreams.loritta.cinnamon.common.commands.ApplicationCommandType import net.perfectdreams.loritta.cinnamon.common.components.ComponentType import net.perfectdreams.loritta.cinnamon.common.utils.DailyTaxPendingDirectMessageState +import net.perfectdreams.loritta.cinnamon.common.utils.DivineInterventionTransactionEntryAction import net.perfectdreams.loritta.cinnamon.common.utils.LorittaBovespaBrokerUtils import net.perfectdreams.loritta.cinnamon.common.utils.SparklyPowerLSXTransactionEntryAction import net.perfectdreams.loritta.cinnamon.pudding.services.BackgroundsService @@ -35,15 +36,24 @@ import net.perfectdreams.loritta.cinnamon.pudding.tables.CachedDiscordUsersDirec import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalMatchmakingQueue import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalMatchmakingResults import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetMatchmakingResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Dailies import net.perfectdreams.loritta.cinnamon.pudding.tables.DailyTaxPendingDirectMessages import net.perfectdreams.loritta.cinnamon.pudding.tables.DailyTaxSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.DailyTaxUsersToSkipDirectMessages +import net.perfectdreams.loritta.cinnamon.pudding.tables.DivineInterventionSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightMatches +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightMatchmakingResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightParticipants +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.ExecutedApplicationCommandsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.ExecutedComponentsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.GuildCountStats import net.perfectdreams.loritta.cinnamon.pudding.tables.InteractionsData import net.perfectdreams.loritta.cinnamon.pudding.tables.Marriages +import net.perfectdreams.loritta.cinnamon.pudding.tables.PaymentSonhosTransactionResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.PaymentSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Payments import net.perfectdreams.loritta.cinnamon.pudding.tables.ProfileDesignGroups import net.perfectdreams.loritta.cinnamon.pudding.tables.ProfileDesigns @@ -51,6 +61,8 @@ import net.perfectdreams.loritta.cinnamon.pudding.tables.Profiles import net.perfectdreams.loritta.cinnamon.pudding.tables.ServerConfigs import net.perfectdreams.loritta.cinnamon.pudding.tables.Sets import net.perfectdreams.loritta.cinnamon.pudding.tables.ShipEffects +import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosBundlePurchaseSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosBundles import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.SparklyPowerLSXSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.TickerPrices @@ -228,7 +240,18 @@ class Pudding(val hikariDataSource: HikariDataSource, private val database: Data CachedDiscordUsersDirectMessageChannels, DailyTaxPendingDirectMessages, DailyTaxSonhosTransactionsLog, - DailyTaxUsersToSkipDirectMessages + DailyTaxUsersToSkipDirectMessages, + CoinFlipBetMatchmakingResults, + CoinFlipBetSonhosTransactionsLog, + EmojiFightMatches, + EmojiFightParticipants, + EmojiFightMatchmakingResults, + EmojiFightSonhosTransactionsLog, + DivineInterventionSonhosTransactionsLog, + PaymentSonhosTransactionResults, + PaymentSonhosTransactionsLog, + SonhosBundles, + SonhosBundlePurchaseSonhosTransactionsLog ) if (schemas.isNotEmpty()) @@ -239,6 +262,7 @@ class Pudding(val hikariDataSource: HikariDataSource, private val database: Data createOrUpdatePostgreSQLEnum(LorittaBovespaBrokerUtils.BrokerSonhosTransactionsEntryAction.values()) createOrUpdatePostgreSQLEnum(SparklyPowerLSXTransactionEntryAction.values()) createOrUpdatePostgreSQLEnum(DailyTaxPendingDirectMessageState.values()) + createOrUpdatePostgreSQLEnum(DivineInterventionTransactionEntryAction.values()) logger.info { "Tables to be created or updated: $schemas" } SchemaUtils.createMissingTablesAndColumns( diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/Service.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/Service.kt index 2490447c15..71f4e8efa5 100644 --- a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/Service.kt +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/Service.kt @@ -10,15 +10,19 @@ import net.perfectdreams.loritta.cinnamon.pudding.data.Background import net.perfectdreams.loritta.cinnamon.pudding.data.BackgroundVariation import net.perfectdreams.loritta.cinnamon.pudding.data.BrokerSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.CoinFlipBetGlobalSonhosTransaction +import net.perfectdreams.loritta.cinnamon.pudding.data.CoinFlipBetSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.Daily import net.perfectdreams.loritta.cinnamon.pudding.data.DailyTaxSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.DefaultBackgroundVariation +import net.perfectdreams.loritta.cinnamon.pudding.data.DivineInterventionSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.Marriage +import net.perfectdreams.loritta.cinnamon.pudding.data.PaymentSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.ProfileDesignGroupBackgroundVariation import net.perfectdreams.loritta.cinnamon.pudding.data.ProfileSettings import net.perfectdreams.loritta.cinnamon.pudding.data.Rectangle import net.perfectdreams.loritta.cinnamon.pudding.data.ServerConfigRoot import net.perfectdreams.loritta.cinnamon.pudding.data.ShipEffect +import net.perfectdreams.loritta.cinnamon.pudding.data.SonhosBundlePurchaseSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.SonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.SparklyPowerLSXSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.UnknownSonhosTransaction @@ -36,12 +40,19 @@ import net.perfectdreams.loritta.cinnamon.pudding.tables.Backgrounds import net.perfectdreams.loritta.cinnamon.pudding.tables.BrokerSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalMatchmakingResults import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetMatchmakingResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Dailies import net.perfectdreams.loritta.cinnamon.pudding.tables.DailyTaxSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.DivineInterventionSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Marriages +import net.perfectdreams.loritta.cinnamon.pudding.tables.PaymentSonhosTransactionResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.PaymentSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Profiles import net.perfectdreams.loritta.cinnamon.pudding.tables.ServerConfigs import net.perfectdreams.loritta.cinnamon.pudding.tables.ShipEffects +import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosBundlePurchaseSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosBundles import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.SparklyPowerLSXSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.UserAchievements @@ -154,7 +165,16 @@ fun BackgroundVariation.Companion.fromRow(row: ResultRow): BackgroundVariation { fun SonhosTransaction.Companion.fromRow(row: ResultRow): SonhosTransaction { // "hasValue" does not work, because it only checks if the value is present on the table BUT it is always present! (but it is null) - return if (row.getOrNull(BrokerSonhosTransactionsLog.id) != null) { + return if (row.getOrNull(PaymentSonhosTransactionsLog.id) != null) { + PaymentSonhosTransaction( + row[SonhosTransactionsLog.id].value, + row[SonhosTransactionsLog.timestamp].toKotlinInstant(), + UserId(row[SonhosTransactionsLog.user].value), + UserId(row[PaymentSonhosTransactionResults.givenBy].value), + UserId(row[PaymentSonhosTransactionResults.receivedBy].value), + row[PaymentSonhosTransactionResults.sonhos], + ) + } else if (row.getOrNull(BrokerSonhosTransactionsLog.id) != null) { BrokerSonhosTransaction( row[SonhosTransactionsLog.id].value, row[SonhosTransactionsLog.timestamp].toKotlinInstant(), @@ -178,6 +198,18 @@ fun SonhosTransaction.Companion.fromRow(row: ResultRow): SonhosTransaction { row[CoinFlipBetGlobalMatchmakingResults.taxPercentage], row[CoinFlipBetGlobalMatchmakingResults.timeOnQueue].toMillis(), ) + } else if (row.getOrNull(CoinFlipBetSonhosTransactionsLog.id) != null) { + CoinFlipBetSonhosTransaction( + row[SonhosTransactionsLog.id].value, + row[SonhosTransactionsLog.timestamp].toKotlinInstant(), + UserId(row[SonhosTransactionsLog.user].value), + UserId(row[CoinFlipBetMatchmakingResults.winner].value), + UserId(row[CoinFlipBetMatchmakingResults.loser].value), + row[CoinFlipBetMatchmakingResults.quantity], + row[CoinFlipBetMatchmakingResults.quantityAfterTax], + row[CoinFlipBetMatchmakingResults.tax], + row[CoinFlipBetMatchmakingResults.taxPercentage] + ) } else if (row.getOrNull(SparklyPowerLSXSonhosTransactionsLog.id) != null) { SparklyPowerLSXSonhosTransaction( row[SonhosTransactionsLog.id].value, @@ -199,6 +231,23 @@ fun SonhosTransaction.Companion.fromRow(row: ResultRow): SonhosTransaction { row[DailyTaxSonhosTransactionsLog.maxDayThreshold], row[DailyTaxSonhosTransactionsLog.minimumSonhosForTrigger] ) + } else if (row.getOrNull(SonhosBundlePurchaseSonhosTransactionsLog.id) != null) { + SonhosBundlePurchaseSonhosTransaction( + row[SonhosTransactionsLog.id].value, + row[SonhosTransactionsLog.timestamp].toKotlinInstant(), + UserId(row[SonhosTransactionsLog.user].value), + row[SonhosBundles.sonhos] + ) + } else if (row.getOrNull(DivineInterventionSonhosTransactionsLog.id) != null) { + DivineInterventionSonhosTransaction( + row[SonhosTransactionsLog.id].value, + row[SonhosTransactionsLog.timestamp].toKotlinInstant(), + UserId(row[SonhosTransactionsLog.user].value), + row[DivineInterventionSonhosTransactionsLog.action], + row[DivineInterventionSonhosTransactionsLog.givenBy]?.let { UserId(it.value) }, + row[DivineInterventionSonhosTransactionsLog.sonhos], + row[DivineInterventionSonhosTransactionsLog.reason] + ) } else { UnknownSonhosTransaction( row[SonhosTransactionsLog.id].value, diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/SonhosService.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/SonhosService.kt index 9d06afef85..70d067ae67 100644 --- a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/SonhosService.kt +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/services/SonhosService.kt @@ -1,16 +1,28 @@ package net.perfectdreams.loritta.cinnamon.pudding.services +import kotlinx.datetime.toKotlinInstant import net.perfectdreams.loritta.cinnamon.common.utils.TransactionType import net.perfectdreams.loritta.cinnamon.pudding.Pudding import net.perfectdreams.loritta.cinnamon.pudding.data.Daily +import net.perfectdreams.loritta.cinnamon.pudding.data.EmojiFightBetSonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.SonhosTransaction import net.perfectdreams.loritta.cinnamon.pudding.data.UserId import net.perfectdreams.loritta.cinnamon.pudding.tables.BrokerSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalMatchmakingResults import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetGlobalSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetMatchmakingResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.CoinFlipBetSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Dailies import net.perfectdreams.loritta.cinnamon.pudding.tables.DailyTaxSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.DivineInterventionSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightMatchmakingResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightParticipants +import net.perfectdreams.loritta.cinnamon.pudding.tables.EmojiFightSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.PaymentSonhosTransactionResults +import net.perfectdreams.loritta.cinnamon.pudding.tables.PaymentSonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.Profiles +import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosBundlePurchaseSonhosTransactionsLog +import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosBundles import net.perfectdreams.loritta.cinnamon.pudding.tables.SonhosTransactionsLog import net.perfectdreams.loritta.cinnamon.pudding.tables.SparklyPowerLSXSonhosTransactionsLog import org.jetbrains.exposed.sql.Op @@ -52,7 +64,29 @@ class SonhosService(private val pudding: Pudding) : Service(pudding) { userTransactionQuery(userId, transactionTypeFilter) .orderBy(SonhosTransactionsLog.id, SortOrder.DESC) .limit(limit, offset) - .map { SonhosTransaction.fromRow(it) } + .map { + // ===[ SPECIAL CASES ]=== + // We need to query how many users lost the bet + if (it.getOrNull(EmojiFightSonhosTransactionsLog.id) != null) { + val usersInMatch = EmojiFightParticipants.select { EmojiFightParticipants.match eq it[EmojiFightParticipants.match] } + .count() + + EmojiFightBetSonhosTransaction( + it[SonhosTransactionsLog.id].value, + it[SonhosTransactionsLog.timestamp].toKotlinInstant(), + UserId(it[SonhosTransactionsLog.user].value), + UserId(it[EmojiFightParticipants.user].value), + usersInMatch, + it[EmojiFightParticipants.emoji], + it[EmojiFightMatchmakingResults.entryPrice], + it[EmojiFightMatchmakingResults.entryPriceAfterTax], + it[EmojiFightMatchmakingResults.tax], + it[EmojiFightMatchmakingResults.taxPercentage] + ) + } else { + SonhosTransaction.fromRow(it) + } + } } } @@ -62,21 +96,41 @@ class SonhosService(private val pudding: Pudding) : Service(pudding) { userId: UserId, transactionTypeFilter: List ) = SonhosTransactionsLog.let { + if (TransactionType.PAYMENT in transactionTypeFilter) + it.leftJoin(PaymentSonhosTransactionsLog.leftJoin(PaymentSonhosTransactionResults)) + else it + }.let { if (TransactionType.HOME_BROKER in transactionTypeFilter) it.leftJoin(BrokerSonhosTransactionsLog) else it + }.let { + if (TransactionType.COINFLIP_BET in transactionTypeFilter) + it.leftJoin(CoinFlipBetSonhosTransactionsLog.leftJoin(CoinFlipBetMatchmakingResults)) + else it }.let { if (TransactionType.COINFLIP_BET_GLOBAL in transactionTypeFilter) it.leftJoin(CoinFlipBetGlobalSonhosTransactionsLog.leftJoin(CoinFlipBetGlobalMatchmakingResults)) else it + }.let { + if (TransactionType.EMOJI_FIGHT_BET in transactionTypeFilter) + it.leftJoin(EmojiFightSonhosTransactionsLog.leftJoin(EmojiFightMatchmakingResults.leftJoin(EmojiFightParticipants))) + else it }.let { if (TransactionType.SPARKLYPOWER_LSX in transactionTypeFilter) it.leftJoin(SparklyPowerLSXSonhosTransactionsLog) else it + }.let { + if (TransactionType.SONHOS_BUNDLE_PURCHASE in transactionTypeFilter) + it.leftJoin(SonhosBundlePurchaseSonhosTransactionsLog.leftJoin(SonhosBundles)) + else it }.let { if (TransactionType.INACTIVE_DAILY_TAX in transactionTypeFilter) it.leftJoin(DailyTaxSonhosTransactionsLog) else it + }.let { + if (TransactionType.DIVINE_INTERVENTION in transactionTypeFilter) + it.leftJoin(DivineInterventionSonhosTransactionsLog) + else it } .select { // Hacky! @@ -87,10 +141,15 @@ class SonhosService(private val pudding: Pudding) : Service(pudding) { for (type in transactionTypeFilter) { cond = when (type) { + TransactionType.PAYMENT -> cond.or(PaymentSonhosTransactionsLog.id.isNotNull()) TransactionType.HOME_BROKER -> cond.or(BrokerSonhosTransactionsLog.id.isNotNull()) + TransactionType.COINFLIP_BET -> cond.or(CoinFlipBetSonhosTransactionsLog.id.isNotNull()) TransactionType.COINFLIP_BET_GLOBAL -> cond.or(CoinFlipBetGlobalSonhosTransactionsLog.id.isNotNull()) + TransactionType.EMOJI_FIGHT_BET -> cond.or(EmojiFightSonhosTransactionsLog.id.isNotNull()) TransactionType.SPARKLYPOWER_LSX -> cond.or(SparklyPowerLSXSonhosTransactionsLog.id.isNotNull()) + TransactionType.SONHOS_BUNDLE_PURCHASE -> cond.or(SonhosBundlePurchaseSonhosTransactionsLog.id.isNotNull()) TransactionType.INACTIVE_DAILY_TAX -> cond.or(DailyTaxSonhosTransactionsLog.id.isNotNull()) + TransactionType.DIVINE_INTERVENTION -> cond.or(DivineInterventionSonhosTransactionsLog.id.isNotNull()) } } diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/CoinFlipBetMatchmakingResults.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/CoinFlipBetMatchmakingResults.kt new file mode 100644 index 0000000000..a092de9e6b --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/CoinFlipBetMatchmakingResults.kt @@ -0,0 +1,14 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable +import org.jetbrains.exposed.sql.javatime.timestamp + +object CoinFlipBetMatchmakingResults : LongIdTable() { + val winner = reference("winner", Profiles).index() + val loser = reference("loser", Profiles).index() + val quantity = long("quantity").index() + val quantityAfterTax = long("quantity_after_tax") + val tax = long("tax").nullable() + val taxPercentage = double("tax_percentage").nullable() + val timestamp = timestamp("timestamp").index() +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/CoinFlipBetSonhosTransactionsLog.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/CoinFlipBetSonhosTransactionsLog.kt new file mode 100644 index 0000000000..1214370363 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/CoinFlipBetSonhosTransactionsLog.kt @@ -0,0 +1,8 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object CoinFlipBetSonhosTransactionsLog : LongIdTable() { + val timestampLog = reference("timestamp_log", SonhosTransactionsLog) + val matchmakingResult = reference("matchmaking_result", CoinFlipBetMatchmakingResults) +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/DivineInterventionSonhosTransactionsLog.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/DivineInterventionSonhosTransactionsLog.kt new file mode 100644 index 0000000000..55d8aa31b8 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/DivineInterventionSonhosTransactionsLog.kt @@ -0,0 +1,13 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import net.perfectdreams.loritta.cinnamon.common.utils.DivineInterventionTransactionEntryAction +import net.perfectdreams.loritta.cinnamon.pudding.utils.exposed.postgresEnumeration +import org.jetbrains.exposed.dao.id.LongIdTable + +object DivineInterventionSonhosTransactionsLog : LongIdTable() { + val timestampLog = reference("timestamp_log", SonhosTransactionsLog) + val action = postgresEnumeration("action") + val givenBy = optReference("given_by", Profiles) + val sonhos = long("sonhos") + val reason = text("reason").nullable() +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightMatches.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightMatches.kt new file mode 100644 index 0000000000..7c523eca91 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightMatches.kt @@ -0,0 +1,11 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable +import org.jetbrains.exposed.sql.javatime.timestamp + +object EmojiFightMatches : LongIdTable() { + val createdBy = reference("created_by", Profiles).index() + val createdAt = timestamp("created_at") + val finishedAt = timestamp("finished_at") + val maxPlayers = integer("max_players") +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightMatchmakingResults.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightMatchmakingResults.kt new file mode 100644 index 0000000000..b3d2a09ee2 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightMatchmakingResults.kt @@ -0,0 +1,11 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object EmojiFightMatchmakingResults : LongIdTable() { + val winner = reference("winner", EmojiFightParticipants).index() + val entryPrice = long("entry_price") + val entryPriceAfterTax = long("entry_price_after_tax") + val tax = long("tax").nullable() + val taxPercentage = double("tax_percentage").nullable() +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightParticipants.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightParticipants.kt new file mode 100644 index 0000000000..cf77934c1f --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightParticipants.kt @@ -0,0 +1,9 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object EmojiFightParticipants : LongIdTable() { + val user = reference("user", Profiles).index() + val match = reference("match", EmojiFightMatches) + val emoji = text("emoji") +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightSonhosTransactionsLog.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightSonhosTransactionsLog.kt new file mode 100644 index 0000000000..29eb040127 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/EmojiFightSonhosTransactionsLog.kt @@ -0,0 +1,8 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object EmojiFightSonhosTransactionsLog : LongIdTable() { + val timestampLog = reference("timestamp_log", SonhosTransactionsLog) + val matchmakingResult = reference("matchmaking_result", EmojiFightMatchmakingResults) +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/PaymentSonhosTransactionResults.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/PaymentSonhosTransactionResults.kt new file mode 100644 index 0000000000..fec0722072 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/PaymentSonhosTransactionResults.kt @@ -0,0 +1,11 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable +import org.jetbrains.exposed.sql.javatime.timestamp + +object PaymentSonhosTransactionResults : LongIdTable() { + val givenBy = reference("given_by", Profiles) + val receivedBy = reference("received_by", Profiles) + val sonhos = long("sonhos") + val timestamp = timestamp("timestamp").index() +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/PaymentSonhosTransactionsLog.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/PaymentSonhosTransactionsLog.kt new file mode 100644 index 0000000000..e2fa31a18e --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/PaymentSonhosTransactionsLog.kt @@ -0,0 +1,8 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object PaymentSonhosTransactionsLog : LongIdTable() { + val timestampLog = reference("timestamp_log", SonhosTransactionsLog) + val paymentResult = reference("payment_result", PaymentSonhosTransactionResults) +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/SonhosBundlePurchaseSonhosTransactionsLog.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/SonhosBundlePurchaseSonhosTransactionsLog.kt new file mode 100644 index 0000000000..8ba6b66da1 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/SonhosBundlePurchaseSonhosTransactionsLog.kt @@ -0,0 +1,8 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object SonhosBundlePurchaseSonhosTransactionsLog : LongIdTable() { + val timestampLog = reference("timestamp_log", SonhosTransactionsLog) + val bundle = reference("bundle", SonhosBundles) +} \ No newline at end of file diff --git a/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/SonhosBundles.kt b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/SonhosBundles.kt new file mode 100644 index 0000000000..bdbeebd005 --- /dev/null +++ b/pudding/client/src/main/kotlin/net/perfectdreams/loritta/cinnamon/pudding/tables/SonhosBundles.kt @@ -0,0 +1,9 @@ +package net.perfectdreams.loritta.cinnamon.pudding.tables + +import org.jetbrains.exposed.dao.id.LongIdTable + +object SonhosBundles : LongIdTable() { + val active = bool("active").index() + val sonhos = long("sonhos") + val price = double("price") +} \ No newline at end of file diff --git a/pudding/data/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/pudding/data/SonhosTransaction.kt b/pudding/data/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/pudding/data/SonhosTransaction.kt index f717c6cfff..22586452c3 100644 --- a/pudding/data/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/pudding/data/SonhosTransaction.kt +++ b/pudding/data/src/commonMain/kotlin/net/perfectdreams/loritta/cinnamon/pudding/data/SonhosTransaction.kt @@ -2,6 +2,7 @@ package net.perfectdreams.loritta.cinnamon.pudding.data import kotlinx.datetime.Instant import kotlinx.serialization.Serializable +import net.perfectdreams.loritta.cinnamon.common.utils.DivineInterventionTransactionEntryAction import net.perfectdreams.loritta.cinnamon.common.utils.LorittaBovespaBrokerUtils import net.perfectdreams.loritta.cinnamon.common.utils.SparklyPowerLSXTransactionEntryAction @@ -12,6 +13,16 @@ sealed class SonhosTransaction { abstract val user: UserId } +@Serializable +data class PaymentSonhosTransaction( + override val id: Long, + override val timestamp: Instant, + override val user: UserId, + val receivedBy: UserId, + val givenBy: UserId, + val sonhos: Long +) : SonhosTransaction() + @Serializable data class BrokerSonhosTransaction( override val id: Long, @@ -24,6 +35,19 @@ data class BrokerSonhosTransaction( val stockQuantity: Long ) : SonhosTransaction() +@Serializable +data class CoinFlipBetSonhosTransaction( + override val id: Long, + override val timestamp: Instant, + override val user: UserId, + val winner: UserId, + val loser: UserId, + val quantity: Long, + val quantityAfterTax: Long, + val tax: Long?, + val taxPercentage: Double? +) : SonhosTransaction() + @Serializable data class CoinFlipBetGlobalSonhosTransaction( override val id: Long, @@ -38,6 +62,20 @@ data class CoinFlipBetGlobalSonhosTransaction( val timeOnQueue: Long ) : SonhosTransaction() +@Serializable +data class EmojiFightBetSonhosTransaction( + override val id: Long, + override val timestamp: Instant, + override val user: UserId, + val winner: UserId, + val usersInMatch: Long, + val emoji: String, + val entryPrice: Long, + val entryPriceAfterTax: Long, + val tax: Long?, + val taxPercentage: Double? +) : SonhosTransaction() + @Serializable data class SparklyPowerLSXSonhosTransaction( override val id: Long, @@ -61,6 +99,25 @@ data class DailyTaxSonhosTransaction( val minimumSonhosForTrigger: Long ) : SonhosTransaction() +@Serializable +data class SonhosBundlePurchaseSonhosTransaction( + override val id: Long, + override val timestamp: Instant, + override val user: UserId, + val sonhos: Long +) : SonhosTransaction() + +@Serializable +data class DivineInterventionSonhosTransaction( + override val id: Long, + override val timestamp: Instant, + override val user: UserId, + val action: DivineInterventionTransactionEntryAction, + val givenBy: UserId?, + val sonhos: Long, + val reason: String? +) : SonhosTransaction() + @Serializable data class UnknownSonhosTransaction( override val id: Long, diff --git a/resources/languages/en/commands/transactions.yml b/resources/languages/en/commands/transactions.yml index 878ee466d2..068b90ad9e 100644 --- a/resources/languages/en/commands/transactions.yml +++ b/resources/languages/en/commands/transactions.yml @@ -24,11 +24,23 @@ unknownPage: - "Then, a beacon illuminates a enormous hand that was in front of you all this time." goToTheLastPage: "I'm scared, get me out of here!" types: + payment: + title: "Payments" + description: "Transactions related to sonhos transfers to other users" + sent: "Sent {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} to `{receiverTag}` (`{receiverId}`)" + received: "Received {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} from `{giverTag}` (`{giverId}`)" homeBroker: title: "Loritta's Stock Market Simulator" description: "Transactions related to Loritta's Stock Market Simulator" boughtShares: "Bought {stockQuantity, plural, one {# share} other {# shares}} of `{ticker}` for {sonhosQuantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} in Loritta's Stock Market Simulator" soldShares: "Sold {stockQuantity, plural, one {# share} other {# shares}} of `{ticker}` for {sonhosQuantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} in Loritta's Stock Market Simulator" + coinFlipBet: + title: "Coin Flip Bets" + description: "Transactions related to sonhos coin flip bets" + wonTaxed: "Received {quantityAfterTax,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (tax-free value: {quantity}) from `{loserTag}` (`{loserId}`) in sonhos coin flip bets" + lostTaxed: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (value after taxes: {quantityAfterTax}) to `{winnerTag}` (`{winnerId}`) in sonhos coin flip bets" + won: "Received {quantityAfterTax,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (no taxes!) from `{loserTag}` (`{loserId}`) in sonhos coin flip bets" + lost: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} sonhos (no taxes!) to `{winnerTag}` (`{winnerId}`) in sonhos coin flip bets" coinFlipBetGlobal: title: "Global Coin Flip Bets" description: "Transactions related to sonhos coin flip bets... globally!" @@ -36,15 +48,31 @@ types: lostTaxed: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (value after taxes: {quantityAfterTax}) to `{winnerTag}` (`{winnerId}`) in global sonhos coin flip bets" won: "Received {quantityAfterTax,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (no taxes!) from `{loserTag}` (`{loserId}`) in global sonhos coin flip bets" lost: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} sonhos (no taxes!) to `{winnerTag}` (`{winnerId}`) in global sonhos coin flip bets" + emojiFightBet: + title: "Emoji Fight Bets" + description: "Transactions related to emoji fight bets" + wonTaxed: "Received {quantityAfterTax,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (tax-free value: {quantity}) from {userInEmojiFight} users in sonhos emoji fight bets because they all feared the mighty {emojiFightEmoji}" + lostTaxed: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (value after taxes: {quantityAfterTax}) to `{winnerTag}`'s {emojiFightEmoji} (`{winnerId}`) in sonhos emoji fight bets" + won: "Received {quantityAfterTax,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} (no taxes!) from {userInEmojiFight} users in sonhos emoji fight bets because they all feared the mighty {emojiFightEmoji}" + lost: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} sonhos (no taxes!) to `{winnerTag}`'s {emojiFightEmoji} (`{winnerId}`) in sonhos emoji fight bets" sparklyPowerLsx: title: "SparklyPower Sonhos Exchange" description: "Transactions related to SparklyPower, Loritta's Minecraft Server" exchangedToSparklyPower: "Exchanged {sonhosQuantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} from Loritta to `{playerName}`'s account on SparklyPower, receiving {sparklyPowerSonhosQuantity, plural, one {# sonho} other {# sonhos}} there [{sparklyPowerIp}]" exchangedFromSparklyPower: "Exchanged {sparklyPowerSonhosQuantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} from `{playerName}`'s account on SparklyPower to Loritta, receiving {sonhosQuantity, plural, one {# sonho} other {# sonhos}} here [{sparklyPowerIp}]" + sonhosBundlePurchase: + title: "Sonhos Bundle Purchase" + description: "Transactions related to sonhos purchases" + purchasedSonhos: "Bought {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} on Loritta's sonhos shop. Thank you for supporting Loritta! {loriKiss}" inactiveDailyTax: title: "Daily Reward Inactivity Tax" description: "Transactions related to the daily reward inactivity tax" lost: "Paid {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}} in taxes, because the user was {daysWithoutGettingDaily,plural,=0{# days} one {# day} other {# days}} without getting the daily reward while they had more than {sonhosBracketQuantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}}" + divineIntervention: + title: "Divine Intervention" + description: "Transactions made by Loritta's admins, \"the powers that be\"" + received: "A divine intervention gave {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}}" + lost: "A divine intervention removed {quantity,plural, =0 {# sonhos} one {# sonho} other {# sonhos}}" options: user: text: "The user that you want to view their transactions"