Compare commits

33 Commits

Author SHA1 Message Date
rakhaliullov
5645ca3dc2 Тесты, веб апи, веи ui. 2025-05-17 07:25:19 +04:00
rakhaliullov
b2c056644f Миграция, изменения в реализации сторадж контрактов. 2025-05-17 07:24:51 +04:00
rakhaliullov
7fdb3f4bd1 Биндинг модели, изменения в дата моделях, вью модели. 2025-05-17 07:24:26 +04:00
rakhaliullov
bbd94485bc Интерфейсы адаптеров. 2025-05-17 07:23:30 +04:00
rakhaliullov
8a3761a91e Изменения в бизнес контрактах 2025-05-17 07:23:14 +04:00
rakhaliullov
aa3a89d7ae Веб апи. 2025-05-16 00:23:41 +04:00
rakhaliullov
a8b724f6bd Миграция. 2025-05-16 00:23:24 +04:00
rakhaliullov
691b097db8 Интерфесы адаптеров и operation responses. 2025-05-16 00:23:12 +04:00
rakhaliullov
4a5ef345b7 Изменения в тестах. 2025-05-16 00:22:16 +04:00
rakhaliullov
31c8295d3d OperationResponse и расширения. 2025-05-16 00:21:57 +04:00
rakhaliullov
bb4a5a5dd2 Binding модели. 2025-05-16 00:21:29 +04:00
rakhaliullov
ce580e9b2b View модели. 2025-05-16 00:21:09 +04:00
rakhaliullov
4742f12d5f Изменение в контрактах хранилища. 2025-05-16 00:20:46 +04:00
rakhaliullov
b164f00eae Изменения в моделях. 2025-05-16 00:20:13 +04:00
rakhaliullov
12854ea69b Реализация бизнес логики. 2025-05-16 00:19:56 +04:00
rakhaliullov
bb3975bc62 Интерфейсы бизнес-логики. 2025-05-16 00:19:35 +04:00
rakhaliullov
2d7b86c828 Тесты репорт контракта. 2025-04-27 15:04:28 +04:00
rakhaliullov
52f6959819 Реализация двух репортов. 2025-04-27 15:04:07 +04:00
rakhaliullov
f6967faa75 Тесты хранилища. 2025-04-27 15:03:08 +04:00
rakhaliullov
39ddcbbe64 Билдеры для работы с документами. 2025-04-27 14:56:09 +04:00
rakhaliullov
18ed312d12 Дополнения. 2025-04-27 14:55:34 +04:00
rakhaliullov
cd3835b441 Правки. 2025-04-27 14:54:34 +04:00
rakhaliullov
3d7decea73 Модели базы данных, DbContext и предварительная реализация логики хранения данных. 2025-04-25 00:08:39 +04:00
rakhaliullov
47891b5e01 Проект и конфигурация базы данных. 2025-04-25 00:06:40 +04:00
rakhaliullov
bc3275cd50 Готовые интерфейсы хранения данных. 2025-04-25 00:04:00 +04:00
rakhaliullov
edba52e371 Кастомные исключения. 2025-04-25 00:03:11 +04:00
rakhaliullov
65f175ee48 Готовые модели. 2025-04-25 00:02:47 +04:00
rakhaliullov
7da4ea5e42 Решение проблем с конфигурацией проекта. 2025-04-25 00:02:17 +04:00
rakhaliullov
c8e8e8bac2 Изменение названий интерфейсов хранения данных. 2025-04-24 19:15:52 +04:00
rakhaliullov
656aa9f708 Создание интерфейсов хранения данных. 2025-04-24 19:08:41 +04:00
rakhaliullov
66932d52cb Правки в моделях. 2025-04-24 19:06:59 +04:00
rakhaliullov
015da38f1c Изменение названия проекта. 2025-04-24 18:28:03 +04:00
rakhaliullov
29d81dd4d8 Data models. 2025-04-24 18:01:07 +04:00
257 changed files with 91265 additions and 11 deletions

117
Bank.sln Normal file
View File

