Compare commits

...

5 Commits

Author SHA1 Message Date
gg12 darfren
2f2f6aa4bc Еще правки 2024-05-01 10:45:25 +04:00
gg12 darfren
0311309a63 Еще допиливаю 2024-04-29 22:52:25 +04:00
gg12 darfren
904264de3d Правлю 2024-04-29 22:29:35 +04:00
04961cbd72 Merge branch 'Worker' 2024-04-29 21:22:58 +04:00
18ba6200b3 ХАХАХАХАХАХА Я ОГРАБИЛ БАНК 2024-04-29 21:22:12 +04:00
38 changed files with 553 additions and 194 deletions

View File

@ -376,7 +376,7 @@ View(APIPharmacist.GetRequest<List<ServiceViewModel>>($"api/service/getservices?
Dictionary<int, IMedicineModel> a = new Dictionary<int, IMedicineModel>();
foreach (int medicine in medicines)
{
a.Add(medicine, new AnimalSearchModel { Id = medicine } as IMedicineModel);
a.Add(medicine, new MedicineSearchModel { Id = medicine } as IMedicineModel);
}
APIPharmacist.PostRequest("api/service/createservice", new ServiceBindingModel
@ -490,7 +490,7 @@ View(APIPharmacist.GetRequest<List<ServiceViewModel>>($"api/service/getservices?
{
return Redirect("~/Home/Enter");
}
var res = APIPharmacist.GetRequest<List<GuidanceViewModel>>($"api/guidance/getguidances");
var res = APIPharmacist.GetRequest<List<GuidanceViewModel>>($"api/guidance/getguidances?pharmacistid={APIPharmacist.Pharmacist.Id}");
return
View(res);
@ -499,7 +499,7 @@ View(res);
[HttpGet]
public IActionResult CreateGuidance()
{
ViewBag.Services = APIPharmacist.GetRequest<List<ServiceViewModel>>("api/service/getservices");
ViewBag.Services = APIPharmacist.GetRequest<List<ServiceViewModel>>($"api/service/getservices?pharmacistid={APIPharmacist.Pharmacist.Id}");
return View();
}
[HttpPost]
@ -524,8 +524,8 @@ View(res);
[HttpGet]
public IActionResult UpdateGuidance()
{
ViewBag.Services = APIPharmacist.GetRequest<List<ServiceViewModel>>("api/service/getservices");
ViewBag.Guidances = APIPharmacist.GetRequest<List<GuidanceViewModel>>($"api/guidance/getguidances");
ViewBag.Services = APIPharmacist.GetRequest<List<ServiceViewModel>>($"api/service/getservices?pharmacistid={APIPharmacist.Pharmacist.Id}");
ViewBag.Guidances = APIPharmacist.GetRequest<List<GuidanceViewModel>>($"api/guidance/getguidances?pharmacistid={APIPharmacist.Pharmacist.Id}");
return View();
}
[HttpPost]
@ -552,7 +552,7 @@ View(res);
[HttpGet]
public IActionResult DeleteGuidance()
{
ViewBag.Guidances = APIPharmacist.GetRequest<List<GuidanceViewModel>>($"api/guidance/getguidances");
ViewBag.Guidances = APIPharmacist.GetRequest<List<GuidanceViewModel>>($"api/guidance/getguidances?pharmacistid={APIPharmacist.Pharmacist.Id}");
return View();
}

View File

@ -22,7 +22,7 @@
<select name="animals" class="form-control" multiple size="5" id="animals">
@foreach (var animal in ViewBag.Animals)
{
<option value="@animal.Id" id="@animal.AnimalName">@animal.AnimalName</option>
<option value="@animal.Id" data-name="@animal.AnimalName">@animal.AnimalName</option>
}
</select>
</div>
@ -50,7 +50,7 @@
$('#price').val(result.item1.price);
$.map(result.item2, function (n) {
console.log("#" + n);
$("#" + n).attr("selected", "selected")
$(`option[data-name=${n}]`).attr("selected", "selected")
});
}

View File

@ -52,7 +52,7 @@ btn-primary" />
success: function (result) {
console.log(result.item2);
$('#text').val(result.text);
$("#" + result.serviceId).attr("selected", "selected")
$(`option[data-name=${result.serviceId}]`).attr("selected", "selected")
}
});

View File

@ -28,7 +28,7 @@
<select name="medicines" class="form-control" multiple size="5" id="medicines">
@foreach (var medicine in ViewBag.Medicines)
{
<option value="@medicine.Id" id="@medicine.MedicineName">@medicine.MedicineName</option>
<option value="@medicine.Id" data-name="@medicine.MedicineName">@medicine.MedicineName</option>
}
</select>
</div>
@ -56,7 +56,7 @@
$('#price').val(result.item1.price);
$.map(result.item2, function ( n ) {
console.log("#" + n);
$("#" + n).attr("selected", "selected")
$(`option[data-name=${n}]`).attr("selected", "selected")
});
}

View File

@ -4,6 +4,8 @@ using System.Diagnostics;
using VetClinicContracts.BindingModels;
using VetClinicContracts.ViewModels;
using VetClinicDataModels.Models;
using System.Text;
using VetClinicContracts.SearchModels;
namespace VetClinicAdminApp.Controllers
@ -24,7 +26,7 @@ namespace VetClinicAdminApp.Controllers
return Redirect("~/Home/Enter");
}
return
View(APIAdmin.GetRequest<List<VisitViewModel>>($"api/visit/getvisits?vistId={APIAdmin.Admin.Id}"));
View(APIAdmin.GetRequest<List<VisitViewModel>>($"api/visit/getvisits?adminId={APIAdmin.Admin.Id}"));
}
public IActionResult IndexAnimals()
@ -34,7 +36,7 @@ View(APIAdmin.GetRequest<List<VisitViewModel>>($"api/visit/getvisits?vistId={API
return Redirect("~/Home/Enter");
}
return
View(APIAdmin.GetRequest<List<AnimalViewModel>>($"api/animal/getanimallist?animalId={APIAdmin.Admin.Id}"));
View(APIAdmin.GetRequest<List<AnimalViewModel>>($"api/animal/getanimallist?adminId={APIAdmin.Admin.Id}"));
}
public IActionResult IndexVaccinations()
@ -63,12 +65,12 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñóäà ïîïàëè? Ñóäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Ââåäèòå email, ïàðîëü è ÔÈÎ");
throw new Exception("Введите email, пароль и ФИО");
}
APIAdmin.PostRequest("api/admin/updatedata", new
AdminBindingModel
@ -95,13 +97,13 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password))
{
throw new Exception("Ââåäèòå email è ïàðîëü");
throw new Exception("Введите email и пароль");
}
APIAdmin.Admin =
APIAdmin.GetRequest<AdminViewModel>($"api/admin/login?login={login}&password={password}");
if (APIAdmin.Admin == null)
{
throw new Exception("Íåâåðíûé ëîãèí/ïàðîëü");
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
@ -116,7 +118,7 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Ââåäèòå ëîãèí, ïàðîëü è ÔÈÎ");
throw new Exception("Введите логин, пароль и ФИО");
}
APIAdmin.PostRequest("api/admin/register", new
AdminBindingModel
@ -156,11 +158,11 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name))
{
throw new Exception("Îøèáêà â ââåäåííûõ äàííûõ");
throw new Exception("Ошибка в введенных данных");
}
APIAdmin.PostRequest("api/visit/createvisit", new VisitBindingModel
{
@ -175,11 +177,11 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(animalname))
{
throw new Exception("Îøèáêà â ââåäåííûõ äàííûõ");
throw new Exception("Ошибка в введенных данных");
}
APIAdmin.PostRequest("api/animal/createanimal", new AnimalBindingModel
{
@ -194,11 +196,11 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name))
{
throw new Exception("Îøèáêà â ââåäåííûõ äàííûõ");
throw new Exception("Ошибка в введенных данных");
}
if (cost <= 0)
{
@ -225,11 +227,11 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
}
[HttpPost]
public void DeleteVisit(int visit)
public void Delete(int visit)
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
APIAdmin.PostRequest("api/visit/deletevisit", new VisitBindingModel
{
@ -290,7 +292,7 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
return Redirect("~/Home/Enter");
}
ViewBag.Medicines = APIAdmin.GetRequest<List<MedicineViewModel>>("api/visit/getvisits");
ViewBag.Visits = APIAdmin.GetRequest<List<VisitViewModel>>("api/visit/getvisits");
return View();
}
@ -299,11 +301,11 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name))
{
throw new Exception("Îøèáêà â ââåäåííûõ äàííûõ");
throw new Exception("Ошибка в введенных данных");
}
APIAdmin.PostRequest("api/visit/updatevisit", new VisitBindingModel
{
@ -330,6 +332,7 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name))
{
throw new Exception("Ошибка в введенных данных");
@ -343,6 +346,82 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
});
Response.Redirect("IndexAnimals");
}
public IActionResult VisitAnimals()
{
if (APIAdmin.Admin == null)
{
return Redirect("~/Home/Enter");
}
ViewBag.Animals = APIAdmin.GetRequest<List<AnimalViewModel>>($"api/animal/getanimallist?adminid={APIAdmin.Admin.Id}");
ViewBag.Visits = APIAdmin.GetRequest<List<VisitViewModel>>($"api/visit/getvisits");
return View();
}
[HttpPost]
public void VisitAnimals(int animal, string name, string family,
List<int> visits)
{
if (APIAdmin.Admin == null)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(family))
{
throw new Exception("Ошибка в введенных данных");
}
Dictionary<int, IVisitModel> v = new Dictionary<int, IVisitModel>();
foreach (int visit in visits)
{
v.Add(visit, new VisitSearchModel { Id = visit } as IVisitModel);
}
APIAdmin.PostRequest("api/animal/updateanimal?isconnection=true", new AnimalBindingModel
{
Id = animal,
AnimalName = name,
Family = family,
AdminId = APIAdmin.Admin.Id,
VisitAnimals = v
});
Response.Redirect("IndexAnimals");
}
public IActionResult ServiceVisits()
{
if (APIAdmin.Admin == null)
{
return Redirect("~/Home/Enter");
}
ViewBag.Visits = APIAdmin.GetRequest<List<VisitViewModel>>($"api/visit/getvisits?adminid={APIAdmin.Admin.Id}");
ViewBag.Services = APIAdmin.GetRequest<List<ServiceViewModel>>($"api/service/getservices");
return View();
}
[HttpPost]
public void ServiceVisits(int visit, string name, DateTime date,
List<int> services)
{
if (APIAdmin.Admin == null)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name) || date == new DateTime())
{
throw new Exception("Ошибка в введенных данных");
}
Dictionary<int, IServiceModel> s = new Dictionary<int, IServiceModel>();
foreach (int service in services)
{
s.Add(service, new ServiceSearchModel { Id = service } as IServiceModel);
}
APIAdmin.PostRequest("api/visit/updatevisit?isconnection=true", new VisitBindingModel
{
Id = visit,
NameVisit = name,
DateVisit = date,
AdminId = APIAdmin.Admin.Id,
ServiceVisits = s
});
Response.Redirect("Index");
}
public IActionResult UpdateVaccination()
{
if (APIAdmin.Admin == null)
@ -383,27 +462,49 @@ View(APIAdmin.GetRequest<List<VaccinationViewModel>>($"api/vaccination/getvaccin
}
[HttpGet]
public Tuple<VisitViewModel, string>? GetVisit(int visitId)
public Tuple<VisitViewModel, List<string>>? GetVisit(int visitId)
{
if (APIAdmin.Admin == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
var result = APIAdmin.GetRequest<Tuple<VisitViewModel, List<string>>>($"api/visit/getvisit?visitid={visitId}");
if (result == null)
{
return default;
}
string table = "";
result.Item1.VisitAnimals.Clear();
for (int i = 0; i < result.Item2.Count; i++)
return result;
}
[HttpGet]
public Tuple<AnimalViewModel, List<string>>? GetAnimal(int animalId)
{
if (APIAdmin.Admin == null)
{
var animal = result.Item2[i];
table += "<tr>";
table += $"<td>{animal}</td>";
table += "</tr>";
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
return Tuple.Create(result.Item1, table);
var result = APIAdmin.GetRequest<Tuple<AnimalViewModel, List<string>>>($"api/animal/getanimal?animalid={animalId}");
if (result == null)
{
return default;
}
return result;
}
[HttpGet]
public Tuple<ServiceViewModel, List<string>>? GetService(int serviceId)
{
if (APIAdmin.Admin == null)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
var result = APIAdmin.GetRequest<Tuple<ServiceViewModel, List<string>>>($"api/service/getservice?serviceid={serviceId}");
if (result == null)
{
return default;
}
return result;
}
}
}

View File

@ -10,13 +10,13 @@
<div class="row">
<div class="col-4">Название:</div>
<div class="col-8">
<input id="title" type="text" name="title" />
<input type="text" name="name" />
</div>
</div>
<div class="row">
<div class="col-4">Дата:</div>
<div class="col-8">
<input type="date" id="date" name="date"/>
<input type="datetime" id="datetime" name="date" />
</div>
</div>
<div class="row">

View File

@ -0,0 +1,18 @@
@{
ViewData["Title"] = "Delete";
}
<div class="text-center">
<h2 class="display-4">Удаление визита</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Визиты:</div>
<div class="col-8">
<select id="visit" name="visit" class="form-control" asp-items="@(new SelectList(@ViewBag.Visits, "Id", "NameVisit"))"></select>
</div>
</div>
<div class="row">
<div class="col-4"></div>
<div class="col-8"><input type="submit" value="Удалить" class="btn btn-danger" /></div>
</div>
</form>

View File

@ -17,7 +17,11 @@
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a asp-action="Update">Редактировать визит</a>
<a asp-action="Delete">Удалить визит</a>
<a asp-action="ServiceVisits">Связать визит и услуги</a>
</p>
<p>
<a asp-action="Create">Создать визит</a>
</p>

View File

@ -19,6 +19,7 @@
}
<p>
<a asp-action="UpdateAnimal">Редактировать животное</a>
<a asp-action="VisitAnimals">Связать животных и визиты </a>
<a asp-action="DeleteAnimal">Удалить животное</a>
</p>
<p>

View File

@ -0,0 +1,65 @@
@using VetClinicContracts.ViewModels;
@{
ViewData["Title"] = "ServiceVisits";
}
<div class="text-center">
<h2 class="display-4">Связывание визита и услуги</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Визит:</div>
<div class="col-8">
<select id="visit" name="visit" class="form-control" asp-items="@(new SelectList(@ViewBag.Visits, "Id", "NameVisit"))"></select>
</div>
</div>
<input style = "visibility: hidden" type="text" name="name" id="name" class="form-control" />
<input style="visibility: hidden" type="datetime" id="datetime" name="date" class="form-control" />
<div class="row">
<div class="col-4">Услуги:</div>
<div class="col-8">
<select name="services" class="form-control" multiple size="5" id="services">
@foreach (var service in ViewBag.Services)
{
<option value="@service.Id" id="@service.ServicesName">@service.ServicesName</option>
}
</select>
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
</div>
</form>
@section Scripts
{
<script>
function check() {
var animal = $('#visit').val();
$("#services option:selected").removeAttr("selected");
if (animal) {
$.ajax({
method: "GET",
url: "/Home/GetVisit",
data: { animalId: animal },
success: function (result) {
console.log(result.item2);
$('#name').val(result.item1.visitName);
$('#date').val(result.item1.date);
$.map(result.item2, function (n) {
console.log("#" + n);
$("#" + n).attr("selected", "selected")
});
}
});
};
}
check();
$('#visit').on('change', function () {
check();
});
</script>
}

View File

@ -0,0 +1,58 @@
@using VetClinicContracts.ViewModels;
@{
ViewData["Title"] = "Update";
}
<div class="text-center">
<h2 class="display-4">Редактирование визит</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Визит:</div>
<div class="col-8">
<select id="visit" name="visit" class="form-control" asp-items="@(new SelectList(@ViewBag.Visits, "Id", "NameVisit"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Название:</div>
<div class="col-8"><input type="text" name="name" id="name" class="form-control" /></div>
</div>
<div class="row">
<div class="col-4">Дата:</div>
<div class="col-8">
<input type="datetime" id="datetime" name="date" />
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
</div>
</form>
@section Scripts
{
<script>
function check() {
var visit = $('#visit').val();
if (visit) {
$.ajax({
method: "GET",
url: "/Home/GetVisit",
data: { visitId: visit },
success: function (result) {
$('#name').val(result.item1.vistName);
$('#date').val(result.item1.date);
}
});
};
}
check();
$('#visit').on('change', function () {
check();
});
</script>
}

View File

@ -0,0 +1,65 @@
@using VetClinicContracts.ViewModels;
@{
ViewData["Title"] = "VisitAnimals";
}
<div class="text-center">
<h2 class="display-4">Связывание животного и визита</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Животное:</div>
<div class="col-8">
<select id="animal" name="animal" class="form-control" asp-items="@(new SelectList(@ViewBag.Animals, "Id", "AnimalName"))"></select>
</div>
</div>
<input style = "visibility: hidden" type="text" name="name" id="name" class="form-control" />
<input style = "visibility: hidden" type="text" id="family" name="family" class="form-control" />
<div class="row">
<div class="col-4">Визиты:</div>
<div class="col-8">
<select name="visits" class="form-control" multiple size="5" id="visits">
@foreach (var visit in ViewBag.Visits)
{
<option value="@visit.Id" id="@visit.NameVisit">@visit.NameVisit</option>
}
</select>
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
</div>
</form>
@section Scripts
{
<script>
function check() {
var animal = $('#animal').val();
$("#visits option:selected").removeAttr("selected");
if (animal) {
$.ajax({
method: "GET",
url: "/Home/GetAnimal",
data: { animalId: animal },
success: function (result) {
console.log(result.item2);
$('#name').val(result.item1.animalName);
$('#family').val(result.item1.family);
$.map(result.item2, function (n) {
console.log("#" + n);
$("#" + n).attr("selected", "selected")
});
}
});
};
}
check();
$('#animal').on('change', function () {
check();
});
</script>
}

View File

@ -103,7 +103,7 @@ namespace VetClinicBusinessLogic.BusinessLogics
throw new ArgumentNullException("Отсутствие пароля в учётной записи", nameof(model.Password));
}
_logger.LogInformation("WorkPiece. AdminFIO:{AdminFIO}. Email:{Email}. Password:{Password}. Id:{Id}",
_logger.LogInformation("Admin. AdminFIO:{AdminFIO}. Email:{Email}. Password:{Password}. Id:{Id}",
model.AdminFIO, model.Email, model.Password, model.Id);
var element = _adminStorage.GetElement(new AdminSearchModel
{

View File

@ -46,7 +46,7 @@ namespace VetClinicBusinessLogic.BusinessLogics
return element;
}
public bool CreateAnimal(AnimalBindingModel model)
public bool Create(AnimalBindingModel model)
{
CheckModel(model);
@ -58,7 +58,7 @@ namespace VetClinicBusinessLogic.BusinessLogics
return true;
}
public bool UpdateAnimal(AnimalBindingModel model)
public bool Update(AnimalBindingModel model)
{
CheckModel(model);
if (_animalStorage.Update(model) == null)
@ -69,7 +69,7 @@ namespace VetClinicBusinessLogic.BusinessLogics
return true;
}
public bool DeleteAnimal(AnimalBindingModel model)
public bool Delete(AnimalBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
@ -90,7 +90,7 @@ namespace VetClinicBusinessLogic.BusinessLogics
{
return;
}
if (model.AnimalName == "")
if (string.IsNullOrEmpty(model.AnimalName))
{
throw new ArgumentNullException("Имя не должно быть пустым", nameof(model.AnimalName));
}
@ -98,12 +98,17 @@ namespace VetClinicBusinessLogic.BusinessLogics
{
throw new ArgumentNullException("Некорректный идентификатор у клиента", nameof(model.AdminId));
}
var element = _animalStorage.GetElement(new AnimalSearchModel
{
Id = model.Id
AnimalName = model.AnimalName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Животное с таким названием уже есть");
}
}
}
}

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using VetClinicContracts.BindingModels;
using VetClinicContracts.BusinessLogicsContracts;
using VetClinicContracts.SearchModels;
@ -107,6 +108,16 @@ namespace VetClinicBusinessLogic.BusinessLogics
}
_logger.LogInformation("Vaccination. NameVaccination:{NameVaccination}. CostVaccination:{CostVaccination}", model.NameVaccination, model.CostVaccination);
var element = _vaccinationStorage.GetElement(new VaccinationSearchModel
{
NameVaccination = model.NameVaccination,
DateStamp = model.DateStamp,
AnimalId = model.AnimalId,
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Прививка для этого услуги с таким текстом уже есть");
}
}
}
}

