From 47f20b530b715c5d1c77799a6c6f873d7e891a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=9A=D1=80?= =?UTF-8?q?=D1=8E=D0=BA=D0=BE=D0=B2?= Date: Tue, 28 May 2024 04:18:31 +0400 Subject: [PATCH] =?UTF-8?q?Stage=209-10=20:=20=D0=BF=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=BB=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=B0=D1=81=D1=81=D0=B8?= =?UTF-8?q?=D1=80=D0=B0,=20=D0=BD=D0=BE=20=D0=B8=D1=85=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD=D0=BE=20=D0=B1=D1=83=D0=B4=D0=B5=D1=82=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=B8=D1=82=D1=8C=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1=8E=20=D0=BF=D0=BE=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0,=20?= =?UTF-8?q?=D1=87=D1=83=D1=82=D1=8C=20=D0=BF=D0=BE=D0=B4=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20RestAPI,=20=D1=87=D1=83=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BF=D0=BE=D0=BC=D0=B5=D1=80=20=D0=B2=20homeco?= =?UTF-8?q?ntroller=20=D0=B2=20=D0=BA=D0=B0=D1=81=D1=81=D0=B8=D1=80=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8(=20=D0=B8=20=D1=82=D1=83=D1=82=20=D0=BE?= =?UTF-8?q?=D0=BD=20=D0=BF=D0=BE=D0=BD=D1=8F=D0=BB=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bank/BankCashierApp/APICashier.cs | 13 +- .../Controllers/HomeController.cs | 684 +++++++++++++++++- .../BankCashierApp/Views/Home/Accounts.cshtml | 27 + .../Views/Home/CloseCrediting.cshtml | 53 ++ .../Views/Home/CloseDebiting.cshtml | 53 ++ .../Views/Home/Crediting.cshtml | 61 ++ .../BankCashierApp/Views/Home/Debiting.cshtml | 62 ++ Bank/BankCashierApp/Views/Home/Diagram.cshtml | 88 +++ .../Views/Home/ErrorPage.cshtml | 10 + .../Views/Home/MoneyTransfers.cshtml | 6 + .../BankCashierApp/Views/Home/Register.cshtml | 41 +- .../Views/Home/ReportSuccess.cshtml | 15 + .../Views/Home/ReportWithAccounts.cshtml | 88 +++ .../Views/Shared/_Layout.cshtml | 1 + .../ViewModels/ClientSelectViewModel.cs | 15 + .../BankDataModels/Enums/TypeOperationEnum.cs | 2 +- Bank/BankRestAPI/BankRestAPI.csproj | 3 +- .../Controllers/ReportController.cs | 246 ++++++- Bank/BankRestAPI/Program.cs | 52 ++ 19 files changed, 1486 insertions(+), 34 deletions(-) create mode 100644 Bank/BankCashierApp/Views/Home/CloseCrediting.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/CloseDebiting.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/Crediting.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/Debiting.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/Diagram.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/ErrorPage.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/ReportSuccess.cshtml create mode 100644 Bank/BankCashierApp/Views/Home/ReportWithAccounts.cshtml create mode 100644 Bank/BankContracts/ViewModels/Cashier/ViewModels/ClientSelectViewModel.cs diff --git a/Bank/BankCashierApp/APICashier.cs b/Bank/BankCashierApp/APICashier.cs index 476808c..f659191 100644 --- a/Bank/BankCashierApp/APICashier.cs +++ b/Bank/BankCashierApp/APICashier.cs @@ -1,5 +1,7 @@ using Azure; +using BankContracts.ViewModels; using BankContracts.ViewModels.Cashier.ViewModels; +using BankContracts.ViewModels.Client.ViewModels; using Newtonsoft.Json; using System.Net.Http.Headers; using System.Text; @@ -11,8 +13,15 @@ namespace BankCashierApp private static readonly HttpClient _cashier = new(); public static CashierViewModel? Cashier { get; set; } = null; + public static CreditingViewModel? Crediting { get; set; } = null; - public static string ErrorMessage = string.Empty; + public static DebitingViewModel? Debiting { get; set; } = null; + + public static AccountViewModel? Account { get; set; } = null; + + public static CardViewModel? Card { get; set; } = null; + + public static string ErrorMessage = string.Empty; public static void Connect(IConfiguration configuration) { @@ -60,7 +69,7 @@ namespace BankCashierApp } // Post-запрос для получения данных - public static T? PostRequetReport(string requestUrl, U model) + public static T? PostRequestReport(string requestUrl, U model) { var json = JsonConvert.SerializeObject(model); var data = new StringContent(json, Encoding.UTF8, "application/json"); diff --git a/Bank/BankCashierApp/Controllers/HomeController.cs b/Bank/BankCashierApp/Controllers/HomeController.cs index 6f3c4f9..6e4ace8 100644 --- a/Bank/BankCashierApp/Controllers/HomeController.cs +++ b/Bank/BankCashierApp/Controllers/HomeController.cs @@ -1,4 +1,13 @@ using BankCashierApp.Models; +using BankContracts.BindingModels.Cashier; +using BankContracts.BindingModels.Reports; +using BankContracts.ViewModels.Cashier.Diagram; +using BankContracts.ViewModels.Cashier.ViewModels; +using BankContracts.ViewModels.Client.ViewModels; +using BankContracts.ViewModels.Reports.Cashier; +using BankContracts.ViewModels.Reports; +using BankContracts.ViewModels; +using BankDataModels.Enums; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; @@ -12,47 +21,698 @@ namespace BankCashierApp.Controllers { _logger = logger; } - + //вытаскивает через API клиента Get-запросом список его собственных заказов + [HttpGet] public IActionResult Index() + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + return View(APICashier.GetRequest>($"/api/Account/GetAllAccounts")); + } + + // Обновление данных пользователя + + //изменемение ланных Get-ом + [HttpGet] + public IActionResult Privacy() + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + return View(APICashier.Cashier); + } + + //изменение данных Post-ом + [HttpPost] + public void Privacy(string login, string password, string name, string surname, string patronymic, string telephone) + { + if (APICashier.Cashier == null) + { + throw new Exception("Вы как сюда попали? Сюда вход только авторизованным"); + } + + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(name) + || string.IsNullOrEmpty(surname) || string.IsNullOrEmpty(patronymic) + || string.IsNullOrEmpty(telephone)) + { + throw new Exception("Введите логин, пароль, ФИО и телефон"); + } + + APICashier.PostRequest("/api/Cashier/UpdateData", new CashierBindingModel + { + Id = APICashier.Cashier.Id, + Name = name, + Surname = surname, + Patronymic = patronymic, + MobilePhone = telephone, + Email = login, + Password = password + }); + + APICashier.Cashier.Name = name; + APICashier.Cashier.Surname = surname; + APICashier.Cashier.Patronymic = patronymic; + APICashier.Cashier.Email = login; + APICashier.Cashier.Password = password; + APICashier.Cashier.MobilePhone = telephone; + + Response.Redirect("Enter"); + } + + [HttpGet] + public IActionResult Login() { return View(); } + + [HttpPost] + public IActionResult Login(string login, string password) + { + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password)) + { + APICashier.SetErrorMessage("Необходимо заполнить оба поля"); + + return Redirect("ErrorPage"); + } + + APICashier.Cashier = APICashier.GetRequest($"api/Cashier/Login?login={login}&password={password}"); + + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Неверный логин или пароль"); + + return Redirect("ErrorPage"); + } + + return Redirect("Enter"); + } + + [HttpPost] + public IActionResult Logout() + { + APICashier.Cashier = null; + + return Redirect("Enter"); + } + + + // Вывод ошибок + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IActionResult Error() + { + return View(new ErrorViewModel + { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier + }); + } + + [HttpGet] + public IActionResult ErrorPage() + { + return View(); + } + + + + + // Вход в приложение + + //просто открытие вьюхи + [HttpGet] public IActionResult Enter() { return View(); } + //отсылаем указанные данные на проверку + [HttpPost] + public IActionResult Enter(string login, string password) + { + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password)) + { + APICashier.SetErrorMessage("Введите логин и пароль"); + + return Redirect("ErrorPage"); + } + + APICashier.Cashier = APICashier.GetRequest($"/api/Cashier/Login?login={login}&password={password}"); + + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Неверный логин или пароль"); + + return Redirect("ErrorPage"); + } + + return Redirect("Index"); + } + + + + // Регистрация + + //просто открытие вьюхи + [HttpGet] public IActionResult Register() { return View(); } - public IActionResult Privacy() + //Post-запрос по созданию нового пользователя + [HttpPost] + public void Register(string login, string password, string name, string surname, string patronymic, string telephone) { - return View(); + if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(name) + || string.IsNullOrEmpty(surname) || string.IsNullOrEmpty(patronymic) || string.IsNullOrEmpty(telephone)) + { + throw new Exception("Введите логин, пароль, ФИО и телефон"); + } + + APICashier.PostRequest("/api/Cashier/Register", new CashierBindingModel + { + Name = name, + Surname = surname, + Patronymic = patronymic, + Email = login, + Password = password, + MobilePhone = telephone + }); + + //переход на вкладку "Enter", чтобы пользователь сразу смог зайти + Response.Redirect("Enter"); + + return; } + + + + // Открытие нового счёта + + //открытие счёта. Получаем и передаём список изделий во вьюху? + [HttpGet] public IActionResult CreateAccount() { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + //запрашиваем список в формате вспомогательной вьюшки из-за работы select в asp net + ViewBag.Clients = APICashier.GetRequest>($"/api/Client/GetAllClients").Select(x => new ClientSelectViewModel + { + Id = x.Id, + FullName = x.Surname + " " + x.Name + " " + x.Patronymic + }).ToList(); + return View(); } - public IActionResult CreateReport() + + //создание заказа Post-запросом + [HttpPost] + public IActionResult CreateAccount(int clientId, string accountNumber, string password, int balance) { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (clientId <= 0 || string.IsNullOrEmpty(accountNumber) || string.IsNullOrEmpty(password) || balance < 0) + { + APICashier.SetErrorMessage("Проверьте корректность вводимых данных"); + + return Redirect("ErrorPage"); + } + + APICashier.PostRequest("/api/Account/Register", new AccountBindingModel + { + CashierId = APICashier.Cashier.Id, + ClientId = clientId, + AccountNumber = accountNumber, + Balance = balance, + DateOpen = DateTime.Now + }); + + return Redirect("Index"); + } + + + + // Работа с заявками на зачисление + + //для страницы "Заявки на зачисление" + [HttpGet] + public IActionResult Crediting() + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + Response.Redirect("ErrorPage"); + } + + return View(APICashier.GetRequest>($"/api/Account/FindOpenCrediting")); + } + + //открытие вьюхи одобрения заявки на зачисление + [HttpGet] + public IActionResult CloseCrediting() + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + ViewBag.Creditings = APICashier.GetRequest>("/api/Account/FindOpenCrediting"); + + ViewBag.Accounts = APICashier.GetRequest>("/api/Account/GetAllAccounts"); + return View(); } + + //одобрения заявки на зачисление Post-запросом + [HttpPost] + public IActionResult CloseCrediting(int creditingId, int accountPayeeId) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (creditingId <= 0 || accountPayeeId <= 0) + { + APICashier.SetErrorMessage("Проверьте коректность передавваемых значений"); + + return Redirect("ErrorPage"); + } + + //получаем необходимые данные для запроса + APICashier.Crediting = APICashier.GetRequest($"/api/Account/FindCrediting?id={creditingId}"); + + APICashier.Card = APICashier.GetRequest($"/api/Card/FindCard?id={APICashier.Crediting.CardId}"); + + APICashier.PostRequest("/api/Account/CloseCrediting", new MoneyTransferBindingModel + { + CashierId = APICashier.Cashier.Id, + CreditingId = creditingId, + Sum = APICashier.Crediting.Sum, + AccountPayeeId = accountPayeeId + }); + + //очистка данных + APICashier.Crediting = null; + APICashier.Card = null; + + return Redirect("Crediting"); + } + + + + // Работа с заявками на снятие + + //для страницы "Заявки на снятие" + [HttpGet] + public IActionResult Debiting() + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + Response.Redirect("ErrorPage"); + } + + + return View(APICashier.GetRequest>($"/api/Account/FindOpenDebiting")); + } + + //открытие вьюхи одобрения заявки на снятие + [HttpGet] + public IActionResult CloseDebiting() + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + Response.Redirect("ErrorPage"); + } + + + ViewBag.Debitings = APICashier.GetRequest>("/api/Account/FindOpenDebiting"); + + ViewBag.Accounts = APICashier.GetRequest>("/api/Account/GetAllAccounts"); + + return View(); + } + + //одобрения заявки на снятие Post-запросом + [HttpPost] + public IActionResult CloseDebiting(int debitingId, int accountId) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (debitingId <= 0 || accountId <= 0) + { + APICashier.SetErrorMessage("Проверьте корректность передаваемых значений"); + + return Redirect("ErrorPage"); + } + + //получаем необходимые данные для запроса + APICashier.Debiting = APICashier.GetRequest($"/api/Account/FindDebiting?id={debitingId}"); + + APICashier.Card = APICashier.GetRequest($"/api/Card/FindCard?id={APICashier.Debiting.CardId}"); + + APICashier.PostRequest("/api/Account/CloseDebiting", new CashWithdrawalBindingModel + { + CashierId = APICashier.Cashier.Id, + DebitingId = debitingId, + Sum = APICashier.Debiting.Sum, + AccountId = accountId + }); + + APICashier.Debiting = null; + APICashier.Card = null; + + return Redirect("Debiting"); + } + + + + //получение номера запрашиваемого счёта для снятия - для работы с начислениями и списаниями + [HttpPost] + public string GetAccountNumber(int id) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + Response.Redirect("ErrorPage"); + } + + APICashier.Debiting = APICashier.GetRequest($"/api/Account/FindDebiting?id={id}"); + + APICashier.Crediting = APICashier.GetRequest($"/api/Account/FindCrediting?id={id}"); + + if (APICashier.Debiting == null) + { + APICashier.Card = APICashier.GetRequest($"/api/Card/FindCard?id={APICashier.Crediting.CardId}"); + } + else + { + APICashier.Card = APICashier.GetRequest($"/api/Card/FindCard?id={APICashier.Debiting.CardId}"); + } + + APICashier.Account = APICashier.GetRequest($"/api/Account/GetAccount?accountId={APICashier.Card.AccountId}"); + + string AccountNumber = APICashier.Account.AccountNumber; + + APICashier.Debiting = null; + APICashier.Card = null; + APICashier.Account = null; + + return AccountNumber; + } + + // Работа с переводом со счёта на счёт + + [HttpGet] public IActionResult MoneyTransfers() { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + ViewBag.Accounts = APICashier.GetRequest>("/api/Account/GetAllAccounts"); + return View(); } - public IActionResult Accounts() - { - return View(); - } - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - public IActionResult Error() + [HttpPost] + public IActionResult MoneyTransfers(int accountSenderId, int accountPayeeId, int sumMoneyTransfer) { - return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (accountPayeeId <= 0 || accountSenderId <= 0 || sumMoneyTransfer <= 0) + { + APICashier.SetErrorMessage("Проверьте корректность передаваемых значений"); + + return Redirect("ErrorPage"); + } + + APICashier.PostRequest("/api/Account/CloseCrediting", new MoneyTransferBindingModel + { + CashierId = APICashier.Cashier.Id, + Sum = sumMoneyTransfer, + AccountPayeeId = accountPayeeId, + AccountSenderId = accountSenderId + }); + + return Redirect("Index"); + } + + + + // Отчёт с выборкой по счетам + + [HttpGet] + public IActionResult ReportWithAccounts() + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + ViewBag.Accounts = APICashier.GetRequest>("/api/Account/GetAllAccounts"); + + return View(new List()); + } + + //создание excel отчёта у касира + [HttpPost] + public IActionResult CreateCashierExcelReport(string accountId) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (string.IsNullOrEmpty(accountId)) + { + APICashier.SetErrorMessage("Необходимо выбрать счёт для создания отчёта"); + + return Redirect("ErrorPage"); + } + + APICashier.PostRequest("api/Report/CreateExcelCashier", new ReportSupportBindingModel() + { + AccountId = int.Parse(accountId), + Email = APICashier.Cashier.Email + }); + + return Redirect("ReportSuccess"); + } + + //создание excel отчёта у касира + [HttpPost] + public IActionResult CreateCashierWordReport(string accountId) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (string.IsNullOrEmpty(accountId)) + { + APICashier.SetErrorMessage("Необходимо выбрать счёт для создания отчёта"); + + return Redirect("ErrorPage"); + } + + APICashier.PostRequest("api/Report/CreateWordCashier", new ReportSupportBindingModel() + { + AccountId = int.Parse(accountId), + Email = APICashier.Cashier.Email + }); + + return Redirect("ReportSuccess"); + } + + [HttpPost] + public IActionResult ReportWithAccounts(string accountId) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (string.IsNullOrEmpty(accountId)) + { + APICashier.SetErrorMessage("Необходимо выбрать счёт для создания отчёта"); + + return Redirect("ErrorPage"); + } + + ViewBag.Accounts = APICashier.GetRequest>("/api/Account/GetAllAccounts"); + var cashWithdrawals = APICashier.GetRequest>("api/Account/FindAllCashWithdrawal").Where(x => x.AccountId == int.Parse(accountId)) + .Select(x => new ReportCashierAccountsViewModel + { + Sum = (int)x.Sum, + AccountSenderNumber = x.AccountNumber, + DateOperation = x.DateWithdrawal, + typeOperation = TypeOperationEnum.Снятие + }); + + var moneyTransfers = APICashier.GetRequest>("/api/Account/FindAllMoneyTransfer").Where(x => (x.AccountPayeeId == int.Parse(accountId) || x.AccountSenderId == int.Parse(accountId))) + .Select(x => new ReportCashierAccountsViewModel + { + CashierSurname = x.CashierSurname, + Sum = (int)x.Sum, + AccountPayeeNumber = x.AccountPayeeNumber, + AccountSenderNumber = x.AccountSenderNumber != null ? x.AccountSenderNumber : "---", + DateOperation = x.DateTransfer, + typeOperation = x.AccountSenderId.HasValue ? TypeOperationEnum.Перевод : TypeOperationEnum.Пополнение + }); + + return View(cashWithdrawals.Concat(moneyTransfers).OrderBy(x => x.DateOperation).ToList()); + } + + + + // Получение отчёта PDF + + [HttpGet] + public IActionResult CreateReport() + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + //запрашиваем список в формате вспомогательной вьюшки из-за работы select в asp net + ViewBag.Clients = APICashier.GetRequest>($"/api/Client/GetAllClients").Select(x => new ClientSelectViewModel + { + Id = x.Id, + FullName = x.Surname + " " + x.Name + " " + x.Patronymic + }).ToList(); + + return View(); + } + + [HttpPost] + public IActionResult CreateReport(int clientId, DateTime dateFrom, DateTime dateTo) + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + return Redirect("ErrorPage"); + } + + if (clientId <= 0 || dateFrom == dateTo || dateFrom > dateTo || dateFrom.Year == 0001 || dateTo.Year == 0001) + { + APICashier.SetErrorMessage("Пожалуйста, установите корректные границы периода для отчёта и выберите счёт"); + + return Redirect("ErrorPage"); + } + + //запрашиваем список в формате вспомогательной вьюшки из-за работы select в asp net + ViewBag.Clients = APICashier.GetRequest>($"/api/Client/GetAllClients").Select(x => new ClientSelectViewModel + { + Id = x.Id, + FullName = x.Surname + " " + x.Name + " " + x.Patronymic + }).ToList(); + + return View(APICashier.PostRequestReport("api/Report/CreateCashierReport", new ReportSupportBindingModel() + { + ClientId = clientId, + Email = APICashier.Cashier.Email, + DateFrom = dateFrom, + DateTo = dateTo + })); + } + + + + // Диаграмма + + [HttpGet] + public IActionResult Diagram() + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + ViewBag.Accounts = APICashier.GetRequest>($"api/Account/GetAllAccounts"); + + return View(); + } + + [HttpPost] + public IActionResult Diagram(int accountId) + { + if (APICashier.Cashier == null) + { + return Redirect("~/Home/Enter"); + } + + if (accountId <= 0) + { + APICashier.SetErrorMessage("Для построения диаграммы необходимо выбрать счёт"); + + return Redirect("ErrorPage"); + } + + ViewBag.Accounts = APICashier.GetRequest>($"api/Account/GetAllAccounts"); + + + return View(new CashierDiagramViewModel() + { + DiagramName = "Hello World", + Elements = APICashier.GetRequest>($"api/Account/getAccountMonthResult?cardId={accountId}") + }); + } + + + + [HttpGet] + public IActionResult ReportSuccess() + { + if (APICashier.Cashier == null) + { + APICashier.SetErrorMessage("Необходимо авторизоваться"); + + Response.Redirect("ErrorPage"); + } + + return View(); } } -} +} \ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Home/Accounts.cshtml b/Bank/BankCashierApp/Views/Home/Accounts.cshtml index 3896443..63138cb 100644 --- a/Bank/BankCashierApp/Views/Home/Accounts.cshtml +++ b/Bank/BankCashierApp/Views/Home/Accounts.cshtml @@ -12,6 +12,11 @@
@{ + if (Model == null) + { +

Сначала авторизируйтесь

+ return; + }

Открыть счёт

@@ -35,6 +40,28 @@ + + @foreach (var item in Model) + { + + + @Html.DisplayFor(modelItem => item.AccountNumber) + + + @Html.DisplayFor(modelItem => item.Name) + + + @Html.DisplayFor(modelItem => item.Patronymic) + + + @Html.DisplayFor(modelItem => item.Balance) + + + @Html.DisplayFor(modelItem => item.DateOpen) + + + } + }
\ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Home/CloseCrediting.cshtml b/Bank/BankCashierApp/Views/Home/CloseCrediting.cshtml new file mode 100644 index 0000000..71ba2fa --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/CloseCrediting.cshtml @@ -0,0 +1,53 @@ +@{ + ViewData["Title"] = "Одобрение зачислений"; +} + +
+

Зачисление

+
+
+
+
Номер запроса на зачисление:
+
+ +
+
+
+
Запрашиваемый счёт для зачисления:
+
+ +
+
+
+
Номер счёта для зачисления:
+
+ +
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Home/CloseDebiting.cshtml b/Bank/BankCashierApp/Views/Home/CloseDebiting.cshtml new file mode 100644 index 0000000..a567f89 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/CloseDebiting.cshtml @@ -0,0 +1,53 @@ +@{ + ViewData["Title"] = "Одобрение снятия"; +} + +
+

Снятие

+
+
+
+
Номер запроса на снятие:
+
+ +
+
+
+
Запрашиваемый счёт для перевода:
+
+ +
+
+
+
Номер счёта для снятия:
+
+ +
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Home/Crediting.cshtml b/Bank/BankCashierApp/Views/Home/Crediting.cshtml new file mode 100644 index 0000000..59ab1b3 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/Crediting.cshtml @@ -0,0 +1,61 @@ +@using BankContracts.ViewModels.Client.ViewModels + +@model List + +@{ + ViewData["Title"] = "Заявки на зачисление"; +} + +
+

Заявки

+
+ +
+ @{ + if (Model == null) + { +

Сначала авторизируйтесь

+ return; + } +

+ Одобрение заявки +

+ + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + } + +
+ Номер заявки + + Номер карты + + Сумма зачисления + + Дата заявки +
+ @Html.DisplayFor(modelItem => item.Id) + + @Html.DisplayFor(modelItem => item.CardNumber) + + @Html.DisplayFor(modelItem => item.Sum) + + @Html.DisplayFor(modelItem => item.DateCredit) +
+ } +
diff --git a/Bank/BankCashierApp/Views/Home/Debiting.cshtml b/Bank/BankCashierApp/Views/Home/Debiting.cshtml new file mode 100644 index 0000000..0d6fe63 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/Debiting.cshtml @@ -0,0 +1,62 @@ +@using BankContracts.ViewModels.Client.ViewModels + + +@model List + +@{ + ViewData["Title"] = "Заявки на снятия"; +} + +
+