@@ -0,0 +1,117 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bank", "Bank", "{99E55959-6A68-8E99-5D13-A3DD7BDE8832}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankContracts", "Bank\BankContracts\BankContracts.csproj", "{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankDatabase", "Bank\BankDatabase\BankDatabase.csproj", "{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankBusinessLogic", "Bank\BankBusinessLogic\BankBusinessLogic.csproj", "{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankWebApi", "Bank\BankWebApi\BankWebApi.csproj", "{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankTests", "Bank\BankTests\BankTests.csproj", "{F87F3481-23A6-4B1F-A97C-257700B09C5C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankWebUi", "BankWebUi\BankWebUi.csproj", "{C0591A91-41A6-4F32-9C07-A3D01039E69F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Debug|x64.ActiveCfg = Debug|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Debug|x64.Build.0 = Debug|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Debug|x86.ActiveCfg = Debug|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Debug|x86.Build.0 = Debug|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Release|Any CPU.Build.0 = Release|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Release|x64.ActiveCfg = Release|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Release|x64.Build.0 = Release|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Release|x86.ActiveCfg = Release|Any CPU
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0}.Release|x86.Build.0 = Release|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Debug|x64.Build.0 = Debug|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Debug|x86.Build.0 = Debug|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Release|Any CPU.Build.0 = Release|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Release|x64.ActiveCfg = Release|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Release|x64.Build.0 = Release|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Release|x86.ActiveCfg = Release|Any CPU
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA}.Release|x86.Build.0 = Release|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Debug|x64.ActiveCfg = Debug|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Debug|x64.Build.0 = Debug|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Debug|x86.ActiveCfg = Debug|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Debug|x86.Build.0 = Debug|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Release|Any CPU.Build.0 = Release|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Release|x64.ActiveCfg = Release|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Release|x64.Build.0 = Release|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Release|x86.ActiveCfg = Release|Any CPU
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291}.Release|x86.Build.0 = Release|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Debug|x64.ActiveCfg = Debug|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Debug|x64.Build.0 = Debug|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Debug|x86.ActiveCfg = Debug|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Debug|x86.Build.0 = Debug|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Release|Any CPU.Build.0 = Release|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Release|x64.ActiveCfg = Release|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Release|x64.Build.0 = Release|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Release|x86.ActiveCfg = Release|Any CPU
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1}.Release|x86.Build.0 = Release|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Debug|x64.ActiveCfg = Debug|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Debug|x64.Build.0 = Debug|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Debug|x86.ActiveCfg = Debug|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Debug|x86.Build.0 = Debug|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Release|Any CPU.Build.0 = Release|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Release|x64.ActiveCfg = Release|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Release|x64.Build.0 = Release|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Release|x86.ActiveCfg = Release|Any CPU
{F87F3481-23A6-4B1F-A97C-257700B09C5C}.Release|x86.Build.0 = Release|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Debug|x64.ActiveCfg = Debug|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Debug|x64.Build.0 = Debug|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Debug|x86.ActiveCfg = Debug|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Debug|x86.Build.0 = Debug|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Release|Any CPU.Build.0 = Release|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Release|x64.ActiveCfg = Release|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Release|x64.Build.0 = Release|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Release|x86.ActiveCfg = Release|Any CPU
{C0591A91-41A6-4F32-9C07-A3D01039E69F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{B1183D31-EEF0-4033-BE27-00D2AFD71BE0} = {99E55959-6A68-8E99-5D13-A3DD7BDE8832}
{2E76A262-7C2C-4B94-8A43-2D62D30AEABA} = {99E55959-6A68-8E99-5D13-A3DD7BDE8832}
{DA53C27E-7223-4B9E-9AC1-D0A2B6189291} = {99E55959-6A68-8E99-5D13-A3DD7BDE8832}
{6B7EBC41-DEF2-46C9-8FD8-751DDFBFD5B1} = {99E55959-6A68-8E99-5D13-A3DD7BDE8832}
{F87F3481-23A6-4B1F-A97C-257700B09C5C} = {99E55959-6A68-8E99-5D13-A3DD7BDE8832}
{C0591A91-41A6-4F32-9C07-A3D01039E69F} = {99E55959-6A68-8E99-5D13-A3DD7BDE8832}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {185B6252-C09C-4DE7-A8E9-0CF9A26B1ED2}
EndGlobalSection
EndGlobal

View File

@@ -1,9 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35919.96 d17.13
VisualStudioVersion = 17.13.35919.96
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bank", "Bank\Bank.csproj", "{4D1918AC-313F-49A6-9FA3-620F496B2484}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankContracts", "BankContracts\BankContracts.csproj", "{4D1918AC-313F-49A6-9FA3-620F496B2484}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankDatabase", "BankDatabase\BankDatabase.csproj", "{B75AC519-6481-400F-B251-CB0819236AC6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankTests", "BankTests\BankTests.csproj", "{BD1C9A0C-8831-4EB8-990C-D0C3B75855AD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankBusinessLogic", "BankBusinessLogic\BankBusinessLogic.csproj", "{F07CED3B-5317-4C44-B1F5-E44281C4B03C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +21,18 @@ Global
{4D1918AC-313F-49A6-9FA3-620F496B2484}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D1918AC-313F-49A6-9FA3-620F496B2484}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D1918AC-313F-49A6-9FA3-620F496B2484}.Release|Any CPU.Build.0 = Release|Any CPU
{B75AC519-6481-400F-B251-CB0819236AC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B75AC519-6481-400F-B251-CB0819236AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B75AC519-6481-400F-B251-CB0819236AC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B75AC519-6481-400F-B251-CB0819236AC6}.Release|Any CPU.Build.0 = Release|Any CPU
{BD1C9A0C-8831-4EB8-990C-D0C3B75855AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD1C9A0C-8831-4EB8-990C-D0C3B75855AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD1C9A0C-8831-4EB8-990C-D0C3B75855AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD1C9A0C-8831-4EB8-990C-D0C3B75855AD}.Release|Any CPU.Build.0 = Release|Any CPU
{F07CED3B-5317-4C44-B1F5-E44281C4B03C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F07CED3B-5317-4C44-B1F5-E44281C4B03C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F07CED3B-5317-4C44-B1F5-E44281C4B03C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F07CED3B-5317-4C44-B1F5-E44281C4B03C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="PDFsharp-MigraDoc-gdi" Version="6.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BankContracts\BankContracts.csproj" />
<ProjectReference Include="..\BankDatabase\BankDatabase.csproj" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="BankTests" />
<InternalsVisibleTo Include="BankContracts" />
<InternalsVisibleTo Include="BankWebApi" />
<InternalsVisibleTo Include="BankWebUi" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,50 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class BindClientDepositsBusinessLogicContract : IBindClientDepositsBusinessLogicContract
{
private readonly IBindClientDepositsStorageContract _bindClientDepositsStorageContract;
public BindClientDepositsBusinessLogicContract(IBindClientDepositsStorageContract bindClientDepositsStorageContract)
{
_bindClientDepositsStorageContract = bindClientDepositsStorageContract;
}
public void BindDepositToClient(ClientDepositDataModel model)
{
try
{
_bindClientDepositsStorageContract.BindClientDeposit(model);
}
catch
{
throw;
}
}
public List<ClientDepositDataModel> GetClientsByDepositId(string id)
{
try
{
return _bindClientDepositsStorageContract.GetClientDeposits(depositId: id);
}
catch (Exception ex)
{
throw;
}
}
public List<ClientDepositDataModel> GetDepositsByClientId(string id)
{
try
{
return _bindClientDepositsStorageContract.GetClientDeposits(clientId: id);
}
catch (Exception ex)
{
throw;
}
}
}

View File

@@ -0,0 +1,50 @@

using BankContracts.BusinessLogicContracts;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class BindClientProgramsBusinessLogicContract : IBindClientProgramsBusinessLogicContract
{
private readonly IBindClientProgramsStorageContract _bindClientProgramsStorageContract;
public BindClientProgramsBusinessLogicContract(IBindClientProgramsStorageContract bindClientProgramsStorageContract)
{
_bindClientProgramsStorageContract = bindClientProgramsStorageContract;
}
public void BindProgramToClient(ClientProgramDataModel model)
{
try
{
_bindClientProgramsStorageContract.BndClientProgram(model);
}
catch
{
throw;
}
}
public List<ClientProgramDataModel> GetClientsByProgramId(string id)
{
try
{
return _bindClientProgramsStorageContract.GetClientPrograms(programId: id);
}
catch (Exception ex)
{
throw;
}
}
public List<ClientProgramDataModel> GetProgramsByClientId(string id)
{
try
{
return _bindClientProgramsStorageContract.GetClientPrograms(clientId: id);
}
catch (Exception ex)
{
throw;
}
}
}

View File

@@ -0,0 +1,82 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StoragesContracts;
using System.Text.Json;
namespace BankBusinessLogic.Implementation;
internal class ClientBusinessLogicContract(IClientStorageContract clientStorageContract) : IClientBusinessLogicContract
{
private readonly IClientStorageContract _clientStorageContract = clientStorageContract;
public List<ClientDataModel> GetAllClients()
{
return _clientStorageContract.GetList() ?? throw new NullListException();
}
public List<ClientDataModel> GetAllClientsByDeposit(string depositId)
{
if (depositId.IsEmpty())
{
throw new ArgumentNullException(nameof(depositId));
}
if (!depositId.IsGuid())
{
throw new ValidationException("The value in the field depositId a unique identifier.");
}
return _clientStorageContract.GetList(depositId) ?? throw new NullListException();
}
public List<ClientDataModel> GetAllClientsByProgram(string programId)
{
if (programId.IsEmpty())
{
throw new ArgumentNullException(nameof(programId));
}
if (!programId.IsGuid())
{
throw new ValidationException("The value in the field programId a unique identifier.");
}
return _clientStorageContract.GetList(programId) ?? throw new NullListException();
}
public ClientDataModel GetClientByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _clientStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _clientStorageContract.GetElementByPassport(data) ?? throw new ElementNotFoundException(data);
}
public void InsertClient(ClientDataModel clientDataModel)
{
ArgumentNullException.ThrowIfNull(clientDataModel);
_clientStorageContract.AddElement(clientDataModel);
}
public void UpdateClient(ClientDataModel clientDataModel)
{
ArgumentNullException.ThrowIfNull(clientDataModel);
_clientStorageContract.UpdateElement(clientDataModel);
}
public void DeleteClient(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_clientStorageContract.DeleteElement(id);
}
}

View File

@@ -0,0 +1,55 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class CurrencyBusinessLogicContract(ICurrencyStorageContract currencyStorageContract) : ICurrencyBusinessLogicContract
{
private readonly ICurrencyStorageContract _currencyStorageContract = currencyStorageContract;
public List<CurrencyDataModel> GetAllCurrencies()
{
return _currencyStorageContract.GetList() ?? throw new NullListException();
}
public CurrencyDataModel GetCurrencyByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _currencyStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _currencyStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
}
public void InsertCurrency(CurrencyDataModel currencyDataModel)
{
ArgumentNullException.ThrowIfNull(currencyDataModel);
_currencyStorageContract.AddElement(currencyDataModel);
}
public void UpdateCurrency(CurrencyDataModel currencyDataModel)
{
ArgumentNullException.ThrowIfNull(currencyDataModel);
_currencyStorageContract.UpdateElement(currencyDataModel);
}
public void DeleteCurrency(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_currencyStorageContract.DeleteElement(id);
}
}

View File

@@ -0,0 +1,77 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class DepositBusinessLogicContract(IDepositStorageContract depositStorageContract) : IDepositBusinessLogicContract
{
private readonly IDepositStorageContract _depositStorageContract = depositStorageContract;
public List<DepositDataModel> GetAllDepositsByPeriod(DateTime fromDate, DateTime toDate)
{
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
return _depositStorageContract.GetList(fromDate, toDate) ?? throw new NullListException();
}
public List<DepositDataModel> GetAllDepositsByCurrencyByPeriod(string currencyId, DateTime fromDate, DateTime toDate)
{
;
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
if (currencyId.IsEmpty())
{
throw new ArgumentNullException(nameof(currencyId));
}
if (!currencyId.IsGuid())
{
throw new ValidationException("The value in the field currencyId is not a unique identifier.");
}
return _depositStorageContract.GetList(fromDate, toDate, currencyId: currencyId) ?? throw new NullListException();
}
public DepositDataModel GetDepositByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (!data.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
return _depositStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
public void InsertDeposit(DepositDataModel depositDataModel)
{
ArgumentNullException.ThrowIfNull(depositDataModel);
_depositStorageContract.AddElement(depositDataModel);
}
public void UpdateDeposit(DepositDataModel depositDataModel)
{
ArgumentNullException.ThrowIfNull(depositDataModel);
_depositStorageContract.UpdateElement(depositDataModel);
}
public void DeleteDeposit(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_depositStorageContract.DeleteElement(id);
}
}

View File

@@ -0,0 +1,68 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class ProgramBusinessLogicContract(IProgramStorageContract programStorageContract) : IProgramBusinessLogicContract
{
private readonly IProgramStorageContract _programStorageContract = programStorageContract;
public List<ProgramDataModel> GetAllPrograms()
{
return _programStorageContract.GetList() ?? throw new NullListException();
}
public List<ProgramDataModel> GetAllProgramsByTerm(string termId)
{
if (termId.IsEmpty())
{
throw new ArgumentNullException(nameof(termId));
}
if (!termId.IsGuid())
{
throw new ValidationException("The value in the field depositId a unique identifier.");
}
return _programStorageContract.GetList(termId) ?? throw new NullListException();
}
public ProgramDataModel GetProgramByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _programStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _programStorageContract.GetElementByName(data) ?? throw new ElementNotFoundException(data);
}
public void InsertProgram(ProgramDataModel programDataModel)
{
ArgumentNullException.ThrowIfNull(programDataModel);
_programStorageContract.AddElement(programDataModel);
}
public void UpdateProgram(ProgramDataModel programDataModel)
{
ArgumentNullException.ThrowIfNull(programDataModel);
_programStorageContract.UpdateElement(programDataModel);
}
public void DeleteProgram(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_programStorageContract.DeleteElement(id);
}
}

View File

@@ -0,0 +1,64 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class RefillBusinessLogicContract(IRefillStorageContract refillStorageContract) : IRefillBusinessLogicContract
{
private readonly IRefillStorageContract _refillStorageContract = refillStorageContract;
public List<RefillDataModel> GetAllRefills()
{
return _refillStorageContract.GetList() ?? throw new NullListException();
}
public List<RefillDataModel> GetAllRefillsByDeposit(string depositId)
{
if (depositId.IsEmpty())
{
throw new ArgumentNullException(nameof(depositId));
}
if (!depositId.IsGuid())
{
throw new ValidationException("The value in the field depositId a unique identifier.");
}
return _refillStorageContract.GetList(depositId) ?? throw new NullListException();
}
public RefillDataModel GetRefillByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (!data.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
return _refillStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
public void InsertRefill(RefillDataModel refillDataModel)
{
ArgumentNullException.ThrowIfNull(refillDataModel);
_refillStorageContract.AddElement(refillDataModel);
}
public void DeleteRefill(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_refillStorageContract.DeleteElement(id);
}
}

View File

@@ -0,0 +1,211 @@
using BankBusinessLogic.OfficePackage;
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
public class ReportContract(
IProgramStorageContract programStorageContract,
IClientStorageContract clientStorageContract,
ICurrencyStorageContract currencyStorageContract,
IDepositStorageContract depositStorageContract,
BaseWordBuilder baseWordBuilder,
BaseExcelBuilder baseExcelBuilder,
BasePdfBuilder basePdfBuilder) : IReportContract
{
private readonly IProgramStorageContract _programStorageContract = programStorageContract;
private readonly IClientStorageContract _clientStorageContract = clientStorageContract;
private readonly ICurrencyStorageContract _currencyStorageContract = currencyStorageContract;
private readonly IDepositStorageContract _depositStorageContract = depositStorageContract;
private readonly BaseWordBuilder _baseWordBuilder = baseWordBuilder;
private readonly BaseExcelBuilder _baseExcelBuilder = baseExcelBuilder;
public List<ProgramReportDataModel> GetDataProgramsByDeposits(List<DepositDataModel> deposits)
{
var programs = _programStorageContract.GetList(); // Все программы
var clients = _clientStorageContract.GetListForReport(); // Все клиенты
var currencies = _currencyStorageContract.GetList(); // Все валюты
var programGroups = deposits
.GroupBy(d => d.ProgramId)
.ToList();
if (!programGroups.Any())
{
throw new Exception("Не найдены вклады для выбранных критериев");
}
var result = new List<ProgramReportDataModel>();
foreach (var group in programGroups)
{
var program = programs.FirstOrDefault(p => p.Id == group.Key);
if (program == null) continue;
var depositInfo = new List<(string, string, string, string)>();
foreach (var deposit in group)
{
var currency = currencies.FirstOrDefault(c => deposit.Currencies.Any(dc => dc.CurrencyId == c.Id));
var client = clients.FirstOrDefault(c => c.Deposits.Any(cd => cd.DepositId == deposit.Id));
var depositName = $"Вклад от {deposit.OpenDate:dd.MM.yyyy}";
depositInfo.Add((
depositName,
currency?.Name ?? "Неизвестная валюта",
client != null ? $"{client.Surname} {client.Name} {client.Patronymic}" : "Неизвестный клиент",
deposit.Amount.ToString("N2")
));
}
result.Add(new ProgramReportDataModel
{
ProgramName = program.Name,
Deposits = depositInfo
});
}
return result;
}
public Stream CreateDocumentProgramsByDeposits(List<ProgramReportDataModel> data, string format)
{
var now = DateTime.Now.ToString("dd.MM.yyyy HH:mm");
var mainHeader = "Список вкладов по кредитным программам";
string[] depositHeader = ["Вклад", "Валюта", "Клиент", "Сумма"];
if (format == ".docx")
{
var wordBuilder = _baseWordBuilder
.AddHeader(mainHeader)
.AddParagraph($"Сформировано: {now}");
foreach (var program in data)
{
wordBuilder
.AddParagraph(program.ProgramName)
.AddTable([3000, 3000, 4000, 2000], new List<string[]> { depositHeader })
.AddTable([3000, 3000, 4000, 2000],
program.Deposits.Select(d =>
new[] { d.DepositName, d.CurrencyName, d.ClientName, d.Amount }).ToList());
wordBuilder.AddParagraph("");
}
return wordBuilder.Build();
}
else if (format == ".xlsx")
{
var excelBuilder = _baseExcelBuilder
.AddHeader(mainHeader, 0, 3)
.AddParagraph($"Сформировано: {now}", 0);
var tableData = new List<string[]>();
foreach (var program in data)
{
tableData.Add(new[] { program.ProgramName, "", "", "" });
tableData.Add(depositHeader);
tableData.AddRange(program.Deposits.Select(d =>
new[] { d.DepositName, d.CurrencyName, d.ClientName, d.Amount }));
}
return excelBuilder
.AddTable([20, 20, 30, 15], tableData)
.Build();
}
throw new NotSupportedException($"Формат {format} не поддерживается");
}
public List<ClientReportDataModel> GetDataClients(List<ClientDataModel> clients)
{
var deposits = _depositStorageContract.GetList() ?? new List<DepositDataModel>();
var programs = _programStorageContract.GetList() ?? new List<ProgramDataModel>();
var currencies = _currencyStorageContract.GetList() ?? new List<CurrencyDataModel>();
var result = new List<ClientReportDataModel>();
foreach (var client in clients)
{
var clientDeposits = new List<(string, string, string, string)>();
foreach (var clientDeposit in client.Deposits)
{
var deposit = deposits.FirstOrDefault(d => d.Id == clientDeposit.DepositId);
if (deposit == null) continue;
var depositName = $"Вклад от {deposit.OpenDate:dd.MM.yyyy}";
var currency = currencies.FirstOrDefault(c => deposit.Currencies.Any(dc => dc.CurrencyId == c.Id));
var program = programs.FirstOrDefault(p => p.Id == deposit.ProgramId);
clientDeposits.Add((
depositName,
currency?.Name ?? "Неизвестная валюта",
program?.Name ?? "Неизвестная программа",
deposit.Amount.ToString("N2")
));
}
result.Add(new ClientReportDataModel
{
ClientName = $"{client.Surname} {client.Name} {client.Patronymic}",
Deposits = clientDeposits
});
}
return result;
}
public Stream CreateDocumentClients(List<ClientReportDataModel> data, string format)
{
var now = DateTime.Now.ToString("dd.MM.yyyy HH:mm");
var mainHeader = "Список клиентов";
string[] depositHeader = ["Вклад", "Валюта", "Кредитная программа", "Сумма"];
if (format == ".docx")
{
var wordBuilder = _baseWordBuilder
.AddHeader(mainHeader)
.AddParagraph($"Сформировано: {now}");
foreach (var client in data)
{
wordBuilder
.AddHeader(client.ClientName)
.AddTable([3000, 3000, 4000, 2000], new List<string[]> { depositHeader })
.AddTable([3000, 3000, 4000, 2000],
client.Deposits.Select(d =>
new[] { d.DepositName, d.CurrencyName, d.ProgramName, d.Amount }).ToList());
wordBuilder.AddParagraph("");
}
return wordBuilder.Build();
}
else if (format == ".xlsx")
{
var excelBuilder = _baseExcelBuilder
.AddHeader(mainHeader, 0, 3)
.AddParagraph($"Сформировано: {now}", 0);
var tableData = new List<string[]>();
foreach (var client in data)
{
tableData.Add(new[] { client.ClientName, "", "", "" });
tableData.Add(depositHeader);
tableData.AddRange(client.Deposits.Select(d =>
new[] { d.DepositName, d.CurrencyName, d.ProgramName, d.Amount }));
}
return excelBuilder
.AddTable([25, 25, 40, 15], tableData)
.Build();
}
throw new NotSupportedException($"Формат {format} не поддерживается");
}
}

View File

@@ -0,0 +1,55 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class TermBusinessLogicContract(ITermStorageContract termStorageContract) : ITermBusinessLogicContract
{
private readonly ITermStorageContract _termStorageContract = termStorageContract;
public List<TermDataModel> GetAllTerms()
{
return _termStorageContract.GetList() ?? throw new NullListException();
}
public TermDataModel GetTermByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (!data.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
return _termStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
public void InsertTerm(TermDataModel termDataModel)
{
ArgumentNullException.ThrowIfNull(termDataModel);
_termStorageContract.AddElement(termDataModel);
}
public void UpdateTerm(TermDataModel termDataModel)
{
ArgumentNullException.ThrowIfNull(termDataModel);
_termStorageContract.UpdateElement(termDataModel);
}
public void DeleteTerm(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_termStorageContract.DeleteElement(id);
}
}

View File

@@ -0,0 +1,67 @@
using BankContracts.BusinessLogicContracts;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.Infrastructure;
using BankContracts.StoragesContracts;
namespace BankBusinessLogic.Implementation;
internal class WorkerBusinessLogicContract(IWorkerStorageContract workerStorageContract) : IWorkerBusinessLogicContract
{
private readonly IWorkerStorageContract _workerStorageContract = workerStorageContract;
public WorkerDataModel GetWorkerByData(string data)
{
if (data.IsEmpty())
{
throw new ArgumentNullException(nameof(data));
}
if (data.IsGuid())
{
return _workerStorageContract.GetElementById(data) ?? throw new ElementNotFoundException(data);
}
return _workerStorageContract.GetElementByLogin(data) ?? throw new ElementNotFoundException(data);
}
public void UpdateWorker(WorkerDataModel workerDataModel)
{
ArgumentNullException.ThrowIfNull(workerDataModel);
_workerStorageContract.UpdateElement(workerDataModel);
}
public void DeleteWorker(string id)
{
if (id.IsEmpty())
{
throw new ArgumentNullException(nameof(id));
}
if (!id.IsGuid())
{
throw new ValidationException("Id is not a unique identifier");
}
_workerStorageContract.DeleteElement(id);
}
public bool CheckLogin(string login, string password)
{
var worker = _workerStorageContract.GetElementByLogin(login);
if (worker == null)
{
return false;
}
var hash = PasswordHelper.HashPassword(password, worker.Salt);
return hash == worker.PasswordHash;
}
public void InsertWorker(WorkerDataModel workerDataModel, string password)
{
var salt = PasswordHelper.GenerateSalt();
var hash = PasswordHelper.HashPassword(password, salt);
var _worker = new WorkerDataModel(workerDataModel.Id, workerDataModel.Login, hash, salt, workerDataModel.PhoneNumber);
_workerStorageContract.AddElement(_worker);
}
}

View File

@@ -0,0 +1,12 @@
namespace BankBusinessLogic.OfficePackage;
public abstract class BaseExcelBuilder
{
public abstract BaseExcelBuilder AddHeader(string header, int startIndex, int count);
public abstract BaseExcelBuilder AddParagraph(string text, int columnIndex);
public abstract BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data);
public abstract Stream Build();
}

View File

@@ -0,0 +1,12 @@
namespace BankBusinessLogic.OfficePackage;
public abstract class BasePdfBuilder
{
public abstract BasePdfBuilder AddHeader(string header);
public abstract BasePdfBuilder AddParagraph(string text);
public abstract BasePdfBuilder AddTable(string[] headers, List<string[]> rows, int[]? columnsWidths = null);
public abstract Stream Build();
}

View File

@@ -0,0 +1,12 @@
namespace BankBusinessLogic.OfficePackage;
public abstract class BaseWordBuilder
{
public abstract BaseWordBuilder AddHeader(string header);
public abstract BaseWordBuilder AddParagraph(string text);
public abstract BaseWordBuilder AddTable(int[] widths, List<string[]> data);
public abstract Stream Build();
}

View File

@@ -0,0 +1,87 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using System.Text;
namespace BankBusinessLogic.OfficePackage;
internal class MigraDocPdfBuilder : BasePdfBuilder
{
private readonly Document _document;
public MigraDocPdfBuilder()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_document = new Document();
DefineStyles();
}
public override BasePdfBuilder AddHeader(string header)
{
_document.AddSection().AddParagraph(header, "NormalBold");
return this;
}
public override BasePdfBuilder AddParagraph(string text)
{
_document.LastSection.AddParagraph(text, "Normal");
return this;
}
public override BasePdfBuilder AddTable(string[] headers, List<string[]> rows, int[]? columnsWidths = null)
{
var section = _document.LastSection ?? _document.AddSection();
var table = section.AddTable();
table.Format.Font.Size = 10;
for (int i = 0; i < headers.Length; i++)
{
var column = table.AddColumn(Unit.FromCentimeter(columnsWidths != null && i < columnsWidths.Length ? columnsWidths[i] / 10.0 : 5.0));
column.Format.Alignment = ParagraphAlignment.Left;
}
var headerRow = table.AddRow();
headerRow.Shading.Color = Colors.LightGray;
headerRow.Format.Font.Bold = true;
for (int i = 0; i < headers.Length; i++)
{
headerRow.Cells[i].AddParagraph(headers[i]);
headerRow.Cells[i].Format.Alignment = ParagraphAlignment.Left;
headerRow.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
foreach (var row in rows)
{
var tableRow = table.AddRow();
for (int i = 0; i < headers.Length; i++)
{
string cellText = i < row.Length ? row[i] : string.Empty;
tableRow.Cells[i].AddParagraph(cellText);
tableRow.Cells[i].Format.Alignment = ParagraphAlignment.Left;
tableRow.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(stream);
return stream;
}
private void DefineStyles()
{
var style = _document.Styles.AddStyle("NormalBold", "Normal");
style.Font.Bold = true;
}
}

View File

@@ -0,0 +1,303 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace BankBusinessLogic.OfficePackage;
internal class OpenXmlExcelBuilder : BaseExcelBuilder
{
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public OpenXmlExcelBuilder()
{
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public override BaseExcelBuilder AddHeader(string header, int startIndex, int count)
{
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
}
_mergeCells.Append(new MergeCell()
{
Reference =
new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}")
});
_rowIndex++;
return this;
}
public override BaseExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
return this;
}
public override BaseExcelBuilder AddTable(int[] columnsWidths, List<string[]> data)
{
if (columnsWidths == null || columnsWidths.Length == 0)
{
throw new ArgumentNullException(nameof(columnsWidths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != columnsWidths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
uint counter = 1;
int coef = 2;
_columns.Append(columnsWidths.Select(x => new Column
{
Min = counter,
Max = counter++,
Width = x * coef,
CustomWidth = true
}));
for (var j = 0; j < data.First().Length; ++j)
{
CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
for (var i = 1; i < data.Count - 1; ++i)
{
for (var j = 0; j < data[i].Length; ++j)
{
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
}
_rowIndex++;
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
using var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
GenerateStyle(workbookpart);
workbookpart.Workbook = new Workbook();
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
if (_columns.HasChildren)
{
worksheetPart.Worksheet.Append(_columns);
}
worksheetPart.Worksheet.Append(_sheetData);
var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист 1"
};
sheets.Append(sheet);
if (_mergeCells.HasChildren)
{
worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());
}
return stream;
}
private static void GenerateStyle(WorkbookPart workbookPart)
{
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2, KnownFonts = BooleanValue.FromBoolean(true) };
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) }
});
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme() { Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor) },
Bold = new Bold()
});
workbookStylesPart.Stylesheet.Append(fonts);
// Default Fill
var fills = new Fills() { Count = 1 };
fills.Append(new Fill
{
PatternFill = new PatternFill() { PatternType = new EnumValue<PatternValues>(PatternValues.None) }
});
workbookStylesPart.Stylesheet.Append(fills);
// Default Border
var borders = new Borders() { Count = 2 };
borders.Append(new Border
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
borders.Append(new Border
{
LeftBorder = new LeftBorder() { Style = BorderStyleValues.Thin },
RightBorder = new RightBorder() { Style = BorderStyleValues.Thin },
TopBorder = new TopBorder() { Style = BorderStyleValues.Thin },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin }
});
workbookStylesPart.Stylesheet.Append(borders);
// Default cell format and a date cell format
var cellFormats = new CellFormats() { Count = 4 };
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Center,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
SimpleTextWithBorder = 1,
BoldTextWithoutBorder = 2,
BoldTextWithBorder = 3
}
private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex)
{
var columnName = GetExcelColumnName(columnIndex);
var cellReference = columnName + rowIndex;
var row = _sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
_sheetData.Append(row);
}
var newCell = row.Elements<Cell>()
.FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
if (newCell == null)
{
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length)
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
}
newCell.CellValue = new CellValue(text);
newCell.DataType = CellValues.String;
newCell.StyleIndex = (uint)styleIndex;
}
private static string GetExcelColumnName(int columnNumber)
{
columnNumber += 1;
int dividend = columnNumber;
string columnName = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
}

