diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..add57be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+bin/
+obj/
+/packages/
+riderModule.iml
+/_ReSharper.Caches/
\ No newline at end of file
diff --git a/.idea/.idea.ConsoleApp2/.idea/projectSettingsUpdater.xml b/.idea/.idea.ConsoleApp2/.idea/projectSettingsUpdater.xml
deleted file mode 100644
index 4bb9f4d..0000000
--- a/.idea/.idea.ConsoleApp2/.idea/projectSettingsUpdater.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/.idea.ConsoleApp2/.idea/workspace.xml b/.idea/.idea.ConsoleApp2/.idea/workspace.xml
deleted file mode 100644
index 3adebf3..0000000
--- a/.idea/.idea.ConsoleApp2/.idea/workspace.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
- ConsoleApp2/ConsoleApp2.csproj
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1649857633410
-
-
- 1649857633410
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ConsoleApp2.sln b/ConsoleApp2.sln
new file mode 100644
index 0000000..7cfc2f1
--- /dev/null
+++ b/ConsoleApp2.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp2", "ConsoleApp2\ConsoleApp2.csproj", "{87E797D6-27CD-427F-89E0-21FBC4702711}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {87E797D6-27CD-427F-89E0-21FBC4702711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87E797D6-27CD-427F-89E0-21FBC4702711}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87E797D6-27CD-427F-89E0-21FBC4702711}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87E797D6-27CD-427F-89E0-21FBC4702711}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/ConsoleApp2/ConsoleApp2.csproj b/ConsoleApp2/ConsoleApp2.csproj
new file mode 100644
index 0000000..562b921
--- /dev/null
+++ b/ConsoleApp2/ConsoleApp2.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/ConsoleApp2/ICollectionItem.cs b/ConsoleApp2/ICollectionItem.cs
new file mode 100644
index 0000000..12ce5c4
--- /dev/null
+++ b/ConsoleApp2/ICollectionItem.cs
@@ -0,0 +1,11 @@
+namespace ConsoleApp2;
+
+public interface ICollectionItem
+{
+ int _id
+ {
+ get;
+ set;
+ }
+ void validateWholeClass();
+ }
\ No newline at end of file
diff --git a/ConsoleApp2/Menu.cs b/ConsoleApp2/Menu.cs
new file mode 100644
index 0000000..462809b
--- /dev/null
+++ b/ConsoleApp2/Menu.cs
@@ -0,0 +1,136 @@
+namespace ConsoleApp2;
+
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using System.Threading;
+using ConsoleTools;
+
+public class Menu
+{
+ private REGISTRATION_CERTIFICATE_COLLECTION _collection;
+ public Menu()
+ {
+ _collection = new REGISTRATION_CERTIFICATE_COLLECTION();
+
+ _collection.deserealizeFromFile();
+ var dictionary = new Dictionary()
+ {
+ { 1, Add},
+ { 2, Remove},
+ { 3, Find},
+ { 4, Sort},
+ { 5, Edit},
+ };
+
+ const string text = "1 - add\n" +
+ "2 - remove\n" +
+ "3 - search\n" +
+ "4 - sort\n" +
+ "5 - edit\n" +
+ "0 - exit";
+
+ foreach (var operation in InterfaceGetOperation(text, 0)) {
+ try
+ {
+ dictionary[operation].DynamicInvoke();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Incorect index\n" +
+ "try again");
+ }
+
+ }
+
+ }
+
+ static public IEnumerable InterfaceGetOperation(string text, int exitKey) {
+ while (true)
+ {
+ Console.WriteLine(text);
+ int operation = Convert.ToInt32(Console.ReadLine());
+
+ if (operation == exitKey)
+ {
+ break;
+ }
+ yield return operation;
+ }
+ }
+
+ private void Sort()
+ {
+ Console.WriteLine("Please enter field by which you want sort: ");
+ var value = Console.ReadLine();
+
+ try
+ {
+ _collection.sort(value);
+ Console.Write(_collection);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("There isn't such fields");
+ }
+ }
+
+ private void Find()
+ {
+ Console.WriteLine("Please enter value for search: ");
+ var value = Console.ReadLine();
+ var seachedByValue = _collection.searchByValue(value);
+ seachedByValue.ForEach(item => Console.WriteLine(item));
+ if(seachedByValue.Count==0)
+ Console.WriteLine("There is no such elements");
+ }
+
+ private void Add()
+ {
+ var certificate = REGISTRATION_CERTIFICATE.readFromConsole();
+ try
+ {
+ _collection.Add(certificate);
+ Console.Write(_collection);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+
+
+ }
+
+ private void Remove()
+ {
+ Console.WriteLine("Please enter id:");
+ try
+ {
+ var index = Convert.ToInt32(Console.ReadLine());
+ _collection.Remove(index);
+ Console.Write(_collection);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Invalid index \n" +
+ "Try again");
+ }
+
+ }
+
+ private void Edit()
+ {
+ Console.WriteLine("Please enter id of certificate which you want to edit:");
+ try
+ {
+ var index = Convert.ToInt32(Console.ReadLine());
+ _collection.Edit(index);
+ Console.Write(_collection);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Invalid values");
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/ConsoleApp2/Program.cs b/ConsoleApp2/Program.cs
new file mode 100644
index 0000000..6208ea2
--- /dev/null
+++ b/ConsoleApp2/Program.cs
@@ -0,0 +1,13 @@
+
+namespace ConsoleApp2
+{
+ public class Registration
+ {
+
+ // This is the main entry point for the application.
+ public static void Main(string[] args)
+ {
+ var menu = new Menu();
+ }
+ }
+}
diff --git a/ConsoleApp2/REGISTRATION_CERTIFICATE.cs b/ConsoleApp2/REGISTRATION_CERTIFICATE.cs
new file mode 100644
index 0000000..a81e58d
--- /dev/null
+++ b/ConsoleApp2/REGISTRATION_CERTIFICATE.cs
@@ -0,0 +1,110 @@
+using System.Reflection;
+
+namespace ConsoleApp2;
+
+public class REGISTRATION_CERTIFICATE: ICollectionItem
+{
+ public int _id{ get; set;}
+ public string _registration_number{ get; set; }
+ public DateTime _date_of_registration { get; set;}
+ public string _VIN_code{ get; set;}
+ public string _car{ get; set;}
+ public int _year_of_manufacture{ get; set;}
+
+
+ public void validateWholeClass()
+ {
+ Validation.ValidateRegistrationNumber(_registration_number);
+ Validation.ValidateDateOfRegistration(_date_of_registration.ToString());
+ Validation.ValidateId(_id);
+ Validation.ValidateVINCode(_VIN_code);
+ }
+ public REGISTRATION_CERTIFICATE(){}
+ public override string ToString()
+ {
+ return $"ID:{_id} \n" +
+ $"Registration number:{_registration_number} \n" +
+ $"Date of registration:{_date_of_registration} \n" +
+ $"VIN code:{_VIN_code} \n" +
+ $"Car:{_car} \n" +
+ $"Year of manufacture:{_year_of_manufacture} \n";
+ }
+
+ public REGISTRATION_CERTIFICATE(string id, string registration_number,string date_of_registration, string vinCode, string nameOfCar, string yearOfCar)
+ {
+ Set_id(id);
+ Set_registration_number(registration_number);
+ Set_date_of_registration(date_of_registration);
+ Set_VIN_code(vinCode);
+ Set_car(nameOfCar);
+ Set_year_of_manufacture(yearOfCar);
+ }
+
+
+ public void Set_id(string idStr)
+ {
+ var id = Convert.ToInt32(idStr);
+ _id = Validation.ValidateId(id);
+ }
+ public void Set_registration_number(string number)
+ {
+
+ _registration_number = Validation.ValidateRegistrationNumber(number);
+
+ }
+
+ public void Set_date_of_registration(string date)
+ {
+ _date_of_registration = Validation.ValidateDateOfRegistration(date);
+ }
+
+ public void Set_VIN_code(string vinCode)
+ {
+ _VIN_code = Validation.ValidateVINCode(vinCode);
+ }
+
+ public void Set_car(string car)
+ {
+ _car = car;
+ }
+
+ public void Set_year_of_manufacture(string yearStr)
+ {
+ var year = Convert.ToInt32(yearStr);
+ if(_date_of_registration.Year < year)
+ {
+ var exception = new Exception("Invalid date of registration");
+ throw exception;
+ }
+
+ _year_of_manufacture = year;
+ }
+
+ public static REGISTRATION_CERTIFICATE readFromConsole()
+ {
+ var resultCertificate = new REGISTRATION_CERTIFICATE();
+
+ try
+ {
+ Console.WriteLine("Please enter ID: ");
+ resultCertificate.Set_id(Console.ReadLine());
+ Console.WriteLine("Please enter car name: ");
+ resultCertificate.Set_car(Console.ReadLine());
+ Console.WriteLine("Please enter registration number: ");
+ resultCertificate.Set_registration_number(Console.ReadLine());
+ Console.WriteLine("Please enter date of registration: ");
+ resultCertificate.Set_date_of_registration(Console.ReadLine());
+ Console.WriteLine("Please enter VIN code: ");
+ resultCertificate.Set_VIN_code(Console.ReadLine());
+ Console.WriteLine("Please enter year of car: ");
+ resultCertificate.Set_year_of_manufacture(Console.ReadLine());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message.Trim('\n'));
+ return readFromConsole();
+ }
+
+ return resultCertificate;
+ }
+}
\ No newline at end of file
diff --git a/ConsoleApp2/REGISTRATION_CERTIFICATE_COLLECTION.cs b/ConsoleApp2/REGISTRATION_CERTIFICATE_COLLECTION.cs
new file mode 100644
index 0000000..c21f83f
--- /dev/null
+++ b/ConsoleApp2/REGISTRATION_CERTIFICATE_COLLECTION.cs
@@ -0,0 +1,158 @@
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace ConsoleApp2;
+
+public class REGISTRATION_CERTIFICATE_COLLECTION where T : ICollectionItem
+{
+ private List _list;
+
+ public void serilizeToFile()
+ {
+ var json = JsonSerializer.Serialize(_list);
+ using StreamWriter file = new("../../../data.json");
+ file.WriteLineAsync(json);
+ }
+
+ public void deserealizeFromFile()
+ {
+ List result = new List();
+ string json = new StreamReader("../../../data.json").ReadToEnd();
+ _list = JsonSerializer.Deserialize>(json);
+ var indexToDelete = new List();
+ for (int i =0; i<_list.Count-1;++i)
+ {
+ try
+ {
+ _list[i].validateWholeClass();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ indexToDelete.Add(i);
+ }
+ }
+
+ foreach (var index in indexToDelete)
+ {
+ _list.RemoveAt(index);
+ }
+ }
+
+ private T ItemById(int id)
+ {
+ foreach (var certificate in _list)
+ {
+ if (certificate._id == id)
+ return certificate;
+ }
+
+ return default(T);
+ }
+
+ public REGISTRATION_CERTIFICATE_COLLECTION()
+ {
+ _list = new List();
+ }
+
+
+ public List searchByValue(string value)
+ {
+ var result = new List();
+ foreach (var item in _list)
+ {
+ foreach (var field in item.GetType().GetProperties())
+ {
+ if (field.GetValue(item).ToString().ToLower().Contains(value.ToLower()))
+ {
+ result.Add(item);
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ public override string ToString()
+ {
+ string resultStr = new string("");
+ foreach (var certificate in _list)
+ {
+ resultStr += certificate.ToString() + '\n';
+ }
+
+ return resultStr;
+ }
+
+ public void sort(string field_to_sort_by="_id")
+ {
+ if(_list.Count == 0)
+ return;
+
+ var type = _list[0].GetType();
+ if (type.GetProperty(field_to_sort_by).CanRead)
+ {
+ _list.Sort((x, y) =>
+ type.GetProperty(field_to_sort_by).GetValue(x).ToString().ToLower()
+ .CompareTo(type.GetProperty(field_to_sort_by).GetValue(y).ToString().ToLower()));
+ }
+ }
+
+ public bool checkIfIdIsUnique(int id)
+ {
+ foreach (var certificate in _list)
+ {
+ if (certificate._id == id)
+ return false;
+ }
+
+ return true;
+ }
+ public void Add(T certificate)
+ {
+ if (!checkIfIdIsUnique(certificate._id))
+ {
+ throw new Exception("You have item with the same id");
+ }
+ _list.Add(certificate);
+ serilizeToFile();
+ }
+
+ public void Remove(int index)
+ {
+ _list.Remove(ItemById(index));
+ serilizeToFile();
+ }
+
+ public void Edit(int index)
+ {
+ T foundCertificate = default(T);
+ foreach (var _certificate in _list)
+ {
+ if (_certificate._id == index)
+ {
+ foundCertificate = _certificate;
+ break;
+ }
+ }
+ if (foundCertificate == null)
+ {
+ throw new Exception("Invalid id");
+ }
+
+ Console.WriteLine("Please enter field which you want to edit");
+ var field = Console.ReadLine();
+ Console.WriteLine("Please enter new value");
+ var newval = Console.ReadLine();
+ var funname = "Set" + field;
+
+ MethodInfo method = foundCertificate.GetType().GetMethod(funname);
+ method.Invoke(foundCertificate, new object[] {newval});
+
+
+ serilizeToFile();
+ }
+
+
+}
\ No newline at end of file
diff --git a/ConsoleApp2/Validation.cs b/ConsoleApp2/Validation.cs
new file mode 100644
index 0000000..f44abed
--- /dev/null
+++ b/ConsoleApp2/Validation.cs
@@ -0,0 +1,43 @@
+using System.Text.RegularExpressions;
+
+namespace ConsoleApp2;
+
+public class Validation
+{
+ public static int ValidateId(int id)
+ {
+ if (id < 0)
+ throw new Exception("Invalid ID");
+ return id;
+ }
+
+ public static string ValidateRegistrationNumber(string number)
+ {
+ Regex re = new Regex("[А-я]{2}\\d{4}[А-я]{2}");
+ if (!re.IsMatch(number))
+ {
+ throw new Exception("Invalid Registration Number");
+ }
+
+ return number;
+ }
+
+ public static DateTime ValidateDateOfRegistration(string date)
+ {
+ if(!DateTime.TryParse(date,out var returnDate))
+ throw new Exception("Invalid date of registration");
+
+ return returnDate;
+ }
+
+ public static string ValidateVINCode(string vinCode)
+ {
+ Regex re = new Regex("[A-HJ-NPR-Za-hj-npr-z\\d]{8}[\\dX][A-HJ-NPR-Za-hj-npr-z\\d]{2}\\d{6}");
+ if (vinCode.Length != 17 || !re.IsMatch(vinCode))
+ {
+ throw new Exception("Invalid VIN Code");
+ }
+
+ return vinCode;
+ }
+}
\ No newline at end of file
diff --git a/ConsoleApp2/data.json b/ConsoleApp2/data.json
new file mode 100644
index 0000000..32cde7f
--- /dev/null
+++ b/ConsoleApp2/data.json
@@ -0,0 +1 @@
+[{"_id":2,"_registration_number":"\u0412\u04219908\u0410\u0412","_date_of_registration":"2008-05-01T00:00:00","_VIN_code":"4Y1SL65848Z411439","_car":"TEst","_year_of_manufacture":2008},{"_id":3,"_registration_number":"\u0412\u04219907\u0410\u0412","_date_of_registration":"2008-05-01T00:00:00","_VIN_code":"4Y1SL65848Z411439","_car":"Audi","_year_of_manufacture":2002},{"_id":43,"_registration_number":"\u0412\u04219909\u0410\u041F","_date_of_registration":"2008-05-01T00:00:00","_VIN_code":"4Y1SL65848Z411439","_car":"\u0430\u0432","_year_of_manufacture":2007}]