Заявки

+
+ +
+ @{ + if (Model == null) + { +

Сначала авторизируйтесь

+ return; + } +

+ Одобрение заявки +

+ + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + } + +
+ Номер заявки + + Номер карты + + Сумма снятия + + Дата открытия заявки +
+ @Html.DisplayFor(modelItem => item.Id) + + @Html.DisplayFor(modelItem => item.CardNumber) + + @Html.DisplayFor(modelItem => item.Sum) + + @Html.DisplayFor(modelItem => item.DateDebit) +
+ } +
diff --git a/Bank/BankCashierApp/Views/Home/Diagram.cshtml b/Bank/BankCashierApp/Views/Home/Diagram.cshtml new file mode 100644 index 0000000..ecae093 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/Diagram.cshtml @@ -0,0 +1,88 @@ +@using BankContracts.ViewModels.Cashier.Diagram + +@model CashierDiagramViewModel + +@{ + ViewData["Title"] = "Диаграмма"; +} + +
+

Диаграмма суммарных поступлений на счёт по месяцам

+
+ +
+
+
Номер счета:
+ +
+
+ +
+
+ +@if (Model == null) return; + +
+
+ +
+ @foreach (var info in Model.Elements) + { + + } +
+
+
+ + + diff --git a/Bank/BankCashierApp/Views/Home/ErrorPage.cshtml b/Bank/BankCashierApp/Views/Home/ErrorPage.cshtml new file mode 100644 index 0000000..9aea6a8 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/ErrorPage.cshtml @@ -0,0 +1,10 @@ +@using BankCashierApp + +@{ + ViewData["Title"] = "Отправка отчета"; +} + +
+