View File

@@ -0,0 +1,94 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace BankBusinessLogic.OfficePackage;
internal class OpenXmlWordBuilder : BaseWordBuilder
{
private readonly Document _document;
private readonly Body _body;
public OpenXmlWordBuilder()
{
_document = new Document();
_body = _document.AppendChild(new Body());
}
public override BaseWordBuilder AddHeader(string header)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new RunProperties(new Bold()));
run.AppendChild(new Text(header));
return this;
}
public override BaseWordBuilder AddParagraph(string text)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new Text(text));
return this;
}
public override BaseWordBuilder AddTable(int[] widths, List<string[]> data)
{
if (widths == null || widths.Length == 0)
{
throw new ArgumentNullException(nameof(widths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != widths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
var table = new Table();
table.AppendChild(new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 }
)
));
// Заголовок
var tr = new TableRow();
for (var j = 0; j < widths.Length; ++j)
{
tr.Append(new TableCell(
new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }),
new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j])))));
}
table.Append(tr);
// Данные
table.Append(data.Skip(1).Select(x =>
new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y))))))));
_body.Append(table);
return this;
}
public override Stream Build()
{
var stream = new MemoryStream();
using var wordDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);
var mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = _document;
return stream;
}
}

View File

@@ -0,0 +1,23 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface IClientAdapter
{
List<ClientViewModel> GetList();
List<ClientViewModel> GetDepositList(string depositId);
List<ClientViewModel> GetProgramList(string programId);
ClientBindingModel GetElement(string data);
ClientViewModel? GetElementByIdView(string id);
void RegisterClient(ClientBindingModel clientBindingModel);
void ChangeClientInfo(ClientBindingModel clientBindingModel);
void RemoveClient(string id);
}

