diff --git a/FinTrack/Enums/CurrencyConversionType.cs b/FinTrack/Enums/CurrencyConversionType.cs new file mode 100644 index 0000000..0b8a3a7 --- /dev/null +++ b/FinTrack/Enums/CurrencyConversionType.cs @@ -0,0 +1,4 @@ +namespace FinTrack.Enums +{ + public enum CurrencyConversionType { Increase, Decrease } +} diff --git a/FinTrack/Enums/DebtStatus.cs b/FinTrack/Enums/DebtStatus.cs new file mode 100644 index 0000000..1ff5f46 --- /dev/null +++ b/FinTrack/Enums/DebtStatus.cs @@ -0,0 +1,13 @@ +namespace FinTrack.Enums +{ + public enum DebtStatus + { + PendingProposal, // Teklif gönderildi, borçlunun onayı bekleniyor + AwaitingVideoUpload, // Teklif kabul edildi, video yüklenmesi bekleniyor + AwaitingOperatorApproval,// Video yüklendi, operatör onayı bekleniyor + Active, // Operatör onayladı, borç aktif + RejectedByBorrower, // Borçlu teklifi reddetti + RejectedByOperator, // Operatör videoyu reddetti + Completed // Borç ödendi + } +} diff --git a/FinTrack/Enums/ExportFormat.cs b/FinTrack/Enums/ExportFormat.cs new file mode 100644 index 0000000..53bd38e --- /dev/null +++ b/FinTrack/Enums/ExportFormat.cs @@ -0,0 +1,12 @@ +namespace FinTrack.Enums +{ + public enum ExportFormat + { + PDF, + Word, + Excel, + Text, + Markdown, + XML + } +} diff --git a/FinTrack/Enums/MessageAuthor.cs b/FinTrack/Enums/MessageAuthor.cs new file mode 100644 index 0000000..c65caa4 --- /dev/null +++ b/FinTrack/Enums/MessageAuthor.cs @@ -0,0 +1,8 @@ +namespace FinTrack.Enums +{ + public enum MessageAuthor + { + Bot, + User + } +} diff --git a/FinTrack/Enums/ReportType.cs b/FinTrack/Enums/ReportType.cs new file mode 100644 index 0000000..b3624b4 --- /dev/null +++ b/FinTrack/Enums/ReportType.cs @@ -0,0 +1,9 @@ +namespace FinTrack.Enums +{ + public enum ReportType + { + Budget, + Account, + Transaction + } +} diff --git a/FinTrack/Helpers/NullToVisibilityConverter.cs b/FinTrack/Helpers/NullToVisibilityConverter.cs new file mode 100644 index 0000000..5fc0802 --- /dev/null +++ b/FinTrack/Helpers/NullToVisibilityConverter.cs @@ -0,0 +1,19 @@ +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace FinTrack.Helpers +{ + public class NullToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value == null ? Visibility.Collapsed : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/FinTrack/Models/Currency/CurrencyModel.cs b/FinTrack/Models/Currency/CurrencyModel.cs new file mode 100644 index 0000000..69f006d --- /dev/null +++ b/FinTrack/Models/Currency/CurrencyModel.cs @@ -0,0 +1,39 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using FinTrack.Enums; +using System.Windows.Media; + +namespace FinTrack.Models.Currency +{ + public partial class CurrencyModel : ObservableObject + { + [ObservableProperty] + private string toCurrencyFlag = string.Empty; + + [ObservableProperty] + private string toCurrencyCode = string.Empty; + + [ObservableProperty] + private string toCurrencyName = string.Empty; + + [ObservableProperty] + private decimal toCurrencyPrice; + + [ObservableProperty] + private string toCurrencyChange = string.Empty; + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(ToCurrencyChangeForeground))] + private CurrencyConversionType type = CurrencyConversionType.Increase; + + private static readonly Brush IncreaseBrush = new SolidColorBrush(Colors.Green); + private static readonly Brush DecreaseBrush = new SolidColorBrush(Colors.Red); + private static readonly Brush DefaultBrush = new SolidColorBrush(Colors.Gray); + + public Brush ToCurrencyChangeForeground => Type switch + { + CurrencyConversionType.Increase => IncreaseBrush, + CurrencyConversionType.Decrease => DecreaseBrush, + _ => DefaultBrush + }; + } +} diff --git a/FinTrack/Models/Debt/DebtModel.cs b/FinTrack/Models/Debt/DebtModel.cs new file mode 100644 index 0000000..661eef3 --- /dev/null +++ b/FinTrack/Models/Debt/DebtModel.cs @@ -0,0 +1,87 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using FinTrack.Enums; +using System.Windows.Media; + +namespace FinTrack.Models.Debt +{ + public partial class DebtModel : ObservableObject + { + [ObservableProperty] + private string lenderName = string.Empty; + + [ObservableProperty] + private string borrowerName = string.Empty; + + [ObservableProperty] + private string borrowerEmail = string.Empty; + + [ObservableProperty] + private decimal amount; + + [ObservableProperty] + private DateTime dueDate; + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(StatusText))] + [NotifyPropertyChangedFor(nameof(StatusBrush))] + [NotifyPropertyChangedFor(nameof(IsActionRequired))] + [NotifyPropertyChangedFor(nameof(IsRejected))] + private DebtStatus status; + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(DebtTitle))] + [NotifyPropertyChangedFor(nameof(UserIconPath))] + [NotifyPropertyChangedFor(nameof(IsCurrentUserTheBorrower))] + private string currentUserName = string.Empty; + + public string DebtTitle => IsCurrentUserTheBorrower ? $"Your debt: {LenderName}" : $"Debt owed to you: {BorrowerName}"; + + public string UserIconPath => IsCurrentUserTheBorrower ? "/Assets/Images/Icons/user-red.png" : "/Assets/Images/Icons/user-green.png"; + + public bool IsCurrentUserTheBorrower => BorrowerName == CurrentUserName; + + [ObservableProperty] + private string? rejectionReason; + + [ObservableProperty] + private DateTime createdDate = DateTime.Now; + + private static readonly Brush GreenBrush = new SolidColorBrush(Colors.Green); + private static readonly Brush RedBrush = new SolidColorBrush(Colors.Red); + private static readonly Brush BlueBrush = new SolidColorBrush(Colors.Blue); + private static readonly Brush OrangeBrush = new SolidColorBrush(Colors.Orange); + private static readonly Brush GrayBrush = new SolidColorBrush(Colors.Gray); + + public Brush StatusBrush => Status switch + { + DebtStatus.Active => GreenBrush, + DebtStatus.AwaitingVideoUpload => BlueBrush, + DebtStatus.AwaitingOperatorApproval => OrangeBrush, + DebtStatus.RejectedByOperator => RedBrush, + DebtStatus.RejectedByBorrower => RedBrush, + _ => GrayBrush + }; + + public string StatusText => Status switch + { + DebtStatus.AwaitingVideoUpload => "Status: Awaiting Video Approval", + DebtStatus.AwaitingOperatorApproval => "Status: FinTrack Operator Approval Pending", + DebtStatus.Active => "Status: Active - In force", + DebtStatus.RejectedByOperator => "Status: Rejected by Operator", + DebtStatus.RejectedByBorrower => "Status: Rejected by Borrower", + _ => "Status: Unknown" + }; + + public bool IsActionRequired => Status == DebtStatus.AwaitingVideoUpload; + + public bool IsRejected => Status == DebtStatus.RejectedByBorrower || Status == DebtStatus.RejectedByOperator; + + public string InfoText => Status switch + { + DebtStatus.Active => $"Final Payment: {DueDate:dd.MM.yyyy}", + DebtStatus.AwaitingOperatorApproval => "Video uploaded", + DebtStatus.RejectedByOperator => $"Reason: {RejectionReason}", + _ => string.Empty + }; + } +} diff --git a/FinTrack/Models/FinBot/ChatMessageModel.cs b/FinTrack/Models/FinBot/ChatMessageModel.cs new file mode 100644 index 0000000..1f8bce7 --- /dev/null +++ b/FinTrack/Models/FinBot/ChatMessageModel.cs @@ -0,0 +1,28 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using FinTrack.Enums; +using System.Collections.ObjectModel; + +namespace FinTrack.Models.FinBot +{ + public partial class ChatMessageModel : ObservableObject + { + [ObservableProperty] + private string text; + + [ObservableProperty] + private MessageAuthor author; + + [ObservableProperty] + private DateTime timestamp = DateTime.Now; + + public ObservableCollection? QuickActions { get; set; } + + public bool IsSentByCurrentUser => Author == MessageAuthor.User; + + public ChatMessageModel(string _text, MessageAuthor _author) + { + text = _text; + author = _author; + } + } +} diff --git a/FinTrack/Models/Report/SelectableOptionReport.cs b/FinTrack/Models/Report/SelectableOptionReport.cs new file mode 100644 index 0000000..edb6041 --- /dev/null +++ b/FinTrack/Models/Report/SelectableOptionReport.cs @@ -0,0 +1,19 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace FinTrack.Models.Report +{ + public partial class SelectableOptionReport : ObservableObject + { + [ObservableProperty] + private string name; + + [ObservableProperty] + private bool isSelected; + + public SelectableOptionReport(string _name, bool _isSelected = false) + { + name = _name; + isSelected = _isSelected; + } + } +} diff --git a/FinTrack/Styles/ModernStyles.xaml b/FinTrack/Styles/ModernStyles.xaml index 0cafa18..bee571b 100644 --- a/FinTrack/Styles/ModernStyles.xaml +++ b/FinTrack/Styles/ModernStyles.xaml @@ -13,6 +13,9 @@ + + + @@ -546,7 +549,7 @@ - + @@ -567,6 +570,41 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/FinTrack/ViewModels/CurrenciesViewModel.cs b/FinTrack/ViewModels/CurrenciesViewModel.cs index 6190991..1bdf317 100644 --- a/FinTrack/ViewModels/CurrenciesViewModel.cs +++ b/FinTrack/ViewModels/CurrenciesViewModel.cs @@ -1,8 +1,139 @@ using CommunityToolkit.Mvvm.ComponentModel; +using FinTrack.Models.Currency; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; namespace FinTrack.ViewModels { public partial class CurrenciesViewModel : ObservableObject { + private ObservableCollection allCurrencies; + + [ObservableProperty] + private ObservableCollection filteredCurrencies; + + [ObservableProperty] + private CurrencyModel? selectedCurrency; + + [ObservableProperty] + private string currencySearch = string.Empty; + + [ObservableProperty] + private string toCurrencyCode = string.Empty; + + [ObservableProperty] + private string toCurrencyName = string.Empty; + + [ObservableProperty] + private string toCurrencyPrice = string.Empty; + + [ObservableProperty] + private string weeklyChange = string.Empty; + + [ObservableProperty] + private string monthlyChange = string.Empty; + + private readonly ILogger _logger; + + public CurrenciesViewModel(ILogger logger) + { + _logger = logger; + + LoadSampleData(); + } + partial void OnCurrencySearchChanged(string value) + { + FilterCurrencies(); + } + + private void FilterCurrencies() + { + if (string.IsNullOrWhiteSpace(CurrencySearch)) + { + FilteredCurrencies = new ObservableCollection(allCurrencies); + } + else + { + var filtered = allCurrencies + .Where(c => c.ToCurrencyCode.Contains(CurrencySearch, StringComparison.OrdinalIgnoreCase) || + c.ToCurrencyName.Contains(CurrencySearch, StringComparison.OrdinalIgnoreCase)); + FilteredCurrencies = new ObservableCollection(filtered); + } + + _logger.LogInformation("Para birimleri '{SearchText}' metnine göre filtrelendi.", CurrencySearch); + } + + private void LoadSampleData() + { + allCurrencies = new ObservableCollection + { + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/try.png", + ToCurrencyCode = "TRY", + ToCurrencyName = "Turkish Lira", + ToCurrencyPrice = 32.56m, + ToCurrencyChange = "+0.12 (0.37%)", + Type = Enums.CurrencyConversionType.Increase + }, + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/eur.png", + ToCurrencyCode = "EUR", + ToCurrencyName = "Euro", + ToCurrencyPrice = 3.06m, + ToCurrencyChange = "-0.12 (0.37%)", + Type = Enums.CurrencyConversionType.Decrease + }, + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/gbp.png", + ToCurrencyCode = "GBP", + ToCurrencyName = "British Pound", + ToCurrencyPrice = 0.08m, + ToCurrencyChange = "+0.20 (0.80%)", + Type = Enums.CurrencyConversionType.Decrease + }, + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/eur.png", + ToCurrencyCode = "EUR", + ToCurrencyName = "Euro", + ToCurrencyPrice = 3.06m, + ToCurrencyChange = "-0.12 (0.37%)", + Type = Enums.CurrencyConversionType.Decrease + }, + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/gbp.png", + ToCurrencyCode = "GBP", + ToCurrencyName = "British Pound", + ToCurrencyPrice = 0.08m, + ToCurrencyChange = "+0.20 (0.80%)", + Type = Enums.CurrencyConversionType.Decrease + }, + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/eur.png", + ToCurrencyCode = "EUR", + ToCurrencyName = "Euro", + ToCurrencyPrice = 3.06m, + ToCurrencyChange = "-0.12 (0.37%)", + Type = Enums.CurrencyConversionType.Decrease + }, + new CurrencyModel + { + ToCurrencyFlag = "https://currencyfreaks.com/photos/flags/gbp.png", + ToCurrencyCode = "GBP", + ToCurrencyName = "British Pound", + ToCurrencyPrice = 0.08m, + ToCurrencyChange = "+0.20 (0.80%)", + Type = Enums.CurrencyConversionType.Decrease + } + }; + FilterCurrencies(); + SelectedCurrency = FilteredCurrencies.FirstOrDefault(); + _logger.LogInformation("Örnek para birimleri yüklendi."); + } } } diff --git a/FinTrack/ViewModels/DebtViewModel.cs b/FinTrack/ViewModels/DebtViewModel.cs index ad9ed1a..5c3e0c1 100644 --- a/FinTrack/ViewModels/DebtViewModel.cs +++ b/FinTrack/ViewModels/DebtViewModel.cs @@ -1,8 +1,169 @@ using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using FinTrack.Enums; +using FinTrack.Models.Debt; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; +using System.Windows; namespace FinTrack.ViewModels { public partial class DebtViewModel : ObservableObject { + private const string CurrentUserName = "Siz"; + + private readonly ILogger _logger; + + private ObservableCollection allDebts; + + [ObservableProperty] + private string? newProposalBorrowerEmail; + + [ObservableProperty] + private decimal newProposalAmount; + + [ObservableProperty] + private DateTime newProposalDueDate = DateTime.Now.AddMonths(1); + + [ObservableProperty] + private ObservableCollection pendingOffers; + + [ObservableProperty] + private ObservableCollection myDebtsList; + + public DebtViewModel(ILogger logger) + { + _logger = logger; + allDebts = new ObservableCollection(); + pendingOffers = new ObservableCollection(); + myDebtsList = new ObservableCollection(); + + LoadSampleData(); + RefreshLists(); + } + + [RelayCommand] + private void SendOffer() + { + if (string.IsNullOrWhiteSpace(NewProposalBorrowerEmail) || NewProposalAmount <= 0) + { + MessageBox.Show("Lütfen tüm alanları doldurun.", "Doğrulama Hatası"); + return; + } + + var newDebt = new DebtModel + { + LenderName = CurrentUserName, + BorrowerName = "Unknown", + Amount = NewProposalAmount, + DueDate = NewProposalDueDate, + Status = DebtStatus.PendingProposal, + CurrentUserName = CurrentUserName + }; + + allDebts.Add(newDebt); + RefreshLists(); + + NewProposalBorrowerEmail = string.Empty; + NewProposalAmount = 0; + _logger.LogInformation("Yeni borç teklifi gönderildi."); + } + + [RelayCommand] + private void ConfirmOffer(DebtModel debt) + { + if (debt == null) return; + + debt.Status = DebtStatus.AwaitingVideoUpload; + debt.BorrowerName = CurrentUserName; + RefreshLists(); + _logger.LogInformation("{Amount} TRY tutarındaki borç teklifi onaylandı.", debt.Amount); + } + + [RelayCommand] + private void RejectOffer(DebtModel debt) + { + if (debt == null) return; + + debt.Status = DebtStatus.RejectedByBorrower; + RefreshLists(); + _logger.LogWarning("{Amount} TRY tutarındaki borç teklifi reddedildi.", debt.Amount); + } + + [RelayCommand] + private void UploadVideo(DebtModel debt) + { + if (debt == null) return; + + debt.Status = DebtStatus.AwaitingOperatorApproval; + RefreshLists(); + _logger.LogInformation("{Amount} TRY borcu için onay videosu yüklendi, operatör onayı bekleniyor.", debt.Amount); + MessageBox.Show("Video başarıyla yüklendi. Operatör onayı bekleniyor.", "Başarılı"); + } + + private void RefreshLists() + { + var pending = allDebts.Where(d => d.Status == DebtStatus.PendingProposal && d.LenderName != CurrentUserName).ToList(); + PendingOffers.Clear(); + foreach (var item in pending) PendingOffers.Add(item); + + var myDebts = allDebts.Where(d => d.Status != DebtStatus.PendingProposal && (d.LenderName == CurrentUserName || d.BorrowerName == CurrentUserName)).ToList(); + MyDebtsList.Clear(); + foreach (var item in myDebts) MyDebtsList.Add(item); + } + + private void LoadSampleData() + { + allDebts = new ObservableCollection + { + new DebtModel + { + LenderName = "Ahmet Yılmaz", + BorrowerName = "Unknown", + Amount = 500, + DueDate = new DateTime(2024, 6, 15), + Status = DebtStatus.PendingProposal, + CurrentUserName = CurrentUserName + }, + new DebtModel + { + LenderName = CurrentUserName, + BorrowerName = "Eylül Korkmaz", + Amount = 2500, + DueDate = new DateTime(2024, 10, 1), + Status = DebtStatus.AwaitingVideoUpload, + CurrentUserName = CurrentUserName + }, + new DebtModel + { + LenderName = "Sinem Berçem", + BorrowerName = CurrentUserName, + Amount = 30000, + DueDate = new DateTime(2024, 8, 31), + Status = DebtStatus.Active, + CurrentUserName = CurrentUserName + }, + new DebtModel + { + LenderName = CurrentUserName, + BorrowerName = "Ali Veli", + Amount = 800000, + DueDate = new DateTime(2025, 1, 1), + Status = DebtStatus.AwaitingOperatorApproval, + CurrentUserName = CurrentUserName + }, + new DebtModel + { + LenderName = CurrentUserName, + BorrowerName = "Canan Aslan", + Amount = 1000, + DueDate = new DateTime(2024, 9, 20), + Status = DebtStatus.RejectedByOperator, + RejectionReason = "Insufficient video", + CurrentUserName = CurrentUserName + } + }; + _logger.LogInformation("Örnek borç verileri yüklendi."); + } } -} +} \ No newline at end of file diff --git a/FinTrack/ViewModels/FinBotViewModel.cs b/FinTrack/ViewModels/FinBotViewModel.cs index 8964c81..38ccf25 100644 --- a/FinTrack/ViewModels/FinBotViewModel.cs +++ b/FinTrack/ViewModels/FinBotViewModel.cs @@ -1,8 +1,106 @@ using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using FinTrack.Enums; +using FinTrack.Models.FinBot; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; namespace FinTrack.ViewModels { public partial class FinBotViewModel : ObservableObject { + public ObservableCollection Messages { get; } + + [ObservableProperty] + [NotifyCanExecuteChangedFor(nameof(SendMessageCommand))] + private string messageInput = string.Empty; + + private readonly ILogger _logger; + + public FinBotViewModel(ILogger logger) + { + _logger = logger; + Messages = new ObservableCollection(); + + LoadInitialMessage(); + } + + private void LoadInitialMessage() + { + var initialMessage = new ChatMessageModel("Welcome to FinBot! How can I assist you today?", MessageAuthor.Bot) + { + QuickActions = new ObservableCollection + { + "View Account Balance", + "Recent Transactions", + "Budget Overview" + } + }; + Messages.Add(initialMessage); + _logger.LogInformation("Initial message loaded: {MessageText}", initialMessage.Text); + } + + [RelayCommand(CanExecute = nameof(CanSendMessage))] + private async Task SendMessageAsync() + { + if (!CanSendMessage) return; + + var userMessage = new ChatMessageModel(MessageInput, MessageAuthor.User); + Messages.Add(userMessage); + + MessageInput = string.Empty; + + _logger.LogInformation("Kullanıcı mesaj yazdı. {MessageText}", userMessage.Text); + + await ProcessBotResponseAsync(userMessage.Text); + } + + private bool CanSendMessage => !string.IsNullOrWhiteSpace(MessageInput); + + [RelayCommand] + private async Task SendQuickActionAsync(string actionText) + { + if (string.IsNullOrWhiteSpace(actionText)) return; + + var userMessage = new ChatMessageModel(actionText, MessageAuthor.User); + Messages.Add(userMessage); + + _logger.LogInformation("Kullanıcı hızlı eylem seçti: {ActionText}", actionText); + + await ProcessBotResponseAsync(actionText); + } + + + + + + + // TODO: [TEST] + private async Task ProcessBotResponseAsync(string userMessage) + { + // Bot "yazıyor..." efekti için küçük bir bekleme + await Task.Delay(1000); + + ChatMessageModel botResponse; + string lowerUserMessage = userMessage.ToLower(); + + if (lowerUserMessage.Contains("bakiye")) + { + botResponse = new ChatMessageModel("Toplam bakiyeniz tüm hesaplarınızda $12,450.75.", MessageAuthor.Bot); + } + else if (lowerUserMessage.Contains("teşekkür")) + { + botResponse = new ChatMessageModel("Rica ederim! Başka bir konuda yardımcı olabilir miyim?", MessageAuthor.Bot); + } + else + { + botResponse = new ChatMessageModel("Üzgünüm, bu isteği anlayamadım. Lütfen farklı bir şekilde sormayı deneyin.", MessageAuthor.Bot) + { + QuickActions = new ObservableCollection { "Yeni Bütçe Oluştur", "Hesap Bakiyem", "Rapor Oluştur" } + }; + } + + Messages.Add(botResponse); + } } } diff --git a/FinTrack/ViewModels/ReportsViewModel.cs b/FinTrack/ViewModels/ReportsViewModel.cs index a58fa8c..345cd82 100644 --- a/FinTrack/ViewModels/ReportsViewModel.cs +++ b/FinTrack/ViewModels/ReportsViewModel.cs @@ -1,8 +1,107 @@ using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using FinTrack.Enums; +using FinTrack.Models.Report; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; +using System.Text; +using System.Windows; namespace FinTrack.ViewModels { public partial class ReportsViewModel : ObservableObject { + public ObservableCollection AvailableReportTypes { get; } + public ObservableCollection AvailableAccounts { get; } + public ObservableCollection AvailableCategories { get; } + public ObservableCollection SortingCriteria { get; } + public ObservableCollection AvailableExportFormats { get; } + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(ReportSummary))] + private ReportType selectedReportType; + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(ReportSummary))] + private DateTime startDate = new DateTime(DateTime.Now.Year, 1, 1); + + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(ReportSummary))] + private DateTime endDate = new DateTime(DateTime.Now.Year, 12, 31); + + [ObservableProperty] + private bool isIncomeSelected = true; + + [ObservableProperty] + private bool isExpenseSelected = true; + + [ObservableProperty] + private string selectedSortingCriterion; + + [ObservableProperty] + private ExportFormat selectedExportFormat; + + private readonly ILogger _logger; + + public string ReportSummary + { + get + { + var summary = new StringBuilder(); + if (SelectedReportType != null) + { + summary.Append($"{SelectedReportType} Report, "); + summary.Append($"{StartDate:dd.MM.yyyy} - {EndDate:dd.MM.yyyy} "); + summary.Append("it will include all accounts and categories between the dates."); + } + return summary.ToString(); + } + } + + public ReportsViewModel(ILogger logger) + { + _logger = logger; + + AvailableReportTypes = new ObservableCollection(Enum.GetValues(typeof(ReportType)).Cast()); + AvailableAccounts = new ObservableCollection(); + AvailableCategories = new ObservableCollection(); + SortingCriteria = new ObservableCollection(); + AvailableExportFormats = new ObservableCollection(Enum.GetValues(typeof(ExportFormat)).Cast()); + + LoadSampleData(); + } + + private void LoadSampleData() + { + AvailableAccounts.Clear(); + AvailableAccounts.Add(new SelectableOptionReport("All Accounts", true)); + AvailableAccounts.Add(new SelectableOptionReport("Cash")); + AvailableAccounts.Add(new SelectableOptionReport("Bank Account - A")); + AvailableAccounts.Add(new SelectableOptionReport("Credit Card - B")); + + AvailableCategories.Clear(); + AvailableCategories.Add(new SelectableOptionReport("All Categories", true)); + AvailableCategories.Add(new SelectableOptionReport("Groceries")); + AvailableCategories.Add(new SelectableOptionReport("Salary")); + AvailableCategories.Add(new SelectableOptionReport("Rent")); + + SortingCriteria.Clear(); + SortingCriteria.Add("By Date (Newest to Oldest)"); + SortingCriteria.Add("By Date (Oldest to Newest)"); + SortingCriteria.Add("By Amount (Highest to Lowest)"); + SortingCriteria.Add("By Amount (Lowest to Highest)"); + SelectedReportType = AvailableReportTypes.FirstOrDefault(); + SelectedSortingCriterion = SortingCriteria.FirstOrDefault(); + SelectedExportFormat = AvailableExportFormats.FirstOrDefault(); + } + + [RelayCommand] + private void CreateReport() + { + _logger?.LogInformation("Aşağıdaki parametrelerle rapor oluşturma: {ReportType}, {StartDate} ila {EndDate}, Seçilen Gelir: {IsIncomeSelected}, Seçilen Gider: {IsExpenseSelected}, Sıralama Kriterleri: {SortingCriteria}, Dışa Aktarma Biçimi: {ExportFormat}", + SelectedReportType, StartDate, EndDate, IsIncomeSelected, IsExpenseSelected, SelectedSortingCriterion, SelectedExportFormat); + + MessageBox.Show("Report creation logic triggered! Check your logs.", "Success"); + } } -} +} \ No newline at end of file diff --git a/FinTrack/Views/AccountView.xaml b/FinTrack/Views/AccountView.xaml index 5e79f91..fa0949a 100644 --- a/FinTrack/Views/AccountView.xaml +++ b/FinTrack/Views/AccountView.xaml @@ -20,7 +20,7 @@ - + - - - - - - - - + + + + + + + - - - - - - - - - - - - - + + - - - - - -