Упс, что-то пошло не так...

+

Ошибка: @APICashier.ErrorMessage

+
\ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Home/MoneyTransfers.cshtml b/Bank/BankCashierApp/Views/Home/MoneyTransfers.cshtml index 01f445e..e23b511 100644 --- a/Bank/BankCashierApp/Views/Home/MoneyTransfers.cshtml +++ b/Bank/BankCashierApp/Views/Home/MoneyTransfers.cshtml @@ -9,11 +9,17 @@
Номер счёта для снятия:
+
Номер счёта для начисления:
+
diff --git a/Bank/BankCashierApp/Views/Home/Register.cshtml b/Bank/BankCashierApp/Views/Home/Register.cshtml index 3573af3..ceae1a0 100644 --- a/Bank/BankCashierApp/Views/Home/Register.cshtml +++ b/Bank/BankCashierApp/Views/Home/Register.cshtml @@ -1,19 +1,38 @@ @{ - ViewData["Title"] = "Регистрация"; + ViewData["Title"] = "Регистрация"; }
-

Регистрация

+

Регистрация

- + + diff --git a/Bank/BankCashierApp/Views/Home/ReportSuccess.cshtml b/Bank/BankCashierApp/Views/Home/ReportSuccess.cshtml new file mode 100644 index 0000000..0fcfe81 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/ReportSuccess.cshtml @@ -0,0 +1,15 @@ +@{ + ViewData["Title"] = "Отправка отчета"; +} + + +
+ @{ + if (APICashier.Cashier == null) + { +

Сначала авторизируйтесь

+ return; + } + } +