View File

@@ -0,0 +1,14 @@
using BankContracts.BindingModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankContracts.AdapterContracts;
public interface IClientDepositAdapter
{
public void AddBindClientDeposit(ClientDepositBindingModel model);
}

View File

@@ -0,0 +1,13 @@
using BankContracts.BindingModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankContracts.AdapterContracts;
public interface IClientProgramAdapter
{
public void AddBindClientProgram(ClientProgramBindingModel model);
}

View File

@@ -0,0 +1,17 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface ICurrencyAdapter
{
List<CurrencyViewModel> GetList();
CurrencyBindingModel GetElement(string data);
void RegisterCurrency(CurrencyBindingModel currencyBindingModel);
void ChangeCurrencyInfo(CurrencyBindingModel currencyBindingModel);
void RemoveCurrency(string id);
}

View File

@@ -0,0 +1,19 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface IDepositAdapter
{
List<DepositViewModel> GetList(DateTime fromDate, DateTime toDate);
List<DepositViewModel> GetCurrencyList(string currencyId, DateTime fromDate, DateTime toDate);
DepositViewModel GetElement(string data);
void RegisterDeposit(DepositBindingModel depositBindingModel);
void ChangeDepositInfo(DepositBindingModel depositBindingModel);
void RemoveDeposit(string id);
}

