Просмотр исходного кода

редактирование продукции

kei 4 лет назад
Родитель
Сommit
bdb65cc165
90 измененных файлов с 1867 добавлено и 13 удалено
  1. 340 13
      articles/cs_edit_product.md
  2. 25 0
      articles/old/mysql.sln
  3. 24 0
      articles/old/mysql/App.config
  4. 9 0
      articles/old/mysql/App.xaml
  5. 17 0
      articles/old/mysql/App.xaml.cs
  6. 16 0
      articles/old/mysql/Classes/Globals.cs
  7. 18 0
      articles/old/mysql/Classes/IDataProvider.cs
  8. 259 0
      articles/old/mysql/Classes/MySQLDataProvider.cs
  9. BIN
      articles/old/mysql/Images/picture.png
  10. 22 0
      articles/old/mysql/Model/Material.cs
  11. 61 0
      articles/old/mysql/Model/Product.cs
  12. 18 0
      articles/old/mysql/Model/ProductType.cs
  13. 55 0
      articles/old/mysql/Properties/AssemblyInfo.cs
  14. 71 0
      articles/old/mysql/Properties/Resources.Designer.cs
  15. 117 0
      articles/old/mysql/Properties/Resources.resx
  16. 30 0
      articles/old/mysql/Properties/Settings.Designer.cs
  17. 7 0
      articles/old/mysql/Properties/Settings.settings
  18. 67 0
      articles/old/mysql/Windows/EditWindow.xaml
  19. 83 0
      articles/old/mysql/Windows/EditWindow.xaml.cs
  20. 22 0
      articles/old/mysql/Windows/EnterMinCostForAgentWindow.xaml
  21. 43 0
      articles/old/mysql/Windows/EnterMinCostForAgentWindow.xaml.cs
  22. 158 0
      articles/old/mysql/Windows/MainWindow.xaml
  23. 201 0
      articles/old/mysql/Windows/MainWindow.xaml.cs
  24. BIN
      articles/old/mysql/bin/Debug/products/tire_0.jpg
  25. BIN
      articles/old/mysql/bin/Debug/products/tire_1.jpg
  26. BIN
      articles/old/mysql/bin/Debug/products/tire_10.jpg
  27. BIN
      articles/old/mysql/bin/Debug/products/tire_11.jpg
  28. BIN
      articles/old/mysql/bin/Debug/products/tire_12.jpg
  29. BIN
      articles/old/mysql/bin/Debug/products/tire_13.jpg
  30. BIN
      articles/old/mysql/bin/Debug/products/tire_14.jpg
  31. BIN
      articles/old/mysql/bin/Debug/products/tire_15.jpg
  32. BIN
      articles/old/mysql/bin/Debug/products/tire_16.jpg
  33. BIN
      articles/old/mysql/bin/Debug/products/tire_17.jpg
  34. BIN
      articles/old/mysql/bin/Debug/products/tire_18.jpg
  35. BIN
      articles/old/mysql/bin/Debug/products/tire_19.jpg
  36. BIN
      articles/old/mysql/bin/Debug/products/tire_2.jpg
  37. BIN
      articles/old/mysql/bin/Debug/products/tire_20.jpg
  38. BIN
      articles/old/mysql/bin/Debug/products/tire_21.jpg
  39. BIN
      articles/old/mysql/bin/Debug/products/tire_22.jpg
  40. BIN
      articles/old/mysql/bin/Debug/products/tire_23.jpg
  41. BIN
      articles/old/mysql/bin/Debug/products/tire_24.jpg
  42. BIN
      articles/old/mysql/bin/Debug/products/tire_25.jpg
  43. BIN
      articles/old/mysql/bin/Debug/products/tire_26.jpg
  44. BIN
      articles/old/mysql/bin/Debug/products/tire_27.jpg
  45. BIN
      articles/old/mysql/bin/Debug/products/tire_28.jpg
  46. BIN
      articles/old/mysql/bin/Debug/products/tire_29.jpg
  47. BIN
      articles/old/mysql/bin/Debug/products/tire_3.jpg
  48. BIN
      articles/old/mysql/bin/Debug/products/tire_30.jpg
  49. BIN
      articles/old/mysql/bin/Debug/products/tire_31.jpg
  50. BIN
      articles/old/mysql/bin/Debug/products/tire_32.jpg
  51. BIN
      articles/old/mysql/bin/Debug/products/tire_33.jpg
  52. BIN
      articles/old/mysql/bin/Debug/products/tire_34.jpg
  53. BIN
      articles/old/mysql/bin/Debug/products/tire_35.jpg
  54. BIN
      articles/old/mysql/bin/Debug/products/tire_36.jpg
  55. BIN
      articles/old/mysql/bin/Debug/products/tire_37.jpg
  56. BIN
      articles/old/mysql/bin/Debug/products/tire_38.jpg
  57. BIN
      articles/old/mysql/bin/Debug/products/tire_39.jpg
  58. BIN
      articles/old/mysql/bin/Debug/products/tire_4.jpg
  59. BIN
      articles/old/mysql/bin/Debug/products/tire_40.jpg
  60. BIN
      articles/old/mysql/bin/Debug/products/tire_41.jpg
  61. BIN
      articles/old/mysql/bin/Debug/products/tire_42.jpg
  62. BIN
      articles/old/mysql/bin/Debug/products/tire_43.jpg
  63. BIN
      articles/old/mysql/bin/Debug/products/tire_44.jpg
  64. BIN
      articles/old/mysql/bin/Debug/products/tire_45.jpg
  65. BIN
      articles/old/mysql/bin/Debug/products/tire_46.jpg
  66. BIN
      articles/old/mysql/bin/Debug/products/tire_47.jpg
  67. BIN
      articles/old/mysql/bin/Debug/products/tire_48.jpg
  68. BIN
      articles/old/mysql/bin/Debug/products/tire_49.jpg
  69. BIN
      articles/old/mysql/bin/Debug/products/tire_5.jpg
  70. BIN
      articles/old/mysql/bin/Debug/products/tire_50.jpg
  71. BIN
      articles/old/mysql/bin/Debug/products/tire_51.jpg
  72. BIN
      articles/old/mysql/bin/Debug/products/tire_52.jpg
  73. BIN
      articles/old/mysql/bin/Debug/products/tire_53.jpg
  74. BIN
      articles/old/mysql/bin/Debug/products/tire_54.jpg
  75. BIN
      articles/old/mysql/bin/Debug/products/tire_55.jpg
  76. BIN
      articles/old/mysql/bin/Debug/products/tire_56.jpg
  77. BIN
      articles/old/mysql/bin/Debug/products/tire_57.jpg
  78. BIN
      articles/old/mysql/bin/Debug/products/tire_58.jpg
  79. BIN
      articles/old/mysql/bin/Debug/products/tire_59.jpg
  80. BIN
      articles/old/mysql/bin/Debug/products/tire_6.jpg
  81. BIN
      articles/old/mysql/bin/Debug/products/tire_60.jpg
  82. BIN
      articles/old/mysql/bin/Debug/products/tire_61.jpg
  83. BIN
      articles/old/mysql/bin/Debug/products/tire_62.jpg
  84. BIN
      articles/old/mysql/bin/Debug/products/tire_63.jpg
  85. BIN
      articles/old/mysql/bin/Debug/products/tire_64.jpg
  86. BIN
      articles/old/mysql/bin/Debug/products/tire_7.jpg
  87. BIN
      articles/old/mysql/bin/Debug/products/tire_8.jpg
  88. BIN
      articles/old/mysql/bin/Debug/products/tire_9.jpg
  89. 189 0
      articles/old/mysql/mysql.csproj
  90. 15 0
      articles/old/mysql/packages.config

+ 340 - 13
articles/cs_edit_product.md

@@ -37,15 +37,15 @@
 При редактировании продукции в поля для ввода загружены данные из БД | 0.3
 Выбор типа продукта реализован в виде выпадающего списка со значениями из БД | 0.3
 Для ввода описания продукции предусмотрено многострочное поле для ввода | 0.2
-Реализован список используемых материалов для текущего продукта | 0.3
-В списке присутствует название материала и используемое количество | 0.2
-При редактировании продукции список материалов заполнен значениями из БД | 0.2
-В список можно добавлять новые позиции | 0.3
-Из списка можно удалять существующие позиции | 0.2
-При добавлении материалы выбираются из выпадающего списка со значениями из БД | 0.3
-В списке материалов реализована возможность поиска по наименованию | 0.2
-Список используемых материалов сохраняется в БД при добавлении | 0.5
-Список используемых материалов сохраняется в БД при редактировании | 0.5
+*Реализован список используемых материалов для текущего продукта* | 0.3
+*В списке присутствует название материала и используемое количество* | 0.2
+*При редактировании продукции список материалов заполнен значениями из БД* | 0.2
+*В список можно добавлять новые позиции* | 0.3
+*Из списка можно удалять существующие позиции* | 0.2
+*При добавлении материалы выбираются из выпадающего списка со значениями из БД* | 0.3
+*В списке материалов реализована возможность поиска по наименованию* | 0.2
+*Список используемых материалов сохраняется в БД при добавлении* | 0.5
+*Список используемых материалов сохраняется в БД при редактировании* | 0.5
 Стоимость продукции не может быть отрицательной | 0.1
 Стоимость продукции записывается только с точностью до сотых | 0.2
 Реализована проверка артикула на уникальность | 0.3
@@ -55,12 +55,339 @@
 Данные при добавлении сохраняются в БД | 0.5
 Данные при редактировании изменяются в БД | 0.5
 Открывается только одно окно редактирования | 0.1
-Реализовано удаление выбранного продукта, у которого не заполнен список используемых материалов | 0.2
-Реализовано удаление продукта вместе с информацией об используемых материалах | 0.5
-Запрещено удаление продукта, по которому были выполнены продажи агентом | 0.3
-После удаления реализован автоматический переход обратно в список | 0.1
+*Реализовано удаление выбранного продукта, у которого не заполнен список используемых материалов* | 0.2
+*Реализовано удаление продукта вместе с информацией об используемых материалах* | 0.5
+*Запрещено удаление продукта, по которому были выполнены продажи агентом* | 0.3
+*После удаления реализован автоматический переход обратно в список* | 0.1
 После закрытия окна данные в таблице обновляются | 0.3
 **Итого** | **7.9**
 
 # Создание окна редактирования продукции
 
+Для добавления и редактирования мы будем использовать одно и то же окно. Название окна будем вычислять по наличию ID у продукции (у новой записи это поле = 0)
+
+1. Создайте новое окно: **EditWindow**
+
+2. В классе окна **EditWindow** добавьте свойство *CurrentProduct*, в котором будет храниться добавляемый/редактируемый экземпляр продукции:
+
+    ```cs
+    public Product CurrentProduct { get; set; }
+    ```
+
+    И геттер для названия окна:
+
+    ```cs
+    public string WindowName {
+        get {
+            return CurrentService.ID == 0 ? "Новая услуга" : "Редактирование услуги";
+        }
+    }
+    ```
+3. В конструктор окна добавьте параметр типа **Product** и присвойте его ранее объявленному свойству:
+
+    ```cs
+    public EditWindow(Product EditProduct)
+    {
+        InitializeComponent();
+        DataContext = this;
+        CurrentProduct = EditProduct;
+    }
+    ```
+
+4. В разметке окна вместо фиксированного названия вставьте привязку к свойству *WindowName*
+
+    ```xml
+    <Window
+        ...
+        Title="{Binding WindowName}">
+    ```
+
+5. В окне создайте сетку из трёх колонок: в первой у нас будет изображение, во второй редактируемые поля продукта, а в третей список материалов
+
+    ```xml
+    <Grid.ColumnDefinitions>
+        <ColumnDefinition Width="auto"/>
+        <ColumnDefinition Width="*"/>
+        <ColumnDefinition Width="auto"/>
+    </Grid.ColumnDefinitions>
+    ```
+
+6. Во вторую колонку добавьте **StackPanel** с границами (чтобы визуальные компоненты не прилипали к границам окна) и в этом списке разместите редактируемые элементы
+
+    >На форме должны быть предусмотрены следующие поля: артикул, наименование, тип продукта (выпадающий список), изображение, количество человек для производства, номер производственного цеха, минимальная стоимость для агента и подробное описание
+
+    ```xml
+    <StackPanel 
+        Margin="5">
+
+        <Label Content="Артикул"/>
+        <TextBox Text="{Binding CurrentProduct.ArticleNumber}"/>
+
+        <Label Content="Наименование продукта"/>
+        <TextBox Text="{Binding CurrentService.Title}"/>
+
+        ...
+
+    </StackPanel>
+    ```
+
+    Обычные поля наклепайте по шаблону сами, а я подробнее остановлюсь на полях: тип продукта, изображение и описание:
+
+    * Выбор типа продукта из списка
+
+        В классе окна объявляем свойство *ProductTypes* - список типов продукции
+
+        ```cs
+        public IEnumerable<ProductType> ProductTypes { get; set; }
+        ```
+
+        И в конструкторе получаем его из поставщика данных
+
+        ```cs
+        ProductTypes = Globals.DataProvider.GetProductTypes();
+        ```
+
+        В выпадающий список мы должны передать собственно список выбираемых объектов (*ItemsSource*) и текущий объект (*SelectedItem*) из этого списка. Но у нас в модели **Product** нет объекта **ProductType**, есть отдельные поля *ProductTypeID* и *ProductTypeTitle*. Изменим модель, вместо этих полей сделаем поле *CurrentProductType*, значение которого будем получать из списка типов по ID
+
+        В поставщик данных добавим переменную, в которой будет храниться список типов продукции:
+
+        ```cs
+        private List<ProductType> ProductTypes = null;
+        ```
+
+        Исправим метод **GetProductTypes**, чтобы он считывал список только в первый раз (поиск объектов происходит по хешу и нам важно, чтобы этот список был всегда один и тот же)
+
+        ```cs
+        public IEnumerable<ProductType> GetProductTypes()
+        {
+            if (ProductTypes == null)
+            {
+                ProductTypes = new List<ProductType>();
+                ...
+        ```
+
+        В модели **Product** убираем свойства *ProductTypeTitle*, *ProductTypeID* и добавляем *CurrentProductType* (после этого пересоберите проект и исправьте возникшие ошибки)
+
+        ```cs
+        // public string ProductTypeTitle { get; set; }
+        // public int ProductTypeID { get; set; }
+        public ProductType CurrentProductType { get; set; }
+        ```
+
+        И в классе **MySQLDataProvider** переделайте получение типа продукта:
+
+        ```cs
+        // NewProduct.ProductTypeID = Reader.GetInt32("ProductTypeID");
+        // NewProduct.ProductTypeTitle = Reader["ProductTypeTitle"].ToString();
+        NewProduct.CurrentProductType = GetProductType(Reader.GetInt32("ProductTypeID"));
+        ```
+
+        Реализация метода *GetProductType*:
+
+        ```cs
+        private ProductType GetProductType(int Id)
+        {
+            // тут заполнится список типов продукции, если он ещё пустой
+            GetProductTypes();
+            return ProductTypes.Find(pt => pt.ID == Id);
+        }
+        ```
+
+        Теперь в верстке окна редактирования продукции мы можем использовать выпадающий список
+
+        ```xml
+        <ComboBox 
+            ItemsSource="{Binding ProductTypes}"
+            SelectedItem="{Binding CurrentProduct.CurrentProductType}"/>
+        ```
+
+    * смена изображения продукции
+
+        Вывод изображения производится как и в главном окне
+
+        ```xml
+        <Image
+            Width="200" 
+            Height="200"
+            Source="{Binding CurrentProduct.ImagePreview,TargetNullValue={StaticResource defaultImage}}" />
+        ```
+
+        А для смены изображения используем стандартный диалог Windows, повесив его на кнопку *Сменить картинку* (кнопку добавьте сами в **StackPanel**)
+
+        Обработчик кнопки:
+
+        ```cs
+        private void ChangeImage_Click(object sender, RoutedEventArgs e)
+        {
+            OpenFileDialog GetImageDialog = new OpenFileDialog();
+            // задаем фильтр для выбираемых файлов
+            // до символа "|" идет произвольный текст, а после него шаблоны файлов разделенные точкой с запятой
+            GetImageDialog.Filter = "Файлы изображений: (*.png, *.jpg)|*.png;*.jpg";
+            // чтобы не искать по всему диску задаем начальный каталог
+            GetImageDialog.InitialDirectory = Environment.CurrentDirectory;
+            if (GetImageDialog.ShowDialog() == true)
+            {
+                // перед присвоением пути к картинке обрезаем начало строки, т.к. диалог возвращает полный путь
+                CurrentProduct.Image = GetImageDialog.FileName.Substring(Environment.CurrentDirectory.Length);
+                // обратите внимание, это другое окно и другой Invalidate, который реализуйте сами
+                Invalidate();
+            }
+        }
+        ```
+
+    * Многострочное описание
+
+        Тут просто - разрешаем переносы и задаем высоту элемента
+
+        ```xml
+        <Label Content="Описание продукта"/>
+        <TextBox 
+            AcceptsReturn="True"
+            Height="2cm"
+            Text="{Binding CurrentProduct.Description}"/>
+        ```
+
+7. Сохранение введенных данных
+
+    В разметку добавьте кнопку **Сохранить** и напишите обработчик
+
+    ```cs
+    private void Button_Click(object sender, RoutedEventArgs e)
+    {
+        // вся работа с БД должна быть завернута в исключения
+        try
+        {
+            // метод SaveProduct реализуем ниже
+            Globals.DataProvider.SaveProduct(CurrentProduct);
+            DialogResult = true;
+        }
+        catch (Exception ex)
+        {
+            MessageBox.Show(ex.Message);
+        }
+    }
+    ```
+
+    В интерфейсе **IDataProvider** объявляем метод *SaveProduct*:
+
+    ```cs
+    void SaveProduct(Product ChangedProduct);
+    ```
+
+    И реализуем его в классе поставщика данных 
+
+    ```cs
+    public void SaveProduct(Product ChangedProduct)
+    {
+        Connection.Open();
+        try
+        {
+            if (ChangedProduct.ID == 0)
+            {
+                // новый продукт - добавляем запись
+                string Query = @"INSERT INTO Product
+                (Title,
+                ProductTypeID,
+                ArticleNumber,
+                Description,
+                Image,
+                ProductionPersonCount,
+                ProductionWorkshopNumber,
+                MinCostForAgent)
+                VALUES
+                (@Title,
+                @ProductTypeID,
+                @ArticleNumber,
+                @Description,
+                @Image,
+                @ProductionPersonCount,
+                @ProductionWorkshopNumber,
+                @MinCostForAgent)";
+
+                MySqlCommand Command = new MySqlCommand(Query, Connection);
+                Command.Parameters.AddWithValue("@Title", ChangedProduct.Title);
+                Command.Parameters.AddWithValue("@ProductTypeID", ChangedProduct.CurrentProductType.ID);
+                Command.Parameters.AddWithValue("@ArticleNumber", ChangedProduct.ArticleNumber);
+                Command.Parameters.AddWithValue("@Description", ChangedProduct.Description);
+                Command.Parameters.AddWithValue("@Image", ChangedProduct.Image);
+                Command.Parameters.AddWithValue("@ProductionPersonCount", ChangedProduct.ProductionPersonCount);
+                Command.Parameters.AddWithValue("@ProductionWorkshopNumber", ChangedProduct.ProductionWorkshopNumber);
+                Command.Parameters.AddWithValue("@MinCostForAgent", ChangedProduct.MinCostForAgent);
+                Command.ExecuteNonQuery();
+            }
+            else
+            {
+                // существующий продукт - изменяем запись
+
+                string Query = @"UPDATE Product
+                SET
+                Title = @Title,
+                ProductTypeID = @ProductTypeID,
+                ArticleNumber = @ArticleNumber,
+                Description = @Description,
+                Image = @Image,
+                ProductionPersonCount = @ProductionPersonCount,
+                ProductionWorkshopNumber = @ProductionWorkshopNumber,
+                MinCostForAgent = @MinCostForAgent
+                WHERE ID = @ID";
+
+                MySqlCommand Command = new MySqlCommand(Query, Connection);
+                Command.Parameters.AddWithValue("@Title", ChangedProduct.Title);
+                Command.Parameters.AddWithValue("@ProductTypeID", ChangedProduct.CurrentProductType.ID);
+                Command.Parameters.AddWithValue("@ArticleNumber", ChangedProduct.ArticleNumber);
+                Command.Parameters.AddWithValue("@Description", ChangedProduct.Description);
+                Command.Parameters.AddWithValue("@Image", ChangedProduct.Image);
+                Command.Parameters.AddWithValue("@ProductionPersonCount", ChangedProduct.ProductionPersonCount);
+                Command.Parameters.AddWithValue("@ProductionWorkshopNumber", ChangedProduct.ProductionWorkshopNumber);
+                Command.Parameters.AddWithValue("@MinCostForAgent", ChangedProduct.MinCostForAgent);
+                Command.Parameters.AddWithValue("@ID", ChangedProduct.ID);
+                Command.ExecuteNonQuery();
+            }
+        }
+        finally
+        {
+            Connection.Close();
+        }
+    }
+    ```
+
+8. Открытие окна редактирования для существующей и новой продукции
+
+    * для редактирования существующей продукции в списке продукции реализуем обработчик двойного клика
+
+        ```cs
+        private void ProductListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+        {
+            // в создаваемое окно передаем выбранный продукт
+            var NewEditWindow = new EditWindow(ProductListView.SelectedItem as Product);
+            if ((bool)NewEditWindow.ShowDialog())
+            {
+                // при успешном сохранении продукта перечитываем список продукции
+                ProductList = Globals.DataProvider.GetProducts();
+            }
+        }
+        ```
+
+    * для создания нового продукта в разметке главного окна создайте кнопку "Добавить продукцию" (либо в верхней панели, либо в левой) и в её обработчике создайте новый экземпляр продукта
+
+        ```cs
+        var NewEditWindow = new EditWindow(new Product());
+        ...
+        ```
+9. Проверки перед сохранением продукта
+
+    Все проверки вставляем в метод *SaveProduct*, до сохранения продукта
+
+    * Стоимость продукции не может быть отрицательной
+
+        ```cs
+        if (ChangedProduct.MinCostForAgent < 0)
+            throw new Exception("Цена продукта не может быть отрицательной");
+        ```
+
+    * Стоимость продукции записывается только с точностью до сотых
+
+    * Реализована проверка артикула на уникальность
+
+        Тут по идее надо делать запрос к базе, но у нас есть метод получения списка продукции и мы можем искать в нём используя LINQ-запросы
+

+ 25 - 0
articles/old/mysql.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30517.126
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mysql", "mysql\mysql.csproj", "{590122C3-15FA-4F95-8B3A-8EBBFA6AAD83}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{590122C3-15FA-4F95-8B3A-8EBBFA6AAD83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{590122C3-15FA-4F95-8B3A-8EBBFA6AAD83}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{590122C3-15FA-4F95-8B3A-8EBBFA6AAD83}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{590122C3-15FA-4F95-8B3A-8EBBFA6AAD83}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {490D9E77-BCE6-41A5-905A-6FEF81927F5C}
+	EndGlobalSection
+EndGlobal

+ 24 - 0
articles/old/mysql/App.config

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <configSections>
+        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+    </configSections>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
+    </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+  <entityFramework>
+    <providers>
+      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+    <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework, Version=8.0.26.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d">
+      </provider></providers>
+  </entityFramework>
+</configuration>

+ 9 - 0
articles/old/mysql/App.xaml

@@ -0,0 +1,9 @@
+<Application x:Class="mysql.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:mysql"
+             StartupUri="Windows/MainWindow.xaml">
+    <Application.Resources>
+         
+    </Application.Resources>
+</Application>

+ 17 - 0
articles/old/mysql/App.xaml.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace mysql
+{
+    /// <summary>
+    /// Логика взаимодействия для App.xaml
+    /// </summary>
+    public partial class App : Application
+    {
+    }
+}

+ 16 - 0
articles/old/mysql/Classes/Globals.cs

@@ -0,0 +1,16 @@
+using mysql.Model;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mysql.Classes
+{
+    class Globals
+    {
+        public static IDataProvider DataProvider;
+        public static IEnumerable<ProductType> ProductTypeList { get; set; }
+    }
+}

+ 18 - 0
articles/old/mysql/Classes/IDataProvider.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using mysql.Model;
+
+namespace mysql.Classes
+{
+    interface IDataProvider
+    {
+        IEnumerable<Product> GetProducts();
+        IEnumerable<ProductType> GetProductTypes();
+        void SetAverageCostForAgent(List<int> ProductIds, decimal NewCost);
+        void SaveProduct(Product ChangedProduct);
+    }
+}

+ 259 - 0
articles/old/mysql/Classes/MySQLDataProvider.cs

@@ -0,0 +1,259 @@
+using mysql.Model;
+using MySql.Data.MySqlClient;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace mysql.Classes
+{
+    class MySQLDataProvider: IDataProvider
+    {
+        private MySqlConnection Connection;
+        private List<ProductType> ProductTypes = null;
+
+        public MySQLDataProvider()
+        {
+            try
+            {
+                Connection = new MySqlConnection("Server=kolei.ru;Database=i31;port=3306;UserId=i31;password=qzesc;");
+            }
+            catch (Exception)
+            {
+            }
+        }
+
+        public IEnumerable<Product> GetProducts()
+        {
+            List<Product> ProductList = new List<Product>();
+            string Query = @"SELECT 
+                p.*,
+                pt.Title AS ProductTypeTitle,
+                pp.MaterialList, pp.Total,Sales.DaysFromLastSale
+            FROM
+                Product p
+            LEFT JOIN
+                ProductType pt ON p.ProductTypeID = pt.ID
+            LEFT JOIN
+                (
+                SELECT
+                    pm.ProductID,
+                    GROUP_CONCAT(m.Title SEPARATOR ', ') as MaterialList, 
+                    SUM(pm.Count * m.Cost / m.CountInPack) as Total
+                FROM
+                    Material m,
+		            ProductMaterial pm
+                WHERE m.ID = pm.MaterialID
+                GROUP BY ProductID
+                ) pp ON pp.ProductID = p.ID
+            LEFT JOIN 
+            (
+                select 
+                    ProductID, 
+                    DATEDIFF(NOW(), max(SaleDate)) as DaysFromLastSale
+                from 
+                    ProductSale
+                group by ProductID
+            ) Sales on Sales.ProductID = p.ID";
+
+            try
+            {
+                Connection.Open();
+                try
+                {
+                    MySqlCommand Command = new MySqlCommand(Query, Connection);
+                    MySqlDataReader Reader = Command.ExecuteReader();
+
+                    while (Reader.Read())
+                    {
+                        Product NewProduct = new Product();
+                        NewProduct.ID = Reader.GetInt32("ID");
+                        NewProduct.Title = Reader.GetString("Title");
+                        NewProduct.ArticleNumber = Reader.GetString("ArticleNumber");
+                        NewProduct.ProductionPersonCount = Reader.GetInt32("ProductionPersonCount");
+                        NewProduct.ProductionWorkshopNumber = Reader.GetInt32("ProductionWorkshopNumber");
+                        NewProduct.MinCostForAgent = Reader.GetInt32("MinCostForAgent");
+
+                        // Методы Get<T> не поддерживают работу с NULL
+                        // для полей, в которых может встретиться NULL (а лучше для всех)
+                        // используйте следующий синтаксис
+                        NewProduct.Description = Reader["Description"].ToString();
+                        NewProduct.Image = Reader["Image"].ToString();
+
+                        // NewProduct.ProductTypeID = Reader.GetInt32("ProductTypeID");
+                        // NewProduct.ProductTypeTitle = Reader["ProductTypeTitle"].ToString();
+                        NewProduct.CurrentProductType = GetProductType(Reader.GetInt32("ProductTypeID"));
+
+                        NewProduct.MaterialString = Reader["MaterialList"].ToString();
+                        NewProduct.Total = Reader["Total"].ToString();
+
+                        NewProduct.DaysFromLastSale = (Reader["DaysFromLastSale"] as int?) ?? 999;
+
+                        ProductList.Add(NewProduct);
+                    }
+                }
+                finally
+                {
+                    Connection.Close();
+                }
+            }
+            catch (Exception)
+            {
+            }
+
+            return ProductList;
+        }
+
+        private ProductType GetProductType(int Id)
+        {
+            GetProductTypes();
+            return ProductTypes.Find(pt => pt.ID == Id);
+        }
+
+        public IEnumerable<ProductType> GetProductTypes()
+        {
+            if (ProductTypes == null)
+            {
+                ProductTypes = new List<ProductType>();
+                string Query = "SELECT * FROM ProductType";
+
+                try
+                {
+                    Connection.Open();
+                    try
+                    {
+                        MySqlCommand Command = new MySqlCommand(Query, Connection);
+                        MySqlDataReader Reader = Command.ExecuteReader();
+
+                        while (Reader.Read())
+                        {
+                            ProductType NewProductType = new ProductType();
+                            NewProductType.ID = Reader.GetInt32("ID");
+                            NewProductType.Title = Reader.GetString("Title");
+
+                            ProductTypes.Add(NewProductType);
+                        }
+                    }
+                    finally
+                    {
+                        Connection.Close();
+                    }
+                }
+                catch (Exception)
+                {
+                }
+
+            }
+            return ProductTypes;
+        }
+
+        public void SetAverageCostForAgent(List<int> ProductIds, decimal NewCost)
+        {
+            try
+            {
+                Connection.Open();
+                try
+                {
+                    string Query = "UPDATE Product SET MinCostForAgent=@MinCostForAgent WHERE ID=@ID";
+
+                    foreach (int item in ProductIds)
+                    {
+                        MySqlCommand Command = new MySqlCommand(Query, Connection);
+                        Command.Parameters.AddWithValue("@MinCostForAgent", NewCost);
+                        Command.Parameters.AddWithValue("@ID", item);
+                        Command.ExecuteNonQuery();
+                    }
+                }
+                finally
+                {
+                    Connection.Close();
+                }
+            }
+            catch (Exception)
+            {
+            }
+        }
+
+        public void SaveProduct(Product ChangedProduct)
+        {
+                Connection.Open();
+                try
+                {
+                    if (ChangedProduct.MinCostForAgent < 0)
+                        throw new Exception("Цена продукта не может быть отрицательной");
+
+
+                    if (ChangedProduct.ID == 0)
+                    {
+                        // новый продукт - добавляем запись
+                        string Query = @"INSERT INTO Product
+                    (Title,
+                    ProductTypeID,
+                    ArticleNumber,
+                    Description,
+                    Image,
+                    ProductionPersonCount,
+                    ProductionWorkshopNumber,
+                    MinCostForAgent)
+                    VALUES
+                    (@Title,
+                    @ProductTypeID,
+                    @ArticleNumber,
+                    @Description,
+                    @Image,
+                    @ProductionPersonCount,
+                    @ProductionWorkshopNumber,
+                    @MinCostForAgent)";
+
+                        MySqlCommand Command = new MySqlCommand(Query, Connection);
+                        Command.Parameters.AddWithValue("@Title", ChangedProduct.Title);
+                        Command.Parameters.AddWithValue("@ProductTypeID", ChangedProduct.CurrentProductType.ID);
+                        Command.Parameters.AddWithValue("@ArticleNumber", ChangedProduct.ArticleNumber);
+                        Command.Parameters.AddWithValue("@Description", ChangedProduct.Description);
+                        Command.Parameters.AddWithValue("@Image", ChangedProduct.Image);
+                        Command.Parameters.AddWithValue("@ProductionPersonCount", ChangedProduct.ProductionPersonCount);
+                        Command.Parameters.AddWithValue("@ProductionWorkshopNumber", ChangedProduct.ProductionWorkshopNumber);
+                        Command.Parameters.AddWithValue("@MinCostForAgent", ChangedProduct.MinCostForAgent);
+                        Command.ExecuteNonQuery();
+                    }
+                    else
+                    {
+                        // существующий продукт - изменяем запись
+
+                        string Query = @"UPDATE Product
+                    SET
+                    Title = @Title,
+                    ProductTypeID = @ProductTypeID,
+                    ArticleNumber = @ArticleNumber,
+                    Description = @Description,
+                    Image = @Image,
+                    ProductionPersonCount = @ProductionPersonCount,
+                    ProductionWorkshopNumber = @ProductionWorkshopNumber,
+                    MinCostForAgent = @MinCostForAgent
+                    WHERE ID = @ID";
+
+                        MySqlCommand Command = new MySqlCommand(Query, Connection);
+                        Command.Parameters.AddWithValue("@Title", ChangedProduct.Title);
+                        Command.Parameters.AddWithValue("@ProductTypeID", ChangedProduct.CurrentProductType.ID);
+                        Command.Parameters.AddWithValue("@ArticleNumber", ChangedProduct.ArticleNumber);
+                        Command.Parameters.AddWithValue("@Description", ChangedProduct.Description);
+                        Command.Parameters.AddWithValue("@Image", ChangedProduct.Image);
+                        Command.Parameters.AddWithValue("@ProductionPersonCount", ChangedProduct.ProductionPersonCount);
+                        Command.Parameters.AddWithValue("@ProductionWorkshopNumber", ChangedProduct.ProductionWorkshopNumber);
+                        Command.Parameters.AddWithValue("@MinCostForAgent", ChangedProduct.MinCostForAgent);
+                        Command.Parameters.AddWithValue("@ID", ChangedProduct.ID);
+                        Command.ExecuteNonQuery();
+
+                    }
+                }
+                finally
+                {
+                    Connection.Close();
+                }
+        }
+    }
+
+}

BIN
articles/old/mysql/Images/picture.png


+ 22 - 0
articles/old/mysql/Model/Material.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mysql.Model
+{
+    public class Material
+    {
+        public int ID { get; set; }
+        public string Title { get; set; }
+        public int CountInPack { get; set; }
+        public string Unit { get; set; }
+        public double CountInStock { get; set; }
+        public double MinCount { get; set; }
+        public string Description { get; set; }
+        public decimal Cost { get; set; }
+        public string Image { get; set; }
+        public int MaterialTypeID { get; set; }
+    }
+}

+ 61 - 0
articles/old/mysql/Model/Product.cs

@@ -0,0 +1,61 @@
+using mysql.Classes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mysql.Model
+{
+    public class Product
+    {
+        public int ID { get; set; }
+        public string Title { get; set; }
+        public string ArticleNumber { get; set; }
+        public string Description { get; set; }
+        public string Image { get; set; }
+        public int ProductionPersonCount { get; set; }
+        public int ProductionWorkshopNumber { get; set; }
+        public decimal MinCostForAgent { get; set; }
+
+        // public string ProductTypeTitle { get; set; }
+        // public int ProductTypeID { get; set; }
+        public ProductType CurrentProductType { get; set; }
+
+        public string MaterialString { get; set; }
+        public string Total { get; set; }
+        public int DaysFromLastSale { get; set; }
+
+        public string LinqTitle {
+            get {
+                return Globals.ProductTypeList
+                    .Where(t=>t.ID== CurrentProductType.ID)
+                    .Select(t=>t.Title)
+                    .FirstOrDefault();
+            }
+        }
+
+        public Uri ImagePreview {
+            get {
+                var imageName = Environment.CurrentDirectory + (Image ?? "");
+                return System.IO.File.Exists(imageName) ? new Uri(imageName) : null;
+            }
+        }
+
+        public string TypeAndName {
+            get {
+                return CurrentProductType.Title+" | "+Title;
+            }
+        }
+
+        public string BackgroundColor
+        {
+            get
+            {
+                if (DaysFromLastSale > 30) return "#fee";
+                return "#fff";
+            }
+        }
+
+    }
+}

+ 18 - 0
articles/old/mysql/Model/ProductType.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mysql.Model
+{
+    public class ProductType
+    {
+        public int ID { get; set; }
+        public string Title { get; set; }
+
+        public override string ToString() {
+            return Title;
+        }
+    }
+}

+ 55 - 0
articles/old/mysql/Properties/AssemblyInfo.cs

@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// Общие сведения об этой сборке предоставляются следующим набором
+// набор атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("mysql")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("mysql")]
+[assembly: AssemblyCopyright("Copyright ©  2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
+// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
+// из модели COM, установите атрибут ComVisible для этого типа в значение true.
+[assembly: ComVisible(false)]
+
+//Чтобы начать создание локализуемых приложений, задайте
+//<UICulture>CultureYouAreCodingWith</UICulture> в файле .csproj
+//в <PropertyGroup>. Например, при использовании английского (США)
+//в своих исходных файлах установите <UICulture> в en-US.  Затем отмените преобразование в комментарий
+//атрибута NeutralResourceLanguage ниже.  Обновите "en-US" в
+//строка внизу для обеспечения соответствия настройки UICulture в файле проекта.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //где расположены словари ресурсов по конкретным тематикам
+                                     //(используется, если ресурс не найден на странице,
+                                     // или в словарях ресурсов приложения)
+    ResourceDictionaryLocation.SourceAssembly //где расположен словарь универсальных ресурсов
+                                              //(используется, если ресурс не найден на странице,
+                                              // в приложении или в каких-либо словарях ресурсов для конкретной темы)
+)]
+
+
+// Сведения о версии для сборки включают четыре следующих значения:
+//
+//      Основной номер версии
+//      Дополнительный номер версии
+//      Номер сборки
+//      Номер редакции
+//
+// Можно задать все значения или принять номера сборки и редакции по умолчанию 
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
articles/old/mysql/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Этот код был создан программным средством.
+//     Версия среды выполнения: 4.0.30319.42000
+//
+//     Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
+//     код создан повторно.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace mysql.Properties
+{
+
+
+    /// <summary>
+    ///   Класс ресурсов со строгим типом для поиска локализованных строк и пр.
+    /// </summary>
+    // Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
+    // класс с помощью таких средств, как ResGen или Visual Studio.
+    // Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
+    // с параметром /str или заново постройте свой VS-проект.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   Возврат кэшированного экземпляра ResourceManager, используемого этим классом.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mysql.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   Переопределяет свойство CurrentUICulture текущего потока для всех
+        ///   подстановки ресурсов с помощью этого класса ресурсов со строгим типом.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
articles/old/mysql/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 30 - 0
articles/old/mysql/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace mysql.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
articles/old/mysql/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 67 - 0
articles/old/mysql/Windows/EditWindow.xaml

@@ -0,0 +1,67 @@
+<Window x:Class="mysql.Windows.EditWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:mysql.Windows"
+        mc:Ignorable="d"
+        Title="{Binding WindowName}" 
+        Height="450" 
+        Width="800">
+
+    <Window.Resources>
+        <BitmapImage 
+            x:Key='defaultImage' 
+            UriSource='./Images/picture.png' />
+    </Window.Resources>
+
+    <Grid>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="auto"/>
+            <ColumnDefinition Width="*"/>
+            <ColumnDefinition Width="auto"/>
+        </Grid.ColumnDefinitions>
+
+        <Image
+            Width="200" 
+            Height="200"
+            Source="{Binding CurrentProduct.ImagePreview,TargetNullValue={StaticResource defaultImage}}" />
+
+        <StackPanel 
+            Grid.Column="1"
+            Margin="5">
+
+            <Label Content="Артикул"/>
+            <TextBox Text="{Binding CurrentProduct.ArticleNumber}"/>
+
+            <Label Content="Наименование продукта"/>
+            <TextBox Text="{Binding CurrentProduct.Title}"/>
+
+            <Label Content="Тип продукта"/>
+            <ComboBox 
+                ItemsSource="{Binding ProductTypes}"
+                SelectedItem="{Binding CurrentProduct.CurrentProductType}"/>
+
+            
+            
+            <!-- тип продукта (выпадающий список), изображение, количество человек для производства, номер производственного цеха, минимальная стоимость для агента и подробное описание -->
+
+            <Label Content="Описание продукта"/>
+            <TextBox 
+                AcceptsReturn="True"
+                Height="2cm"
+                Text="{Binding CurrentProduct.Description}"/>
+
+            <Button
+                x:Name="ChangeImage"
+                Click="ChangeImage_Click"
+                Content="Выбрать картинку"/>
+
+            <Button
+                Content="Сохранить"
+                Click="Button_Click"/>
+
+        </StackPanel>
+
+    </Grid>
+</Window>

+ 83 - 0
articles/old/mysql/Windows/EditWindow.xaml.cs

@@ -0,0 +1,83 @@
+using Microsoft.Win32;
+using mysql.Classes;
+using mysql.Model;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace mysql.Windows
+{
+    /// <summary>
+    /// Логика взаимодействия для EditWindow.xaml
+    /// </summary>
+    public partial class EditWindow : Window, INotifyPropertyChanged
+    {
+        public Product CurrentProduct { get; set; }
+        public IEnumerable<ProductType> ProductTypes { get; set; }
+
+        public EditWindow(Product EditProduct)
+        {
+            InitializeComponent();
+            DataContext = this;
+            CurrentProduct = EditProduct;
+            ProductTypes = Globals.DataProvider.GetProductTypes();
+        }
+
+        public string WindowName
+        {
+            get
+            {
+                return CurrentProduct.ID == 0 ? "Новый продукт" : "Редактирование продукта";
+            }
+        }
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        private void ChangeImage_Click(object sender, RoutedEventArgs e)
+        {
+            OpenFileDialog GetImageDialog = new OpenFileDialog();
+            // задаем фильтр для выбираемых файлов
+            // до символа "|" идет произвольный текст, а после него шаблоны файлов раздеренные точкой с запятой
+            GetImageDialog.Filter = "Файлы изображений: (*.png, *.jpg)|*.png;*.jpg";
+            // чтобы не искать по всему диску задаем начальный каталог
+            GetImageDialog.InitialDirectory = Environment.CurrentDirectory;
+            if (GetImageDialog.ShowDialog() == true)
+            {
+                // перед присвоением пути к картинке обрезаем начало строки, т.к. диалог возвращает полный путь
+                // (тут конечно еще надо проверить есть ли в начале Environment.CurrentDirectory)
+                CurrentProduct.Image = GetImageDialog.FileName.Substring(Environment.CurrentDirectory.Length);
+                Invalidate();
+            }
+        }
+
+        private void Invalidate(string ComponentName = "CurrentProduct")
+        {
+            if (PropertyChanged != null)
+                PropertyChanged(this, new PropertyChangedEventArgs(ComponentName));
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                Globals.DataProvider.SaveProduct(CurrentProduct);
+                DialogResult = true;
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.Message);
+            }
+        }
+    }
+}

+ 22 - 0
articles/old/mysql/Windows/EnterMinCostForAgentWindow.xaml

@@ -0,0 +1,22 @@
+<Window x:Class="mysql.Windows.EnterMinCostForAgentWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:mysql.Windows"
+        mc:Ignorable="d"
+        Title="Введите минимальную стоимость для выделенной продукции" Height="177" Width="494">
+    <Grid>
+        <StackPanel
+            Orientation="Vertical" Margin="0,50,0,0">
+
+            <TextBox
+                Name="CostTextBox"
+                />
+            <Button 
+                Content="Изменить"
+                Click="Button_Click"
+                />
+        </StackPanel>
+    </Grid>
+</Window>

+ 43 - 0
articles/old/mysql/Windows/EnterMinCostForAgentWindow.xaml.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace mysql.Windows
+{
+    /// <summary>
+    /// Логика взаимодействия для EnterMinCostForAgentWindow.xaml
+    /// </summary>
+    public partial class EnterMinCostForAgentWindow : Window
+    {
+        public decimal Result;
+
+        public EnterMinCostForAgentWindow(decimal AvgCost)
+        {
+            InitializeComponent();
+            CostTextBox.Text = AvgCost.ToString();
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                Result = Convert.ToDecimal(CostTextBox.Text);
+                DialogResult = true;
+            }
+            catch (Exception)
+            {
+                MessageBox.Show("Стоимость должна быть числом");
+            }
+        }
+    }
+}