Отчeт был отправлен на почту @APICashier.Cashier.Email

+
\ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Home/ReportWithAccounts.cshtml b/Bank/BankCashierApp/Views/Home/ReportWithAccounts.cshtml new file mode 100644 index 0000000..2983da5 --- /dev/null +++ b/Bank/BankCashierApp/Views/Home/ReportWithAccounts.cshtml @@ -0,0 +1,88 @@ +@using BankContracts.ViewModels.Reports.Cashier + +@model List? + +@{ + ViewData["Title"] = "Отчет по счетам"; +} + +
+

Отчет

+
+ +
+ +
+
+
+
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + + } + +
+ Тип операции + + Кассир + + Счет отправителя + + Счет получателя + + Сумма операции + + Дата +
+ @Html.DisplayFor(modelItem => item.typeOperation) + + @Html.DisplayFor(modelItem => item.CashierSurname) + + @Html.DisplayFor(modelItem => item.AccountSenderNumber) + + @Html.DisplayFor(modelItem => item.AccountPayeeNumber) + + @Html.DisplayFor(modelItem => item.Sum) + + @Html.DisplayFor(modelItem => item.DateOperation) +
+
+
+
+
\ No newline at end of file diff --git a/Bank/BankCashierApp/Views/Shared/_Layout.cshtml b/Bank/BankCashierApp/Views/Shared/_Layout.cshtml index dc16660..5f2bacc 100644 --- a/Bank/BankCashierApp/Views/Shared/_Layout.cshtml +++ b/Bank/BankCashierApp/Views/Shared/_Layout.cshtml @@ -58,6 +58,7 @@
+
diff --git a/Bank/BankContracts/ViewModels/Cashier/ViewModels/ClientSelectViewModel.cs b/Bank/BankContracts/ViewModels/Cashier/ViewModels/ClientSelectViewModel.cs new file mode 100644 index 0000000..9ec5e75 --- /dev/null +++ b/Bank/BankContracts/ViewModels/Cashier/ViewModels/ClientSelectViewModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankContracts.ViewModels.Cashier.ViewModels +{ + public class ClientSelectViewModel + { + public int Id { get; set; } + + public string FullName { get; set; } = string.Empty; + } +} diff --git a/Bank/BankDataModels/Enums/TypeOperationEnum.cs b/Bank/BankDataModels/Enums/TypeOperationEnum.cs index f0086e1..9603d83 100644 --- a/Bank/BankDataModels/Enums/TypeOperationEnum.cs +++ b/Bank/BankDataModels/Enums/TypeOperationEnum.cs @@ -12,6 +12,6 @@ namespace BankDataModels.Enums Пополнение = 2, - Переыод = 3 + Перевод = 3 } } diff --git a/Bank/BankRestAPI/BankRestAPI.csproj b/Bank/BankRestAPI/BankRestAPI.csproj index e6ee65f..ca88e4a 100644 --- a/Bank/BankRestAPI/BankRestAPI.csproj +++ b/Bank/BankRestAPI/BankRestAPI.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -13,6 +13,7 @@ + diff --git a/Bank/BankRestAPI/Controllers/ReportController.cs b/Bank/BankRestAPI/Controllers/ReportController.cs index 002a195..4fefabb 100644 --- a/Bank/BankRestAPI/Controllers/ReportController.cs +++ b/Bank/BankRestAPI/Controllers/ReportController.cs @@ -1,12 +1,244 @@ -using Microsoft.AspNetCore.Mvc; +using BankContracts.BindingModels.Reports; +using BankContracts.BusinessLogicsContracts.Reports; +using BankContracts.ViewModels.Reports; +using BankDataModels.Enums; +using Microsoft.AspNetCore.Mvc; namespace BankRestAPI.Controllers { - public class ReportController : Controller + [Route("api/[controller]/[action]")] + [ApiController] + public class ReportController : Controller { - public IActionResult Index() - { - return View(); - } - } + private readonly ILogger _logger; + + private readonly IReportClientLogic _reportClientLogic; + + private readonly IReportCashierLogic _reportCashierLogic; + + //хранят данные для отображения отчёта на вебе + private ReportClientViewModelForHTML _reportClientViewModelForHTML; + + private ReportCashierViewModelForHTML _reportCashierViewModelForHTML; + + public ReportController(ILogger logger, IReportClientLogic reportClientLogic, IReportCashierLogic reportCashierLogic) + { + _logger = logger; + _reportClientLogic = reportClientLogic; + _reportCashierLogic = reportCashierLogic; + } + + + //метод генерации отчёта за период по картам клиента + [HttpPost] + public ReportClientViewModelForHTML CreateClientReport(ReportSupportBindingModel model) + { + try + { + var result = _reportClientLogic.SaveClientReportToPdfFile(new ReportBindingModel + { + FileName = "Отчёт_по_картам.pdf", + DateFrom = model.DateFrom, + DateTo = model.DateTo, + Role = MailsEnum.Клиент, + Email = model.Email + }); + + return result; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //метод генерации отчёта по всем счетм клиентов + [HttpPost] + public ReportCashierViewModelForHTML CreateCashierReport(ReportSupportBindingModel model) + { + try + { + var result = _reportCashierLogic.SaveAccountsToPdfFile(new ReportBindingModel + { + FileName = "Отчёт_по_счетам.pdf", + ClientId = model.ClientId, + DateFrom = model.DateFrom, + DateTo = model.DateTo, + Role = MailsEnum.Кассир, + Email = model.Email + }); + + return result; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + + //отчёт клиента Excel по переводу денег + [HttpPost] + public void CreateExcelClient(ReportSupportBindingModel model) + { + try + { + _reportClientLogic.SaveToExcelFile(new ReportBindingModel + { + FileName = "Отчёт по переводам.xlsx", + CardList = model.CardList, + Email = model.Email + }, OfficeOperationEnum.Между_cчетами); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //отчёт клиента Excel по переводу денег + [HttpPost] + public void CreateExcelCrediting(ReportSupportBindingModel model) + { + try + { + _reportClientLogic.SaveToExcelFile(new ReportBindingModel + { + FileName = "Отчёт по пополнениям.xlsx", + CardList = model.CardList, + Email = model.Email + }, OfficeOperationEnum.Пополнение_карт); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //отчёт клиента Excel по выдаче денег + [HttpPost] + public void CreateExcelDebiting(ReportSupportBindingModel model) + { + try + { + _reportClientLogic.SaveToExcelFile(new ReportBindingModel + { + FileName = "Отчёт по снятиям.xlsx", + CardList = model.CardList, + Email = model.Email + }, OfficeOperationEnum.Cнятие_с_карты); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //отчёт клиента Excel по переводу денег + [HttpPost] + public void CreateExcelCashier(ReportSupportBindingModel model) + { + try + { + _reportCashierLogic.SaveAccountsToExcelFile(new ReportBindingModel + { + FileName = "Отчёт по зявкам на снятие.xlsx", + AccountId = model.AccountId, + Email = model.Email + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + + //отчёт клиента Word по переводу денег + [HttpPost] + public void CreateWordClient(ReportSupportBindingModel model) + { + try + { + _reportClientLogic.SaveToWordFile(new ReportBindingModel + { + FileName = "Отчёт по переводам.docx", + CardList = model.CardList, + Email = model.Email + }, OfficeOperationEnum.Между_cчетами); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //отчёт клиента Word по переводу денег + [HttpPost] + public void CreateWordCrediting(ReportSupportBindingModel model) + { + try + { + _reportClientLogic.SaveToWordFile(new ReportBindingModel + { + FileName = "Отчёт по пополнениям.docx", + CardList = model.CardList, + Email = model.Email + }, OfficeOperationEnum.Пополнение_карт); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //отчёт клиента Word по выдаче денег + [HttpPost] + public void CreateWordDebiting(ReportSupportBindingModel model) + { + try + { + _reportClientLogic.SaveToWordFile(new ReportBindingModel + { + FileName = "Отчёт по снятиям.docx", + CardList = model.CardList, + Email = model.Email + }, OfficeOperationEnum.Cнятие_с_карты); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + //отчёт клиента Word по переводу денег + [HttpPost] + public void CreateWordCashier(ReportSupportBindingModel model) + { + try + { + _reportCashierLogic.SaveAccountsToWordFile(new ReportBindingModel + { + FileName = "Отчёт по зявкам на снятие.docx", + AccountId = model.AccountId, + Email = model.Email + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + } } diff --git a/Bank/BankRestAPI/Program.cs b/Bank/BankRestAPI/Program.cs index 7393486..bb318f1 100644 --- a/Bank/BankRestAPI/Program.cs +++ b/Bank/BankRestAPI/Program.cs @@ -1,5 +1,20 @@ +using BankBusinessLogic.BusinessLogic.Cashier; +using BankBusinessLogic.BusinessLogic.Client; +using BankBusinessLogic.BusinessLogic.Reports; +using BankBusinessLogic.MailWorker; +using BankBusinessLogic.OfficePackage; +using BankBusinessLogic.OfficePackage.Implements; +using BankContracts.BindingModels.Messages; +using BankContracts.BusinessLogicsContracts.Cashier; +using BankContracts.BusinessLogicsContracts.Client; +using BankContracts.BusinessLogicsContracts.Reports; +using BankContracts.StoragesModels.Cashier; +using BankContracts.StoragesModels.Client; +using BankDatabaseImplement.Implements.CashierImplements; +using BankDatabaseImplement.Implements.ClientImplements; + var builder = WebApplication.CreateBuilder(args); @@ -7,6 +22,33 @@ builder.Logging.SetMinimumLevel(LogLevel.Trace); builder.Logging.AddLog4Net("log4net.config"); // Add services to the container. +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +builder.Services.AddTransient(); +builder.Services.AddSingleton(); + +builder.Services.AddSingleton(); + +// +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle @@ -15,6 +57,16 @@ builder.Services.AddSwaggerGen(); var app = builder.Build(); +var mailSender = app.Services.GetService(); + +mailSender?.MailConfig(new MailConfigBindingModel +{ + MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty, + MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty, + SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty, + SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()), +}); + // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) {