Removed async/await keywords from methods that don't perform any async operations. The methods were triggering CS1998 warnings and running synchronously despite being marked async.
115 lines
3.7 KiB
C#
115 lines
3.7 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using MoneyMap.Data;
|
|
using MoneyMap.Models;
|
|
using MoneyMap.Services;
|
|
|
|
namespace MoneyMap.Pages;
|
|
|
|
public class ReviewAISuggestionsModel : PageModel
|
|
{
|
|
private readonly MoneyMapContext _db;
|
|
private readonly ITransactionAICategorizer _aiCategorizer;
|
|
|
|
public ReviewAISuggestionsModel(MoneyMapContext db, ITransactionAICategorizer aiCategorizer)
|
|
{
|
|
_db = db;
|
|
_aiCategorizer = aiCategorizer;
|
|
}
|
|
|
|
public List<TransactionWithProposal> Transactions { get; set; } = new();
|
|
public bool IsGenerating { get; set; }
|
|
public int TotalUncategorized { get; set; }
|
|
|
|
[TempData]
|
|
public string? SuccessMessage { get; set; }
|
|
|
|
[TempData]
|
|
public string? ErrorMessage { get; set; }
|
|
|
|
public async Task OnGetAsync()
|
|
{
|
|
// Get uncategorized transactions
|
|
var uncategorized = await _db.Transactions
|
|
.Include(t => t.Merchant)
|
|
.Where(t => string.IsNullOrEmpty(t.Category))
|
|
.OrderByDescending(t => t.Date)
|
|
.Take(50) // Limit to 50 most recent
|
|
.ToListAsync();
|
|
|
|
TotalUncategorized = uncategorized.Count;
|
|
Transactions = uncategorized.Select(t => new TransactionWithProposal
|
|
{
|
|
Transaction = t,
|
|
Proposal = null // Will be populated via AJAX or on generate
|
|
}).ToList();
|
|
}
|
|
|
|
public async Task<IActionResult> OnPostGenerateSuggestionsAsync()
|
|
{
|
|
// Get uncategorized transactions
|
|
var uncategorized = await _db.Transactions
|
|
.Where(t => string.IsNullOrEmpty(t.Category))
|
|
.OrderByDescending(t => t.Date)
|
|
.Take(20) // Limit to 20 for cost control
|
|
.ToListAsync();
|
|
|
|
if (!uncategorized.Any())
|
|
{
|
|
ErrorMessage = "No uncategorized transactions found.";
|
|
return RedirectToPage();
|
|
}
|
|
|
|
// Generate proposals
|
|
var proposals = await _aiCategorizer.ProposeBatchCategorizationAsync(uncategorized);
|
|
|
|
// Store proposals in session for review
|
|
HttpContext.Session.SetString("AIProposals", System.Text.Json.JsonSerializer.Serialize(proposals));
|
|
|
|
SuccessMessage = $"Generated {proposals.Count} AI suggestions. Review them below.";
|
|
return RedirectToPage("ReviewAISuggestionsWithProposals");
|
|
}
|
|
|
|
public async Task<IActionResult> OnPostApplyProposalAsync(long transactionId, string category, string? merchant, string? pattern, decimal confidence, bool createRule)
|
|
{
|
|
var proposal = new AICategoryProposal
|
|
{
|
|
TransactionId = transactionId,
|
|
Category = category,
|
|
CanonicalMerchant = merchant,
|
|
Pattern = pattern,
|
|
Confidence = confidence,
|
|
CreateRule = createRule
|
|
};
|
|
|
|
var result = await _aiCategorizer.ApplyProposalAsync(transactionId, proposal, createRule);
|
|
|
|
if (result.Success)
|
|
{
|
|
SuccessMessage = result.RuleCreated
|
|
? "Transaction categorized and rule created!"
|
|
: "Transaction categorized!";
|
|
}
|
|
else
|
|
{
|
|
ErrorMessage = result.ErrorMessage ?? "Failed to apply suggestion.";
|
|
}
|
|
|
|
return RedirectToPage();
|
|
}
|
|
|
|
public IActionResult OnPostRejectProposalAsync(long transactionId)
|
|
{
|
|
// Just refresh the page, removing this transaction from view
|
|
SuccessMessage = "Suggestion rejected.";
|
|
return RedirectToPage();
|
|
}
|
|
|
|
public class TransactionWithProposal
|
|
{
|
|
public Transaction Transaction { get; set; } = null!;
|
|
public AICategoryProposal? Proposal { get; set; }
|
|
}
|
|
}
|