Skip to content

Commit

Permalink
Added invoice notifications (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
zefir-git authored Sep 16, 2024
2 parents c6502b0 + 3a032a9 commit 8baf07a
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 1 deletion.
22 changes: 22 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/BankAccounts.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import com.google.gson.JsonParser;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import net.kyori.adventure.text.Component;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
Expand Down Expand Up @@ -162,6 +164,12 @@ public static void reload() {
getInstance().getLogger().warning("Update details: https://modrinth.com/plugin/bankaccounts/version/" + latestVersion);
}));
getInstance().startInterestTimer();
if (getInstance().invoiceNotificationTask != null) {
final int taskId = getInstance().invoiceNotificationTask.getTaskId();
getInstance().getServer().getScheduler().cancelTask(taskId);
getInstance().invoiceNotificationTask = null;
}
getInstance().setupInvoiceNotificationTimer();
}

/**
Expand Down Expand Up @@ -247,6 +255,20 @@ private void startInterestTimer() {
}, 0L, 20L*60);
}

private @Nullable BukkitTask invoiceNotificationTask = null;

private void setupInvoiceNotificationTimer() {
if (config().invoiceNotifyInterval() <= 0) return;
this.invoiceNotificationTask = getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
for (final @NotNull Player player : getServer().getOnlinePlayers()) {
final @NotNull Optional<@NotNull Component> message = BankAccounts.getInstance().config().messagesInvoiceNotify(Invoice.countUnpaid(player));
if (message.isEmpty()) continue;
if (player.hasPermission(Permissions.INVOICE_NOTIFY) && Invoice.countUnpaid(player) > 0)
player.sendMessage(message.get());
}
}, config().invoiceNotifyInterval() * 20L, config().invoiceNotifyInterval() * 20L);
}

private void interestPayment(final @NotNull Account account, final @NotNull BigDecimal amount, final double rate, final @NotNull Account serverAccount) {
if (account.balance == null) return;
if (account.id.equals(serverAccount.id)) return;
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/BankConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,16 @@ public int invoicePerPage() {
public @NotNull Pattern disallowedRegex() {
return Pattern.compile(Objects.requireNonNull(config.getString("disallowed-regex")));
}

// invoice.notify.join
public boolean invoiceNotifyJoin() {
return config.getBoolean("invoice.notify.join");
}

// invoice.notify.interval
public int invoiceNotifyInterval() {
return config.getInt("invoice.notify.interval");
}

// messages.command-usage
public @NotNull Component messagesCommandUsage(final @NotNull String command, final @NotNull String arguments) {
Expand Down Expand Up @@ -1379,6 +1389,17 @@ public int invoicePerPage() {
);
}

// messages.invoice.notify
public @NotNull Optional<@NotNull Component> messagesInvoiceNotify(final int unpaid) {
final @NotNull String message = Objects.requireNonNull(config.getString("messages.invoice.notify"));
if (message.isBlank()) return Optional.empty();
return Optional.of(MiniMessage.miniMessage().deserialize(
message
.replace("<unpaid>", String.valueOf(unpaid)),
Formatter.choice("unpaid-choice", unpaid)
));
}

// messages.update-available
public @NotNull Component messagesUpdateAvailable(final @NotNull String version) {
return MiniMessage.miniMessage().deserialize(
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/Invoice.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,19 @@ public void update() {
return new @NotNull Invoice[0];
}
}

public static int countUnpaid(final @NotNull OfflinePlayer player) {
try (final @NotNull Connection conn = BankAccounts.getInstance().getDb().getConnection();
final @NotNull PreparedStatement stmt = conn.prepareStatement("SELECT COUNT(`id`) as `count` FROM `bank_invoices` WHERE `buyer` = ? AND `transaction` IS NULL")) {
stmt.setString(1, player.getUniqueId().toString());

final @NotNull ResultSet rs = stmt.executeQuery();
if (rs.next()) return rs.getInt("count");
return 0;
}
catch (final @NotNull SQLException e) {
BankAccounts.getInstance().getLogger().log(Level.SEVERE, "Could not count unpaid invoices for player: " + player.getUniqueId(), e);
return 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public final class Permissions {
public static final @NotNull String INVOICE_CREATE_OTHER = "bank.invoice.create.other";
public static final @NotNull String INVOICE_VIEW = "bank.invoice.view";
public static final @NotNull String INVOICE_VIEW_OTHER = "bank.invoice.view.other";
public static final @NotNull String INVOICE_NOTIFY = "bank.invoice.notify";
public static final @NotNull String INVOICE_PAY_OTHER = "bank.invoice.pay.other";
public static final @NotNull String INVOICE_PAY_ACCOUNT_OTHER = "bank.invoice.pay.account-other";
public static final @NotNull String INVOICE_SEND = "bank.invoice.send";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public static boolean create(final @NotNull CommandSender sender, @NotNull Strin
invoice.insert();

final @NotNull Optional<@NotNull Player> onlineRecipient = invoice.buyer().isPresent() ? Optional.ofNullable(invoice.buyer().get().getPlayer()) : Optional.empty();
onlineRecipient.ifPresent(player -> sendMessage(player, BankAccounts.getInstance().config().messagesInvoiceCreated(invoice)));
onlineRecipient.ifPresent(player -> sendMessage(player, BankAccounts.getInstance().config().messagesInvoiceReceived(invoice)));
return sendMessage(sender, BankAccounts.getInstance().config().messagesInvoiceCreated(invoice));
}

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/pro/cloudnode/smp/bankaccounts/events/Join.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package pro.cloudnode.smp.bankaccounts.events;

import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.jetbrains.annotations.NotNull;
import pro.cloudnode.smp.bankaccounts.Account;
import pro.cloudnode.smp.bankaccounts.BankAccounts;
import pro.cloudnode.smp.bankaccounts.Invoice;
import pro.cloudnode.smp.bankaccounts.Permissions;

import java.math.BigDecimal;
Expand Down Expand Up @@ -35,5 +37,11 @@ else if (BankAccounts.getInstance().config().integrationsVaultEnabled()) {
player.sendMessage(BankAccounts.getInstance().config().messagesUpdateAvailable(latestVersion))
), 20L);
}
if (player.hasPermission(Permissions.INVOICE_NOTIFY) && BankAccounts.getInstance().config().invoiceNotifyJoin() && Invoice.countUnpaid(player) > 0) {
BankAccounts.getInstance().getServer().getScheduler().runTaskLater(BankAccounts.getInstance(), () -> {
final @NotNull Optional<@NotNull Component> message = BankAccounts.getInstance().config().messagesInvoiceNotify(Invoice.countUnpaid(player));
message.ifPresent(player::sendMessage);
}, 20L);
}
}
}
17 changes: 17 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,15 @@ invoice:
# Number of invoices to return per page
per-page: 10

# Notifications for unpaid invoices (see messages.invoice.notify)
notify:
# Send message when a player joins
join: true
# Periodically send message while player is online
# Interval between messages in seconds
# Set to 0 or negative to disable
interval: 300

# Advanced: do not edit unless you have good understanding of RegEx
# Regular expression for disallowed characters user-provided text inputs
# e.g. account name, transaction description, POS description, invoice description
Expand Down Expand Up @@ -602,6 +611,14 @@ messages:
# Same placeholders as details
footer: "<hover:show_text:'Click to see the previous page'><click:run_command:<cmd-prev>><green>← Previous</green></click></hover> <gray>Page <page></gray> <hover:show_text:'Click to see the next page'><click:run_command:<cmd-next>><green>Next →</green></click></hover>"

# You have unpaid invoices
# Sent periodically and on login (as configured in invoice.notify)
# Set to empty string to disable
# Placeholders:
# <unpaid> - number of unpaid invoices></yellow>."
# <unpaid-choice> - choice placeholder for unpaid invoices; see https://docs.advntr.dev/minimessage/dynamic-replacements.html#insert-a-choice
notify: "<click:run_command:/invoice list><hover:show_text:'Click to view unpaid invoices'><yellow>(!) You have <gray><unpaid></gray> unpaid invoice<unpaid-choice:'1#|1<s'>. <gray>Click to view.</gray></yellow></hover></click>"

# New version available
# Placeholders:
# <version> - New version
Expand Down

0 comments on commit 8baf07a

Please sign in to comment.