Enhance transaction fetching with pagination support and improved error handling
Signed-off-by: Dmitrii <computer@yawaflua.tech> Took 22 minutes
This commit is contained in:
@@ -22,7 +22,7 @@ jobs:
|
|||||||
- name: Restore dependencies
|
- name: Restore dependencies
|
||||||
run: dotnet restore --project backend/SpMega.Backend/SpMega.Backend.csproj
|
run: dotnet restore --project backend/SpMega.Backend/SpMega.Backend.csproj
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build --no-restore --project backend/SpMega.Backend/SpMega.Backend.csproj
|
run: dotnet build --no-restore backend/SpMega.Backend/SpMega.Backend.csproj
|
||||||
- name: Test
|
- name: Test
|
||||||
run: dotnet test --no-build --verbosity normal --project backend/SpMega.Backend/SpMega.Backend.csproj
|
run: dotnet test --no-build --verbosity normal --project backend/SpMega.Backend/SpMega.Backend.csproj
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.Text.Json.Nodes;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Driver;
|
||||||
using SpMega.Backend.Persistent.Database;
|
using SpMega.Backend.Persistent.Database;
|
||||||
using SpMega.Backend.Persistent.Models.Transactions;
|
using SpMega.Backend.Persistent.Models.Transactions;
|
||||||
using SpMega.Backend.Persistent.Models.Users;
|
using SpMega.Backend.Persistent.Models.Users;
|
||||||
@@ -16,6 +18,7 @@ namespace SpMega.Backend.Controllers.v1;
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
public class TransactionsController(AppDbContext context, ILogger<TransactionsController> logger, IConfiguration config) : ControllerBase
|
public class TransactionsController(AppDbContext context, ILogger<TransactionsController> logger, IConfiguration config) : ControllerBase
|
||||||
{
|
{
|
||||||
|
private const int LIMIT = 10;
|
||||||
private const string BASE_URL = "https://spworlds.ru/api/public/";
|
private const string BASE_URL = "https://spworlds.ru/api/public/";
|
||||||
|
|
||||||
[HttpGet("{billId}")]
|
[HttpGet("{billId}")]
|
||||||
@@ -127,9 +130,13 @@ public class TransactionsController(AppDbContext context, ILogger<TransactionsCo
|
|||||||
|
|
||||||
[HttpGet()]
|
[HttpGet()]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public async Task<ActionResult<List<Transaction>>> GetAllTransactions()
|
public async Task<ActionResult<List<Transaction>>> GetAllTransactions([FromQuery] int p = 1)
|
||||||
{
|
{
|
||||||
return Ok(await context.Transactions.Where(k => k.Sender.Id == ((User)HttpContext.Items["@me"]).Id).ToListAsync());
|
return Ok(await context.Transactions
|
||||||
|
.Where(k => EF.Property<Guid>(k, "SenderId") == ((User)HttpContext.Items["@me"]).Id)
|
||||||
|
.Skip(p - 1 * LIMIT)
|
||||||
|
.Take(p * LIMIT)
|
||||||
|
.ToListAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonAction]
|
[NonAction]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package git.yawaflua.tech.spmega.client.ui;
|
|||||||
import git.yawaflua.tech.spmega.client.ui.service.BackendAuthenticator;
|
import git.yawaflua.tech.spmega.client.ui.service.BackendAuthenticator;
|
||||||
import git.yawaflua.tech.spmega.client.ui.service.BankDatabase.LocalTransaction;
|
import git.yawaflua.tech.spmega.client.ui.service.BankDatabase.LocalTransaction;
|
||||||
import git.yawaflua.tech.spmega.client.ui.service.BankUiService;
|
import git.yawaflua.tech.spmega.client.ui.service.BankUiService;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import net.minecraft.client.gui.DrawContext;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||||
@@ -19,6 +20,8 @@ public class TransactionHistoryScreen extends Screen {
|
|||||||
private final List<LocalTransaction> transactions = new ArrayList<>();
|
private final List<LocalTransaction> transactions = new ArrayList<>();
|
||||||
private boolean loading = true;
|
private boolean loading = true;
|
||||||
private String errorMessage = "";
|
private String errorMessage = "";
|
||||||
|
private int scrollOffset = 0;
|
||||||
|
private int currentPage = 1;
|
||||||
|
|
||||||
public TransactionHistoryScreen(Screen parent, String cardId, String cardTitle) {
|
public TransactionHistoryScreen(Screen parent, String cardId, String cardTitle) {
|
||||||
super(Text.literal("История транзакций"));
|
super(Text.literal("История транзакций"));
|
||||||
@@ -36,40 +39,112 @@ public class TransactionHistoryScreen extends Screen {
|
|||||||
.dimensions(centerX - 60, startY + 10, 120, 20)
|
.dimensions(centerX - 60, startY + 10, 120, 20)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
// Scroll Up/Down buttons
|
||||||
|
this.addDrawableChild(ButtonWidget.builder(Text.literal("▲"), button -> scrollUp())
|
||||||
|
.dimensions(centerX + 140, 65, 20, 20)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
this.addDrawableChild(ButtonWidget.builder(Text.literal("▼"), button -> scrollDown())
|
||||||
|
.dimensions(centerX + 140, 155, 20, 20)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
// Prev Page button
|
||||||
|
this.addDrawableChild(ButtonWidget.builder(Text.literal("<"), button -> {
|
||||||
|
if (currentPage > 1) {
|
||||||
|
currentPage--;
|
||||||
|
scrollOffset = 0;
|
||||||
|
loadTransactions();
|
||||||
|
}
|
||||||
|
}).dimensions(centerX - 100, startY - 15, 30, 20).build());
|
||||||
|
|
||||||
|
// Next Page button
|
||||||
|
this.addDrawableChild(ButtonWidget.builder(Text.literal(">"), button -> {
|
||||||
|
currentPage++;
|
||||||
|
scrollOffset = 0;
|
||||||
|
loadTransactions();
|
||||||
|
}).dimensions(centerX + 70, startY - 15, 30, 20).build());
|
||||||
|
|
||||||
loadTransactions();
|
loadTransactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void scrollUp() {
|
||||||
|
if (scrollOffset > 0) {
|
||||||
|
scrollOffset--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scrollDown() {
|
||||||
|
if (scrollOffset < Math.max(0, transactions.size() - 6)) {
|
||||||
|
scrollOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support pre-1.20.2 mouse scroll
|
||||||
|
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
||||||
|
if (amount > 0) {
|
||||||
|
scrollUp();
|
||||||
|
} else if (amount < 0) {
|
||||||
|
scrollDown();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support 1.20.2+ mouse scroll
|
||||||
|
@Override
|
||||||
|
public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
|
||||||
|
if (verticalAmount > 0) {
|
||||||
|
scrollUp();
|
||||||
|
} else if (verticalAmount < 0) {
|
||||||
|
scrollDown();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void loadTransactions() {
|
private void loadTransactions() {
|
||||||
loading = true;
|
loading = true;
|
||||||
errorMessage = "";
|
errorMessage = "";
|
||||||
transactions.clear();
|
transactions.clear();
|
||||||
|
|
||||||
|
UiNotifications.instance().show(Text.literal("Загрузка..."));
|
||||||
|
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("[SPMEGA] Transaction history loading started for card: " + cardId + ", page: " + currentPage);
|
||||||
List<LocalTransaction> list = null;
|
List<LocalTransaction> list = null;
|
||||||
git.yawaflua.tech.spmega.ModConfig config = git.yawaflua.tech.spmega.SPMega.getConfig();
|
git.yawaflua.tech.spmega.ModConfig config = git.yawaflua.tech.spmega.SPMega.getConfig();
|
||||||
if (config != null && config.allowBackend()) {
|
if (config != null && config.allowBackend()) {
|
||||||
try {
|
try {
|
||||||
list = BackendAuthenticator.fetchTransactionsFromBackend(cardId);
|
list = BackendAuthenticator.fetchTransactionsFromBackend(cardId, currentPage);
|
||||||
|
System.out.println("[SPMEGA] Fetched " + (list != null ? list.size() : "null") + " transactions from backend.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("[SPMEGA] Failed to fetch transactions from server, falling back to DB: " + e.getMessage());
|
System.err.println("[SPMEGA] Failed to fetch transactions from server, falling back to DB: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
list = BankUiService.instance().getDatabase().loadTransferHistory(cardId);
|
list = BankUiService.instance().getDatabase().loadTransferHistory(cardId);
|
||||||
|
System.out.println("[SPMEGA] Loaded " + (list != null ? list.size() : "null") + " transactions from database.");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<LocalTransaction> finalList = list;
|
List<LocalTransaction> finalList = list != null ? list : new ArrayList<>();
|
||||||
if (this.client != null) {
|
MinecraftClient minecraftClient = MinecraftClient.getInstance();
|
||||||
this.client.execute(() -> {
|
if (minecraftClient != null) {
|
||||||
|
minecraftClient.execute(() -> {
|
||||||
|
System.out.println("[SPMEGA] Setting transactions list on main thread. Count: " + finalList.size());
|
||||||
this.transactions.addAll(finalList);
|
this.transactions.addAll(finalList);
|
||||||
|
this.scrollOffset = 0;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
System.out.println("[SPMEGA] MinecraftClient.getInstance() is null in loadTransactions callback!");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (this.client != null) {
|
System.err.println("[SPMEGA] Outer exception in loadTransactions: " + e.getMessage());
|
||||||
this.client.execute(() -> {
|
e.printStackTrace();
|
||||||
|
MinecraftClient minecraftClient = MinecraftClient.getInstance();
|
||||||
|
if (minecraftClient != null) {
|
||||||
|
minecraftClient.execute(() -> {
|
||||||
this.errorMessage = e.getMessage();
|
this.errorMessage = e.getMessage();
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
@@ -91,30 +166,38 @@ public class TransactionHistoryScreen extends Screen {
|
|||||||
|
|
||||||
int centerX = this.width / 2;
|
int centerX = this.width / 2;
|
||||||
int startY = 50;
|
int startY = 50;
|
||||||
|
int bottomStartY = this.height / 2 + 50;
|
||||||
|
|
||||||
context.drawCenteredTextWithShadow(this.textRenderer, this.title, centerX, 20, 0xFFFFFF);
|
context.drawCenteredTextWithShadow(this.textRenderer, this.title, centerX, 20, 0xFFFFFFFF);
|
||||||
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Карта: " + cardTitle), centerX, 35, 0xBFBFBF);
|
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Карта: " + cardTitle), centerX, 35, 0xFFBFBFBF);
|
||||||
|
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Стр. " + currentPage), centerX, bottomStartY - 9, 0xFFFFFFFF);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Загрузка транзакций..."), centerX, this.height / 2 - 10, 0xCCCCCC);
|
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Загрузка транзакций..."), centerX, this.height / 2 - 10, 0xFFCCCCCC);
|
||||||
} else if (!errorMessage.isEmpty()) {
|
} else if (!errorMessage.isEmpty()) {
|
||||||
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Ошибка: " + errorMessage), centerX, this.height / 2 - 10, 0xFF5555);
|
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Ошибка: " + errorMessage), centerX, this.height / 2 - 10, 0xFFFF5555);
|
||||||
} else if (transactions.isEmpty()) {
|
} else if (transactions.isEmpty()) {
|
||||||
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Транзакций не найдено"), centerX, this.height / 2 - 10, 0xCCCCCC);
|
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal("Транзакций не найдено"), centerX, this.height / 2 - 10, 0xFFCCCCCC);
|
||||||
} else {
|
} else {
|
||||||
int y = startY + 15;
|
int y = startY + 15;
|
||||||
for (int i = 0; i < Math.min(6, transactions.size()); i++) {
|
int limit = Math.min(6, transactions.size() - scrollOffset);
|
||||||
LocalTransaction tx = transactions.get(i);
|
for (int i = 0; i < limit; i++) {
|
||||||
|
LocalTransaction tx = transactions.get(scrollOffset + i);
|
||||||
|
|
||||||
String amountText = tx.amount() + " АР";
|
String amountText = tx.amount() + " АР";
|
||||||
String dateText = tx.createdAt();
|
String dateText = tx.createdAt();
|
||||||
|
if (dateText == null) {
|
||||||
|
dateText = "";
|
||||||
|
}
|
||||||
if (dateText.length() > 19) {
|
if (dateText.length() > 19) {
|
||||||
dateText = dateText.substring(0, 19).replace("T", " ");
|
dateText = dateText.substring(0, 19).replace("T", " ");
|
||||||
}
|
}
|
||||||
String commentText = tx.comment().isEmpty() ? "" : " (" + tx.comment() + ")";
|
String commentText = tx.comment().isEmpty() ? "" : " (" + tx.comment() + ")";
|
||||||
|
|
||||||
String line = String.format("%s -> %s | %s%s", dateText, tx.receiver(), amountText, commentText);
|
String line = String.format("%s -> %s | %s%s", dateText, tx.receiver(), amountText, commentText);
|
||||||
int color = tx.status().equalsIgnoreCase("SUCCESS") ? 0x55FF55 : 0xFF5555;
|
|
||||||
|
String status = tx.status();
|
||||||
|
int color = (status != null && status.equalsIgnoreCase("SUCCESS")) ? 0xFF55FF55 : 0xFFFF5555;
|
||||||
|
|
||||||
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal(line), centerX, y, color);
|
context.drawCenteredTextWithShadow(this.textRenderer, Text.literal(line), centerX, y, color);
|
||||||
y += 18;
|
y += 18;
|
||||||
|
|||||||
+77
-10
@@ -1,5 +1,6 @@
|
|||||||
package git.yawaflua.tech.spmega.client.ui.service;
|
package git.yawaflua.tech.spmega.client.ui.service;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
import com.mojang.authlib.exceptions.AuthenticationException;
|
||||||
@@ -314,9 +315,11 @@ public class BackendAuthenticator {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<BankDatabase.LocalTransaction> fetchTransactionsFromBackend(String cardId) throws IOException, InterruptedException {
|
public static List<BankDatabase.LocalTransaction> fetchTransactionsFromBackend(String cardId, int page) throws IOException, InterruptedException {
|
||||||
|
System.out.println("[SPMEGA] fetchTransactionsFromBackend called for cardId: " + cardId + ", page: " + page);
|
||||||
ModConfig config = SPMega.getConfig();
|
ModConfig config = SPMega.getConfig();
|
||||||
if (config == null || !config.allowBackend()) {
|
if (config == null || !config.allowBackend()) {
|
||||||
|
System.out.println("[SPMEGA] fetchTransactionsFromBackend aborted: config is null or backend not allowed.");
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +331,8 @@ public class BackendAuthenticator {
|
|||||||
apiDomain = apiDomain.substring(0, apiDomain.length() - 1);
|
apiDomain = apiDomain.substring(0, apiDomain.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = apiDomain + "/api/v1/transactions?cardId=" + cardId;
|
String url = apiDomain + "/api/v1/transactions?p=" + page;
|
||||||
|
System.out.println("[SPMEGA] Requesting transactions from URL: " + url);
|
||||||
|
|
||||||
HttpClient httpClient = HttpClient.newHttpClient();
|
HttpClient httpClient = HttpClient.newHttpClient();
|
||||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
|
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
|
||||||
@@ -338,22 +342,85 @@ public class BackendAuthenticator {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
System.out.println("[SPMEGA] Response status code: " + response.statusCode());
|
||||||
if (response.statusCode() != 200) {
|
if (response.statusCode() != 200) {
|
||||||
|
System.err.println("[SPMEGA] Failed response body: " + response.body());
|
||||||
throw new IOException("Server returned status code " + response.statusCode() + " on fetch transactions.");
|
throw new IOException("Server returned status code " + response.statusCode() + " on fetch transactions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
com.google.gson.JsonArray transactionsArray = JsonParser.parseString(response.body()).getAsJsonArray();
|
String body = response.body();
|
||||||
|
System.out.println("[SPMEGA] Response body: " + (body.length() > 500 ? body.substring(0, 500) + "..." : body));
|
||||||
|
|
||||||
|
JsonElement parsed = JsonParser.parseString(body);
|
||||||
|
com.google.gson.JsonArray transactionsArray = null;
|
||||||
|
|
||||||
|
if (parsed.isJsonArray()) {
|
||||||
|
transactionsArray = parsed.getAsJsonArray();
|
||||||
|
} else if (parsed.isJsonObject()) {
|
||||||
|
JsonObject obj = parsed.getAsJsonObject();
|
||||||
|
if (obj.has("$values") && obj.get("$values").isJsonArray()) {
|
||||||
|
transactionsArray = obj.getAsJsonArray("$values");
|
||||||
|
} else if (obj.has("transactions") && obj.get("transactions").isJsonArray()) {
|
||||||
|
transactionsArray = obj.getAsJsonArray("transactions");
|
||||||
|
} else if (obj.has("values") && obj.get("values").isJsonArray()) {
|
||||||
|
transactionsArray = obj.getAsJsonArray("values");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transactionsArray == null) {
|
||||||
|
System.err.println("[SPMEGA] Response body is not a JSON array or wrapped array: " + body);
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("[SPMEGA] Total transactions returned from server: " + transactionsArray.size());
|
||||||
List<BankDatabase.LocalTransaction> list = new ArrayList<>();
|
List<BankDatabase.LocalTransaction> list = new ArrayList<>();
|
||||||
for (com.google.gson.JsonElement el : transactionsArray) {
|
for (com.google.gson.JsonElement el : transactionsArray) {
|
||||||
JsonObject json = el.getAsJsonObject();
|
try {
|
||||||
String receiver = json.has("receiver") ? json.get("receiver").getAsString() : (json.has("recipient") ? json.get("recipient").getAsString() : "unknown");
|
JsonObject json = el.getAsJsonObject();
|
||||||
long amount = json.has("amount") ? json.get("amount").getAsLong() : 0L;
|
|
||||||
String comment = json.has("comment") && !json.get("comment").isJsonNull() ? json.get("comment").getAsString() : "";
|
|
||||||
String status = json.has("status") ? json.get("status").getAsString() : "SUCCESS";
|
|
||||||
String createdAt = json.has("createdAt") ? json.get("createdAt").getAsString() : (json.has("created_at") ? json.get("created_at").getAsString() : "");
|
|
||||||
|
|
||||||
list.add(new BankDatabase.LocalTransaction(receiver, amount, comment, status, createdAt));
|
// Check cardId filter
|
||||||
|
String senderCardNumber = "";
|
||||||
|
if (json.has("senderCardNumber") && !json.get("senderCardNumber").isJsonNull()) {
|
||||||
|
senderCardNumber = json.get("senderCardNumber").getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!senderCardNumber.equalsIgnoreCase(cardId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String receiver = "unknown";
|
||||||
|
if (json.has("receiver") && !json.get("receiver").isJsonNull()) {
|
||||||
|
receiver = json.get("receiver").getAsString();
|
||||||
|
} else if (json.has("receiverName") && !json.get("receiverName").isJsonNull()) {
|
||||||
|
receiver = json.get("receiverName").getAsString();
|
||||||
|
} else if (json.has("receiverCardNumber") && !json.get("receiverCardNumber").isJsonNull()) {
|
||||||
|
receiver = json.get("receiverCardNumber").getAsString();
|
||||||
|
} else if (json.has("recipient") && !json.get("recipient").isJsonNull()) {
|
||||||
|
receiver = json.get("recipient").getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
long amount = json.has("amount") ? json.get("amount").getAsLong() : 0L;
|
||||||
|
String comment = json.has("comment") && !json.get("comment").isJsonNull() ? json.get("comment").getAsString() : "";
|
||||||
|
String status = json.has("status") && !json.get("status").isJsonNull() ? json.get("status").getAsString() : "SUCCESS";
|
||||||
|
|
||||||
|
String createdAt = "";
|
||||||
|
if (json.has("transactionDate") && !json.get("transactionDate").isJsonNull()) {
|
||||||
|
createdAt = json.get("transactionDate").getAsString();
|
||||||
|
} else if (json.has("createdAt") && !json.get("createdAt").isJsonNull()) {
|
||||||
|
createdAt = json.get("createdAt").getAsString();
|
||||||
|
} else if (json.has("created_at") && !json.get("created_at").isJsonNull()) {
|
||||||
|
createdAt = json.get("created_at").getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("[SPMEGA] Parsed transaction: %s -> %s, amount=%d, comment=%s, status=%s%n",
|
||||||
|
createdAt, receiver, amount, comment, status);
|
||||||
|
|
||||||
|
list.add(new BankDatabase.LocalTransaction(receiver, amount, comment, status, createdAt));
|
||||||
|
} catch (Exception parseEx) {
|
||||||
|
System.err.println("[SPMEGA] Error parsing transaction element: " + parseEx.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
System.out.println("[SPMEGA] Returning " + list.size() + " filtered transactions for card " + cardId);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package git.yawaflua.tech.spmega;
|
|||||||
public record ModConfig(String apiDomain, String apiToken, boolean allowBackend, boolean signQuickPayEnabled,
|
public record ModConfig(String apiDomain, String apiToken, boolean allowBackend, boolean signQuickPayEnabled,
|
||||||
boolean gpsEnabled, GpsHudPosition gpsPosition) {
|
boolean gpsEnabled, GpsHudPosition gpsPosition) {
|
||||||
public static final String DEFAULT_API_DOMAIN = "http://localhost:5129";
|
public static final String DEFAULT_API_DOMAIN = "http://localhost:5129";
|
||||||
public static final boolean ALLOW_BACKEND = false;
|
public static final boolean ALLOW_BACKEND = true;
|
||||||
public static final String DEFAULT_API_TOKEN = "ulBKE9MWEtIGiPAhXV69I28W9BRiSrV3";
|
public static final String DEFAULT_API_TOKEN = "-";
|
||||||
public static final boolean DEFAULT_SIGN_QUICK_PAY_ENABLED = true;
|
public static final boolean DEFAULT_SIGN_QUICK_PAY_ENABLED = true;
|
||||||
public static final boolean DEFAULT_GPS_ENABLED = true;
|
public static final boolean DEFAULT_GPS_ENABLED = true;
|
||||||
public static final GpsHudPosition DEFAULT_GPS_POSITION = GpsHudPosition.TOP_LEFT;
|
public static final GpsHudPosition DEFAULT_GPS_POSITION = GpsHudPosition.TOP_CENTER;
|
||||||
|
|
||||||
public static ModConfig createDefault() {
|
public static ModConfig createDefault() {
|
||||||
return new ModConfig(
|
return new ModConfig(
|
||||||
|
|||||||
Reference in New Issue
Block a user