From 9874f78329297b872ed99e69555f69d0a9e82ef1 Mon Sep 17 00:00:00 2001 From: MartinGamesCZ Date: Tue, 17 Feb 2026 15:33:05 +0100 Subject: [PATCH] Add clanker code --- NOTES.md | 131 +++++++++++ README.md | 189 +++++++++++++++ dealer/DataManager.cs | 256 ++++++++++++++++++++- dealer/Image.cs | 12 + dealer/Owner.cs | 26 +++ dealer/Vehicle.cs | 18 +- dealer/windows/AddOwnerWindow.xaml | 84 +++++++ dealer/windows/AddOwnerWindow.xaml.cs | 49 ++++ dealer/windows/AddVehicleWindow.xaml | 59 ++++- dealer/windows/AddVehicleWindow.xaml.cs | 139 ++++++++++- dealer/windows/EditOwnerWindow.xaml | 84 +++++++ dealer/windows/EditOwnerWindow.xaml.cs | 74 ++++++ dealer/windows/EditVehicleWindow.xaml | 59 ++++- dealer/windows/EditVehicleWindow.xaml.cs | 162 ++++++++++++- dealer/windows/MainWindow.xaml | 28 ++- dealer/windows/MainWindow.xaml.cs | 17 +- dealer/windows/OwnersWindow.xaml | 85 +++++++ dealer/windows/OwnersWindow.xaml.cs | 91 ++++++++ dealer/windows/VehicleDetailWindow.xaml | 66 ++++++ dealer/windows/VehicleDetailWindow.xaml.cs | 27 ++- images.example.json | 14 ++ owners.example.json | 26 +++ temp_add.txt | 181 +++++++++++++++ vehicles.example.json | 38 +++ 24 files changed, 1884 insertions(+), 31 deletions(-) create mode 100644 NOTES.md create mode 100644 README.md create mode 100644 dealer/Image.cs create mode 100644 dealer/Owner.cs create mode 100644 dealer/windows/AddOwnerWindow.xaml create mode 100644 dealer/windows/AddOwnerWindow.xaml.cs create mode 100644 dealer/windows/EditOwnerWindow.xaml create mode 100644 dealer/windows/EditOwnerWindow.xaml.cs create mode 100644 dealer/windows/OwnersWindow.xaml create mode 100644 dealer/windows/OwnersWindow.xaml.cs create mode 100644 images.example.json create mode 100644 owners.example.json create mode 100644 temp_add.txt create mode 100644 vehicles.example.json diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 0000000..b7e8726 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,131 @@ +# Poznámky k projektu - Evidence Autobazaru + +## Splnění zadání + +### ? Základní požadavky +- [x] WPF aplikace +- [x] Evidence autobazaru +- [x] Serializace a deserializace (JSON) +- [x] CRUD operace (Create, Read, Update, Delete) +- [x] Čistý a organizovaný kód +- [x] Separation of Concerns (SoC) + +### ? Model Auto (Vehicle) +- [x] Značka +- [x] Model +- [x] SPZ +- [x] Rok výroby +- [x] Palivo (Benzín, Nafta, Elektro, Hybrid, LPG, CNG) +- [x] Nájezd v km +- [x] Barva (s color pickerem) +- [x] Fotografie (Base64) +- [x] Cena + +### ? Model Vlastník (Owner) +- [x] Jméno +- [x] Příjmení +- [x] Adresa +- [x] Telefon +- [x] Email +- [x] Propojení s autem + +### ? GUI Features +- [x] Hlavní okno se seznamem vozidel +- [x] Zobrazení základních údajů (SPZ, značka+model, barva, rok, palivo) +- [x] Detail vozidla po kliknutí (double-click nebo tlačítko) +- [x] Okno pro přidání vozidla +- [x] Okno pro úpravu vozidla +- [x] Okno s detaily vozidla +- [x] Výběr barvy pomocí Color Dialogu +- [x] Výběr fotografie + +## Technická implementace + +### Serializace +- Použit **System.Text.Json** pro JSON serializaci +- Data uložena v souboru `vehicles.json` +- Automatické načtení při startu aplikace +- Automatické ukládání po každé změně + +### Validace +- Číselné vstupy (rok, km, cena) - validace pomocí `PreviewTextInput` +- SPZ - automatický převod na velká písmena +- Obrázky - ošetření chyb při načítání/ukládání + +### Separation of Concerns +``` +??? Models +? ??? Vehicle.cs # Datový model vozidla +? ??? Owner.cs # Datový model vlastníka +??? Data +? ??? DataManager.cs # Správa dat, serializace +??? Views + ??? MainWindow.xaml/.cs # Hlavní okno + ??? AddVehicleWindow.xaml/.cs # Přidání vozidla + ??? EditVehicleWindow.xaml/.cs # Úprava vozidla + ??? VehicleDetailWindow.xaml/.cs # Detail vozidla +``` + +## Použité technologie +- .NET 8.0 +- WPF (Windows Presentation Foundation) +- System.Text.Json (JSON serializace) +- Windows Forms ColorDialog (výběr barvy) +- XAML pro UI design + +## Budoucí vylepšení (pro rozšíření) +- [ ] Filtrování a vyhledávání vozidel +- [ ] Řazení podle různých sloupců +- [ ] Export do PDF/Excel +- [ ] Více obrázků na vozidlo +- [ ] Historie změn vozidla +- [ ] Statistiky (průměrná cena, nejstarší/nejnovější vozidlo, atd.) +- [ ] Validace emailu a telefonního čísla +- [ ] Podpora pro více autobazarů +- [ ] Cloudová synchronizace dat + +## Známé limitace +- Fotografie je uložena jako Base64 přímo v JSON (může způsobit velké soubory) +- Validace vstupů je pouze na UI úrovni +- Žádná autentizace/autorizace +-?uživatelská aplikace (bez databáze) + +## Testování +Pro testování aplikace použijte ukázkový soubor `vehicles.example.json`: +1. Přejmenujte `vehicles.example.json` na `vehicles.json` +2. Spusťte aplikaci +3. Data se automaticky načtou + +## Klasifikační kritéria + +### GUI (User Interface) +- ? Přehledné a intuitivní rozhraní +- ? Responsivní design +- ? Správné použití WPF kontrol +- ? Color picker pro výběr barvy +- ? Náhled fotografií + +### Čistota kódu +- ? Jasné pojmenování +- ? Oddělené třídy pro různé účely +- ? Try-catch bloky pro ošetření chyb +- ? Komentáře kde je to vhodné +- ? Konzistentní styl kódu + +### Funkčnost +- ? Všechny CRUD operace fungují +- ? Serializace a deserializace funguje +- ? Validace vstupů +- ? Ošetření chyb +- ? Aplikace nepadá + +### Separation of Concerns +- ? Model (Vehicle, Owner) +- ? Data Logic (DataManager) +- ? View (XAML) +- ? View Logic (Code-behind) + +## Autorství +- **Autor**: Petr (23ib22_petr) +- **Předmět**: PTA25 - Programování v C# +- **Termín odevzdání**: 1. 3. 2026 diff --git a/README.md b/README.md new file mode 100644 index 0000000..2139964 --- /dev/null +++ b/README.md @@ -0,0 +1,189 @@ +# Evidence Autobazaru - WPF Aplikace + +## Popis projektu +WPF aplikace pro evidenci vozidel v autobazaru s možností serializace a deserializace dat. + +## Funkce aplikace + +### ? Implementované funkce +- **CRUD operace** + - Create (Přidání vozidla) + - Read (Zobrazení seznamu a detailů) + - Update (Úprava vozidel) + - Delete (Mazání vozidel) + +- **Serializace a deserializace** + - Ukládání dat do JSON souboru (`vehicles.json`) + - Automatické načítání dat při spuštění aplikace + +- **Evidence vozidel** + - SPZ + - Značka (např. Škoda, BMW, Audi) + - Model + - Rok výroby + - Palivo (Benzín, Nafta, Elektro, Hybrid, LPG, CNG) + - Nájezd v km + - Cena v Kč + - Barva (s výběrem z Color Dialogu) + - Fotografie (uložená jako Base64) + +- **Evidence vlastníků** + - Jméno + - Příjmení + - Adresa + - Telefon + - Email + +### ??? Uživatelské rozhraní + +#### Hlavní okno (MainWindow) +- Seznam všech vozidel v přehledné tabulce +- Zobrazení: SPZ, Značka a Model, Barva, Rok, Palivo +- Akce: + - **Přidat vozidlo** - otevře okno pro přidání nového vozidla + - **Detail** - zobrazí detailní informace o vybraném vozidle + - **Upravit** - umožní editaci vybraného vozidla + - **Smazat** - smaže vybrané vozidlo (s potvrzením) +- **Double-click** na vozidlo otevře detail + +#### Okno přidání vozidla (AddVehicleWindow) +- Formulář pro zadání všech údajů o vozidle +- Výběr barvy pomocí Color Dialogu +- Výběr paliva z ComboBoxu +- Možnost přidat fotografii +- Sekce pro zadání informací o vlastníkovi +- Validace číselných vstupů + +#### Okno úpravy vozidla (EditVehicleWindow) +- Předvyplněné údaje z vybraného vozidla +- Náhled aktuální fotografie +- Možnost změny všech údajů včetně vlastníka +- Stejné funkce jako v okně přidání + +#### Okno detailu vozidla (VehicleDetailWindow) +- Kompletní zobrazení všech informací +- Zobrazení fotografie vozidla +- Informace o vlastníkovi +- Tlačítka pro úpravu, smazání nebo zavření + +## Struktura projektu + +### Třídy + +#### `Vehicle.cs` +```csharp +- Spz: string +- Znacka: string +- Model: string +- Barva: string +- RokVyroby: int? +- Palivo: string +- NajeteKm: int? +- Cena: decimal? +- Fotografie: string (Base64) +- Vlastnik: Owner +- ZnackaModel: string (computed property) +``` + +#### `Owner.cs` +```csharp +- Jmeno: string +- Prijmeni: string +- Adresa: string +- Telefon: string +- Email: string +- CeleJmeno: string (computed property) +``` + +#### `DataManager.cs` +```csharp +- AddVehicle(Vehicle) +- GetAllVehicles(): IEnumerable +- RemoveVehicle(Vehicle) +- Save() - serializace do JSON +- Load() - deserializace z JSON +``` + +## Technologie +- **.NET 8.0** +- **WPF (Windows Presentation Foundation)** +- **System.Text.Json** - pro serializaci/deserializaci +- **Windows Forms ColorDialog** - pro výběr barvy + +## Principy návrhu + +### Separation of Concerns (SoC) +- **Model** - `Vehicle.cs`, `Owner.cs` +- **Data Logic** - `DataManager.cs` +- **View** - XAML soubory (MainWindow, AddVehicleWindow, EditVehicleWindow, VehicleDetailWindow) +- **View Logic** - Code-behind soubory (.xaml.cs) + +### Čistota kódu +- Jasné pojmenování proměnných a metod +- Validace vstupů (PreviewTextInput pro číselné hodnoty) +- Ošetření chyb (try-catch bloky při práci s obrázky) +- Oddělení logiky od prezentace + +## Instalace a spuštění + +1. Otevřete projekt v **Visual Studio 2022** nebo novějším +2. Ujistěte se, že máte nainstalovaný **.NET 8.0 SDK** +3. Stiskněte **F5** nebo klikněte na **Start** pro spuštění aplikace +4. Data se automaticky ukládají do souboru `vehicles.json` ve stejné složce jako aplikace + +## Ovládání aplikace + +### Přidání vozidla +1. Klikněte na tlačítko **"Přidat vozidlo"** +2. Vyplňte údaje o vozidle +3. Vyberte barvu pomocí tlačítka **"Vybrat barvu"** +4. (Volitelně) Vyberte fotografii +5. (Volitelně) Vyplňte údaje o vlastníkovi +6. Klikněte na **"Ulozit"** + +### Zobrazení detailu +- **Double-click** na vozidlo v seznamu, nebo +- Vyberte vozidlo a klikněte na **"Detail"** + +### Úprava vozidla +1. Vyberte vozidlo v seznamu +2. Klikněte na **"Upravit"** +3. Změňte požadované údaje +4. Klikněte na **"Ulozit"** + +### Smazání vozidla +1. Vyberte vozidlo v seznamu +2. Klikněte na **"Smazat"** +3. Potvrďte smazání + +## Ukládání dat + +Data jsou uložena v souboru **`vehicles.json`** ve formátu: +```json +[ + { + "Spz": "1A2 3456", + "Znacka": "Skoda", + "Model": "Octavia", + "Barva": "#FF0000", + "RokVyroby": 2020, + "Palivo": "Benzín", + "NajeteKm": 50000, + "Cena": 350000, + "Fotografie": "base64_string...", + "Vlastnik": { + "Jmeno": "Jan", + "Prijmeni": "Novak", + "Adresa": "Praha 1", + "Telefon": "+420123456789", + "Email": "jan.novak@email.cz" + } + } +] +``` + +## Autor +Vytvořeno pro předmět PTA25 - Programování v C# + +## Termín odevzdání +**1. 3. 2026** diff --git a/dealer/DataManager.cs b/dealer/DataManager.cs index 822dbad..3593dea 100644 --- a/dealer/DataManager.cs +++ b/dealer/DataManager.cs @@ -9,7 +9,10 @@ namespace dealer public class DataManager { private List vehicles = new List(); + private List owners = new List(); + private List images = new List(); + // Vehicle CRUD public void AddVehicle(Vehicle vehicle) { vehicles.Add(vehicle); @@ -25,23 +28,260 @@ namespace dealer vehicles.Remove(vehicle); } + // Owner CRUD + public void AddOwner(Owner owner) + { + owners.Add(owner); + } + + public IEnumerable GetAllOwners() + { + return owners; + } + + public Owner? GetOwnerById(Guid? id) + { + if (id == null) return null; + return owners.FirstOrDefault(o => o.Id == id); + } + + public void RemoveOwner(Owner owner) + { + // Remove owner reference from all vehicles + foreach (var vehicle in vehicles.Where(v => v.VlastnikId == owner.Id)) + { + vehicle.VlastnikId = null; + vehicle.Vlastnik = null; + } + owners.Remove(owner); + } + + public IEnumerable SearchOwners(string searchText) + { + if (string.IsNullOrWhiteSpace(searchText)) + return owners; + + searchText = searchText.ToLower(); + return owners.Where(o => + (o.Jmeno?.ToLower().Contains(searchText) ?? false) || + (o.Prijmeni?.ToLower().Contains(searchText) ?? false) || + (o.Email?.ToLower().Contains(searchText) ?? false) || + (o.Telefon?.Contains(searchText) ?? false) || + (o.CeleJmeno?.ToLower().Contains(searchText) ?? false)); + } + + // Image CRUD + public void AddImage(Image image) + { + images.Add(image); + } + + public IEnumerable GetAllImages() + { + return images; + } + + public Image? GetImageById(Guid? id) + { + if (id == null) return null; + return images.FirstOrDefault(i => i.Id == id); + } + + public void RemoveImage(Image image) + { + // Remove image reference from all vehicles + foreach (var vehicle in vehicles.Where(v => v.FotografieId == image.Id)) + { + vehicle.FotografieId = null; + vehicle.Fotografie = null; + } + images.Remove(image); + } + + // Link owners and images to vehicles after loading + private void LinkRelationsToVehicles() + { + foreach (var vehicle in vehicles) + { + if (vehicle.VlastnikId.HasValue) + { + vehicle.Vlastnik = GetOwnerById(vehicle.VlastnikId); + } + if (vehicle.FotografieId.HasValue) + { + vehicle.Fotografie = GetImageById(vehicle.FotografieId); + } + } + } + public void Save() { - // Implementace ukládánĂ­ dat do souboru - JSON - var json = System.Text.Json.JsonSerializer.Serialize(vehicles); - System.IO.File.WriteAllText("vehicles.json", json); + // Save vehicles + var vehiclesJson = System.Text.Json.JsonSerializer.Serialize(vehicles); + System.IO.File.WriteAllText("vehicles.json", vehiclesJson); + + // Save owners + var ownersJson = System.Text.Json.JsonSerializer.Serialize(owners); + System.IO.File.WriteAllText("owners.json", ownersJson); + + // Save images + var imagesJson = System.Text.Json.JsonSerializer.Serialize(images); + System.IO.File.WriteAllText("images.json", imagesJson); } public void Load() { - string path = "vehicles.json"; - - // Implementace naÄŤĂ­tánĂ­ dat ze souboru - JSON - if (System.IO.File.Exists(path)) + // Load owners first + string ownersPath = "owners.json"; + if (System.IO.File.Exists(ownersPath)) { - var json = System.IO.File.ReadAllText(path); + var json = System.IO.File.ReadAllText(ownersPath); + owners = System.Text.Json.JsonSerializer.Deserialize>(json) ?? new List(); + } + + // Load images + string imagesPath = "images.json"; + if (System.IO.File.Exists(imagesPath)) + { + var json = System.IO.File.ReadAllText(imagesPath); + images = System.Text.Json.JsonSerializer.Deserialize>(json) ?? new List(); + } + + // Load vehicles + string vehiclesPath = "vehicles.json"; + if (System.IO.File.Exists(vehiclesPath)) + { + var json = System.IO.File.ReadAllText(vehiclesPath); vehicles = System.Text.Json.JsonSerializer.Deserialize>(json) ?? new List(); } + + // Link relations to vehicles + LinkRelationsToVehicles(); + + // If no data exists, seed with sample data + if (!vehicles.Any() && !owners.Any()) + { + SeedData(); + } + } + + private void SeedData() + { + // Seed owners + var owner1 = new Owner + { + Id = Guid.NewGuid(), + Jmeno = "Jan", + Prijmeni = "Novak", + Adresa = "Praha 1, Vaclavske namesti 1", + Telefon = "+420 123 456 789", + Email = "jan.novak@email.cz" + }; + + var owner2 = new Owner + { + Id = Guid.NewGuid(), + Jmeno = "Marie", + Prijmeni = "Svobodova", + Adresa = "Brno, Husova 23", + Telefon = "+420 987 654 321", + Email = "marie.svobodova@email.cz" + }; + + var owner3 = new Owner + { + Id = Guid.NewGuid(), + Jmeno = "Petr", + Prijmeni = "Dvorak", + Adresa = "Ostrava, Hlavni 45", + Telefon = "+420 777 888 999", + Email = "petr.dvorak@email.cz" + }; + + owners.Add(owner1); + owners.Add(owner2); + owners.Add(owner3); + + // Seed images (1x1 pixel placeholder images in different colors) + var image1 = new Image + { + Id = Guid.NewGuid(), + Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg==", + FileName = "skoda_octavia.png", + ContentType = "image/png" + }; + + var image2 = new Image + { + Id = Guid.NewGuid(), + Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg==", + FileName = "bmw_x5.png", + ContentType = "image/png" + }; + + var image3 = new Image + { + Id = Guid.NewGuid(), + Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==", + FileName = "tesla_model3.png", + ContentType = "image/png" + }; + + images.Add(image1); + images.Add(image2); + images.Add(image3); + + // Seed vehicles + vehicles.Add(new Vehicle + { + Spz = "1A2 3456", + Znacka = "Skoda", + Model = "Octavia", + Barva = "#0055AA", + RokVyroby = 2020, + Palivo = "BenzĂ­n", + NajeteKm = 45000, + Cena = 350000, + VlastnikId = owner1.Id, + Vlastnik = owner1, + FotografieId = image1.Id, + Fotografie = image1 + }); + + vehicles.Add(new Vehicle + { + Spz = "7B8 9012", + Znacka = "BMW", + Model = "X5", + Barva = "#000000", + RokVyroby = 2019, + Palivo = "Nafta", + NajeteKm = 78000, + Cena = 850000, + VlastnikId = owner2.Id, + Vlastnik = owner2, + FotografieId = image2.Id, + Fotografie = image2 + }); + + vehicles.Add(new Vehicle + { + Spz = "3C4 5678", + Znacka = "Tesla", + Model = "Model 3", + Barva = "#FFFFFF", + RokVyroby = 2022, + Palivo = "Elektro", + NajeteKm = 15000, + Cena = 1200000, + VlastnikId = owner3.Id, + Vlastnik = owner3, + FotografieId = image3.Id, + Fotografie = image3 + }); + + // Save the seeded data + Save(); } } } diff --git a/dealer/Image.cs b/dealer/Image.cs new file mode 100644 index 0000000..f1f9978 --- /dev/null +++ b/dealer/Image.cs @@ -0,0 +1,12 @@ +using System; + +namespace dealer +{ + public class Image + { + public Guid Id { get; set; } = Guid.NewGuid(); + public string? Data { get; set; } // Base64 encoded image data or file path + public string? FileName { get; set; } + public string? ContentType { get; set; } + } +} diff --git a/dealer/Owner.cs b/dealer/Owner.cs new file mode 100644 index 0000000..ffa5e96 --- /dev/null +++ b/dealer/Owner.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace dealer +{ + public class Owner + { + public Guid Id { get; set; } = Guid.NewGuid(); + public string? Jmeno { get; set; } + public string? Prijmeni { get; set; } + public string? Adresa { get; set; } + public string? Telefon { get; set; } + public string? Email { get; set; } + + public string CeleJmeno => $"{Jmeno} {Prijmeni}".Trim(); + + public string DisplayText => string.IsNullOrEmpty(CeleJmeno) + ? Email ?? Telefon ?? "Neznamy vlastnik" + : CeleJmeno; + + public override string ToString() => DisplayText; + } +} diff --git a/dealer/Vehicle.cs b/dealer/Vehicle.cs index 04d2650..6aacdb9 100644 --- a/dealer/Vehicle.cs +++ b/dealer/Vehicle.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json.Serialization; using System.Threading.Tasks; namespace dealer @@ -9,11 +10,26 @@ namespace dealer public class Vehicle { public string? Spz { get; set; } + public string? Znacka { get; set; } public string? Model { get; set; } public string? Barva { get; set; } public int? RokVyroby { get; set; } + public string? Palivo { get; set; } public int? NajeteKm { get; set; } public decimal? Cena { get; set; } - public string? Fotografie { get; set; } + + public Guid? FotografieId { get; set; } + + [JsonIgnore] + public Image? Fotografie { get; set; } + + public Guid? VlastnikId { get; set; } + + [JsonIgnore] + public Owner? Vlastnik { get; set; } + + public string ZnackaModel => !string.IsNullOrEmpty(Znacka) && !string.IsNullOrEmpty(Model) + ? $"{Znacka} {Model}" + : Model ?? Znacka ?? "Nezadano"; } } diff --git a/dealer/windows/AddOwnerWindow.xaml b/dealer/windows/AddOwnerWindow.xaml new file mode 100644 index 0000000..148e429 --- /dev/null +++ b/dealer/windows/AddOwnerWindow.xaml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +