Пагинация, сортировка, фильтрация, поиск Содержание Создание, изменение продукции
# Подсветка элементов по условию. Дополнительные выборки. >В списке продукции необходимо подсвечивать светло-красным цветом те продукты, которые не продавались агентами в последний месяц. Критерий | Баллы ---------|:---: Реализовано выделение (любым образом) продуктов, которые не продавались агентами в последний месяц | 1.5 Выделение реализовано в виде светло-красной подсветки элемента продукции | 0.5 **Итого** | **2** В самом списке продукции данных о продажах нет. Судя по названиям таблиц данные эти должны быть в таблице **ProductSale**. Судя по связям этой таблицы, мы должны заполнить ещё таблицы **Agent** и **AgentType**. ![](../img/01068.png) На демо-экзамене до этого вы вряд-ли дойдёте (хотя критерий достаточно жирный), но в рамках курсовой/дипломной работы реализовать дополнительный функционал надо. ## Добавление данных вручную 1. Добавляем типы агентов Исходных данных для этой и последующих таблиц нет, поэтому вы можете писать туда что угодно (но близко к предметной области). Для типов агентов подойдут "индивидуальный предприниматель" и "Общество с ограниченной ответственностью" (для не обязательных таблиц много данных придумывать не надо, достаточно одной-двух записей) И так как исходных данных нет, ~~а редактировать напрямую из **MySQL Workbench** нельзя, то пишем SQL-запрос вставки данных в основном его синтаксисе (с VALUE)~~ то добавляем данные прямо в таблицы. 2. Добавляем агента Тут заполняем только обязательные поля. *AgentTypeID* смотрим в таблице **AgentType**. 3. Создание продаж продукции Добавляем несколько записей. Поля *AgentID* и *ProductID* смотрим в соответствующих таблицах. Дата продажи заполняется в формате `YYYY-MM-DD` ## Дополнительная выборка Сначала пишем и отлаживаем запрос получения количества дней с последней продажи (дата продажи сама по себе нам не нужна, достаточно знать сколько дней прошло с момента продажи) ```sql SELECT ProductID, DATEDIFF(NOW(), max(SaleDate)) AS LastSaleDate FROM ProductSale GROUP BY ProductID ``` * Функция **DATEDIFF** вычисляет количество дней между датами. * Функция **NOW** возвращает текущую дату. Теперь этот запрос можно вставить в нашу основную выборку ещё одним **LEFT JOIN**-ом ```sql 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 ; ``` Атрибут *DaysFromLastSale* в модель пропишите сами. В методе получения данных с сервера надо вставить проверку на тип **NULL** ```cs NewProduct.DaysFromLastSale = (Reader["DaysFromLastSale"] as int?) ?? 999; ``` Или просто завернуть чтение этого поля в `try...except` и, при возникновении исключения, подставлять данные по-умолчанию ```cs try { NewProduct.DaysFromLastSale = Convert.ToInt32( Reader["DaysFromLastSale"].ToString()); } catch (Exception) { // нам не интересно всё, что больше 30 NewProduct.DaysFromLastSale = 999; } ``` ## Раскраска по условию Тут элементарно. У элемента рамка (Border) задаем цвет фона: ```cs ``` И добавляем в модель геттер *BackgroundColor* ```cs public string BackgroundColor { get { if(DaysFromLastSale>30) return "#fee"; return "#fff"; } } ``` >Про цвета: их можно отдавать в формате **#RGB**. Причём, чем ближе к **F**, тем светлее (**#FFF** - белый) ![](../img/01069.png) # Массовая смена цены продукции >Необходимо добавить возможность изменения минимальной стоимости продукции для агента сразу для нескольких выбранных продуктов. Для этой цели реализуйте возможность выделения сразу нескольких элементов в списке продукции, после чего должна появиться кнопка “Изменить стоимость на ...”. При нажатии на кнопку необходимо отобразить модальное окно с возможностью ввода числового значения, на которое и будет увеличена стоимость выбранных продуктов. По умолчанию в поле должно быть введено среднее значение цены на продукцию для агента. После нажатия кнопки “Изменить” стоимость выделенных продуктов должна быть изменена в базе данных, а также обновлена в интерфейсе. Критерий | Баллы ---------|:---: Реализована возможность выделения сразу нескольких элементов в списке | 0.2 После выделения элементов в списке появляется кнопка "Изменить стоимость на ..." | 0.3 При нажатии на кнопку отображается модальное окно для изменения цены | 0.1 В модальном окне есть возможность ввода числового значения | 0.1 По умолчанию введено значение средней цены выбранных продуктов | 0.2 Реализована проверка на ввод только числового значения | 0.2 После нажатия кнопки "Изменить" стоимость всех выбранных продуктов изменяется в БД | 0.5 После нажатия кнопки "Изменить" стоимость всех выбранных продуктов обновляется в списке | 0.2 **Итого** | **1.8** ## Выделение нескольких элементов Возможность выделения нескольких элементов в **ListView** есть, специально её реаизовывать не надо. Надо лишь поймать это событие и сосчитать количество выделенных элементов. В **ListView** нужно добавить название (мы потом будем по нему искать количество выделенных элементов) и обработчик события *SelectionChanged* ```cs x:Name="ProductListView" SelectionChanged="ListView_SelectionChanged" ``` Реализуем обработчик *ListView_SelectionChanged*: ```cs public int ProductsSelectedCount = 0; private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { ProductsSelectedCount = ProductListView.SelectedItems.Count; } ``` ## Отображение кнопки "Изменить стоимость на ..." Сначала просто добавляем эту кнопку в разметку ```xml