+ 158 - 0
articles/old/mysql/Windows/MainWindow.xaml

@@ -0,0 +1,158 @@
+<Window x:Class="mysql.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:mysql"
+        mc:Ignorable="d"
+        Title="MainWindow" Height="450" Width="1000">
+
+    <Window.Resources>
+        <BitmapImage 
+            x:Key='defaultImage' 
+            UriSource='./Images/picture.png' />
+    </Window.Resources>
+    
+    <Grid>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="150"/>
+            <ColumnDefinition Width="*"/>
+        </Grid.ColumnDefinitions>
+        <Grid Grid.Column="1">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="auto"/>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="auto"/>
+            </Grid.RowDefinitions>
+
+            <WrapPanel 
+                Orientation="Horizontal" 
+                ItemHeight="30">
+                
+                <Label 
+                    Content="Сортировка: "
+                    Margin="10,0,0,0"
+                    VerticalAlignment="Center"/>
+                <ComboBox
+                    Name="SortTypeComboBox"
+                    SelectedIndex="0"
+                    VerticalContentAlignment="Center"
+                    MinWidth="200"
+                    SelectionChanged="SortTypeComboBox_SelectionChanged"
+                    ItemsSource="{Binding SortList}"/>
+
+                <Label 
+                    Content="Тип продукции" 
+                    VerticalAlignment="Center"/>
+                <ComboBox
+                    MinWidth="150"
+                    x:Name="ProductTypeFilter"
+                    VerticalAlignment="Center"
+                    SelectedIndex="0"
+                    SelectionChanged="ProductTypeFilter_SelectionChanged"
+                    ItemsSource="{Binding ProductTypeList}"/>
+
+                <Label 
+                    Content="Поиск" 
+                    VerticalAlignment="Center"/>
+                <TextBox
+                    Width="200"
+                    VerticalAlignment="Center"
+                    x:Name="SearchFilterTextBox" 
+                    KeyUp="SearchFilterTextBox_KeyUp"/>
+
+                <Button
+                    x:Name="CostChangeButton"
+                    Visibility="{Binding CostChangeButtonVisible}"
+                    Click="CostChangeButton_Click"
+                    Content="Изменить стоимость на..."
+                    />
+
+
+            </WrapPanel>
+
+
+            <ListView
+                Grid.Row="1"
+                Grid.Column="1"
+                x:Name="ProductListView"
+                SelectionChanged="ListView_SelectionChanged"
+                MouseDoubleClick="ProductListView_MouseDoubleClick"
+                ItemsSource="{Binding ProductList}"
+            >
+                <ListView.ItemContainerStyle>
+                    <Style 
+                        TargetType="ListViewItem">
+                        <Setter 
+                            Property="HorizontalContentAlignment"
+                            Value="Stretch" />
+                    </Style>
+                </ListView.ItemContainerStyle>
+
+                <ListView.ItemTemplate>
+                    <DataTemplate>
+                        <Border 
+                            BorderThickness="1" 
+                            BorderBrush="Black"
+                            Background="{Binding BackgroundColor}"
+                            CornerRadius="5">
+
+                            <Grid 
+                                Margin="10" 
+                                HorizontalAlignment="Stretch">
+
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition Width="64"/>
+                                    <ColumnDefinition Width="*"/>
+                                    <ColumnDefinition Width="auto"/>
+                                </Grid.ColumnDefinitions>
+
+                                <Image
+                                    Width="64" 
+                                    Height="64"
+                                    Source="{Binding ImagePreview,TargetNullValue={StaticResource defaultImage}}" />
+
+                                <StackPanel
+                                    Grid.Column="1"
+                                    Margin="5"
+                                    Orientation="Vertical">
+
+                                    <TextBlock 
+                                        Text="{Binding TypeAndName}"/>
+
+                                    <TextBlock 
+                                        Text="{Binding ArticleNumber}"/>
+
+                                    <TextBlock 
+                                        Text="{Binding MaterialString}"/>
+
+
+                                </StackPanel>
+
+                                <StackPanel
+                                    Grid.Column="2"
+                                    Margin="5"
+                                    HorizontalAlignment="Right" 
+                                    Orientation="Vertical">
+
+                                    <TextBlock 
+                                        Text="{Binding MinCostForAgent}" />
+                                    <TextBlock 
+                                        Text="{Binding Total}" />
+                                </StackPanel>
+                            </Grid>
+
+                        </Border>
+                    </DataTemplate>
+                </ListView.ItemTemplate>                
+            </ListView>
+
+            <StackPanel 
+                x:Name="Paginator"
+                Margin="5"
+                Grid.Row="2" 
+                HorizontalAlignment="Right" 
+                Orientation="Horizontal"/>
+        </Grid>
+    </Grid>
+</Window>