View File

@ -101,8 +101,12 @@ true)
throw new ArgumentNullException("Нет названия визита",
nameof(model.NameVisit));
}
_logger.LogInformation("Medicine. Medicine:{NameVisit}. Id: { Id}", model.NameVisit, model.Id);
if (model.DateVisit != null)
{
throw new ArgumentNullException("Нет времени визита",
nameof(model.DateVisit));
}
_logger.LogInformation("Visit. Visit:{NameVisit}. DateVisit:{ DateVisit } Id: { Id}", model.NameVisit, model.DateVisit, model.Id);
var element = _visitStorage.GetElement(new VisitSearchModel
{
NameVisit = model.NameVisit

View File

@ -1,6 +1,8 @@
namespace VetClinicContracts.BindingModels
using VetClinicDataModels.Models;
namespace VetClinicContracts.BindingModels
{
public class AdminBindingModel
public class AdminBindingModel : IAdminModel
{
public int Id { get; set; }
public string AdminFIO { get; set; } = string.Empty;

View File

@ -12,6 +12,7 @@ namespace VetClinicContracts.BindingModels
public int Id { get; set; }
public int AdminId { get; set; }
public Dictionary<int, IVisitModel> VisitAnimals { get; set; } = new();
public string AnimalName { get; set; } = string.Empty;
public string? Family { get; set; } = string.Empty;

View File

@ -7,12 +7,10 @@ using VetClinicDataModels.Models;
namespace VetClinicContracts.BindingModels
{
public class VisitBindingModel
public class VisitBindingModel : IVisitModel
{
public int Id { get; set; }
public int AdminId { get; set; }
public Dictionary<int, IAnimalModel> VisitAnimals { get; set; } = new();
public Dictionary<int, IServiceModel> ServiceVisits { get; set; } = new ();
public string NameVisit { get; set; } = string.Empty;
public DateTime DateVisit { get; set; }

View File

@ -13,8 +13,8 @@ namespace VetClinicContracts.BusinessLogicsContracts
{
List<AnimalViewModel>? ReadList(AnimalSearchModel? model);
AnimalViewModel? ReadElement(AnimalSearchModel model);
bool CreateAnimal(AnimalBindingModel model);
bool UpdateAnimal(AnimalBindingModel model);
bool DeleteAnimal(AnimalBindingModel model);
bool Create(AnimalBindingModel model);
bool Update(AnimalBindingModel model);
bool Delete(AnimalBindingModel model);
}
}

View File

@ -10,6 +10,7 @@ namespace VetClinicContracts.SearchModels
{
public int? Id { get; set; }
public string? Text { get; set; }
public int? PharmacistId { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }
public int? ServiceId { get; set; }

View File

@ -12,6 +12,7 @@ namespace VetClinicContracts.SearchModels
public string? NameVaccination { get; set; }
public double? CostVaccination { get; set; }
public DateTime? DateStamp { get; set; }
public DateTime? DateFrom { get; set; }
public DateTime? DateTo { get; set; }

View File

@ -19,5 +19,7 @@ namespace VetClinicContracts.ViewModels
[DisplayName("Семейство")]
public string? Family { get; set; } = string.Empty;
public Dictionary<int, IVisitModel> VisitAnimals { get; set; } = new();
}
}

View File

@ -14,21 +14,14 @@ namespace VetClinicContracts.ViewModels
public int Id { get; set; }
public int AdminId { get; set; }
[DisplayName("Животное")]
public string AnimalName { get; set; } = string.Empty;
[DisplayName("Название визита")]
public string NameVisit { get; set; } = string.Empty;
[DisplayName("Админ")]
public string AdminFIO { get; set; } = string.Empty;
[DisplayName("Название услуг")]
public string ServiceName { get; set; } = string.Empty;
[DisplayName("Дата визита")]
public DateTime DateVisit { get; set; }
public Dictionary<int, IAnimalModel> VisitAnimals { get; set; } = new();
public Dictionary<int, IServiceModel> ServiceVisits { get; set; } = new();
}

View File

@ -35,23 +35,17 @@ namespace VetClinicDataBaseImplement.Implements
public AdminViewModel? GetElement(AdminSearchModel model)
{
using var context = new VetClinicDatabase();
if (model.Id.HasValue)
if (string.IsNullOrEmpty(model.AdminFIO) && string.IsNullOrEmpty(model.Email) &&
!model.Id.HasValue)
{
return context.Admins
.Include(x => x.Visits)
.Include(x => x.Animals)
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
return null;
}
else if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password))
{
return context.Admins
.Include(x => x.Visits)
.Include(x => x.Animals)
.FirstOrDefault(x => (x.Email == model.Email && x.Password == model.Password))
?.GetViewModel;
}
return new();
return context.Admins
.FirstOrDefault(x => (string.IsNullOrEmpty(model.AdminFIO) || x.AdminFIO == model.AdminFIO) &&
(!model.Id.HasValue || x.Id == model.Id) && (string.IsNullOrEmpty(model.Email) || x.Email == model.Email) &&
(string.IsNullOrEmpty(model.Password) || x.Password == model.Password))
?.GetViewModel;
}
public List<AdminViewModel> GetFilteredList(AdminSearchModel model)

View File

@ -16,22 +16,21 @@ namespace VetClinicBaseImplement.Implements
return context.Animals
.Include(x => x.Admin)
.Include(x => x.Visits)
.ThenInclude(x => x.Visit)
.Select(x => x.GetViewModel)
.ToList();
}
public List<AnimalViewModel> GetFilteredList(AnimalSearchModel model)
{
if (string.IsNullOrEmpty(model.AnimalName))
{
return new();
}
using var context = new VetClinicDatabase();
return context.Animals
.Include(x => x.Admin)
.Where(x => x.AnimalName.Contains(model.AnimalName))
.ToList()
.Select(x => x.GetViewModel).ToList();
return context.Animals.Include(x => x.Admin).Include(x => x.Visits)
.ThenInclude(x => x.Visit)
.Where(x => (string.IsNullOrEmpty(model.AnimalName) || x.AnimalName.Contains(model.AnimalName))
&& (!model.AdminId.HasValue || x.AdminId == model.AdminId))
.Select(x => x.GetViewModel)
.ToList();
}
public AnimalViewModel? GetElement(AnimalSearchModel model)
{
@ -42,6 +41,8 @@ namespace VetClinicBaseImplement.Implements
using var context = new VetClinicDatabase();
return context.Animals
.Include(x => x.Admin)
.Include(x => x.Visits)
.ThenInclude(x => x.Visit)
.Include(x => x.Vaccinations)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.AnimalName) && x.AnimalName == model.AnimalName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
@ -54,6 +55,7 @@ namespace VetClinicBaseImplement.Implements
return null;
}
context.Animals.Add(newAnimal);
context.SaveChanges();
return newAnimal.GetViewModel;
}
@ -64,13 +66,21 @@ namespace VetClinicBaseImplement.Implements
try
{
var animal = context.Animals.FirstOrDefault(rec => rec.Id == model.Id);
var animal = context.Animals.Include(x => x.Admin)
.Include(x => x.Visits)
.ThenInclude(x => x.Visit).FirstOrDefault(rec =>
rec.Id == model.Id);
if (animal == null)
{
return null;
}
animal.Update(model);
context.SaveChanges();
if (model.VisitAnimals != null)
{
animal.UpdateVisits(context, model);
}
transaction.Commit();
return animal.GetViewModel;
}
@ -85,6 +95,7 @@ namespace VetClinicBaseImplement.Implements
using var context = new VetClinicDatabase();
var element = context.Animals
.Include(x => x.Vaccinations)
.Include(x => x.Visits).ThenInclude(x => x.Visit)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)