View File

@@ -0,0 +1,19 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface IProgramAdapter
{
List<ProgramViewModel> GetList();
List<ProgramViewModel> GetTermList(string termId);
ProgramBindingModel GetElement(string data);
void RegisterProgram(ProgramBindingModel programBindingModel);
void ChangeProgramInfo(ProgramBindingModel programBindingModel);
void RemoveProgram(string id);
}

View File

@@ -0,0 +1,17 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface IRefillAdapter
{
List<RefillViewModel> GetList();
List<RefillViewModel> GetDepositList(string depositId);
RefillBindingModel GetElement(string data);
void RegisterRefill(RefillBindingModel refillBindingModel);
void RemoveRefill(string id);
}

View File

@@ -0,0 +1,26 @@
using BankContracts.DataModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface IReportAdapter
{
/// <summary>
/// Получить отчёт по программам с группировкой по вкладам
/// </summary>
List<ProgramReportViewModel> GetProgramsByDeposits(List<string> depositIds);
/// <summary>
/// Получить отчёт по клиентам с расшифровкой по валютам и пополнениям за период
/// </summary>
List<ClientReportViewModel> GetClientsReport(DateTime? dateFrom, DateTime? dateTo);
/// <summary>
/// Сформировать файл отчёта по программам
/// </summary>
Stream BuildProgramsReportFile(List<string> depositIds, string format);
/// <summary>
/// Сформировать файл отчёта по клиентам
/// </summary>
Stream BuildClientsReportFile(DateTime? dateFrom, DateTime? dateTo, string format);
}

View File

@@ -0,0 +1,17 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface ITermAdapter
{
List<TermViewModel> GetList();
TermBindingModel GetElement(string data);
void RegisterTerm(TermBindingModel termBindingModel);
void ChangeTermInfo(TermBindingModel termBindingModel);
void RemoveTerm(string id);
}

View File