+ 201 - 0
articles/old/mysql/Windows/MainWindow.xaml.cs

@@ -0,0 +1,201 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using mysql.Classes;
+using mysql.Model;
+using mysql.Windows;
+using MySql.Data.MySqlClient;
+
+namespace mysql
+{
+    /// <summary>
+    /// Логика взаимодействия для MainWindow.xaml
+    /// </summary>
+    public partial class MainWindow : Window, INotifyPropertyChanged
+    {
+        private IEnumerable<Product> _ProductList;
+        private int _CurrentPage = 0;
+        private int ProductTypeFilterId = 0;
+
+        public List<ProductType> ProductTypeList { get; set; }
+
+        public string[] SortList { get; set; } = {
+            "Без сортировки",
+            "название по убыванию",
+            "название по возрастанию",
+            "номер цеха по убыванию",
+            "номер цеха по возрастанию",
+            "цена по убыванию",
+            "цена по возрастанию" };
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        private int CurrentPage {
+            get {
+                return _CurrentPage;
+            }
+            set {
+                _CurrentPage = value;
+                Invalidate();
+            }
+        }
+
+        private int SortType = 0;
+
+        public IEnumerable<Product> ProductList {
+            get {
+                var Result = _ProductList;
+
+                if (ProductTypeFilterId > 0)
+                    Result = Result.Where(i => i.CurrentProductType.ID == ProductTypeFilterId);
+
+                switch (SortType)
+                {
+                    // сортировка по названию продукции
+                    case 1:
+                        Result = Result.OrderBy(p => p.Title);
+                        break;
+                    case 2:
+                        Result = Result.OrderByDescending(p => p.Title);
+                        break;
+                        // остальные сортировки реализуйте сами
+
+                }
+
+                // ищем вхождение строки фильтра в названии и описании объекта без учета регистра
+                if (SearchFilter != "")
+                    Result = Result.Where(
+                        p => p.Title.IndexOf(SearchFilter, StringComparison.OrdinalIgnoreCase) >= 0 ||
+                             p.Description.IndexOf(SearchFilter, StringComparison.OrdinalIgnoreCase) >= 0
+                    );
+
+                Paginator.Children.Clear();
+
+                Paginator.Children.Add(new TextBlock { Text = " < " });
+                for (int i = 1; i <= (Result.Count() / 20)+1; i++)
+                    Paginator.Children.Add(new TextBlock { Text = " " + i.ToString() + " " });
+                Paginator.Children.Add(new TextBlock { Text = " > " });
+                foreach (TextBlock tb in Paginator.Children)
+                    tb.PreviewMouseDown += PrevPage_PreviewMouseDown;
+
+                if (CurrentPage > Result.Count() / 20)
+                    CurrentPage = Result.Count() / 20;
+
+                return Result.Skip(20 * CurrentPage).Take(20);
+            } 
+            set {
+                _ProductList = value;
+                Invalidate();
+            }
+        }
+
+        private void Invalidate(string ComponentName = "ProductList") {
+            if (PropertyChanged != null)
+                PropertyChanged(this, new PropertyChangedEventArgs(ComponentName));
+        }
+
+        public MainWindow()
+        {
+            InitializeComponent();
+            DataContext = this;
+
+            Globals.DataProvider = new MySQLDataProvider();
+            Globals.ProductTypeList = Globals.DataProvider.GetProductTypes();
+            ProductList = Globals.DataProvider.GetProducts();
+            ProductTypeList = Globals.DataProvider.GetProductTypes().ToList();
+            ProductTypeList.Insert(0, new ProductType { Title = "Все типы" });
+        }
+
+        private void PrevPage_PreviewMouseDown(object sender, MouseButtonEventArgs e)
+        {
+            switch ((sender as TextBlock).Text)
+            {
+                case " < ":
+                    if (CurrentPage > 0) CurrentPage--;
+                    return;
+                case " > ":
+                    if (CurrentPage < _ProductList.Count() / 20) CurrentPage++;
+                    return;
+                default:
+                    CurrentPage = Convert.ToInt32((sender as TextBlock).Text.Trim())-1;
+                    return;
+            }   
+        }
+
+        private void SortTypeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            SortType = SortTypeComboBox.SelectedIndex;
+            Invalidate();
+        }
+
+        private void ProductTypeFilter_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            ProductTypeFilterId = (ProductTypeFilter.SelectedItem as ProductType).ID;
+            Invalidate();
+        }
+
+        private string SearchFilter="";
+        private void SearchFilterTextBox_KeyUp(object sender, KeyEventArgs e)
+        {
+            SearchFilter = SearchFilterTextBox.Text;
+            Invalidate();
+        }
+
+
+        public string CostChangeButtonVisible {
+            get {
+                if (ProductsSelectedCount > 1) return "Visible";
+                return "Collapsed";
+            }
+        }
+
+        public int ProductsSelectedCount = 0;
+        private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            ProductsSelectedCount = ProductListView.SelectedItems.Count;
+            Invalidate("CostChangeButtonVisible");
+        }
+
+        private void CostChangeButton_Click(object sender, RoutedEventArgs e)
+        {
+            decimal AvgSum = 0;
+            List<int> idList = new List<int>();
+            foreach (Product item in ProductListView.SelectedItems)
+            {
+                AvgSum += item.MinCostForAgent;
+                idList.Add(item.ID);
+            }
+
+            var ww = new EnterMinCostForAgentWindow(AvgSum / ProductListView.SelectedItems.Count);
+
+            if((bool)ww.ShowDialog())
+            {
+                Globals.DataProvider.SetAverageCostForAgent(idList, ww.Result);
+                ProductList = Globals.DataProvider.GetProducts();
+            }
+        }
+
+        private void ProductListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+        {
+            var NewEditWindow = new EditWindow(ProductListView.SelectedItem as Product);
+            if ((bool)NewEditWindow.ShowDialog())
+            {
+                ProductList = Globals.DataProvider.GetProducts();
+            }
+        }
+    }
+}