View File

@ -25,7 +25,7 @@ namespace VetClinicDataBaseImplement.Implements
using var context = new VetClinicDatabase();
return context.Guidances.Include(x => x.Service).Where(x => (!model.Id.HasValue || model.Id == x.Id)
&& (!model.ServiceId.HasValue || model.ServiceId == x.ServiceId) && (!model.DateFrom.HasValue || model.DateFrom <= x.Date)
&& (!model.DateTo.HasValue || model.DateTo >= x.Date))
&& (!model.DateTo.HasValue || model.DateTo >= x.Date) && (!model.PharmacistId.HasValue || model.PharmacistId == x.Service.PharmacistId))
.Select(x => x.GetViewModel)
.ToList();
}

View File

@ -21,8 +21,7 @@ namespace VetClinicDataBaseImplement.Implements
return context.Visits
.Include(x => x.Admin)
.Include(x => x.Animals)
.ThenInclude(x => x.Animal)
.Include(x => x.Services)
.ThenInclude(x => x.Service)
.Select(x => x.GetViewModel)
@ -30,22 +29,13 @@ namespace VetClinicDataBaseImplement.Implements
}
public List<VisitViewModel> GetFilteredList(VisitSearchModel model)
{
if (string.IsNullOrEmpty(model.NameVisit))
{
return new();
}
using var context = new VetClinicDatabase();
return context.Visits
.Include(x => x.Admin)
.Include(x => x.Animals)
.ThenInclude(x => x.Animal)
.Where(x => x.NameVisit.Contains(model.NameVisit))
.Include(x => x.Services)
return context.Visits.Include(x => x.Admin).Include(x => x.Services)
.ThenInclude(x => x.Service)
.Where(x => x.NameVisit.Contains(model.NameVisit))
.ToList()
.Select(x => x.GetViewModel).ToList();
.Where(x => (string.IsNullOrEmpty(model.NameVisit) || x.NameVisit.Contains(model.NameVisit))
&& (!model.AdminId.HasValue || x.AdminId == model.AdminId))
.Select(x => x.GetViewModel)
.ToList();
}
public VisitViewModel? GetElement(VisitSearchModel model)
{
@ -56,11 +46,13 @@ namespace VetClinicDataBaseImplement.Implements
using var context = new VetClinicDatabase();
return context.Visits
.Include(x => x.Admin)
.Include(x => x.Animals)
.ThenInclude(x => x.Animal)
.Include(x => x.Services)
.ThenInclude(x => x.Service)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.NameVisit) && x.NameVisit == model.NameVisit) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.NameVisit) &&
x.NameVisit == model.NameVisit) ||
(model.Id.HasValue && x.Id ==
model.Id))
?.GetViewModel;
}
public VisitViewModel? Insert(VisitBindingModel model)
{
@ -88,7 +80,8 @@ namespace VetClinicDataBaseImplement.Implements
}
visit.Update(model);
context.SaveChanges();
visit.UpdateAnimals(context, model);
if (model.ServiceVisits != null)
visit.UpdateServices(context, model);
transaction.Commit();
return visit.GetViewModel;
}
@ -102,11 +95,10 @@ namespace VetClinicDataBaseImplement.Implements
{
using var context = new VetClinicDatabase();
var element = context.Visits
.Include(x => x.Animals).ThenInclude(x => x.Animal)
.Include(x => x.Admin)
.Include(x => x.Services).ThenInclude(x => x.Service)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{

View File

@ -37,7 +37,22 @@ namespace VetClinicDataBaseImplement.Models
[ForeignKey("AnimalId")]
public virtual List<MedicineAnimal> Medicines { get; set; } = new();
public Dictionary<int, IVisitModel>? _visitAnimals = null;
[NotMapped]
public Dictionary<int, IVisitModel> VisitAnimals
{
get
{
if (_visitAnimals == null)
{
_visitAnimals = Visits.ToDictionary(recPC => recPC.VisitId, recPC =>
recPC.Visit as IVisitModel);
}
return _visitAnimals;
}
}
public static Animal? Create(VetClinicDatabase context, AnimalBindingModel? model)
{
if (model == null)
@ -50,7 +65,10 @@ namespace VetClinicDataBaseImplement.Models
AdminId = model.AdminId,
AnimalName = model.AnimalName,
Family = model.Family,
Visits = model.VisitAnimals.Select(x => new VisitAnimal
{
Visit = context.Visits.First(y => y.Id == x.Key)
}).ToList()
};
}
public void Update(AnimalBindingModel? model)
@ -65,11 +83,37 @@ namespace VetClinicDataBaseImplement.Models
public AnimalViewModel GetViewModel => new()
{
Id = Id,
VisitAnimals = VisitAnimals,
AdminId = AdminId,
AnimalName = AnimalName,
Family = Family
};
public void UpdateVisits(VetClinicDatabase context, AnimalBindingModel model)
{
var visitAnimals = context.VisitAnimals.Where(rec => rec.AnimalId == model.Id).ToList();
if (visitAnimals != null)
{
context.VisitAnimals.RemoveRange(visitAnimals.Where(rec => !model.VisitAnimals.ContainsKey(rec.VisitId)));
context.SaveChanges();
foreach (var visit in visitAnimals)
{
model.VisitAnimals.Remove(visit.VisitId);
}
context.SaveChanges();
}
var animal = context.Animals.First(x => x.Id == Id);
foreach (var pc in model.VisitAnimals)
{
context.VisitAnimals.Add(new VisitAnimal
{
Animal = animal,
Visit = context.Visits.First(x => x.Id == pc.Key),
});
context.SaveChanges();
}
_visitAnimals = null;
}
}
}