@@ -0,0 +1,11 @@
using BankContracts.BindingModels;
using BankContracts.ViewModels;
namespace BankContracts.AdapterContracts;
public interface IWorkerAdapter
{
public void Register(WorkerRegisterBindingModel user);
public WorkerViewModel? Login(string login, string password);
public bool CheckLoginExists(string login);
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,32 @@
using BankContracts.DataModels;
using System.ComponentModel.DataAnnotations;
using System.Xml.Linq;
namespace BankContracts.BindingModels;
public class ClientBindingModel
{
public string? Id { get; set; }
[Display(Name = "Имя")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Name { get; set; }
[Display(Name = "Фамилия")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Surname { get; set; }
[Display(Name = "Отчество")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Patronymic { get; set; }
[Display(Name = "Номер телефона")]
[Phone(ErrorMessage = "Некорректный формат номера телефона")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? PhoneNumber { get; set; }
[Display(Name = "Паспорт")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Passport { get; set; }
public string? WorkerId { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.BindingModels;
public class ClientDepositBindingModel
{
public string? ClientId { get; set; }
public string? DepositId { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.BindingModels;
public class ClientProgramBindingModel
{
public string? ClientId { get; set; }
public string? ProgramId { get; set; }
}

View File

@@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class CurrencyBindingModel
{
public string? Id { get; set; }
[Display(Name = "Валюта")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Name { get; set; }
[Display(Name = "Курс")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public double Course { get; set; }
}

View File

@@ -0,0 +1,27 @@
using BankContracts.DataModels;
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class DepositBindingModel
{
public string? Id { get; set; }
[Display(Name = "Сумма")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public int Amount { get; set; }
[Display(Name = "Дата открытия")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public DateTime OpenDate { get; set; }
[Display(Name = "Дата закрытия")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public DateTime CloseDate { get; set; }
[Display(Name = "Программа")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? ProgramId { get; set; }
public string? WorkerId { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.BindingModels;
public class DepositCurrencyBindingModel
{
public string? DepositId { get; set; }
public string? CurrencyId { get; set; }
}

View File

@@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class ProgramBindingModel
{
public string? Id { get; set; }
[Display(Name = "Название программы")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Name { get; set; }
[Display(Name = "Ставка")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public double InterestRate { get; set; }
[Display(Name = "Срок")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? TermId { get; set; }
}

View File

@@ -0,0 +1,23 @@
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class RefillBindingModel
{
public string? Id { get; set; }
[Display(Name = "Сумма")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? Amount { get; set; }
[Display(Name = "Дата")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public DateTime Date { get; set; }
[Display(Name = "Работник")]
public string? WorkerId { get; set; }
[Display(Name = "Вклад")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public string? DepositId { get; set; }
}

View File

@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class TermBindingModel
{
public string? Id { get; set; }
[Display(Name = "Срок")]
[Required(ErrorMessage = "Это поле обязательно для заполнения")]
public double Duration { get; set; }
}

View File

@@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class WorkerLoginBindingModel
{
[Required]
[Display(Name = "Логин")]
public string Login { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Пароль")]
public string Password { get; set; }
}

View File

@@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
namespace BankContracts.BindingModels;
public class WorkerRegisterBindingModel
{
[Required(ErrorMessage = "Логин обязателен.")]
[Display(Name = "Логин")]
[StringLength(50, MinimumLength = 4, ErrorMessage = "Логин должен содержать от 4 до 50 символов.")]
public string Login { get; set; }
[Required(ErrorMessage = "Пароль обязателен.")]
[Display(Name = "Пароль")]
[StringLength(100, MinimumLength = 7, ErrorMessage = "Пароль должен содержать минимум 7 символов.")]
public string Password { get; set; }
[Required(ErrorMessage = "Номер телефона обязателен.")]
[Phone(ErrorMessage = "Некорректный формат.")]
[Display(Name = "Номер телефона")]
public string PhoneNumber { get; set; }
}

View File

@@ -0,0 +1,11 @@

using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IBindClientDepositsBusinessLogicContract
{
public List<ClientDepositDataModel> GetClientsByDepositId(string id);
public List<ClientDepositDataModel> GetDepositsByClientId(string id);
public void BindDepositToClient(ClientDepositDataModel model);
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.BusinessLogicContracts;
public interface IBindClientProgramsBusinessLogicContract
{
public List<ClientProgramDataModel> GetClientsByProgramId(string id);
public List<ClientProgramDataModel> GetProgramsByClientId(string id);
public void BindProgramToClient(ClientProgramDataModel model);
}

View File

@@ -0,0 +1,20 @@
using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IClientBusinessLogicContract
{
List<ClientDataModel> GetAllClients();
List<ClientDataModel> GetAllClientsByDeposit(string depositId);
List<ClientDataModel> GetAllClientsByProgram(string programId);
ClientDataModel GetClientByData(string data);
void InsertClient(ClientDataModel clientDataModel);
void UpdateClient(ClientDataModel clientDataModel);
void DeleteClient(string id);
}

View File

@@ -0,0 +1,16 @@
using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface ICurrencyBusinessLogicContract
{
List<CurrencyDataModel> GetAllCurrencies();
CurrencyDataModel GetCurrencyByData(string data);
void InsertCurrency(CurrencyDataModel currencyDataModel);
void UpdateCurrency(CurrencyDataModel currencyDataModel);
void DeleteCurrency(string id);
}

View File

@@ -0,0 +1,20 @@

using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IDepositBusinessLogicContract
{
List<DepositDataModel> GetAllDepositsByPeriod(DateTime fromDate, DateTime toDate);
List<DepositDataModel> GetAllDepositsByCurrencyByPeriod(string currencyId, DateTime fromDate, DateTime toDate);
DepositDataModel GetDepositByData(string data);
void InsertDeposit (DepositDataModel depositDataModel);
void UpdateDeposit (DepositDataModel depositDataModel);
void DeleteDeposit (string id);
}

View File

@@ -0,0 +1,18 @@
using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IProgramBusinessLogicContract
{
List<ProgramDataModel> GetAllPrograms();
List<ProgramDataModel> GetAllProgramsByTerm(string termId);
ProgramDataModel GetProgramByData(string data);
void InsertProgram(ProgramDataModel programDataModel);
void UpdateProgram(ProgramDataModel programDataModel);
void DeleteProgram(string id);
}

View File

@@ -0,0 +1,16 @@
using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IRefillBusinessLogicContract
{
List<RefillDataModel> GetAllRefills();
List<RefillDataModel> GetAllRefillsByDeposit(string depositId);
RefillDataModel GetRefillByData(string data);
void InsertRefill(RefillDataModel refillDataModel);
void DeleteRefill(string id);
}

View File

@@ -0,0 +1,14 @@
using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IReportContract
{
List<ProgramReportDataModel> GetDataProgramsByDeposits(List<DepositDataModel> deposits);
Stream CreateDocumentProgramsByDeposits(List<ProgramReportDataModel> data, string format);
List<ClientReportDataModel> GetDataClients(List<ClientDataModel> clients);
Stream CreateDocumentClients(List<ClientReportDataModel> data, string format);
}

View File

@@ -0,0 +1,16 @@
using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface ITermBusinessLogicContract
{
List<TermDataModel> GetAllTerms();
TermDataModel GetTermByData(string data);
void InsertTerm(TermDataModel termDataModel);
void UpdateTerm(TermDataModel termDataModel);
void DeleteTerm(string id);
}

View File

@@ -0,0 +1,17 @@

using BankContracts.DataModels;
namespace BankContracts.BusinessLogicContracts;
public interface IWorkerBusinessLogicContract
{
WorkerDataModel GetWorkerByData(string data);
public bool CheckLogin(string login, string password);
void InsertWorker(WorkerDataModel workerDataModel, string password);
void UpdateWorker(WorkerDataModel workerDataModel);
void DeleteWorker(string id);
}

View File

@@ -0,0 +1,49 @@
namespace BankContracts.DataModels;
public class ClientDataModel
{
public string Id { get; private set; }
public string Name { get; private set; }
public string Surname { get; private set; }
public string Patronymic { get; private set; }
public string PhoneNumber { get; private set; }
public string Passport { get; private set; }
public string WorkerId { get; private set; }
public List<ClientDepositDataModel> Deposits { get; private set; }
public List<ClientProgramDataModel> Programs { get; private set; }
public ClientDataModel(string id, string name, string surname, string patronymic, string phoneNumber, string passport, string workerId, List<ClientDepositDataModel> clientDeposits, List<ClientProgramDataModel> clientPrograms)
{
Id = id;
Name = name;
Surname = surname;
Patronymic = patronymic;
PhoneNumber = phoneNumber;
Passport = passport;
WorkerId = workerId;
Deposits = clientDeposits;
Programs = clientPrograms;
}
public ClientDataModel()
{
Id = Guid.NewGuid().ToString();
Name = string.Empty;
Surname = string.Empty;
Patronymic = string.Empty;
PhoneNumber = string.Empty;
Passport = string.Empty;
WorkerId = Guid.NewGuid().ToString();
Deposits = new List<ClientDepositDataModel>();
Programs = new List<ClientProgramDataModel>();
}
}

View File

@@ -0,0 +1,12 @@
namespace BankContracts.DataModels;
public class ClientDepositDataModel(string clientId,string depositId)
{
public string ClientId { get; private set; } = clientId;
public string DepositId { get; private set; } = depositId;
public DepositDataModel Deposit { get; set; } = null!;
public ClientDataModel Client { get; set; } = null!;
}

View File

@@ -0,0 +1,10 @@
using BankContracts.DataModels;
public class ClientProgramDataModel(string programId, string clientId)
{
public string ProgramId { get; private set; } = programId;
public string ClientId { get; private set; } = clientId;
public ProgramDataModel Program { get; set; } = null!;
public ClientDataModel Client { get; set; } = null!;
}

View File

@@ -0,0 +1,7 @@
namespace BankContracts.DataModels;
public class ClientReportDataModel
{
public string? ClientName { get; set; }
public List<(string DepositName, string CurrencyName, string ProgramName, string Amount)>? Deposits { get; set; }
}

View File

@@ -0,0 +1,23 @@
namespace BankContracts.DataModels;
public class CurrencyDataModel
{
public string Id { get; private set; }
public string Name { get; private set; }
public double Course { get; private set; }
public CurrencyDataModel(string id, string name, double course)
{
Id = id;
Name = name;
Course = course;
}
public CurrencyDataModel()
{
Id = Guid.NewGuid().ToString();
Name = string.Empty;
Course = 0;
}
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.DataModels;
public class DepositCurrencyDataModel(string currencyId, string depositId)
{
public string CurrencyId { get; private set; } = currencyId;
public string DepositId { get; private set; } = depositId;
}

View File

@@ -0,0 +1,37 @@
namespace BankContracts.DataModels;
public class DepositDataModel
{
public string Id { get; private set; }
public int Amount { get; private set; }
public DateTime OpenDate { get; private set; } = DateTime.Now;
public DateTime CloseDate { get; private set; }
public string ProgramId { get; private set; }
public string WorkerId { get; private set; }
public List<DepositCurrencyDataModel> Currencies { get; private set; }
public DepositDataModel(string id, int amount, DateTime closeDate, string programId, string workerId, List<DepositCurrencyDataModel> сurrencies)
{
Id = id;
Amount = amount;
CloseDate = closeDate;
ProgramId = programId;
WorkerId = workerId;
Currencies = сurrencies;
}
public DepositDataModel()
{
Id = Guid.NewGuid().ToString();
Amount = 0;
CloseDate = DateTime.UtcNow;
ProgramId = Guid.NewGuid().ToString();
WorkerId = Guid.NewGuid().ToString();
Currencies = [];
}
}

View File

@@ -0,0 +1,9 @@
public class ProgramDataModel(string id, string name, double interestRate, string termId)
{
public string Id { get; private set; } = id;
public string Name { get; private set; } = name;
public double InterestRate { get; private set; } = interestRate;
public string TermId { get; private set; } = termId;
public List<ClientProgramDataModel> Clients { get; set; } = new();
}

View File

@@ -0,0 +1,7 @@
namespace BankContracts.DataModels;
public class ProgramReportDataModel
{
public required string ProgramName { get; set; }
public List<(string DepositName, string CurrencyName, string ClientName, string Amount)>? Deposits { get; set; }
}

View File

@@ -0,0 +1,14 @@
namespace BankContracts.DataModels;
public class RefillDataModel(string id, string amount, string workerId, string depositId)
{
public string Id { get; private set; } = id;
public string Amount { get; private set; } = amount;
public DateTime Date { get; private set; } = DateTime.Now;
public string WorkerId { get; private set; } = workerId;
public string DepositId { get; private set; } = depositId;
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.DataModels;
public class TermDataModel(string id, double duration)
{
public string Id { get; private set; } = id;
public double Duration { get; private set; } = duration;
}

View File

@@ -0,0 +1,31 @@
namespace BankContracts.DataModels;
public class WorkerDataModel
{
public string Id { get; private set; }
public string Login { get; private set; }
public string PasswordHash { get; private set; }
public string Salt { get; private set; }
public string PhoneNumber { get; private set; }
public WorkerDataModel(string id, string login, string passwordHash, string salt, string phoneNumber)
{
Id = id;
Login = login;
Salt = salt;
PasswordHash = passwordHash + Salt;
PhoneNumber = phoneNumber;
}
public WorkerDataModel(string login, string phoneNumber)
{
Id = Guid.NewGuid().ToString();
Login = login;
PasswordHash = "";
Salt = "";
PhoneNumber = phoneNumber;
}
}

View File

@@ -0,0 +1,6 @@
namespace BankContracts.Exceptions;
public class ElementDeletedException : Exception
{
public ElementDeletedException(string id) : base($"Cannot modify a deleted item (id: {id})") { }
}

View File

@@ -0,0 +1,14 @@
namespace BankContracts.Exceptions;
public class ElementExistsException : Exception
{
public string ParamName { get; private set; }
public string ParamValue { get; private set; }
public ElementExistsException(string paramName, string paramValue) : base($"There is already an element with value{paramValue} of parameter {paramName}")
{
ParamName = paramName;
ParamValue = paramValue;
}
}

View File

@@ -0,0 +1,11 @@
namespace BankContracts.Exceptions;
public class ElementNotFoundException : Exception
{
public string Value { get; private set; }
public ElementNotFoundException(string value) : base($"Element not found at value = {value}")
{
Value = value;
}
}

View File

@@ -0,0 +1,6 @@
namespace BankContracts.Exceptions;
public class IncorrectDatesException : Exception
{
public IncorrectDatesException(DateTime start, DateTime end) : base($"The end date must be later than the start date.. StartDate: {start:dd.MM.YYYY}. EndDate: {end:dd.MM.YYYY}") { }
}

View File

@@ -0,0 +1,6 @@
namespace BankContracts.Exceptions;
public class NullListException : Exception
{
public NullListException() : base("The returned list is null") { }
}

View File

@@ -0,0 +1,6 @@
namespace BankContracts.Exceptions;
public class StorageException : Exception
{
public StorageException(Exception ex) : base($"Error while working in storage: {ex.Message}", ex) { }
}

View File

@@ -0,0 +1,5 @@
namespace BankContracts.Exceptions;
public class ValidationException(string message) : Exception(message)
{
}

View File

@@ -0,0 +1,9 @@
namespace BankContracts.Extensions;
public static class DateTimeExtensions
{
public static bool IsDateNotOlder(this DateTime date, DateTime olderDate)
{
return date >= olderDate;
}
}

View File

@@ -0,0 +1,14 @@
namespace BankContracts.Extensions;
public static class StringExtensions
{
public static bool IsEmpty(this string str)
{
return string.IsNullOrWhiteSpace(str);
}
public static bool IsGuid(this string str)
{
return Guid.TryParse(str, out _);
}
}

View File

@@ -0,0 +1,6 @@
namespace BankContracts.Infrastructure;
public interface IConfigurationDatabase
{
string ConnectionString { get; }
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace BankContracts.Infrastructure;
public static class PasswordHelper
{
public static string GenerateSalt()
{
var buffer = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(buffer);
}
return Convert.ToBase64String(buffer);
}
public static string HashPassword(string password, string salt)
{
using (var sha256 = SHA256.Create())
{
var saltedPassword = Encoding.UTF8.GetBytes(password + salt);
var hash = sha256.ComputeHash(saltedPassword);
return Convert.ToBase64String(hash);
}
}
}

View File

@@ -0,0 +1,9 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface IBindClientDepositsStorageContract
{
public List<ClientDepositDataModel> GetClientDeposits(string? clientId = null, string? depositId = null);
public void BindClientDeposit(ClientDepositDataModel model);
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankContracts.StoragesContracts;
public interface IBindClientProgramsStorageContract
{
public List<ClientProgramDataModel> GetClientPrograms(string? clientId = null, string? programId = null);
public void BndClientProgram(ClientProgramDataModel model);
}

View File

@@ -0,0 +1,19 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface IClientStorageContract
{
List<ClientDataModel> GetList(string? workerId = null, string? depositId = null, string? programId = null);
List<ClientDataModel> GetListForReport(string? workerId = null, string? depositId = null, string? programId = null);
ClientDataModel? GetElementById(string id);
ClientDataModel? GetElementByPassport(string passport);
void AddElement(ClientDataModel clientDataModel);
void UpdateElement(ClientDataModel clientDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,19 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface ICurrencyStorageContract
{
List<CurrencyDataModel> GetList();
CurrencyDataModel? GetElementById(string id);
CurrencyDataModel? GetElementByName(string name);
void AddElement(CurrencyDataModel currencyDataModel);
void UpdateElement(CurrencyDataModel currencyDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,16 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface IDepositStorageContract
{
List<DepositDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? workerId = null, string? programId = null, string? currencyId = null);
DepositDataModel? GetElementById(string id);
void AddElement(DepositDataModel depositDataModel);
void UpdateElement(DepositDataModel depositDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,18 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface IProgramStorageContract
{
List<ProgramDataModel> GetList(string? termId = null);
ProgramDataModel? GetElementById(string id);
ProgramDataModel? GetElementByName(string name);
void AddElement(ProgramDataModel programDataModel);
void UpdateElement(ProgramDataModel programDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,14 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface IRefillStorageContract
{
List<RefillDataModel> GetList(string? workerId = null, string? depositId = null);
RefillDataModel? GetElementById(string id);
void AddElement(RefillDataModel refillDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,18 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface ITermStorageContract
{
List<TermDataModel> GetList();
TermDataModel? GetElementById(string id);
List<TermDataModel> GetFullList();
void AddElement(TermDataModel termDataModel);
void UpdateElement(TermDataModel termDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,18 @@
using BankContracts.DataModels;
namespace BankContracts.StoragesContracts;
public interface IWorkerStorageContract
{
List<WorkerDataModel> GetList();
WorkerDataModel? GetElementById(string id);
WorkerDataModel? GetElementByLogin(string login);
void AddElement(WorkerDataModel workerDataModel);
void UpdateElement(WorkerDataModel workerDataModel);
void DeleteElement(string id);
}

View File

@@ -0,0 +1,16 @@

using System.ComponentModel.DataAnnotations;
namespace BankContracts.ViewModels;
public class ClientDepositBindViewModel
{
[Required(ErrorMessage = "Клиент обязателен")]
public string? SelectedClientId { get; set; }
[Required(ErrorMessage = "Депозит обязателен")]
public string? SelectedDepositId { get; set; }
public List<ClientViewModel> Clients { get; set; } = new();
public List<DepositViewModel> Deposits { get; set; } = new();
}

View File

@@ -0,0 +1,10 @@
using BankContracts.Exceptions;
namespace BankContracts.ViewModels;
public class ClientDepositViewModel
{
public required string ClientId { get; set; }
public string DepositId { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,16 @@
using BankContracts.ViewModels;
using System.ComponentModel.DataAnnotations;
namespace BankContracts.ViewModels;
public class ClientProgramBindViewModel
{
[Required(ErrorMessage = "Клиент обязателен")]
public string? SelectedClientId { get; set; }
[Required(ErrorMessage = "Программа обязательна")]
public string? SelectedProgramId { get; set; }
public List<ClientViewModel> Clients { get; set; } = new();
public List<ProgramViewModel> Programs { get; set; } = new();
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.ViewModels;
public class ClientProgramViewModel
{
public required string ClientId { get; set; }
public string ProgramId { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,8 @@

namespace BankContracts.ViewModels;
public class ClientReportViewModel
{
public required string? ClientName { get; set; }
public required List<(string DepositName, string CurrencyName, string ProgramName, string Amount)>? Deposits { get; set; }
}

View File

@@ -0,0 +1,28 @@
using BankContracts.DataModels;
namespace BankContracts.ViewModels;
public class ClientViewModel
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Surname { get; set; }
public required string Patronymic { get; set; }
public required string PhoneNumber { get; set; }
public required string Passport { get; set; }
public required string WorkerId { get; set; }
public List<ClientDepositDataModel> ClientDeposits { get; set; } = new();
public List<ClientProgramDataModel> ClientPrograms { get; set; } = new();
public List<ProgramViewModel> Programs { get; set; } = new();
public List<DepositViewModel> Deposits { get; set; } = new();
}

View File

@@ -0,0 +1,10 @@
namespace BankContracts.ViewModels;
public class CurrencyViewModel
{
public required string Id { get; set; }
public required string Name { get; set; }
public double Course { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.ViewModels;
public class DepositCurrencyViewModel
{
public required string DepositId { get; set; }
public string CurrencyId { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,24 @@
using BankContracts.DataModels;
namespace BankContracts.ViewModels;
public class DepositViewModel
{
public required string Id { get; set; }
public int Amount { get; set; }
public DateTime OpenDate { get; set; }
public DateTime CloseDate { get; set; }
public required string ProgramId { get; set; }
public required string WorkerId { get; set; }
public string? ProgramName { get; set; }
public List<DepositCurrencyDataModel> Currencies { get; set; } = new();
public List<DepositViewModel> Deposits { get; set; } = new();
}

View File

@@ -0,0 +1,7 @@
namespace BankContracts.ViewModels;
public class ProgramReportViewModel
{
public required string ProgramName { get; set; }
public required List<(string DepositName, string CurrencyName, string ClientName, string Amount)>? Deposits { get; set; }
}

View File

@@ -0,0 +1,18 @@
using System.Xml.Linq;
namespace BankContracts.ViewModels;
public class ProgramViewModel
{
public required string Id { get; set; }
public required string Name { get; set; }
public double InterestRate { get; set; }
public required string TermId { get; set; }
public string TermName { get; set; } = string.Empty; // 🔥 добавлено
public List<ProgramViewModel> Programs { get; set; } = new();
}

View File

@@ -0,0 +1,20 @@
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace BankContracts.ViewModels;
public class RefillViewModel
{
public required string Id { get; set; }
public required string Amount { get; set; }
public DateTime Date { get; set; }
public required string WorkerId { get; set; }
public required string DepositId { get; set; }
public string? WorkerLogin { get; set; }
public string? DepositName { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.ViewModels;
public class TermViewModel
{
public required string Id { get; set; }
public double Duration { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace BankContracts.ViewModels;
public class WorkerViewModel
{
public required string Id { get; set; }
public required string Login { get; set; }
public required string PhoneNumber { get; set; }
}

View File

@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="BankTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="BankTests" />
<InternalsVisibleTo Include="BankContracts" />
<InternalsVisibleTo Include="BankWebApi" />
<InternalsVisibleTo Include="BankWebUi" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BankContracts\BankContracts.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,71 @@
using BankContracts.Infrastructure;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
namespace BankDatabase;
internal class BankDbContext : DbContext
{
private readonly IConfigurationDatabase? _configurationDatabase;
public BankDbContext(IConfigurationDatabase configurationDatabase)
{
_configurationDatabase = configurationDatabase;
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(_configurationDatabase?.ConnectionString, o => o.SetPostgresVersion(12, 2));
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ClientProgram>()
.HasOne(cp => cp.Client)
.WithMany(c => c.ClientPrograms)
.HasForeignKey(cp => cp.ClientId);
// IsUnique
modelBuilder.Entity<Client>()
.HasIndex(x => x.Passport).IsUnique();
modelBuilder.Entity<Worker>()
.HasIndex(x => x.Login).IsUnique();
// HasKey
modelBuilder.Entity<ClientDeposit>()
.HasKey(cd => new { cd.ClientId, cd.DepositId });
modelBuilder.Entity<ClientProgram>()
.HasKey(cp => new { cp.ClientId, cp.ProgramId });
modelBuilder.Entity<DepositCurrency>()
.HasKey(dc => new { dc.DepositId, dc.CurrencyId });
}
public DbSet<Client> Clients { get; set; }
public DbSet<ClientDeposit> ClientDeposits { get; set; }
public DbSet<ClientProgram> ClientPrograms { get; set; }
public DbSet<Currency> Currencies { get; set; }
public DbSet<Deposit> Deposits { get; set; }
public DbSet<DepositCurrency> DepositCurrencies { get; set; }
public DbSet<Program> Programs { get; set; }
public DbSet<Refill> Refills { get; set; }
public DbSet<Term> Terms { get; set; }
public DbSet<Worker> Workers { get; set; }
}

Some files were not shown because too many files have changed in this diff Show More