BIN
articles/old/mysql/bin/Debug/products/tire_0.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_1.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_10.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_11.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_12.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_13.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_14.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_15.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_16.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_17.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_18.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_19.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_2.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_20.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_21.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_22.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_23.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_24.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_25.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_26.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_27.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_28.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_29.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_3.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_30.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_31.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_32.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_33.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_34.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_35.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_36.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_37.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_38.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_39.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_4.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_40.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_41.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_42.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_43.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_44.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_45.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_46.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_47.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_48.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_49.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_5.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_50.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_51.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_52.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_53.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_54.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_55.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_56.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_57.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_58.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_59.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_6.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_60.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_61.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_62.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_63.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_64.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_7.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_8.jpg


BIN
articles/old/mysql/bin/Debug/products/tire_9.jpg


+ 189 - 0
articles/old/mysql/mysql.csproj

@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" />
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{590122C3-15FA-4F95-8B3A-8EBBFA6AAD83}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>mysql</RootNamespace>
+    <AssemblyName>mysql</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="BouncyCastle.Crypto, Version=1.8.5.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
+      <HintPath>..\packages\BouncyCastle.1.8.5\lib\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
+    </Reference>
+    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.14.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.14.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="K4os.Compression.LZ4, Version=1.1.11.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
+      <HintPath>..\packages\K4os.Compression.LZ4.1.1.11\lib\net46\K4os.Compression.LZ4.dll</HintPath>
+    </Reference>
+    <Reference Include="K4os.Compression.LZ4.Streams, Version=1.1.11.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
+      <HintPath>..\packages\K4os.Compression.LZ4.Streams.1.1.11\lib\net46\K4os.Compression.LZ4.Streams.dll</HintPath>
+    </Reference>
+    <Reference Include="K4os.Hash.xxHash, Version=1.0.6.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
+      <HintPath>..\packages\K4os.Hash.xxHash.1.0.6\lib\net46\K4os.Hash.xxHash.dll</HintPath>
+    </Reference>
+    <Reference Include="MySql.Data, Version=8.0.26.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <HintPath>..\packages\MySql.Data.8.0.26\lib\net452\MySql.Data.dll</HintPath>
+    </Reference>
+    <Reference Include="MySql.Data.EntityFramework, Version=8.0.26.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <HintPath>..\packages\MySql.Data.EntityFramework.8.0.26\lib\net452\MySql.Data.EntityFramework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Configuration.Install" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Management" />
+    <Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security" />
+    <Reference Include="System.Transactions" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="Ubiety.Dns.Core, Version=2.2.1.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <HintPath>..\packages\MySql.Data.8.0.26\lib\net452\Ubiety.Dns.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="Zstandard.Net, Version=1.1.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <HintPath>..\packages\MySql.Data.8.0.26\lib\net452\Zstandard.Net.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Compile Include="Windows\EditWindow.xaml.cs">
+      <DependentUpon>EditWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Windows\EnterMinCostForAgentWindow.xaml.cs">
+      <DependentUpon>EnterMinCostForAgentWindow.xaml</DependentUpon>
+    </Compile>
+    <Page Include="Windows\EditWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Windows\MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Classes\Globals.cs" />
+    <Compile Include="Classes\IDataProvider.cs" />
+    <Compile Include="Classes\MySQLDataProvider.cs" />
+    <Compile Include="Windows\MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Page Include="Windows\EnterMinCostForAgentWindow.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Model\Material.cs" />
+    <Compile Include="Model\Product.cs" />
+    <Compile Include="Model\ProductType.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\DataSources\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="Images\picture.png" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их.  Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.props'))" />
+    <Error Condition="!Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.4\build\EntityFramework.targets'))" />
+  </Target>
+  <Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" />
+</Project>

+ 15 - 0
articles/old/mysql/packages.config

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="BouncyCastle" version="1.8.5" targetFramework="net472" />
+  <package id="EntityFramework" version="6.4.4" targetFramework="net472" />
+  <package id="Google.Protobuf" version="3.14.0" targetFramework="net472" />
+  <package id="K4os.Compression.LZ4" version="1.1.11" targetFramework="net472" />
+  <package id="K4os.Compression.LZ4.Streams" version="1.1.11" targetFramework="net472" />
+  <package id="K4os.Hash.xxHash" version="1.0.6" targetFramework="net472" />
+  <package id="MySql.Data" version="8.0.26" targetFramework="net472" />
+  <package id="MySql.Data.EntityFramework" version="8.0.26" targetFramework="net472" />
+  <package id="System.Buffers" version="4.5.1" targetFramework="net472" />
+  <package id="System.Memory" version="4.5.3" targetFramework="net472" />
+  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
+  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
+</packages>