View File

@ -31,23 +31,11 @@ namespace VetClinicDataBaseImplement.Models
[ForeignKey("VisitId")]
public virtual List<VisitService> Services { get; set; } = new();
public virtual Admin Admin { get; set; }
public Dictionary<int, IAnimalModel>? _visitAnimals = null;
public Dictionary<int, IServiceModel>? _serviceVisits = null;
[NotMapped]
public Dictionary<int, IAnimalModel> VisitAnimals
{
get
{
if (_visitAnimals == null)
{
_visitAnimals = Animals.ToDictionary(recPC => recPC.AnimalId, recPC =>
recPC.Animal as IAnimalModel);
}
return _visitAnimals;
}
}
[NotMapped]
public Dictionary<int, IServiceModel> ServiceVisits
{
@ -74,10 +62,6 @@ namespace VetClinicDataBaseImplement.Models
NameVisit = model.NameVisit,
DateVisit = model.DateVisit,
Animals = model.VisitAnimals.Select(x => new VisitAnimal
{
Animal = context.Animals.First(y => y.Id == x.Key)
}).ToList(),
Services = model.ServiceVisits.Select(x => new VisitService
{
Service = context.Services.First(y => y.Id == x.Key)
@ -96,43 +80,26 @@ namespace VetClinicDataBaseImplement.Models
public VisitViewModel GetViewModel => new()
{
Id = Id,
VisitAnimals = VisitAnimals,
AdminId = AdminId,
NameVisit = NameVisit,
DateVisit = DateVisit,
ServiceVisits = ServiceVisits
};
public void UpdateAnimals(VetClinicDatabase context, VisitBindingModel model)
{
var visitAnimals = context.VisitAnimals.Where(rec => rec.VisitId == model.Id).ToList();
if (visitAnimals != null)
{ // удалили те, которых нет в модели
context.VisitAnimals.RemoveRange(visitAnimals.Where(rec => !model.VisitAnimals.ContainsKey(rec.AnimalId)));
context.SaveChanges();
}
var visit = context.Visits.First(x => x.Id == Id);
foreach (var pc in model.VisitAnimals)
{
context.VisitAnimals.Add(new VisitAnimal
{
Visit = visit,
Animal = context.Animals.First(x => x.Id == pc.Key),
});
context.SaveChanges();
}
_visitAnimals = null;
}
public void UpdateService(VetClinicDatabase context, VisitBindingModel model)
public void UpdateServices(VetClinicDatabase context, VisitBindingModel model)
{
var serviceVisits = context.ServiceVisits.Where(rec => rec.VisitId == model.Id).ToList();
if (serviceVisits != null)
{ // удалили те, которых нет в модели
context.ServiceVisits.RemoveRange(serviceVisits.Where(rec => !model.ServiceVisits.ContainsKey(rec.ServiceId)));
context.SaveChanges();
foreach (var service in serviceVisits)
{
model.ServiceVisits.Remove(service.ServiceId);
}
context.SaveChanges();
}
var visit = context.Visits.First(x => x.Id == Id);
foreach (var pc in model.ServiceVisits)

View File

@ -11,5 +11,7 @@ namespace VetClinicDataModels.Models
int AdminId { get; }
string AnimalName { get; }
string? Family { get; }
}
Dictionary<int, IVisitModel> VisitAnimals { get; }
}
}

View File

@ -8,7 +8,6 @@ namespace VetClinicDataModels.Models
{
public interface IVaccinationModel : IId
{
int Id { get; }
int AnimalId { get; }
string NameVaccination { get; }
double CostVaccination { get; }

View File

@ -8,12 +8,9 @@ namespace VetClinicDataModels.Models
{
public interface IVisitModel : IId
{
int Id { get;}
int AdminId { get; }
string NameVisit { get;}
DateTime DateVisit { get; }
Dictionary<int,IAnimalModel> VisitAnimals { get; }
Dictionary<int, IServiceModel> ServiceVisits { get; }
}
}

View File

@ -4,6 +4,7 @@ using VetClinicContracts.BindingModels;
using VetClinicContracts.BusinessLogicsContracts;
using VetClinicContracts.SearchModels;
using VetClinicContracts.ViewModels;
using VetClinicDataBaseImplement.Models;
namespace VetClinicRestApi.Controllers
{
@ -20,14 +21,16 @@ namespace VetClinicRestApi.Controllers
}
[HttpGet]
public AnimalViewModel? GetAnimal(int animalId)
public Tuple<AnimalViewModel, List<string>>? GetAnimal(int animalId)
{
try
{
return _animal.ReadElement(new AnimalSearchModel
{
Id = animalId
});
var elem = _animal.ReadElement(new AnimalSearchModel { Id = animalId });
if (elem == null)
return null;
var res = Tuple.Create(elem, elem.VisitAnimals.Select(x => x.Value.NameVisit).ToList());
res.Item1.VisitAnimals = null!;
return res;
}
catch (Exception ex)
{
@ -37,11 +40,18 @@ namespace VetClinicRestApi.Controllers
}
[HttpGet]
public List<AnimalViewModel>? GetAnimalList()
public List<AnimalViewModel>? GetAnimalList(int? adminId = null)
{
try
try
{
return _animal.ReadList(null);
List<AnimalViewModel> res;
if (!adminId.HasValue)
res = _animal.ReadList(null);
else
res = _animal.ReadList(new AnimalSearchModel { AdminId = adminId });
foreach (var animal in res)
animal.VisitAnimals = null!;
return res;
}
catch (Exception ex)
{
@ -54,7 +64,7 @@ namespace VetClinicRestApi.Controllers
{
try
{
return _animal.CreateAnimal(model);
return _animal.Create(model);
}
catch (Exception ex)
{
@ -64,11 +74,13 @@ namespace VetClinicRestApi.Controllers
}
[HttpPost]
public bool UpdateAnimal(AnimalBindingModel model)
public bool UpdateAnimal(bool isConnection,AnimalBindingModel model)
{
try
{
return _animal.UpdateAnimal(model);
if (!isConnection)
model.VisitAnimals = null!;
return _animal.Update(model);
}
catch (Exception ex)
{
@ -82,7 +94,7 @@ namespace VetClinicRestApi.Controllers
{
try
{
return _animal.DeleteAnimal(model);
return _animal.Delete(model);
}
catch (Exception ex)
{

View File

@ -27,8 +27,6 @@ namespace VetClinicRestApi.Controllers
try
{
var elem = _guidance.ReadElement(new GuidanceSearchModel { Id = guidanceId });
if (elem == null)
return null;
return elem;
}
catch (Exception ex)
@ -38,20 +36,20 @@ namespace VetClinicRestApi.Controllers
}
}
[HttpGet]
public List<GuidanceViewModel>? GetGuidances(int? serviceId = null)
public List<GuidanceViewModel>? GetGuidances(int? pharmacistId = null)
{
try
{
if (!serviceId.HasValue)
if (!pharmacistId.HasValue)
return _guidance.ReadList(null);
return _guidance.ReadList(new GuidanceSearchModel
{
ServiceId = serviceId
PharmacistId = pharmacistId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка рекомендааций услуги id ={ Id}", serviceId);
_logger.LogError(ex, "Ошибка получения списка рекомендааций пользователя id ={ Id}", pharmacistId);
throw;
}
}

View File

@ -49,7 +49,7 @@ namespace VetClinicRestApi.Controllers
else
res = _medicine.ReadList(new MedicineSearchModel { PharmacistId = pharmacistId });
foreach (var medicine in res)
medicine.MedicineAnimals = null;
medicine.MedicineAnimals = null!;
return res;
}
catch (Exception ex)

View File

@ -23,10 +23,12 @@ namespace VetClinicRestApi.Controllers
}
[HttpGet]
public List<VaccinationViewModel>? GetVaccinations(int animalId)
public List<VaccinationViewModel>? GetVaccinations(int? animalId)
{
try
{
if (!animalId.HasValue)
return _vaccination.ReadList(null);
return _vaccination.ReadList(new VaccinationSearchModel
{
AnimalId = animalId

View File

@ -4,6 +4,7 @@ using VetClinicContracts.BindingModels;
using VetClinicContracts.BusinessLogicsContracts;
using VetClinicContracts.SearchModels;
using VetClinicContracts.ViewModels;
using VetClinicDataBaseImplement.Models;
namespace VetClinicRestApi.Controllers
{
@ -27,7 +28,9 @@ namespace VetClinicRestApi.Controllers
var elem = _visit.ReadElement(new VisitSearchModel { Id = VisitId });
if (elem == null)
return null;
return Tuple.Create(elem, elem.VisitAnimals.Select(x => x.Value.AnimalName).ToList());
var res = Tuple.Create(elem, elem.ServiceVisits.Select(x => x.Value.ServiceName).ToList());
res.Item1.ServiceVisits = null;
return res;
}
catch (Exception ex)
{
@ -36,15 +39,22 @@ namespace VetClinicRestApi.Controllers
}
}
[HttpGet]
public List<VisitViewModel> GetVisits(int adminId)
public List<VisitViewModel> GetVisits(int? adminId = null)
{
try
{
return _visit.ReadList(new VisitSearchModel { AdminId = adminId});
List<VisitViewModel> res;
if (!adminId.HasValue)
res = _visit.ReadList(null);
else
res = _visit.ReadList(new VisitSearchModel { AdminId = adminId });
foreach (var visit in res)
visit.ServiceVisits = null!;
return res;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка визитовв");
_logger.LogError(ex, "Ошибка получения списка визитов");
throw;
}
}
@ -63,11 +73,12 @@ namespace VetClinicRestApi.Controllers
}
[HttpPost]
public bool UpdateVisit(VisitBindingModel model)
public bool UpdateVisit(bool isConnection,VisitBindingModel model)
{
try
{
model.VisitAnimals = null!;
if (!isConnection)
model.ServiceVisits = null!;
return _visit.Update(model);
}
catch (Exception ex)