Aggiunta calcolo valore prodotto e miglioramenti UI

Implementato il calcolo del valore reale dei prodotti in asta,
includendo il prezzo "Compra Subito", spese di spedizione e
risparmio stimato. Aggiunta una nuova sezione "Info Prodotto"
nella UI per visualizzare i dettagli estratti e i calcoli.

- **AuctionMonitorControl.xaml**: Aggiunta sezione fissa per
  mostrare informazioni prodotto e calcolo valore.
- **AuctionMonitorControl.xaml.cs**: Gestiti eventi per il
  caricamento e aggiornamento delle informazioni prodotto.
- **MainWindow**: Integrati handler per il calcolo e refresh
  delle informazioni prodotto.
- **AuctionInfo.cs**: Aggiunte proprietà per gestire prezzo
  "Compra Subito", spese di spedizione e limiti di vincita.
- **ProductValueCalculator.cs**: Nuova utility per calcolare
  il valore del prodotto e parsare informazioni dall'HTML.
- **AuctionViewModel.cs**: Binding per visualizzare risparmio,
  costo totale e convenienza nella UI.
- **Documentazione**: Aggiornata con dettagli sull'algoritmo
  di calcolo e layout UI.

Fix:
- Risolto problema di encoding UTF-8 per emoji nella UI.
- Migliorato parsing HTML per prezzi e limiti di vincita.

TODO:
- Testare parsing su più aste e gestire edge cases.
- Implementare caricamento automatico delle informazioni.
This commit is contained in:
2025-11-21 16:55:21 +01:00
parent f124f2e4e8
commit ee67bedc31
171 changed files with 134519 additions and 241 deletions
@@ -231,5 +231,107 @@ namespace AutoBidder
Log($"[ERRORE] Errore caricamento aste: {ex.Message}");
}
}
/// <summary>
/// Aggiorna i dettagli dell'asta selezionata nel pannello Info Prodotto
/// </summary>
private void UpdateSelectedAuctionDetails(AuctionViewModel? vm)
{
if (vm == null || vm.AuctionInfo == null)
{
// Resetta campi se nessuna asta selezionata
AuctionMonitor.ProductBuyNowPriceText.Text = "-";
AuctionMonitor.ProductShippingCostText.Text = "-";
AuctionMonitor.ProductWinLimitText.Text = "-";
return;
}
var auction = vm.AuctionInfo;
// CARICA AUTOMATICAMENTE INFO PRODOTTO SE NON PRESENTI
if (!auction.BuyNowPrice.HasValue && !auction.ShippingCost.HasValue)
{
// Carica in background senza bloccare l'UI
_ = LoadProductInfoInBackgroundAsync(auction);
}
// Aggiorna i campi delle impostazioni
UpdateAuctionSettingsDisplay(vm);
// Aggiorna Valore (Compra Subito)
if (auction.BuyNowPrice.HasValue)
{
AuctionMonitor.ProductBuyNowPriceText.Text = $"{auction.BuyNowPrice.Value:F2}€";
}
else
{
AuctionMonitor.ProductBuyNowPriceText.Text = "-";
}
// Aggiorna Spese di Spedizione
if (auction.ShippingCost.HasValue)
{
AuctionMonitor.ProductShippingCostText.Text = $"{auction.ShippingCost.Value:F2}€";
}
else
{
AuctionMonitor.ProductShippingCostText.Text = "-";
}
// Aggiorna Limiti di Vincita
if (auction.HasWinLimit && !string.IsNullOrWhiteSpace(auction.WinLimitDescription))
{
AuctionMonitor.ProductWinLimitText.Text = auction.WinLimitDescription;
}
else if (!auction.HasWinLimit)
{
AuctionMonitor.ProductWinLimitText.Text = "Nessun limite";
}
else
{
AuctionMonitor.ProductWinLimitText.Text = "-";
}
}
/// <summary>
/// Carica le informazioni del prodotto in background quando selezioni un'asta
/// </summary>
private async System.Threading.Tasks.Task LoadProductInfoInBackgroundAsync(AuctionInfo auction)
{
try
{
Log($"[PRODUCT INFO] Caricamento automatico per: {auction.Name}", Utilities.LogLevel.Info);
// Scarica HTML
using var httpClient = new System.Net.Http.HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(10);
var html = await httpClient.GetStringAsync(auction.OriginalUrl);
// Estrai informazioni prodotto
var extracted = Utilities.ProductValueCalculator.ExtractProductInfo(html, auction);
if (extracted)
{
// Salva le aste con le nuove informazioni
SaveAuctions();
// Aggiorna UI sul thread UI
Dispatcher.Invoke(() =>
{
if (_selectedAuction != null && _selectedAuction.AuctionId == auction.AuctionId)
{
UpdateSelectedAuctionDetails(_selectedAuction);
}
});
Log($"[PRODUCT INFO] Valore={auction.BuyNowPrice:F2}€, Spedizione={auction.ShippingCost:F2}€", Utilities.LogLevel.Success);
}
}
catch (Exception ex)
{
Log($"[PRODUCT INFO] Errore caricamento: {ex.Message}", Utilities.LogLevel.Warn);
}
}
}
}