Compare commits
36 Commits
EmployeeMa
...
main
Author | SHA1 | Date | |
---|---|---|---|
e61e753300 | |||
2f7e26689d | |||
3eff31e7b3 | |||
6715396027 | |||
61311886a1 | |||
66c0dcc6c6 | |||
e61e11a192 | |||
c36d12c9dd | |||
f8e8a0cc2b | |||
5389b63b05 | |||
69726bde25 | |||
7b0a8dd3d6 | |||
206ffc4c76 | |||
f5f36425c0 | |||
b83fcba0aa | |||
22b0af7ad5 | |||
1c04d20d13 | |||
41e4e00fd2 | |||
1cca9432eb | |||
eaf9cdb71d | |||
c228db433f | |||
bdf3269ea7 | |||
8b68e2c7ec | |||
e2c838da47 | |||
a2631c83cb | |||
a3dda6e679 | |||
f063934489 | |||
43903ceb95 | |||
7db0881977 | |||
d299dc1a45 | |||
94277268fd | |||
af01b18e80 | |||
74f1fda7c7 | |||
ca42b880f1 | |||
4b004a2628 | |||
|
7847a4e41a |
@ -11,7 +11,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmployeeManagmentBusinessLo
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmployeeManagmentDataModels", "EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj", "{C5293211-E924-4CFA-9DE5-69003D8C9F48}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmployeeManagmentDataModels", "EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj", "{C5293211-E924-4CFA-9DE5-69003D8C9F48}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmployeeManagmentDataBaseImplement", "EmployeeManagmentDataBaseImplement\EmployeeManagmentDataBaseImplement.csproj", "{18CB8173-C3E1-4655-A453-A48F20E1DF2E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmployeeManagmentDataBaseImplement", "EmployeeManagmentDataBaseImplement\EmployeeManagmentDataBaseImplement.csproj", "{18CB8173-C3E1-4655-A453-A48F20E1DF2E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmployeeManagmentTests", "EmployeeManagmentTests\EmployeeManagmentTests.csproj", "{6C2F1F37-B54C-493D-82DC-70561145CF49}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -39,6 +41,10 @@ Global
|
|||||||
{18CB8173-C3E1-4655-A453-A48F20E1DF2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{18CB8173-C3E1-4655-A453-A48F20E1DF2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{18CB8173-C3E1-4655-A453-A48F20E1DF2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{18CB8173-C3E1-4655-A453-A48F20E1DF2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{18CB8173-C3E1-4655-A453-A48F20E1DF2E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{18CB8173-C3E1-4655-A453-A48F20E1DF2E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6C2F1F37-B54C-493D-82DC-70561145CF49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6C2F1F37-B54C-493D-82DC-70561145CF49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6C2F1F37-B54C-493D-82DC-70561145CF49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6C2F1F37-B54C-493D-82DC-70561145CF49}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1,31 +1,67 @@
|
|||||||
using EmployeeManagmentContracts.BindingModels;
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
using EmployeeManagmentContracts.BusinessLogicContracts;
|
|
||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.StoragesContracts;
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
||||||
{
|
{
|
||||||
public class EmployeeLogic : IEmployeeLogic
|
public class EmployeeLogic : IEmployeeLogic
|
||||||
{
|
{
|
||||||
public void CreateOrUpdate(EmployeeBindingModel model)
|
private readonly ILogger<EmployeeLogic> _logger;
|
||||||
|
private readonly IEmployeeStorage _employeeStorage;
|
||||||
|
|
||||||
|
public EmployeeLogic(ILogger<EmployeeLogic> logger, IEmployeeStorage employeeStorage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_logger = logger;
|
||||||
|
_employeeStorage = employeeStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmployeeViewModel> GetFullList()
|
||||||
|
{
|
||||||
|
return _employeeStorage.GetFullList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmployeeViewModel> GetFilteredList(EmployeeSearchModel model)
|
||||||
|
{
|
||||||
|
return _employeeStorage.GetFilteredList(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmployeeViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
return _employeeStorage.GetElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(EmployeeViewModel model)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(model.NameJob))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Название должности обязательно для заполнения.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_employeeStorage.Insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(EmployeeViewModel model)
|
||||||
|
{
|
||||||
|
var element = _employeeStorage.GetElement(model.Id);
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Сотрудник не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_employeeStorage.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var element = _employeeStorage.GetElement(id);
|
||||||
}
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Сотрудник не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
public EmployeeViewModel? GetEmployeeById(int id)
|
_employeeStorage.Delete(id);
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EmployeeViewModel> GetEmployees(EmployeeSearchModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,34 +2,75 @@
|
|||||||
using EmployeeManagmentContracts.BusinessLogicContracts;
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Models;
|
||||||
|
using EmployeeManagmentDataBaseImplement;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Implements;
|
||||||
|
|
||||||
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
||||||
{
|
{
|
||||||
public class PhisicalPersonLogic : IPhisicalPersonLogic
|
public class PhisicalPersonLogic : IPhisicalPersonLogic
|
||||||
{
|
{
|
||||||
public void CreateOrUpdate(PhisicalPersonBindingModel model)
|
private readonly ILogger<PhisicalPersonLogic> _logger;
|
||||||
|
private readonly IPhisicalPersonStorage _phisicalPersonStorage;
|
||||||
|
|
||||||
|
public PhisicalPersonLogic(ILogger<PhisicalPersonLogic> logger, IPhisicalPersonStorage phisicalPersonStorage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_logger = logger;
|
||||||
|
_phisicalPersonStorage = phisicalPersonStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PhisicalPersonViewModel> GetFullList()
|
||||||
|
{
|
||||||
|
return _phisicalPersonStorage.GetFullList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PhisicalPersonViewModel> GetFilteredList(PhisicalPersonSearchModel model)
|
||||||
|
{
|
||||||
|
return _phisicalPersonStorage.GetFilteredList(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhisicalPersonViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
return _phisicalPersonStorage.GetElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(PhisicalPersonViewModel model)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(model.Name) || string.IsNullOrWhiteSpace(model.Surname))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Имя и фамилия обязательны для заполнения.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_phisicalPersonStorage.Insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(PhisicalPersonViewModel model)
|
||||||
|
{
|
||||||
|
var element = _phisicalPersonStorage.GetElement(model.Id);
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Элемент не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_phisicalPersonStorage.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var element = _phisicalPersonStorage.GetElement(id);
|
||||||
}
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Элемент не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
public PhisicalPersonViewModel? GetPhisicalPersonById(int id)
|
_phisicalPersonStorage.Delete(id);
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PhisicalPersonViewModel> GetPhisicalPersons(PhisicalPersonSearchModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,69 @@
|
|||||||
using EmployeeManagmentContracts.BindingModels;
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
using EmployeeManagmentContracts.BusinessLogicContracts;
|
|
||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.StoragesContracts;
|
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
||||||
{
|
{
|
||||||
public class SalaryLogic : ISalaryLogic
|
public class SalaryLogic : ISalaryLogic
|
||||||
{
|
{
|
||||||
public void CreateOrUpdate(SalaryBindingModel model)
|
private readonly ILogger<SalaryLogic> _logger;
|
||||||
|
private readonly ISalaryStorage _salaryStorage;
|
||||||
|
|
||||||
|
public SalaryLogic(ILogger<SalaryLogic> logger, ISalaryStorage salaryStorage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_logger = logger;
|
||||||
|
_salaryStorage = salaryStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SalaryViewModel> GetFullList()
|
||||||
|
{
|
||||||
|
return _salaryStorage.GetFullList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SalaryViewModel> GetFilteredList(SalarySearchModel model)
|
||||||
|
{
|
||||||
|
return _salaryStorage.GetFilteredList(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SalaryViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
return _salaryStorage.GetElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(SalaryViewModel model)
|
||||||
|
{
|
||||||
|
if (model.EmployeeId == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Сотрудник обязательно должен быть указан.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_salaryStorage.Insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(SalaryViewModel model)
|
||||||
|
{
|
||||||
|
var element = _salaryStorage.GetElement(model.Id);
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Зарплата не найдена.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_salaryStorage.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var element = _salaryStorage.GetElement(id);
|
||||||
}
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Зарплата не найдена.");
|
||||||
|
}
|
||||||
|
|
||||||
public List<SalaryViewModel> GetSalaries(SalarySearchModel model)
|
_salaryStorage.Delete(id);
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SalaryViewModel? GetSalaryById(int id)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,69 @@
|
|||||||
using EmployeeManagmentContracts.BindingModels;
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
using EmployeeManagmentContracts.BusinessLogicContracts;
|
|
||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.StoragesContracts;
|
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
namespace EmployeeManagmentBusinessLogic.BusinessLogic
|
||||||
{
|
{
|
||||||
public class VacationLogic : IVacationLogic
|
public class VacationLogic : IVacationLogic
|
||||||
{
|
{
|
||||||
public void CreateOrUpdate(VacationBindingModel model)
|
private readonly ILogger<VacationLogic> _logger;
|
||||||
|
private readonly IVacationStorage _vacationStorage;
|
||||||
|
|
||||||
|
public VacationLogic(ILogger<VacationLogic> logger, IVacationStorage vacationStorage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_logger = logger;
|
||||||
|
_vacationStorage = vacationStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<VacationViewModel> GetFullList()
|
||||||
|
{
|
||||||
|
return _vacationStorage.GetFullList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<VacationViewModel> GetFilteredList(VacationSearchModel model)
|
||||||
|
{
|
||||||
|
return _vacationStorage.GetFilteredList(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VacationViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
return _vacationStorage.GetElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(VacationViewModel model)
|
||||||
|
{
|
||||||
|
if (model.EmployeeId == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Сотрудник обязательно должен быть указан.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_vacationStorage.Insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(VacationViewModel model)
|
||||||
|
{
|
||||||
|
var element = _vacationStorage.GetElement(model.Id);
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Отпуск не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_vacationStorage.Update(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var element = _vacationStorage.GetElement(id);
|
||||||
}
|
if (element == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Отпуск не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
public VacationViewModel? GetVacationById(int id)
|
_vacationStorage.Delete(id);
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<VacationViewModel> GetVacations(VacationSearchModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,22 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\EmployeeManagmentContracts\EmployeeManagmentContracts.csproj" />
|
<ProjectReference Include="..\EmployeeManagmentContracts\EmployeeManagmentContracts.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataBaseImplement\EmployeeManagmentDataBaseImplement.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -14,6 +14,6 @@ namespace EmployeeManagmentContracts.BindingModels
|
|||||||
public DateTime? EndJob { get; set; }
|
public DateTime? EndJob { get; set; }
|
||||||
public string? PartTimeJob { get; set; }
|
public string? PartTimeJob { get; set; }
|
||||||
public float Bid { get; set; }
|
public float Bid { get; set; }
|
||||||
public int PhisicalPersonId { get; set; }
|
public int PhisicalPersonsId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ namespace EmployeeManagmentContracts.BusinessLogicContracts
|
|||||||
{
|
{
|
||||||
public interface IEmployeeLogic
|
public interface IEmployeeLogic
|
||||||
{
|
{
|
||||||
List<EmployeeViewModel> GetEmployees(EmployeeSearchModel model);
|
List<EmployeeViewModel> GetFullList();
|
||||||
EmployeeViewModel? GetEmployeeById(int id);
|
List<EmployeeViewModel> GetFilteredList(EmployeeSearchModel model);
|
||||||
void CreateOrUpdate(EmployeeBindingModel model);
|
EmployeeViewModel? GetElement(int id);
|
||||||
|
void Insert(EmployeeViewModel model);
|
||||||
|
void Update(EmployeeViewModel model);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,11 @@ namespace EmployeeManagmentContracts.BusinessLogicContracts
|
|||||||
{
|
{
|
||||||
public interface IPhisicalPersonLogic
|
public interface IPhisicalPersonLogic
|
||||||
{
|
{
|
||||||
List<PhisicalPersonViewModel> GetPhisicalPersons(PhisicalPersonSearchModel model);
|
List<PhisicalPersonViewModel> GetFullList();
|
||||||
PhisicalPersonViewModel? GetPhisicalPersonById(int id);
|
List<PhisicalPersonViewModel> GetFilteredList(PhisicalPersonSearchModel model);
|
||||||
void CreateOrUpdate(PhisicalPersonBindingModel model);
|
PhisicalPersonViewModel? GetElement(int id);
|
||||||
|
void Insert(PhisicalPersonViewModel model);
|
||||||
|
void Update(PhisicalPersonViewModel model);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ namespace EmployeeManagmentContracts.BusinessLogicContracts
|
|||||||
{
|
{
|
||||||
public interface ISalaryLogic
|
public interface ISalaryLogic
|
||||||
{
|
{
|
||||||
List<SalaryViewModel> GetSalaries(SalarySearchModel model);
|
List<SalaryViewModel> GetFullList();
|
||||||
SalaryViewModel? GetSalaryById(int id);
|
List<SalaryViewModel> GetFilteredList(SalarySearchModel model);
|
||||||
void CreateOrUpdate(SalaryBindingModel model);
|
SalaryViewModel? GetElement(int id);
|
||||||
|
void Insert(SalaryViewModel model);
|
||||||
|
void Update(SalaryViewModel model);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,11 @@ namespace EmployeeManagmentContracts.BusinessLogicContracts
|
|||||||
{
|
{
|
||||||
public interface IVacationLogic
|
public interface IVacationLogic
|
||||||
{
|
{
|
||||||
List<VacationViewModel> GetVacations(VacationSearchModel model);
|
List<VacationViewModel> GetFullList();
|
||||||
VacationViewModel? GetVacationById(int id);
|
List<VacationViewModel> GetFilteredList(VacationSearchModel model);
|
||||||
void CreateOrUpdate(VacationBindingModel model);
|
VacationViewModel? GetElement(int id);
|
||||||
|
void Insert(VacationViewModel model);
|
||||||
|
void Update(VacationViewModel model);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,19 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj" />
|
<ProjectReference Include="..\EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -10,11 +10,14 @@ namespace EmployeeManagmentContracts.ViewModels
|
|||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string NameJob { get; set; } = string.Empty;
|
public string NameJob { get; set; } = string.Empty;
|
||||||
public DateTime StartJob { get; set; }
|
public DateTime? StartJob { get; set; }
|
||||||
public DateTime? EndJob { get; set; }
|
public DateTime? EndJob { get; set; }
|
||||||
public string? PartTimeJob { get; set; }
|
public string? PartTimeJob { get; set; }
|
||||||
public float Bid { get; set; }
|
public float Bid { get; set; }
|
||||||
public string PhisicalPersonName { get; set; } = string.Empty;
|
public int? PhysicalPersonsId { get; set; }
|
||||||
|
public string? PhysicalPersonName { get; set; }
|
||||||
|
// Новое свойство для отображения комбинированного текста
|
||||||
|
public string DisplayText => $"{NameJob} ({PhysicalPersonName})";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,17 @@ namespace EmployeeManagmentContracts.ViewModels
|
|||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string Surname { get; set; } = string.Empty;
|
public string Surname { get; set; } = string.Empty;
|
||||||
public string Patronomic { get; set; } = string.Empty;
|
public string Patronymic { get; set; } = string.Empty;
|
||||||
public DateTime Birthday { get; set; }
|
public DateTime Birthday { get; set; }
|
||||||
public string Gender { get; set; } = string.Empty;
|
public string Gender { get; set; } = string.Empty;
|
||||||
public string Address { get; set; } = string.Empty;
|
public string Address { get; set; } = string.Empty;
|
||||||
public string Telephone { get; set; } = string.Empty;
|
public string Telephone { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
// Вычисляемое свойство для полного имени
|
||||||
|
public string FullName => $"{Surname} {Name} {Patronymic}";
|
||||||
|
|
||||||
|
// Вычисляемое свойство для полного имени с датой рождения
|
||||||
|
public string FullNameWithBirthday => $"{Surname} {Name} {Patronymic} ({Birthday:dd.MM.yyyy})";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,16 @@ namespace EmployeeManagmentContracts.ViewModels
|
|||||||
public float? Premium { get; set; }
|
public float? Premium { get; set; }
|
||||||
public DateTime? Date { get; set; }
|
public DateTime? Date { get; set; }
|
||||||
public bool Passed { get; set; }
|
public bool Passed { get; set; }
|
||||||
public string EmployeeName { get; set; } = string.Empty;
|
|
||||||
|
public int? EmployeeId { get; set; }
|
||||||
|
public string? EmployeeName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return $"{EmployeeName} ({Date:dd.MM.yyyy})";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,17 @@ namespace EmployeeManagmentContracts.ViewModels
|
|||||||
public DateTime StartData { get; set; }
|
public DateTime StartData { get; set; }
|
||||||
public DateTime EndData { get; set; }
|
public DateTime EndData { get; set; }
|
||||||
public bool Passed { get; set; }
|
public bool Passed { get; set; }
|
||||||
public string EmployeeName { get; set; } = string.Empty;
|
public int? EmployeeId { get; set; }
|
||||||
|
public string? EmployeeName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return $"{EmployeeName} ({StartData:dd.MM.yyyy} - {EndData:dd.MM.yyyy})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
using EmployeeManagmentDataBaseImplement.Models;
|
using EmployeeManagmentDataBaseImplement.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement
|
namespace EmployeeManagmentDataBaseImplement
|
||||||
{
|
{
|
||||||
public class EmployeeManagementDbContext : DbContext
|
public class EmployeeManagementDbContext : DbContext
|
||||||
{
|
{
|
||||||
public DbSet<Employee> Employees { get; set; }
|
// DbSets для моделей
|
||||||
public DbSet<PhisicalPerson> PhisicalPersons { get; set; }
|
public virtual DbSet<Employee> Employees { get; set; }
|
||||||
public DbSet<Salary> Salaries { get; set; }
|
public virtual DbSet<PhisicalPerson> PhysicalPersons { get; set; }
|
||||||
public DbSet<Vacation> Vacations { get; set; }
|
public virtual DbSet<Salary> Salaries { get; set; }
|
||||||
|
public virtual DbSet<Vacation> Vacations { get; set; }
|
||||||
|
|
||||||
|
// Метод для настройки конфигурации
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
optionsBuilder.UseSqlServer("YourConnectionStringHere");
|
if (!optionsBuilder.IsConfigured)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseNpgsql("Host=localhost;Database=EmployeeManagementDB;Username=postgres;Password=23859");
|
||||||
|
}
|
||||||
|
base.OnConfiguring(optionsBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,24 +9,21 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.10" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\EmployeeManagmentContracts\EmployeeManagmentContracts.csproj" />
|
<ProjectReference Include="..\EmployeeManagmentContracts\EmployeeManagmentContracts.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -7,34 +7,130 @@ namespace EmployeeManagmentDataBaseImplement.Implements
|
|||||||
{
|
{
|
||||||
public class EmployeeStorage : IEmployeeStorage
|
public class EmployeeStorage : IEmployeeStorage
|
||||||
{
|
{
|
||||||
public void Delete(int id)
|
// Получить полный список сотрудников
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public EmployeeViewModel? GetElement(int id)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EmployeeViewModel> GetFilteredList(EmployeeSearchModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EmployeeViewModel> GetFullList()
|
public List<EmployeeViewModel> GetFullList()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
return context.Employees
|
||||||
|
.Select(e => new EmployeeViewModel
|
||||||
|
{
|
||||||
|
Id = e.Id,
|
||||||
|
NameJob = e.NameJob,
|
||||||
|
StartJob = e.StartJob,
|
||||||
|
EndJob = e.EndJob,
|
||||||
|
PartTimeJob = e.PartTimeJob,
|
||||||
|
Bid = e.Bid,
|
||||||
|
PhysicalPersonsId = e.PhisicalPersonsId,
|
||||||
|
PhysicalPersonName = $"{e.PhisicalPerson.Surname} {e.PhisicalPerson.Name} {e.PhisicalPerson.Patronymic} "
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Получить отфильтрованный список сотрудников
|
||||||
|
public List<EmployeeViewModel> GetFilteredList(EmployeeSearchModel model)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
if (model == null) return new List<EmployeeViewModel>();
|
||||||
|
|
||||||
|
return context.Employees
|
||||||
|
.Where(e =>
|
||||||
|
(string.IsNullOrEmpty(model.NameJob) || e.NameJob.Contains(model.NameJob)) &&
|
||||||
|
(!model.StartDateFrom.HasValue || e.StartJob >= model.StartDateFrom) &&
|
||||||
|
(!model.StartDateTo.HasValue || e.EndJob <= model.StartDateTo))
|
||||||
|
.Select(e => new EmployeeViewModel
|
||||||
|
{
|
||||||
|
Id = e.Id,
|
||||||
|
NameJob = e.NameJob,
|
||||||
|
StartJob = e.StartJob,
|
||||||
|
EndJob = e.EndJob,
|
||||||
|
PartTimeJob = e.PartTimeJob,
|
||||||
|
Bid = e.Bid,
|
||||||
|
PhysicalPersonsId = e.PhisicalPersonsId,
|
||||||
|
PhysicalPersonName = $"{e.PhisicalPerson.Surname} {e.PhisicalPerson.Name} {e.PhisicalPerson.Patronymic}",
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить сотрудника по ID
|
||||||
|
public EmployeeViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Employees
|
||||||
|
.FirstOrDefault(e => e.Id == id);
|
||||||
|
|
||||||
|
return entity == null ? null : new EmployeeViewModel
|
||||||
|
{
|
||||||
|
Id = entity.Id,
|
||||||
|
NameJob = entity.NameJob,
|
||||||
|
StartJob = entity.StartJob,
|
||||||
|
EndJob = entity.EndJob,
|
||||||
|
PartTimeJob = entity.PartTimeJob,
|
||||||
|
Bid = entity.Bid,
|
||||||
|
PhysicalPersonsId = entity.PhisicalPersonsId,
|
||||||
|
PhysicalPersonName = entity.PhisicalPerson != null
|
||||||
|
? $"{entity.PhisicalPerson.Surname} {entity.PhisicalPerson.Name} {entity.PhisicalPerson.Patronymic} "
|
||||||
|
: "Не указано" // Обработка отсутствующего физического лица
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Добавить нового сотрудника
|
||||||
public void Insert(EmployeeViewModel model)
|
public void Insert(EmployeeViewModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var newEmployee = new Employee
|
||||||
|
{
|
||||||
|
NameJob = model.NameJob,
|
||||||
|
StartJob = model.StartJob,
|
||||||
|
EndJob = model.EndJob,
|
||||||
|
PartTimeJob = model.PartTimeJob,
|
||||||
|
Bid = model.Bid,
|
||||||
|
PhisicalPersonsId = model.PhysicalPersonsId
|
||||||
|
};
|
||||||
|
|
||||||
|
context.Employees.Add(newEmployee);
|
||||||
|
context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Обновить сотрудника
|
||||||
public void Update(EmployeeViewModel model)
|
public void Update(EmployeeViewModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Employees.FirstOrDefault(e => e.Id == model.Id);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
entity.NameJob = model.NameJob;
|
||||||
|
entity.StartJob = model.StartJob;
|
||||||
|
entity.EndJob = model.EndJob;
|
||||||
|
entity.PartTimeJob = model.PartTimeJob;
|
||||||
|
entity.Bid = model.Bid;
|
||||||
|
entity.PhisicalPersonsId = model.PhysicalPersonsId;
|
||||||
|
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Удалить сотрудника
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Employees.FirstOrDefault(e => e.Id == id);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
// Убедимся, что связи остаются нетронутыми
|
||||||
|
entity.PhisicalPersonsId = null; // Удаляем связь, если это нужно
|
||||||
|
context.Employees.Remove(entity);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.StoragesContracts;
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -12,34 +13,117 @@ namespace EmployeeManagmentDataBaseImplement.Implements
|
|||||||
{
|
{
|
||||||
public class PhisicalPersonStorage : IPhisicalPersonStorage
|
public class PhisicalPersonStorage : IPhisicalPersonStorage
|
||||||
{
|
{
|
||||||
public void Delete(int id)
|
// Метод для получения полного списка
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PhisicalPersonViewModel? GetElement(int id)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PhisicalPersonViewModel> GetFilteredList(PhisicalPersonSearchModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PhisicalPersonViewModel> GetFullList()
|
public List<PhisicalPersonViewModel> GetFullList()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
return context.PhysicalPersons
|
||||||
|
.Select(p => new PhisicalPersonViewModel
|
||||||
|
{
|
||||||
|
Id = p.Id,
|
||||||
|
Name = p.Name,
|
||||||
|
Surname = p.Surname,
|
||||||
|
Patronymic = p.Patronymic,
|
||||||
|
Birthday = p.Birthday,
|
||||||
|
Gender = p.Gender,
|
||||||
|
Address = p.Address,
|
||||||
|
Telephone = p.Telephone
|
||||||
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Метод для получения отфильтрованного списка
|
||||||
|
public List<PhisicalPersonViewModel> GetFilteredList(PhisicalPersonSearchModel model)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
if (model == null) return new List<PhisicalPersonViewModel>();
|
||||||
|
|
||||||
|
return context.PhysicalPersons
|
||||||
|
.Where(p => p.Surname.Contains(model.Surname ?? string.Empty))
|
||||||
|
.Select(p => new PhisicalPersonViewModel
|
||||||
|
{
|
||||||
|
Id = p.Id,
|
||||||
|
Name = p.Name,
|
||||||
|
Surname = p.Surname,
|
||||||
|
Patronymic = p.Patronymic,
|
||||||
|
Birthday = p.Birthday,
|
||||||
|
Gender = p.Gender,
|
||||||
|
Address = p.Address,
|
||||||
|
Telephone = p.Telephone
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для получения одного элемента по ID
|
||||||
|
public PhisicalPersonViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.PhysicalPersons.FirstOrDefault(p => p.Id == id);
|
||||||
|
return entity == null ? null : new PhisicalPersonViewModel
|
||||||
|
{
|
||||||
|
Id = entity.Id,
|
||||||
|
Name = entity.Name,
|
||||||
|
Surname = entity.Surname,
|
||||||
|
Patronymic = entity.Patronymic,
|
||||||
|
Birthday = entity.Birthday,
|
||||||
|
Gender = entity.Gender,
|
||||||
|
Address = entity.Address,
|
||||||
|
Telephone = entity.Telephone
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для добавления нового физического лица
|
||||||
public void Insert(PhisicalPersonViewModel model)
|
public void Insert(PhisicalPersonViewModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var newPerson = new PhisicalPerson
|
||||||
|
{
|
||||||
|
Name = model.Name,
|
||||||
|
Surname = model.Surname,
|
||||||
|
Patronymic = model.Patronymic,
|
||||||
|
Birthday = model.Birthday,
|
||||||
|
Gender = model.Gender,
|
||||||
|
Address = model.Address,
|
||||||
|
Telephone = model.Telephone
|
||||||
|
};
|
||||||
|
|
||||||
|
context.PhysicalPersons.Add(newPerson);
|
||||||
|
context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Метод для обновления физического лица
|
||||||
public void Update(PhisicalPersonViewModel model)
|
public void Update(PhisicalPersonViewModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.PhysicalPersons.FirstOrDefault(p => p.Id == model.Id);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
entity.Name = model.Name;
|
||||||
|
entity.Surname = model.Surname;
|
||||||
|
entity.Patronymic = model.Patronymic;
|
||||||
|
entity.Birthday = model.Birthday;
|
||||||
|
entity.Gender = model.Gender;
|
||||||
|
entity.Address = model.Address;
|
||||||
|
entity.Telephone = model.Telephone;
|
||||||
|
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для удаления физического лица
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.PhysicalPersons.FirstOrDefault(p => p.Id == id);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
context.PhysicalPersons.Remove(entity);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,125 @@
|
|||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.StoragesContracts;
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement.Implements
|
namespace EmployeeManagmentDataBaseImplement.Implements
|
||||||
{
|
{
|
||||||
public class SalaryStorage : ISalaryStorage
|
public class SalaryStorage : ISalaryStorage
|
||||||
{
|
{
|
||||||
public void Delete(int id)
|
public List<SalaryViewModel> GetFullList()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
}
|
|
||||||
|
|
||||||
public SalaryViewModel? GetElement(int id)
|
return context.Salaries
|
||||||
{
|
.Select(s => new SalaryViewModel
|
||||||
throw new NotImplementedException();
|
{
|
||||||
|
Id = s.Id,
|
||||||
|
CountHours = s.CountHours,
|
||||||
|
PriceHour = s.PriceHour,
|
||||||
|
Premium = s.Premium,
|
||||||
|
Date = s.Data,
|
||||||
|
Passed = s.Passed,
|
||||||
|
EmployeeId = s.EmployeesId,
|
||||||
|
EmployeeName = s.Employee != null ? $"{s.Employee.PhisicalPerson.Surname} {s.Employee.PhisicalPerson.Name} {s.Employee.PhisicalPerson.Patronymic} ({s.Employee.NameJob})" : "Не указано"
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SalaryViewModel> GetFilteredList(SalarySearchModel model)
|
public List<SalaryViewModel> GetFilteredList(SalarySearchModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
if (model == null) return new List<SalaryViewModel>();
|
||||||
|
|
||||||
|
return context.Salaries
|
||||||
|
.Where(s =>
|
||||||
|
(!model.Date.HasValue || s.Data >= model.Date))
|
||||||
|
.Select(s => new SalaryViewModel
|
||||||
|
{
|
||||||
|
Id = s.Id,
|
||||||
|
CountHours = s.CountHours,
|
||||||
|
PriceHour = s.PriceHour,
|
||||||
|
Premium = s.Premium,
|
||||||
|
Date = s.Data,
|
||||||
|
Passed = s.Passed,
|
||||||
|
EmployeeId = s.EmployeesId,
|
||||||
|
EmployeeName = s.Employee != null ? $"{s.Employee.PhisicalPerson.Surname} {s.Employee.PhisicalPerson.Name} {s.Employee.PhisicalPerson.Patronymic} ({s.Employee.NameJob})" : "Не указано"
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SalaryViewModel> GetFullList()
|
public SalaryViewModel? GetElement(int id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Salaries
|
||||||
|
.FirstOrDefault(s => s.Id == id);
|
||||||
|
|
||||||
|
return entity == null ? null : new SalaryViewModel
|
||||||
|
{
|
||||||
|
Id = entity.Id,
|
||||||
|
CountHours = entity.CountHours,
|
||||||
|
PriceHour = entity.PriceHour,
|
||||||
|
Premium = entity.Premium,
|
||||||
|
Date = entity.Data,
|
||||||
|
Passed = entity.Passed,
|
||||||
|
EmployeeId = entity.EmployeesId,
|
||||||
|
EmployeeName = entity.Employee != null ? $"{entity.Employee.PhisicalPerson.Surname} {entity.Employee.PhisicalPerson.Name} {entity.Employee.PhisicalPerson.Patronymic} ({entity.Employee.NameJob})" : "Не указано"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Insert(SalaryViewModel model)
|
public void Insert(SalaryViewModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var newSalary = new Salary
|
||||||
|
{
|
||||||
|
CountHours = model.CountHours,
|
||||||
|
PriceHour = model.PriceHour,
|
||||||
|
Premium = model.Premium,
|
||||||
|
Data = model.Date,
|
||||||
|
Passed = model.Passed,
|
||||||
|
EmployeesId = model.EmployeeId
|
||||||
|
};
|
||||||
|
|
||||||
|
context.Salaries.Add(newSalary);
|
||||||
|
context.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(SalaryViewModel model)
|
public void Update(SalaryViewModel model)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Salaries.FirstOrDefault(s => s.Id == model.Id);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
entity.CountHours = model.CountHours;
|
||||||
|
entity.PriceHour = model.PriceHour;
|
||||||
|
entity.Premium = model.Premium;
|
||||||
|
entity.Data = model.Date;
|
||||||
|
entity.Passed = model.Passed;
|
||||||
|
entity.EmployeesId = model.EmployeeId;
|
||||||
|
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Salaries.FirstOrDefault(s => s.Id == id);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
context.Salaries.Remove(entity);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,117 @@
|
|||||||
using EmployeeManagmentContracts.SearchModels;
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
using EmployeeManagmentContracts.StoragesContracts;
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
using EmployeeManagmentContracts.ViewModels;
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement.Implements
|
namespace EmployeeManagmentDataBaseImplement.Implements
|
||||||
{
|
{
|
||||||
public class VacationStorage : ISalaryStorage
|
public class VacationStorage : IVacationStorage
|
||||||
{
|
{
|
||||||
|
public List<VacationViewModel> GetFullList()
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
return context.Vacations
|
||||||
|
.Select(v => new VacationViewModel
|
||||||
|
{
|
||||||
|
Id = v.Id,
|
||||||
|
StartData = v.StartData,
|
||||||
|
EndData = v.EndData,
|
||||||
|
Passed = v.Passed,
|
||||||
|
EmployeeId = v.EmployeesId,
|
||||||
|
EmployeeName = v.Employee != null ? $"{v.Employee.PhisicalPerson.Surname} {v.Employee.PhisicalPerson.Name} {v.Employee.PhisicalPerson.Patronymic} ({v.Employee.NameJob})" : "Не указано"
|
||||||
|
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<VacationViewModel> GetFilteredList(VacationSearchModel model)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
if (model == null) return new List<VacationViewModel>();
|
||||||
|
|
||||||
|
return context.Vacations
|
||||||
|
.Where(v =>
|
||||||
|
(!model.StartData.HasValue || v.StartData >= model.StartData) &&
|
||||||
|
(!model.EndData.HasValue || v.EndData <= model.EndData))
|
||||||
|
.Select(v => new VacationViewModel
|
||||||
|
{
|
||||||
|
Id = v.Id,
|
||||||
|
StartData = v.StartData,
|
||||||
|
EndData = v.EndData,
|
||||||
|
Passed = v.Passed,
|
||||||
|
EmployeeId = v.EmployeesId,
|
||||||
|
EmployeeName = v.Employee != null ? $"{v.Employee.PhisicalPerson.Surname} {v.Employee.PhisicalPerson.Name} {v.Employee.PhisicalPerson.Patronymic} ({v.Employee.NameJob})" : "Не указано"
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VacationViewModel? GetElement(int id)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Vacations
|
||||||
|
.FirstOrDefault(v => v.Id == id);
|
||||||
|
|
||||||
|
return entity == null ? null : new VacationViewModel
|
||||||
|
{
|
||||||
|
Id = entity.Id,
|
||||||
|
StartData = entity.StartData,
|
||||||
|
EndData = entity.EndData,
|
||||||
|
Passed = entity.Passed,
|
||||||
|
EmployeeId = entity.EmployeesId,
|
||||||
|
EmployeeName = entity.Employee != null ? $"{entity.Employee.PhisicalPerson.Surname} {entity.Employee.PhisicalPerson.Name} {entity.Employee.PhisicalPerson.Patronymic} ({entity.Employee.NameJob})" : "Не указано"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(VacationViewModel model)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var newVacation = new Vacation
|
||||||
|
{
|
||||||
|
StartData = model.StartData,
|
||||||
|
EndData = model.EndData,
|
||||||
|
Passed = model.Passed,
|
||||||
|
EmployeesId = model.EmployeeId
|
||||||
|
};
|
||||||
|
|
||||||
|
context.Vacations.Add(newVacation);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(VacationViewModel model)
|
||||||
|
{
|
||||||
|
using var context = new EmployeeManagementDbContext();
|
||||||
|
|
||||||
|
var entity = context.Vacations.FirstOrDefault(v => v.Id == model.Id);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
entity.StartData = model.StartData;
|
||||||
|
entity.EndData = model.EndData;
|
||||||
|
entity.Passed = model.Passed;
|
||||||
|
entity.EmployeesId = model.EmployeeId;
|
||||||
|
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var context = new EmployeeManagementDbContext();
|
||||||
}
|
|
||||||
|
|
||||||
public SalaryViewModel? GetElement(int id)
|
var entity = context.Vacations.FirstOrDefault(v => v.Id == id);
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SalaryViewModel> GetFilteredList(SalarySearchModel model)
|
if (entity != null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
context.Vacations.Remove(entity);
|
||||||
}
|
context.SaveChanges();
|
||||||
|
}
|
||||||
public List<SalaryViewModel> GetFullList()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Insert(SalaryViewModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(SalaryViewModel model)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
202
EmployeeManagmentDataBaseImplement/Migrations/20241126175607_Init.Designer.cs
generated
Normal file
202
EmployeeManagmentDataBaseImplement/Migrations/20241126175607_Init.Designer.cs
generated
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using EmployeeManagmentDataBaseImplement;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataBaseImplement.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(EmployeeManagementDbContext))]
|
||||||
|
[Migration("20241126175607_Init")]
|
||||||
|
partial class Init
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.10")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Employee", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<float>("Bid")
|
||||||
|
.HasColumnType("real");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("EndJob")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("NameJob")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("PartTimeJob")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int?>("PhisicalPersonsId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("StartJob")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PhisicalPersonsId");
|
||||||
|
|
||||||
|
b.ToTable("Employees");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.PhisicalPerson", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Address")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Birthday")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Gender")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Patronymic")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Surname")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Telephone")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PhysicalPersons");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Salary", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CountHours")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Data")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int?>("EmployeesId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<bool>("Passed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<float?>("Premium")
|
||||||
|
.HasColumnType("real");
|
||||||
|
|
||||||
|
b.Property<float>("PriceHour")
|
||||||
|
.HasColumnType("real");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("EmployeesId");
|
||||||
|
|
||||||
|
b.ToTable("Salaries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Vacation", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int?>("EmployeesId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("EndData")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<bool>("Passed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTime>("StartData")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("EmployeesId");
|
||||||
|
|
||||||
|
b.ToTable("Vacations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Employee", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("EmployeeManagmentDataBaseImplement.Models.PhisicalPerson", "PhisicalPerson")
|
||||||
|
.WithMany("Employees")
|
||||||
|
.HasForeignKey("PhisicalPersonsId");
|
||||||
|
|
||||||
|
b.Navigation("PhisicalPerson");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Salary", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("EmployeeManagmentDataBaseImplement.Models.Employee", "Employee")
|
||||||
|
.WithMany("Salaries")
|
||||||
|
.HasForeignKey("EmployeesId");
|
||||||
|
|
||||||
|
b.Navigation("Employee");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Vacation", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("EmployeeManagmentDataBaseImplement.Models.Employee", "Employee")
|
||||||
|
.WithMany("Vacations")
|
||||||
|
.HasForeignKey("EmployeesId");
|
||||||
|
|
||||||
|
b.Navigation("Employee");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Employee", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Salaries");
|
||||||
|
|
||||||
|
b.Navigation("Vacations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.PhisicalPerson", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Employees");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataBaseImplement.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Init : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "PhysicalPersons",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
Name = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Surname = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Patronymic = table.Column<string>(type: "text", nullable: true),
|
||||||
|
Birthday = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||||
|
Gender = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Address = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Telephone = table.Column<string>(type: "text", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_PhysicalPersons", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Employees",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
NameJob = table.Column<string>(type: "text", nullable: false),
|
||||||
|
StartJob = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
EndJob = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
PartTimeJob = table.Column<string>(type: "text", nullable: true),
|
||||||
|
Bid = table.Column<float>(type: "real", nullable: false),
|
||||||
|
PhisicalPersonsId = table.Column<int>(type: "integer", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Employees", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Employees_PhysicalPersons_PhisicalPersonsId",
|
||||||
|
column: x => x.PhisicalPersonsId,
|
||||||
|
principalTable: "PhysicalPersons",
|
||||||
|
principalColumn: "Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Salaries",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
CountHours = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
PriceHour = table.Column<float>(type: "real", nullable: false),
|
||||||
|
Premium = table.Column<float>(type: "real", nullable: true),
|
||||||
|
Data = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
Passed = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
EmployeesId = table.Column<int>(type: "integer", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Salaries", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Salaries_Employees_EmployeesId",
|
||||||
|
column: x => x.EmployeesId,
|
||||||
|
principalTable: "Employees",
|
||||||
|
principalColumn: "Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Vacations",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
StartData = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||||
|
EndData = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||||
|
Passed = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
EmployeesId = table.Column<int>(type: "integer", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Vacations", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Vacations_Employees_EmployeesId",
|
||||||
|
column: x => x.EmployeesId,
|
||||||
|
principalTable: "Employees",
|
||||||
|
principalColumn: "Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Employees_PhisicalPersonsId",
|
||||||
|
table: "Employees",
|
||||||
|
column: "PhisicalPersonsId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Salaries_EmployeesId",
|
||||||
|
table: "Salaries",
|
||||||
|
column: "EmployeesId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Vacations_EmployeesId",
|
||||||
|
table: "Vacations",
|
||||||
|
column: "EmployeesId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Salaries");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Vacations");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Employees");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "PhysicalPersons");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using EmployeeManagmentDataBaseImplement;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataBaseImplement.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(EmployeeManagementDbContext))]
|
||||||
|
partial class EmployeeManagementDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.10")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Employee", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<float>("Bid")
|
||||||
|
.HasColumnType("real");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("EndJob")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("NameJob")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("PartTimeJob")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int?>("PhisicalPersonsId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("StartJob")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PhisicalPersonsId");
|
||||||
|
|
||||||
|
b.ToTable("Employees");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.PhisicalPerson", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Address")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Birthday")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Gender")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Patronymic")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Surname")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Telephone")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PhysicalPersons");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Salary", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int>("CountHours")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Data")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int?>("EmployeesId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<bool>("Passed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<float?>("Premium")
|
||||||
|
.HasColumnType("real");
|
||||||
|
|
||||||
|
b.Property<float>("PriceHour")
|
||||||
|
.HasColumnType("real");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("EmployeesId");
|
||||||
|
|
||||||
|
b.ToTable("Salaries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Vacation", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<int?>("EmployeesId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("EndData")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<bool>("Passed")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTime>("StartData")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("EmployeesId");
|
||||||
|
|
||||||
|
b.ToTable("Vacations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Employee", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("EmployeeManagmentDataBaseImplement.Models.PhisicalPerson", "PhisicalPerson")
|
||||||
|
.WithMany("Employees")
|
||||||
|
.HasForeignKey("PhisicalPersonsId");
|
||||||
|
|
||||||
|
b.Navigation("PhisicalPerson");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Salary", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("EmployeeManagmentDataBaseImplement.Models.Employee", "Employee")
|
||||||
|
.WithMany("Salaries")
|
||||||
|
.HasForeignKey("EmployeesId");
|
||||||
|
|
||||||
|
b.Navigation("Employee");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Vacation", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("EmployeeManagmentDataBaseImplement.Models.Employee", "Employee")
|
||||||
|
.WithMany("Vacations")
|
||||||
|
.HasForeignKey("EmployeesId");
|
||||||
|
|
||||||
|
b.Navigation("Employee");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.Employee", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Salaries");
|
||||||
|
|
||||||
|
b.Navigation("Vacations");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("EmployeeManagmentDataBaseImplement.Models.PhisicalPerson", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Employees");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +1,29 @@
|
|||||||
using System;
|
using EmployeeManagmentDataModels.Models;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EmployeeManagmentDataModels.Models;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement.Models
|
namespace EmployeeManagmentDataBaseImplement.Models
|
||||||
{
|
{
|
||||||
public class Employee
|
public class Employee : IEmployee
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string Name { get; set; } = string.Empty;
|
public string NameJob { get; set; } = string.Empty;
|
||||||
|
|
||||||
public DateTime? StartJob { get; set; }
|
public DateTime? StartJob { get; set; }
|
||||||
public DateTime? EndJob { get; set; }
|
public DateTime? EndJob { get; set; }
|
||||||
|
|
||||||
public string? PartTimeJob { get; set; }
|
public string? PartTimeJob { get; set; }
|
||||||
|
|
||||||
public float Bid { get; set; }
|
public float Bid { get; set; }
|
||||||
|
|
||||||
[ForeignKey("PhysicalPerson")]
|
[ForeignKey("PhisicalPerson")]
|
||||||
public int PhysicalPersonsId { get; set; }
|
public int? PhisicalPersonsId { get; set; }
|
||||||
public PhysicalPerson? PhysicalPerson { get; set; }
|
public PhisicalPerson? PhisicalPerson { get; set; }
|
||||||
|
|
||||||
|
public List<Salary> Salaries { get; set; } = new();
|
||||||
|
public List<Vacation> Vacations { get; set; } = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using EmployeeManagmentDataModels.Models;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -7,21 +8,27 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement.Models
|
namespace EmployeeManagmentDataBaseImplement.Models
|
||||||
{
|
{
|
||||||
public class PhisicalPerson
|
public class PhisicalPerson : IPhisicalPerson
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string Surname { get; set; } = string.Empty;
|
public string Surname { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string? Patronymic { get; set; }
|
public string? Patronymic { get; set; }
|
||||||
|
[Required]
|
||||||
public DateTime Birthday { get; set; }
|
public DateTime Birthday { get; set; }
|
||||||
|
[Required]
|
||||||
public string Gender { get; set; } = string.Empty;
|
public string Gender { get; set; } = string.Empty;
|
||||||
|
[Required]
|
||||||
public string Address { get; set; } = string.Empty;
|
public string Address { get; set; } = string.Empty;
|
||||||
|
[Required]
|
||||||
public string Telephone { get; set; } = string.Empty;
|
public string Telephone { get; set; } = string.Empty;
|
||||||
|
|
||||||
// Связь с сотрудниками
|
public List<Employee> Employees { get; set; } = new();
|
||||||
public List<Employee>? Employees { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,27 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using EmployeeManagmentDataModels.Models;
|
||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement.Models
|
namespace EmployeeManagmentDataBaseImplement.Models
|
||||||
{
|
{
|
||||||
public class Salary
|
public class Salary : ISalary
|
||||||
{
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int CountHours { get; set; }
|
||||||
|
public float PriceHour { get; set; }
|
||||||
|
public float? Premium { get; set; }
|
||||||
|
public DateTime? Data { get; set; }
|
||||||
|
public bool Passed { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("Employee")]
|
||||||
|
public int? EmployeesId { get; set; }
|
||||||
|
public Employee? Employee { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,25 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using EmployeeManagmentDataModels.Models;
|
||||||
|
|
||||||
namespace EmployeeManagmentDataBaseImplement.Models
|
namespace EmployeeManagmentDataBaseImplement.Models
|
||||||
{
|
{
|
||||||
public class Vacation
|
public class Vacation : IVacation
|
||||||
{
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public DateTime StartData { get; set; }
|
||||||
|
public DateTime EndData { get; set; }
|
||||||
|
public bool Passed { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("Employee")]
|
||||||
|
public int? EmployeesId { get; set; }
|
||||||
|
public Employee? Employee { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
version: '3.9'
|
version: '3.9'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
sqlserver-db:
|
mysql:
|
||||||
image: mcr.microsoft.com/mssql/server:2022-latest
|
image: mysql:8.0
|
||||||
container_name: sqlserver-db
|
container_name: employee_db
|
||||||
environment:
|
|
||||||
- ACCEPT_EULA=Y
|
|
||||||
- SA_PASSWORD=YourStrong@Password123
|
|
||||||
- MSSQL_PID=Express
|
|
||||||
ports:
|
|
||||||
- "1433:1433"
|
|
||||||
volumes:
|
|
||||||
- sql_data:/var/opt/mssql
|
|
||||||
restart: always
|
restart: always
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: SuperSecretPasswork2003
|
||||||
|
MYSQL_DATABASE: EmployeeDB
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- employee_network
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
sql_data:
|
mysql_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
employee_network:
|
||||||
|
driver: bridge
|
@ -5,5 +5,21 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
|
<PackageReference Include="PresentationFramework" Version="4.6.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Enums
|
||||||
|
{
|
||||||
|
public class BooleanToSalaryConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (value is bool booleanValue)
|
||||||
|
{
|
||||||
|
return booleanValue ? "Заплачено" : "Не заплачено";
|
||||||
|
}
|
||||||
|
return "Неизвестно";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Обратное преобразование не поддерживается.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Enums
|
||||||
|
{
|
||||||
|
public class BooleanToVacationConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (value is bool booleanValue)
|
||||||
|
{
|
||||||
|
return booleanValue ? "Завершен" : "Не завершено";
|
||||||
|
}
|
||||||
|
return "Неизвестно";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Обратное преобразование не поддерживается.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
EmployeeManagmentDataModels/Enums/GenderType.cs
Normal file
14
EmployeeManagmentDataModels/Enums/GenderType.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Enums
|
||||||
|
{
|
||||||
|
public enum GenderType
|
||||||
|
{
|
||||||
|
Мужчина,
|
||||||
|
Женщина
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
using EmployeeManagmentDataModels.Enums;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataModels.Models
|
|
||||||
{
|
|
||||||
public class Employee
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string NameJob { get; set; } = string.Empty;
|
|
||||||
public DateTime StartJob { get; set; }
|
|
||||||
public DateTime? EndJob { get; set; }
|
|
||||||
public JobType PartTimeJob { get; set; }
|
|
||||||
public decimal Bid { get; set; } // Ставка
|
|
||||||
public int PhysicalPersonId { get; set; }
|
|
||||||
|
|
||||||
// Связь с физическим лицом
|
|
||||||
public PhysicalPerson? PhysicalPerson { get; set; }
|
|
||||||
public List<Salary>? Salaries { get; set; }
|
|
||||||
public List<Vacation>? Vacations { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
20
EmployeeManagmentDataModels/Models/IEmployee.cs
Normal file
20
EmployeeManagmentDataModels/Models/IEmployee.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using EmployeeManagmentDataModels.Enums;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Models
|
||||||
|
{
|
||||||
|
public interface IEmployee
|
||||||
|
{
|
||||||
|
int Id { get; set; }
|
||||||
|
string NameJob { get; set; }
|
||||||
|
DateTime? StartJob { get; set; }
|
||||||
|
DateTime? EndJob { get; set; }
|
||||||
|
string? PartTimeJob { get; set; }
|
||||||
|
float Bid { get; set; }
|
||||||
|
int? PhisicalPersonsId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
20
EmployeeManagmentDataModels/Models/IPhisicalPerson.cs
Normal file
20
EmployeeManagmentDataModels/Models/IPhisicalPerson.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Models
|
||||||
|
{
|
||||||
|
public interface IPhisicalPerson
|
||||||
|
{
|
||||||
|
int Id { get; set; }
|
||||||
|
string Name { get; set; }
|
||||||
|
string Surname { get; set; }
|
||||||
|
string? Patronymic { get; set; }
|
||||||
|
DateTime Birthday { get; set; }
|
||||||
|
string Gender { get; set; }
|
||||||
|
string Address { get; set; }
|
||||||
|
string Telephone { get; set; }
|
||||||
|
}
|
||||||
|
}
|
19
EmployeeManagmentDataModels/Models/ISalary.cs
Normal file
19
EmployeeManagmentDataModels/Models/ISalary.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Models
|
||||||
|
{
|
||||||
|
public interface ISalary
|
||||||
|
{
|
||||||
|
int Id { get; set; }
|
||||||
|
int CountHours { get; set; }
|
||||||
|
float PriceHour { get; set; }
|
||||||
|
float? Premium { get; set; }
|
||||||
|
DateTime? Data { get; set; }
|
||||||
|
bool Passed { get; set; }
|
||||||
|
int? EmployeesId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
18
EmployeeManagmentDataModels/Models/IVacation.cs
Normal file
18
EmployeeManagmentDataModels/Models/IVacation.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using EmployeeManagmentDataModels.Enums;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentDataModels.Models
|
||||||
|
{
|
||||||
|
public interface IVacation
|
||||||
|
{
|
||||||
|
int Id { get; set; }
|
||||||
|
DateTime StartData { get; set; }
|
||||||
|
DateTime EndData { get; set; }
|
||||||
|
bool Passed { get; set; }
|
||||||
|
int? EmployeesId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataModels.Models
|
|
||||||
{
|
|
||||||
public class PhysicalPerson
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Name { get; set; } = string.Empty;
|
|
||||||
public DateTime BirthDate { get; set; }
|
|
||||||
public string Address { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
// Связь с сотрудниками
|
|
||||||
public List<Employee>? Employees { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataModels.Models
|
|
||||||
{
|
|
||||||
public class Salary
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int CountHours { get; set; }
|
|
||||||
public decimal PriceHour { get; set; }
|
|
||||||
public decimal Premium { get; set; }
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
public bool Passed { get; set; }
|
|
||||||
public int EmployeeId { get; set; }
|
|
||||||
|
|
||||||
// Связь с сотрудником
|
|
||||||
public Employee? Employee { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
using EmployeeManagmentDataModels.Enums;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentDataModels.Models
|
|
||||||
{
|
|
||||||
public class Vacation
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public DateTime StartData { get; set; }
|
|
||||||
public DateTime EndData { get; set; }
|
|
||||||
public VacationStatus Passed { get; set; }
|
|
||||||
public int EmployeeId { get; set; }
|
|
||||||
|
|
||||||
// Связь с сотрудником
|
|
||||||
public Employee? Employee { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
34
EmployeeManagmentTests/EmployeeManagmentTests.csproj
Normal file
34
EmployeeManagmentTests/EmployeeManagmentTests.csproj
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Appium.WebDriver" Version="6.0.1" />
|
||||||
|
<PackageReference Include="FlaUI.Core" Version="4.0.0" />
|
||||||
|
<PackageReference Include="FlaUI.UIA3" Version="4.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||||
|
<PackageReference Include="Microsoft.TestPlatform" Version="17.12.0" />
|
||||||
|
<PackageReference Include="Moq" Version="4.20.72" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="3.6.3" />
|
||||||
|
<PackageReference Include="xunit" Version="2.9.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentBusinessLogic\EmployeeManagmentBusinessLogic.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentContracts\EmployeeManagmentContracts.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataBaseImplement\EmployeeManagmentDataBaseImplement.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentView\EmployeeManagmentView.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
191
EmployeeManagmentTests/UI/EmployeeWindowTests.cs
Normal file
191
EmployeeManagmentTests/UI/EmployeeWindowTests.cs
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
using EmployeeManagmentView.PhysicalPerson;
|
||||||
|
using FlaUI.Core;
|
||||||
|
using FlaUI.Core.AutomationElements;
|
||||||
|
using FlaUI.UIA3;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.UI
|
||||||
|
{
|
||||||
|
[Collection("Sequential")]
|
||||||
|
public class EmployeeWindowTests
|
||||||
|
{
|
||||||
|
private readonly Application _application;
|
||||||
|
private readonly AutomationBase _automation;
|
||||||
|
|
||||||
|
public EmployeeWindowTests()
|
||||||
|
{
|
||||||
|
_automation = new UIA3Automation();
|
||||||
|
_application = Application.Launch("C:\\Users\\kashi\\Desktop\\Univer\\7\\КПО\\Project\\EmployeeManagmentView\\bin\\Debug\\net8.0-windows\\EmployeeManagmentView.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenAddEmployeeManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var employeeButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var employeeManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Добавление сотрудника");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var employeeAddWindow = WaitForWindow("Добавление сотрудника");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Добавление сотрудника");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
employeeManagementWindow?.Close();
|
||||||
|
employeeAddWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenDeleteEmployeeManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var employeeButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var employeeManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Удаление сотрудников");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var employeeAddWindow = WaitForWindow("Удаление сотрудников");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Удаление сотрудников");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
employeeManagementWindow?.Close();
|
||||||
|
employeeAddWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenEditEmployeeManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var employeeButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var employeeManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Редактирование сотрудника");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var employeeAddWindow = WaitForWindow("Редактирование сотрудника");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Редактирование сотрудника");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
employeeManagementWindow?.Close();
|
||||||
|
employeeAddWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenViewEmployeeManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var employeeButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var employeeManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var employeeAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
employeeManagementWindow?.Close();
|
||||||
|
employeeAddWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private Window WaitForWindow(string windowTitle, int timeout = 10000) // Увеличен таймаут
|
||||||
|
{
|
||||||
|
var startTime = DateTime.Now;
|
||||||
|
while ((DateTime.Now - startTime).TotalMilliseconds < timeout)
|
||||||
|
{
|
||||||
|
var window = _application.GetAllTopLevelWindows(_automation)
|
||||||
|
.FirstOrDefault(w => w.Title.Contains(windowTitle));
|
||||||
|
if (window != null && window.IsEnabled)
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
Thread.Sleep(200); // Увеличена пауза между попытками
|
||||||
|
}
|
||||||
|
return null; // Если окно не найдено в пределах тайм-аута
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_application.Close();
|
||||||
|
_automation.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
EmployeeManagmentTests/UI/MainWindowTests.cs
Normal file
98
EmployeeManagmentTests/UI/MainWindowTests.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
using FlaUI.Core;
|
||||||
|
using FlaUI.Core.AutomationElements;
|
||||||
|
using FlaUI.Core.Input;
|
||||||
|
using FlaUI.Core.Tools;
|
||||||
|
using FlaUI.UIA3;
|
||||||
|
using Xunit;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using EmployeeManagmentView.PhysicalPerson;
|
||||||
|
using EmployeeManagmentView.Employee;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.UI
|
||||||
|
{
|
||||||
|
[Collection("Sequential")]
|
||||||
|
public class MainWindowTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Application _application;
|
||||||
|
private readonly AutomationBase _automation;
|
||||||
|
|
||||||
|
public MainWindowTests()
|
||||||
|
{
|
||||||
|
_automation = new UIA3Automation();
|
||||||
|
_application = Application.Launch("C:\\Users\\kashi\\Desktop\\Univer\\7\\КПО\\Project\\EmployeeManagmentView\\bin\\Debug\\net8.0-windows\\EmployeeManagmentView.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenEmployeeManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var employeeButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(employeeButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
employeeButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с сотрудниками" с тайм-аутом
|
||||||
|
var employeeManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(employeeManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(employeeManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
mainWindow?.Close();
|
||||||
|
employeeManagementWindow?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenPhysicalPersonManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var physicalPersonButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с физ. лицами")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Работа с физ. лицами");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var physicalPersonManagementWindow = WaitForWindow("Управление физическими лицами");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Управление физическими лицами");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
mainWindow?.Close();
|
||||||
|
physicalPersonManagementWindow?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private Window WaitForWindow(string windowTitle, int timeout = 10000) // Увеличен таймаут
|
||||||
|
{
|
||||||
|
var startTime = DateTime.Now;
|
||||||
|
while ((DateTime.Now - startTime).TotalMilliseconds < timeout)
|
||||||
|
{
|
||||||
|
var window = _application.GetAllTopLevelWindows(_automation)
|
||||||
|
.FirstOrDefault(w => w.Title.Contains(windowTitle));
|
||||||
|
if (window != null && window.IsEnabled)
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
Thread.Sleep(200); // Увеличена пауза между попытками
|
||||||
|
}
|
||||||
|
return null; // Если окно не найдено в пределах тайм-аута
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_application.Close();
|
||||||
|
_automation.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
188
EmployeeManagmentTests/UI/PhysicalPersonWindowTests.cs
Normal file
188
EmployeeManagmentTests/UI/PhysicalPersonWindowTests.cs
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
using EmployeeManagmentView.Employee;
|
||||||
|
using FlaUI.Core;
|
||||||
|
using FlaUI.Core.AutomationElements;
|
||||||
|
using FlaUI.UIA3;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.UI
|
||||||
|
{
|
||||||
|
[Collection("Sequential")]
|
||||||
|
public class PhysicalPersonWindowTests
|
||||||
|
{
|
||||||
|
private readonly Application _application;
|
||||||
|
private readonly AutomationBase _automation;
|
||||||
|
|
||||||
|
public PhysicalPersonWindowTests()
|
||||||
|
{
|
||||||
|
_automation = new UIA3Automation();
|
||||||
|
_application = Application.Launch("C:\\Users\\kashi\\Desktop\\Univer\\7\\КПО\\Project\\EmployeeManagmentView\\bin\\Debug\\net8.0-windows\\EmployeeManagmentView.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenAddPhysicalPersonManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var physicalPersonButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с физ. лицами")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Работа с физ. лицами");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var physicalPersonManagementWindow = WaitForWindow("Управление физическими лицами");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Управление физическими лицами");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Добавление физического лица");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var physicalPersonAddWindow = WaitForWindow("Добавление физического лица");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Добавление физического лица");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
physicalPersonAddWindow?.Close();
|
||||||
|
physicalPersonManagementWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenDeletePhysicalPersonManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var physicalPersonButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с физ. лицами")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Работа с физ. лицами");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var physicalPersonManagementWindow = WaitForWindow("Управление физическими лицами");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Управление физическими лицами");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Удаление физического лица");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var physicalPersonAddWindow = WaitForWindow("Удаление физического лица");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Удаление физического лица");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
physicalPersonAddWindow?.Close();
|
||||||
|
physicalPersonManagementWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenEditPhysicalPersonManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var physicalPersonButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с физ. лицами")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Работа с физ. лицами");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var physicalPersonManagementWindow = WaitForWindow("Управление физическими лицами");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Управление физическими лицами");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Редактирование физического лица");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var physicalPersonAddWindow = WaitForWindow("Редактирование физического лица");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Редактирование физического лица");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
physicalPersonAddWindow?.Close();
|
||||||
|
physicalPersonManagementWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenViewPhysicalPersonManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var physicalPersonButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с физ. лицами")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Работа с физ. лицами");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var physicalPersonManagementWindow = WaitForWindow("Управление физическими лицами");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Управление физическими лицами");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(physicalPersonButton.IsEnabled, "Просмотр физического лица");
|
||||||
|
physicalPersonButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var physicalPersonAddWindow = WaitForWindow("Просмотр физического лица");
|
||||||
|
Assert.NotNull(physicalPersonManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(physicalPersonManagementWindow.IsEnabled, "Просмотр физического лица");
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
physicalPersonAddWindow?.Close();
|
||||||
|
physicalPersonManagementWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private Window WaitForWindow(string windowTitle, int timeout = 10000) // Увеличен таймаут
|
||||||
|
{
|
||||||
|
var startTime = DateTime.Now;
|
||||||
|
while ((DateTime.Now - startTime).TotalMilliseconds < timeout)
|
||||||
|
{
|
||||||
|
var window = _application.GetAllTopLevelWindows(_automation)
|
||||||
|
.FirstOrDefault(w => w.Title.Contains(windowTitle));
|
||||||
|
if (window != null && window.IsEnabled)
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
Thread.Sleep(200); // Увеличена пауза между попытками
|
||||||
|
}
|
||||||
|
return null; // Если окно не найдено в пределах тайм-аута
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_application.Close();
|
||||||
|
_automation.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
306
EmployeeManagmentTests/UI/SalaryWindowTests.cs
Normal file
306
EmployeeManagmentTests/UI/SalaryWindowTests.cs
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
using FlaUI.Core;
|
||||||
|
using FlaUI.Core.AutomationElements;
|
||||||
|
using FlaUI.UIA3;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.UI
|
||||||
|
{
|
||||||
|
public class SalaryWindowTests
|
||||||
|
{
|
||||||
|
private readonly Application _application;
|
||||||
|
private readonly AutomationBase _automation;
|
||||||
|
|
||||||
|
public SalaryWindowTests()
|
||||||
|
{
|
||||||
|
_automation = new UIA3Automation();
|
||||||
|
_application = Application.Launch("C:\\Users\\kashi\\Desktop\\Univer\\7\\КПО\\Project\\EmployeeManagmentView\\bin\\Debug\\net8.0-windows\\EmployeeManagmentView.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenViewSalaryManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var salaryButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var salaryManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с зарплатой");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryManagmentWindow = WaitForWindow("Управление зарплатой");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление зарплатой");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Просмотр зарплат");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryCrudWindow = WaitForWindow("Список зарплат");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Список зарплат");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
salaryManagementWindow?.Close();
|
||||||
|
salaryAddWindow?.Close();
|
||||||
|
salaryManagmentWindow?.Close();
|
||||||
|
salaryCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenEditSalaryManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var salaryButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var salaryManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с зарплатой");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryManagmentWindow = WaitForWindow("Управление зарплатой");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление зарплатой");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Редактирование зарплат");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryCrudWindow = WaitForWindow("Редактирование зарплат");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Редактирование зарплат");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
salaryManagementWindow?.Close();
|
||||||
|
salaryAddWindow?.Close();
|
||||||
|
salaryManagmentWindow?.Close();
|
||||||
|
salaryCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenDeleteSalaryManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var salaryButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var salaryManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с зарплатой");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryManagmentWindow = WaitForWindow("Управление зарплатой");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление зарплатой");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Удаление зарплат");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryCrudWindow = WaitForWindow("Удаление зарплат");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Удаление зарплат");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
salaryManagementWindow?.Close();
|
||||||
|
salaryAddWindow?.Close();
|
||||||
|
salaryManagmentWindow?.Close();
|
||||||
|
salaryCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenAddSalaryManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var salaryButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var salaryManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Работа с зарплатой");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryManagmentWindow = WaitForWindow("Управление зарплатой");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Управление зарплатой");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(salaryButton.IsEnabled, "Добавление зарплаты");
|
||||||
|
salaryButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var salaryCrudWindow = WaitForWindow("Добавление зарплаты");
|
||||||
|
Assert.NotNull(salaryManagementWindow);
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(salaryManagementWindow.IsEnabled, "Добавление зарплаты");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
salaryManagementWindow?.Close();
|
||||||
|
salaryAddWindow?.Close();
|
||||||
|
salaryManagmentWindow?.Close();
|
||||||
|
salaryCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Window WaitForWindow(string windowTitle, int timeout = 10000) // Увеличен таймаут
|
||||||
|
{
|
||||||
|
var startTime = DateTime.Now;
|
||||||
|
while ((DateTime.Now - startTime).TotalMilliseconds < timeout)
|
||||||
|
{
|
||||||
|
var window = _application.GetAllTopLevelWindows(_automation)
|
||||||
|
.FirstOrDefault(w => w.Title.Contains(windowTitle));
|
||||||
|
if (window != null && window.IsEnabled)
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
Thread.Sleep(200); // Увеличена пауза между попытками
|
||||||
|
}
|
||||||
|
return null; // Если окно не найдено в пределах тайм-аута
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_application.Close();
|
||||||
|
_automation.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
283
EmployeeManagmentTests/UI/VacationWindowTests.cs
Normal file
283
EmployeeManagmentTests/UI/VacationWindowTests.cs
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
using FlaUI.Core;
|
||||||
|
using FlaUI.Core.AutomationElements;
|
||||||
|
using FlaUI.UIA3;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.UI
|
||||||
|
{
|
||||||
|
[Collection("Sequential")]
|
||||||
|
public class VacationWindowTests
|
||||||
|
{
|
||||||
|
private readonly Application _application;
|
||||||
|
private readonly AutomationBase _automation;
|
||||||
|
|
||||||
|
public VacationWindowTests()
|
||||||
|
{
|
||||||
|
_automation = new UIA3Automation();
|
||||||
|
_application = Application.Launch("C:\\Users\\kashi\\Desktop\\Univer\\7\\КПО\\Project\\EmployeeManagmentView\\bin\\Debug\\net8.0-windows\\EmployeeManagmentView.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenViewVacationManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var vacationButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var vacationManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с отпусками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationManagmentWindow = WaitForWindow("Управление отпуском");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление отпуском");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Просмотр отпусков");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationCrudWindow = WaitForWindow("Список отпусков сотрудников");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Список отпусков сотрудников");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
vacationManagementWindow?.Close();
|
||||||
|
vacationAddWindow?.Close();
|
||||||
|
vacationManagmentWindow?.Close();
|
||||||
|
vacationCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenEditVacationManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var vacationButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var vacationManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с отпусками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationManagmentWindow = WaitForWindow("Управление отпуском");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление отпуском");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Редактирование отпуска");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationCrudWindow = WaitForWindow("Редактирование отпуска");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Редактирование отпуска");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
vacationManagementWindow?.Close();
|
||||||
|
vacationAddWindow?.Close();
|
||||||
|
vacationManagmentWindow?.Close();
|
||||||
|
vacationCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenDeleteVacationManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var vacationButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var vacationManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с отпусками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationManagmentWindow = WaitForWindow("Управление отпуском");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление зарплатой");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Удаление отпуска");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationCrudWindow = WaitForWindow("Удаление отпуска");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Удаление отпуска");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
vacationManagementWindow?.Close();
|
||||||
|
vacationAddWindow?.Close();
|
||||||
|
vacationManagmentWindow?.Close();
|
||||||
|
vacationCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestOpenAddVacationManagementWindow()
|
||||||
|
{
|
||||||
|
var mainWindow = _application.GetMainWindow(_automation);
|
||||||
|
var vacationButton = mainWindow.FindFirstDescendant(cf => cf.ByText("Работа с сотрудниками")).AsButton();
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с сотрудниками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Работа с физ. лицами" с тайм-аутом
|
||||||
|
var vacationManagementWindow = WaitForWindow("Управление сотрудниками");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление сотрудниками");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Просмотр сотрудников");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationAddWindow = WaitForWindow("Просмотр сотрудников");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Просмотр сотрудников");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Работа с отпусками");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationManagmentWindow = WaitForWindow("Управление отпуском");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Управление отпуском");
|
||||||
|
|
||||||
|
// Проверяем, что кнопка доступна и выполняем клик
|
||||||
|
Assert.True(vacationButton.IsEnabled, "Добавление отпуска");
|
||||||
|
vacationButton.Invoke();
|
||||||
|
|
||||||
|
// Ждем появления окна "Добавление физ.лица" с тайм-аутом
|
||||||
|
var vacationCrudWindow = WaitForWindow("Добавление отпуска");
|
||||||
|
Assert.NotNull(vacationManagementWindow);
|
||||||
|
|
||||||
|
// Проверяем, что окно доступно и готово к взаимодействию
|
||||||
|
Assert.True(vacationManagementWindow.IsEnabled, "Добавление отпуска");
|
||||||
|
|
||||||
|
|
||||||
|
// Закрытие окон
|
||||||
|
vacationManagementWindow?.Close();
|
||||||
|
vacationAddWindow?.Close();
|
||||||
|
vacationManagmentWindow?.Close();
|
||||||
|
vacationCrudWindow?.Close();
|
||||||
|
mainWindow?.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Window WaitForWindow(string windowTitle, int timeout = 10000) // Увеличен таймаут
|
||||||
|
{
|
||||||
|
var startTime = DateTime.Now;
|
||||||
|
while ((DateTime.Now - startTime).TotalMilliseconds < timeout)
|
||||||
|
{
|
||||||
|
var window = _application.GetAllTopLevelWindows(_automation)
|
||||||
|
.FirstOrDefault(w => w.Title.Contains(windowTitle));
|
||||||
|
if (window != null && window.IsEnabled)
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
Thread.Sleep(200); // Увеличена пауза между попытками
|
||||||
|
}
|
||||||
|
return null; // Если окно не найдено в пределах тайм-аута
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
138
EmployeeManagmentTests/Unit/EmployeeLogicTests.cs
Normal file
138
EmployeeManagmentTests/Unit/EmployeeLogicTests.cs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
using Xunit;
|
||||||
|
using Moq;
|
||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.Unit
|
||||||
|
{
|
||||||
|
public class EmployeeLogicTests
|
||||||
|
{
|
||||||
|
private readonly Mock<IEmployeeStorage> _mockStorage;
|
||||||
|
private readonly Mock<ILogger<EmployeeLogic>> _mockLogger;
|
||||||
|
private readonly EmployeeLogic _logic;
|
||||||
|
|
||||||
|
public EmployeeLogicTests()
|
||||||
|
{
|
||||||
|
_mockStorage = new Mock<IEmployeeStorage>();
|
||||||
|
_mockLogger = new Mock<ILogger<EmployeeLogic>>();
|
||||||
|
_logic = new EmployeeLogic(_mockLogger.Object, _mockStorage.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFullList_ShouldReturnListOfEmployees()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedList = new List<EmployeeViewModel>
|
||||||
|
{
|
||||||
|
new EmployeeViewModel { Id = 1, NameJob = "Developer", StartJob = DateTime.Now.AddYears(-1) },
|
||||||
|
new EmployeeViewModel { Id = 2, NameJob = "Manager", StartJob = DateTime.Now.AddYears(-2) }
|
||||||
|
};
|
||||||
|
|
||||||
|
_mockStorage.Setup(x => x.GetFullList()).Returns(expectedList);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _logic.GetFullList();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedList.Count, result.Count);
|
||||||
|
Assert.Equal(expectedList[0].NameJob, result[0].NameJob);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFilteredList_ShouldReturnFilteredResults()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = new EmployeeSearchModel { NameJob = "Developer" };
|
||||||
|
var expectedList = new List<EmployeeViewModel>
|
||||||
|
{
|
||||||
|
new EmployeeViewModel { Id = 1, NameJob = "Developer", StartJob = DateTime.Now.AddYears(-1) }
|
||||||
|
};
|
||||||
|
|
||||||
|
_mockStorage.Setup(x => x.GetFilteredList(model)).Returns(expectedList);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _logic.GetFilteredList(model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Single(result);
|
||||||
|
Assert.Equal("Developer", result[0].NameJob);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFilteredList_ShouldReturnEmptyList_IfNoMatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = new EmployeeSearchModel { NameJob = "Unknown" };
|
||||||
|
_mockStorage.Setup(x => x.GetFilteredList(model)).Returns(new List<EmployeeViewModel>());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _logic.GetFilteredList(model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Insert_ShouldThrowException_IfNameJobIsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var invalidModel = new EmployeeViewModel { NameJob = "" };
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<ArgumentException>(() => _logic.Insert(invalidModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Insert_ShouldCallStorageInsert_IfDataIsValid()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var validModel = new EmployeeViewModel { NameJob = "Developer", StartJob = DateTime.Now };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_logic.Insert(validModel);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mockStorage.Verify(x => x.Insert(validModel), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_ShouldThrowException_IfElementNotFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = new EmployeeViewModel { Id = 1, NameJob = "Developer" };
|
||||||
|
_mockStorage.Setup(x => x.GetElement(model.Id)).Returns((EmployeeViewModel?)null);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<ArgumentException>(() => _logic.Update(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Delete_ShouldThrowException_IfElementNotFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var id = 1;
|
||||||
|
_mockStorage.Setup(x => x.GetElement(id)).Returns((EmployeeViewModel?)null);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<ArgumentException>(() => _logic.Delete(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Delete_ShouldCallStorageDelete_IfElementExists()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var id = 1;
|
||||||
|
var model = new EmployeeViewModel { Id = id };
|
||||||
|
_mockStorage.Setup(x => x.GetElement(id)).Returns(model);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_logic.Delete(id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mockStorage.Verify(x => x.Delete(id), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
139
EmployeeManagmentTests/Unit/PhisicalPersonLogicTests.cs
Normal file
139
EmployeeManagmentTests/Unit/PhisicalPersonLogicTests.cs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
using Xunit;
|
||||||
|
using Moq;
|
||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.Unit
|
||||||
|
{
|
||||||
|
public class PhisicalPersonLogicTests
|
||||||
|
{
|
||||||
|
private readonly Mock<IPhisicalPersonStorage> _mockStorage;
|
||||||
|
private readonly Mock<ILogger<PhisicalPersonLogic>> _mockLogger;
|
||||||
|
private readonly PhisicalPersonLogic _logic;
|
||||||
|
|
||||||
|
public PhisicalPersonLogicTests()
|
||||||
|
{
|
||||||
|
_mockStorage = new Mock<IPhisicalPersonStorage>();
|
||||||
|
_mockLogger = new Mock<ILogger<PhisicalPersonLogic>>();
|
||||||
|
_logic = new PhisicalPersonLogic(_mockLogger.Object, _mockStorage.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFullList_ShouldReturnListOfPhisicalPersons()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedList = new List<PhisicalPersonViewModel>
|
||||||
|
{
|
||||||
|
new PhisicalPersonViewModel { Id = 1, Name = "John", Surname = "Doe" },
|
||||||
|
new PhisicalPersonViewModel { Id = 2, Name = "Jane", Surname = "Smith" }
|
||||||
|
};
|
||||||
|
|
||||||
|
_mockStorage.Setup(x => x.GetFullList()).Returns(expectedList);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _logic.GetFullList();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedList.Count, result.Count);
|
||||||
|
Assert.Equal(expectedList[0].Name, result[0].Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFilteredList_ShouldReturnFilteredResults()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = new PhisicalPersonSearchModel { Surname = "Doe" };
|
||||||
|
var expectedList = new List<PhisicalPersonViewModel>
|
||||||
|
{
|
||||||
|
new PhisicalPersonViewModel { Id = 1, Name = "John", Surname = "Doe" }
|
||||||
|
};
|
||||||
|
|
||||||
|
_mockStorage.Setup(x => x.GetFilteredList(model)).Returns(expectedList);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _logic.GetFilteredList(model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Single(result);
|
||||||
|
Assert.Equal("Doe", result[0].Surname);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFilteredList_ShouldReturnEmptyList_IfNoMatch()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = new PhisicalPersonSearchModel { Surname = "Unknown" };
|
||||||
|
_mockStorage.Setup(x => x.GetFilteredList(model)).Returns(new List<PhisicalPersonViewModel>());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _logic.GetFilteredList(model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Insert_ShouldThrowException_IfNameOrSurnameIsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var invalidModel = new PhisicalPersonViewModel { Name = "", Surname = "" };
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<ArgumentException>(() => _logic.Insert(invalidModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Insert_ShouldCallStorageInsert_IfDataIsValid()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var validModel = new PhisicalPersonViewModel { Name = "John", Surname = "Doe" };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_logic.Insert(validModel);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mockStorage.Verify(x => x.Insert(validModel), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_ShouldThrowException_IfElementNotFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = new PhisicalPersonViewModel { Id = 1, Name = "John", Surname = "Doe" };
|
||||||
|
_mockStorage.Setup(x => x.GetElement(model.Id)).Returns((PhisicalPersonViewModel?)null);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<ArgumentException>(() => _logic.Update(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Delete_ShouldThrowException_IfElementNotFound()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var id = 1;
|
||||||
|
_mockStorage.Setup(x => x.GetElement(id)).Returns((PhisicalPersonViewModel?)null);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<ArgumentException>(() => _logic.Delete(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Delete_ShouldCallStorageDelete_IfElementExists()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var id = 1;
|
||||||
|
var model = new PhisicalPersonViewModel { Id = id };
|
||||||
|
_mockStorage.Setup(x => x.GetElement(id)).Returns(model);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_logic.Delete(id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_mockStorage.Verify(x => x.Delete(id), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
142
EmployeeManagmentTests/Unit/SalaryLogicTests.cs
Normal file
142
EmployeeManagmentTests/Unit/SalaryLogicTests.cs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Implements;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.Unit
|
||||||
|
{
|
||||||
|
public class SalaryLogicTests
|
||||||
|
{
|
||||||
|
private readonly Mock<ILogger<SalaryLogic>> _loggerMock;
|
||||||
|
private readonly SalaryStorage _salaryStorage;
|
||||||
|
private readonly SalaryLogic _salaryLogic;
|
||||||
|
|
||||||
|
public SalaryLogicTests()
|
||||||
|
{
|
||||||
|
_loggerMock = new Mock<ILogger<SalaryLogic>>();
|
||||||
|
_salaryStorage = new SalaryStorage();
|
||||||
|
_salaryLogic = new SalaryLogic(_loggerMock.Object, _salaryStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFullList_ShouldReturnAllSalaries()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedCount = _salaryStorage.GetFullList().Count;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _salaryLogic.GetFullList();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(expectedCount, result.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFilteredList_ShouldReturnFilteredSalaries()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var filter = new SalarySearchModel
|
||||||
|
{
|
||||||
|
Date = DateTime.UtcNow.AddMonths(-1) // Используйте UTC
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _salaryLogic.GetFilteredList(filter);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.All(result, salary => Assert.True(salary.Date >= filter.Date));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetElement_ShouldReturnCorrectSalary()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var salaries = _salaryLogic.GetFullList();
|
||||||
|
if (salaries.Count == 0)
|
||||||
|
{
|
||||||
|
Assert.True(false, "No salaries available for testing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var salaryId = salaries.First().Id;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _salaryLogic.GetElement(salaryId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(salaryId, result.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Insert_ShouldAddSalary()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var newSalary = new SalaryViewModel
|
||||||
|
{
|
||||||
|
CountHours = 40,
|
||||||
|
PriceHour = 15,
|
||||||
|
Premium = 200,
|
||||||
|
Date = DateTime.UtcNow, // Используем UTC для даты
|
||||||
|
Passed = false,
|
||||||
|
EmployeeId = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
var initialCount = _salaryLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_salaryLogic.Insert(newSalary);
|
||||||
|
var updatedCount = _salaryLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(initialCount + 1, updatedCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_ShouldModifySalary()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var salary = _salaryLogic.GetFullList().FirstOrDefault();
|
||||||
|
if (salary == null)
|
||||||
|
{
|
||||||
|
Assert.True(false, "No salaries available for testing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
salary.PriceHour += 5;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_salaryLogic.Update(salary);
|
||||||
|
var updatedSalary = _salaryLogic.GetElement(salary.Id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(updatedSalary);
|
||||||
|
Assert.Equal(salary.PriceHour, updatedSalary.PriceHour);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Delete_ShouldRemoveSalary()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var salary = _salaryLogic.GetFullList().LastOrDefault();
|
||||||
|
if (salary == null)
|
||||||
|
{
|
||||||
|
Assert.True(false, "No salaries available for testing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var initialCount = _salaryLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_salaryLogic.Delete(salary.Id);
|
||||||
|
var updatedCount = _salaryLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(initialCount - 1, updatedCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
144
EmployeeManagmentTests/Unit/VacationLogicTests.cs
Normal file
144
EmployeeManagmentTests/Unit/VacationLogicTests.cs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.SearchModels;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Implements;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentTests.Unit
|
||||||
|
{
|
||||||
|
public class VacationLogicTests
|
||||||
|
{
|
||||||
|
private readonly Mock<ILogger<VacationLogic>> _loggerMock;
|
||||||
|
private readonly VacationStorage _vacationStorage;
|
||||||
|
private readonly VacationLogic _vacationLogic;
|
||||||
|
|
||||||
|
public VacationLogicTests()
|
||||||
|
{
|
||||||
|
_loggerMock = new Mock<ILogger<VacationLogic>>();
|
||||||
|
_vacationStorage = new VacationStorage();
|
||||||
|
_vacationLogic = new VacationLogic(_loggerMock.Object, _vacationStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFullList_ShouldReturnAllVacations()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedCount = _vacationStorage.GetFullList().Count;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _vacationLogic.GetFullList();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(expectedCount, result.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFilteredList_ShouldReturnFilteredVacations()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var filter = new VacationSearchModel
|
||||||
|
{
|
||||||
|
StartData = DateTime.UtcNow.AddMonths(-1),
|
||||||
|
EndData = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _vacationLogic.GetFilteredList(filter);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.All(result, vacation =>
|
||||||
|
Assert.True(vacation.StartData >= filter.StartData && vacation.EndData <= filter.EndData)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetElement_ShouldReturnCorrectVacation()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var vacations = _vacationLogic.GetFullList();
|
||||||
|
if (vacations.Count == 0)
|
||||||
|
{
|
||||||
|
Assert.True(false, "No vacations available for testing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var vacationId = vacations.First().Id;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _vacationLogic.GetElement(vacationId);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(vacationId, result.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Insert_ShouldAddVacation()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var newVacation = new VacationViewModel
|
||||||
|
{
|
||||||
|
StartData = DateTime.UtcNow.AddDays(1).ToUniversalTime(), // Преобразование в UTC
|
||||||
|
EndData = DateTime.UtcNow.AddDays(10).ToUniversalTime(), // Преобразование в UTC
|
||||||
|
Passed = false,
|
||||||
|
EmployeeId = 1 // ID существующего сотрудника
|
||||||
|
};
|
||||||
|
|
||||||
|
var initialCount = _vacationLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_vacationLogic.Insert(newVacation);
|
||||||
|
var updatedCount = _vacationLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(initialCount + 1, updatedCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_ShouldModifyVacation()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var vacation = _vacationLogic.GetFullList().FirstOrDefault();
|
||||||
|
if (vacation == null)
|
||||||
|
{
|
||||||
|
Assert.True(false, "No vacations available for testing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
vacation.EndData = DateTime.UtcNow.AddDays(20).ToUniversalTime(); // Преобразование в UTC
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_vacationLogic.Update(vacation);
|
||||||
|
var updatedVacation = _vacationLogic.GetElement(vacation.Id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(updatedVacation);
|
||||||
|
|
||||||
|
// Сравниваем с учетом допустимой погрешности в миллисекундах
|
||||||
|
Assert.Equal(vacation.EndData, updatedVacation.EndData, TimeSpan.FromMilliseconds(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Delete_ShouldRemoveVacation()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var vacation = _vacationLogic.GetFullList().LastOrDefault();
|
||||||
|
if (vacation == null)
|
||||||
|
{
|
||||||
|
Assert.True(false, "No vacations available for testing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var initialCount = _vacationLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_vacationLogic.Delete(vacation.Id);
|
||||||
|
var updatedCount = _vacationLogic.GetFullList().Count;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(initialCount - 1, updatedCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,184 @@
|
|||||||
<Application x:Class="EmployeeManagmentView.App"
|
<Application x:Class="EmployeeManagmentView.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
xmlns:local="clr-namespace:EmployeeManagmentView"
|
|
||||||
StartupUri="MainWindow.xaml">
|
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
|
|
||||||
|
<!-- Стиль для закругленных кнопок -->
|
||||||
|
<Style x:Key="RoundedButtonStyle" TargetType="Button">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<Grid>
|
||||||
|
<Border Background="{TemplateBinding Background}"
|
||||||
|
CornerRadius="15"
|
||||||
|
BorderBrush="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
x:Name="ButtonBorder">
|
||||||
|
<Border.Effect>
|
||||||
|
<DropShadowEffect Color="Black" BlurRadius="10" ShadowDepth="2" Opacity="0.4" />
|
||||||
|
</Border.Effect>
|
||||||
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
|
</Border>
|
||||||
|
<Grid.RenderTransform>
|
||||||
|
<ScaleTransform x:Name="scaleTransform" ScaleX="1" ScaleY="1" />
|
||||||
|
</Grid.RenderTransform>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimation Storyboard.TargetName="ButtonBorder"
|
||||||
|
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
|
||||||
|
To="#0066CC" Duration="0:0:0.2" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimation Storyboard.TargetName="ButtonBorder"
|
||||||
|
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
|
||||||
|
To="#004890" Duration="0:0:0.2" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
|
||||||
|
<Setter Property="RenderTransform" TargetName="ButtonBorder">
|
||||||
|
<Setter.Value>
|
||||||
|
<ScaleTransform ScaleX="0.95" ScaleY="0.95" />
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Setter TargetName="ButtonBorder" Property="Effect">
|
||||||
|
<Setter.Value>
|
||||||
|
<DropShadowEffect Color="Black" BlurRadius="15" ShadowDepth="0" Opacity="0.6" />
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="scaleTransform"
|
||||||
|
Storyboard.TargetProperty="ScaleX"
|
||||||
|
To="0.95" Duration="0:0:0.2" />
|
||||||
|
<DoubleAnimation Storyboard.TargetName="scaleTransform"
|
||||||
|
Storyboard.TargetProperty="ScaleY"
|
||||||
|
To="0.95" Duration="0:0:0.2" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="scaleTransform"
|
||||||
|
Storyboard.TargetProperty="ScaleX"
|
||||||
|
To="1.0" Duration="0:0:0.2" />
|
||||||
|
<DoubleAnimation Storyboard.TargetName="scaleTransform"
|
||||||
|
Storyboard.TargetProperty="ScaleY"
|
||||||
|
To="1.0" Duration="0:0:0.2" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Стиль для закругленного TextBox -->
|
||||||
|
<Style x:Key="RoundedTextBoxStyle" TargetType="TextBox">
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="TextBox">
|
||||||
|
<Border Background="White"
|
||||||
|
CornerRadius="15"
|
||||||
|
BorderBrush="Black">
|
||||||
|
<ScrollViewer Margin="5" x:Name="PART_ContentHost"/>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Style.Triggers>
|
||||||
|
<!-- Подсветка рамки при фокусе -->
|
||||||
|
<Trigger Property="IsFocused" Value="True">
|
||||||
|
<Setter Property="BorderBrush" Value="#004890"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Стиль для DataGrid -->
|
||||||
|
<Style x:Key="RoundedDataGridStyle" TargetType="DataGrid">
|
||||||
|
<Setter Property="Background" Value="#FFFFFF"/>
|
||||||
|
<Setter Property="Foreground" Value="#000000"/>
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Padding" Value="10"/>
|
||||||
|
<Setter Property="AlternatingRowBackground" Value="#FFFFFF"/>
|
||||||
|
<Setter Property="RowHeight" Value="30"/>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<!-- Эффект при наведении на строку -->
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="#FFFFFF"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
|
||||||
|
<Style.Resources>
|
||||||
|
<!-- Стиль для ячеек DataGrid -->
|
||||||
|
<Style TargetType="DataGridCell">
|
||||||
|
<Setter Property="Padding" Value="10"/>
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="#004890"/>
|
||||||
|
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Стиль для строк -->
|
||||||
|
<Style TargetType="DataGridRow">
|
||||||
|
<Setter Property="Padding" Value="5"/>
|
||||||
|
<Setter Property="Margin" Value="5"/>
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="#0D2D4F"/>
|
||||||
|
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||||
|
</Trigger>
|
||||||
|
<!-- Стиль для выделенной строки (не должна быть белой) -->
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Setter Property="Background" Value="#0D2D4F"/>
|
||||||
|
<!-- Цвет фона выделенной строки -->
|
||||||
|
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||||
|
<!-- Цвет текста в выделенной строке -->
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Стиль для шапки DataGrid -->
|
||||||
|
<Style TargetType="DataGridColumnHeader">
|
||||||
|
<Setter Property="Background" Value="#0D2D4F"/>
|
||||||
|
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||||
|
<Setter Property="Height" Value="40"/>
|
||||||
|
<!-- Увеличение высоты шапки -->
|
||||||
|
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Padding" Value="10"/>
|
||||||
|
</Style>
|
||||||
|
</Style.Resources>
|
||||||
|
</Style>
|
||||||
|
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</Application>
|
</Application>
|
||||||
|
@ -1,14 +1,59 @@
|
|||||||
using System.Configuration;
|
using EmployeeManagmentDataBaseImplement;
|
||||||
using System.Data;
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using EmployeeManagmentContracts.StoragesContracts;
|
||||||
|
using EmployeeManagmentDataBaseImplement.Implements;
|
||||||
|
|
||||||
namespace EmployeeManagmentView
|
namespace EmployeeManagmentView
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for App.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
}
|
private static ServiceProvider? _serviceProvider;
|
||||||
|
public static ServiceProvider? ServiceProvider => _serviceProvider;
|
||||||
|
|
||||||
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
|
{
|
||||||
|
var serviceCollection = new ServiceCollection();
|
||||||
|
ConfigureServices(serviceCollection);
|
||||||
|
_serviceProvider = serviceCollection.BuildServiceProvider();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
|
||||||
|
mainWindow.Show();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(ex.Message, "Ошибка при открытии MainWindow", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
base.OnStartup(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureServices(ServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddLogging(configure => configure.AddConsole());
|
||||||
|
|
||||||
|
services.AddTransient<IEmployeeStorage, EmployeeStorage>();
|
||||||
|
services.AddTransient<IPhisicalPersonStorage, PhisicalPersonStorage>();
|
||||||
|
services.AddTransient<ISalaryStorage, SalaryStorage>();
|
||||||
|
services.AddTransient<IVacationStorage, VacationStorage>();
|
||||||
|
|
||||||
|
services.AddTransient<IPhisicalPersonLogic, PhisicalPersonLogic>();
|
||||||
|
services.AddTransient<IEmployeeLogic, EmployeeLogic>();
|
||||||
|
services.AddTransient<ISalaryLogic, SalaryLogic>();
|
||||||
|
services.AddTransient<IVacationLogic, VacationLogic>();
|
||||||
|
|
||||||
|
services.AddTransient<MainWindow>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
[assembly: ThemeInfo(
|
[assembly: ThemeInfo(
|
||||||
@ -8,3 +9,6 @@ using System.Windows;
|
|||||||
//(used if a resource is not found in the page,
|
//(used if a resource is not found in the page,
|
||||||
// app, or any theme specific resource dictionaries)
|
// app, or any theme specific resource dictionaries)
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("EmployeeManagmentTests")]
|
||||||
|
|
||||||
|
115
EmployeeManagmentView/Employee/AddEmployeeWindow.xaml
Normal file
115
EmployeeManagmentView/Employee/AddEmployeeWindow.xaml
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.AddEmployeeWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Добавление сотрудника"
|
||||||
|
Height="500" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Добавление сотрудника"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Сетка для ввода данных в два столбца -->
|
||||||
|
<Grid Margin="0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поле для имени работы -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Название должности" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="JobNameTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Введите название должности" HorizontalAlignment="Center"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для даты начала работы -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Дата начала работы" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="StartDatePicker"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Выберите дату начала работы" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для даты окончания работы -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Дата окончания работы" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="EndDatePicker"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Выберите дату окончания работы (если есть)" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для ставки -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Ставка" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="BidTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Введите почасовую ставку" HorizontalAlignment="Center"
|
||||||
|
PreviewTextInput="DecimalTextBox_PreviewTextInput"
|
||||||
|
TextChanged="DecimalTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для физического лица -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Физическое лицо" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="PhysicalPersonComboBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Выберите физическое лицо"
|
||||||
|
Background="White" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для совместительства -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Совместительство" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PartTimeJobTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Введите почасовую ставку" HorizontalAlignment="Center"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Кнопка для добавления сотрудника -->
|
||||||
|
<Button Grid.Row="3" Grid.ColumnSpan="2" Content="Добавить сотрудника"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="20,10,0,0"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="SaveButton_Click"
|
||||||
|
Background="#004890" Foreground="#FFFFFF" HorizontalAlignment="Left"/>
|
||||||
|
<Button Grid.Row="3" Grid.ColumnSpan="2" Content="Сформировать договор"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,10,20,0"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="GenerateContractButton_Click"
|
||||||
|
Background="#004890" Foreground="#FFFFFF" HorizontalAlignment="Right"/>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
374
EmployeeManagmentView/Employee/AddEmployeeWindow.xaml.cs
Normal file
374
EmployeeManagmentView/Employee/AddEmployeeWindow.xaml.cs
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
using DocumentFormat.OpenXml.Packaging;
|
||||||
|
using DocumentFormat.OpenXml.Wordprocessing;
|
||||||
|
using DocumentFormat.OpenXml;
|
||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для AddEmployeeWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class AddEmployeeWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
|
||||||
|
public AddEmployeeWindow(IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadPhysicalPersons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadPhysicalPersons()
|
||||||
|
{
|
||||||
|
if (PhysicalPersonComboBox == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("PhysicalPersonComboBox не инициализирован.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var persons = _phisicalPersonLogic.GetFullList();
|
||||||
|
PhysicalPersonComboBox.ItemsSource = persons;
|
||||||
|
PhysicalPersonComboBox.DisplayMemberPath = "FullNameWithBirthday";
|
||||||
|
PhysicalPersonComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка на ввод только чисел и одной запятой
|
||||||
|
private void DecimalTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Разрешаем только цифры и запятую
|
||||||
|
e.Handled = !(char.IsDigit(e.Text, 0) || e.Text == ",");
|
||||||
|
|
||||||
|
// Проверка на количество запятых
|
||||||
|
if (e.Text == "," && textBox.Text.Contains(","))
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ограничение на 2 знака после запятой
|
||||||
|
private void DecimalTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Проверяем наличие запятой
|
||||||
|
int commaIndex = currentText.IndexOf(',');
|
||||||
|
|
||||||
|
if (commaIndex != -1 && currentText.Length - commaIndex > 3)
|
||||||
|
{
|
||||||
|
// Обрезаем текст до двух знаков после запятой
|
||||||
|
textBox.Text = currentText.Substring(0, commaIndex + 3);
|
||||||
|
textBox.SelectionStart = textBox.Text.Length; // Устанавливаем курсор в конец текста
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateEmploymentContract(string filePath, string employeeName, string jobTitle, DateTime startDate, DateTime? endDate, decimal hourlyRate, string partTimeInfo)
|
||||||
|
{
|
||||||
|
using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document))
|
||||||
|
{
|
||||||
|
// Добавление основной части документа
|
||||||
|
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
|
||||||
|
mainPart.Document = new Document();
|
||||||
|
Body body = new Body();
|
||||||
|
|
||||||
|
// Канцелярская информация
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Номер договора: {Guid.NewGuid().ToString("N").ToUpper().Substring(0, 10)}"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Дата составления: {DateTime.Now:dd.MM.yyyy}"))));
|
||||||
|
|
||||||
|
// Заголовок
|
||||||
|
body.Append(new Paragraph(new Run(new Text("Трудовой договор"))
|
||||||
|
{
|
||||||
|
RunProperties = new RunProperties
|
||||||
|
{
|
||||||
|
Bold = new Bold(),
|
||||||
|
FontSize = new FontSize { Val = "28" }
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Преамбула
|
||||||
|
body.Append(new Paragraph(new Run(new Text(
|
||||||
|
"Настоящий трудовой договор (далее – Договор) заключается между Работодателем, " +
|
||||||
|
"именуемым далее «Работодатель», и Работником, именуемым далее «Работник», на " +
|
||||||
|
"основании Трудового кодекса Российской Федерации. Работодатель обязуется " +
|
||||||
|
"предоставить Работнику работу по должности, указанной в настоящем договоре, " +
|
||||||
|
"обеспечивать необходимые условия труда, а Работник обязуется лично выполнять " +
|
||||||
|
"трудовые функции в соответствии с условиями договора."
|
||||||
|
))));
|
||||||
|
|
||||||
|
// Сведения о работнике
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Сотрудник: {employeeName}"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Должность: {jobTitle}"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Дата начала работы: {startDate:dd.MM.yyyy}"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text(endDate.HasValue ? $"Дата окончания работы: {endDate:dd.MM.yyyy}" : "Дата окончания работы: бессрочный договор"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Ставка: {hourlyRate}"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text($"Совместительство: {partTimeInfo}"))));
|
||||||
|
|
||||||
|
// Создание параграфа с текстом, который будет перенесен
|
||||||
|
body.Append(new Paragraph(
|
||||||
|
new Run(new Text("Условия трудового договора:"))));
|
||||||
|
|
||||||
|
// Пример добавления нескольких строк с переносом
|
||||||
|
string contractConditions =
|
||||||
|
"1. Рабочее время Работника составляет 40 часов в неделю, если иное не предусмотрено " +
|
||||||
|
"действующим законодательством. Работник обязуется являться на рабочее место своевременно, " +
|
||||||
|
"выполнять свои трудовые обязанности добросовестно и качественно.\n" +
|
||||||
|
"2. Работодатель обязуется своевременно выплачивать Работнику заработную плату. Заработная плата " +
|
||||||
|
"состоит из оклада и дополнительных выплат в виде премий и надбавок.\n" +
|
||||||
|
"3. Работник имеет право на ежегодный оплачиваемый отпуск продолжительностью 28 календарных дней, " +
|
||||||
|
"а также другие виды отпусков в соответствии с законодательством.\n" +
|
||||||
|
"4. Работодатель имеет право привлекать Работника к дисциплинарной ответственности в случаях, " +
|
||||||
|
"предусмотренных Трудовым кодексом РФ.";
|
||||||
|
|
||||||
|
// Разбиваем на строки и добавляем в документ
|
||||||
|
foreach (var line in contractConditions.Split('\n'))
|
||||||
|
{
|
||||||
|
body.Append(new Paragraph(new Run(new Text(line))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Права и обязанности работника
|
||||||
|
body.Append(new Paragraph(new Run(new Text("Права и обязанности Работника:"))));
|
||||||
|
string rules = "1. Работник имеет право на:\n" +
|
||||||
|
" 1.1. Получение своевременной оплаты труда.\n" +
|
||||||
|
" 1.2. Условия труда, соответствующие установленным нормам охраны труда.\n" +
|
||||||
|
" 1.3. Отдых в соответствии с трудовым законодательством Российской Федерации.\n" +
|
||||||
|
"2. Работник обязан:\n" +
|
||||||
|
" 2.1. Соблюдать правила внутреннего трудового распорядка.\n" +
|
||||||
|
" 2.2. Выполнять должностные обязанности в соответствии с трудовым договором и локальными нормативными актами Работодателя.\n" +
|
||||||
|
" 2.3. Бережно относиться к имуществу Работодателя.";
|
||||||
|
|
||||||
|
// Разбиваем на строки и добавляем в документ
|
||||||
|
foreach (var line in rules.Split('\n'))
|
||||||
|
{
|
||||||
|
body.Append(new Paragraph(new Run(new Text(line))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Права и обязанности работодателя
|
||||||
|
body.Append(new Paragraph(new Run(new Text("Права и обязанности Работодателя:"))));
|
||||||
|
string rulesRussia =
|
||||||
|
"1. Работодатель имеет право на:\n" +
|
||||||
|
" 1.1. Привлечение Работника к выполнению трудовых функций в рамках установленных обязанностей.\n" +
|
||||||
|
" 1.2. Осуществление контроля за выполнением Работником трудовых обязанностей.\n" +
|
||||||
|
"2. Работодатель обязан:\n" +
|
||||||
|
" 2.1. Своевременно выплачивать заработную плату Работнику.\n" +
|
||||||
|
" 2.2. Предоставлять Работнику возможность использовать ежегодный оплачиваемый отпуск.\n" +
|
||||||
|
" 2.3. Соблюдать нормы трудового законодательства Российской Федерации.";
|
||||||
|
|
||||||
|
// Разбиваем на строки и добавляем в документ
|
||||||
|
foreach (var line in rulesRussia.Split('\n'))
|
||||||
|
{
|
||||||
|
body.Append(new Paragraph(new Run(new Text(line))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подписи сторон
|
||||||
|
body.Append(new Paragraph(new Run(new Text("\nПодписи сторон:"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text("\nРаботодатель: _______________________"))));
|
||||||
|
body.Append(new Paragraph(new Run(new Text("\nРаботник: ___________________________"))));
|
||||||
|
|
||||||
|
// Привязка тела документа
|
||||||
|
mainPart.Document.Append(body);
|
||||||
|
mainPart.Document.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void GenerateContractButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// Проверка данных
|
||||||
|
if (string.IsNullOrWhiteSpace(JobNameTextBox.Text) ||
|
||||||
|
!StartDatePicker.SelectedDate.HasValue ||
|
||||||
|
string.IsNullOrWhiteSpace(BidTextBox.Text) ||
|
||||||
|
string.IsNullOrWhiteSpace(PhysicalPersonComboBox.Text))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Пожалуйста, заполните все обязательные поля.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение данных
|
||||||
|
string employeeName = PhysicalPersonComboBox.Text;
|
||||||
|
string jobTitle = JobNameTextBox.Text;
|
||||||
|
DateTime startDate = StartDatePicker.SelectedDate.Value;
|
||||||
|
DateTime? endDate = EndDatePicker.SelectedDate;
|
||||||
|
decimal hourlyRate = decimal.Parse(BidTextBox.Text);
|
||||||
|
string partTimeInfo = PartTimeJobTextBox.Text;
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Открытие диалогового окна для сохранения файла
|
||||||
|
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||||||
|
{
|
||||||
|
Filter = "Excel файлы (*.docx)|*.docx", // фильтр для файлов .docx
|
||||||
|
Title = "Сохранить договор о трудоустройстве", // заголовок окна
|
||||||
|
FileName = "Договор.docx" // имя по умолчанию
|
||||||
|
};
|
||||||
|
|
||||||
|
// Проверка, что пользователь выбрал путь и имя файла
|
||||||
|
if (saveFileDialog.ShowDialog() == true)
|
||||||
|
{
|
||||||
|
string filePath = saveFileDialog.FileName; // Путь и имя файла
|
||||||
|
CreateEmploymentContract(filePath, employeeName, jobTitle, startDate, endDate, hourlyRate, partTimeInfo); // Генерация отчета
|
||||||
|
MessageBox.Show($"Договор успешно сохранен: {filePath}", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка при создании документа: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
// Проверка обязательных полей
|
||||||
|
if (string.IsNullOrWhiteSpace(JobNameTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Название должности' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PartTimeJobTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Совместительство' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(BidTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Ставка' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StartDatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Начало работы' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EndDatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Конец работы' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var model = new EmployeeViewModel
|
||||||
|
{
|
||||||
|
NameJob = JobNameTextBox.Text,
|
||||||
|
StartJob = StartDatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
EndJob = EndDatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
Bid = float.Parse(BidTextBox.Text),
|
||||||
|
PartTimeJob = PartTimeJobTextBox.Text,
|
||||||
|
PhysicalPersonsId = (int?)PhysicalPersonComboBox.SelectedValue
|
||||||
|
};
|
||||||
|
|
||||||
|
_employeeLogic.Insert(model);
|
||||||
|
MessageBox.Show("Данные сотрудника успешно сохранены!");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
EmployeeManagmentView/Employee/DeleteEmployeeWindow.xaml
Normal file
52
EmployeeManagmentView/Employee/DeleteEmployeeWindow.xaml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.DeleteEmployeeWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Удаление сотрудников"
|
||||||
|
Height="500" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список сотрудников для удаления"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поле поиска -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица сотрудников -->
|
||||||
|
<DataGrid x:Name="EmployeesDataGrid"
|
||||||
|
Margin="20,100,20,80"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Должность" Binding="{Binding NameJob}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата начала" Binding="{Binding StartJob, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата окончания" Binding="{Binding EndJob, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Частичная занятость" Binding="{Binding PartTimeJob}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Ставка" Binding="{Binding Bid}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Физическое лицо" Binding="{Binding PhysicalPersonName}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<!-- Кнопка удаления -->
|
||||||
|
<Button Content="Удалить"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||||
|
Width="100" Height="40"
|
||||||
|
Margin="0,0,0,20"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="DeleteButton_Click" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
68
EmployeeManagmentView/Employee/DeleteEmployeeWindow.xaml.cs
Normal file
68
EmployeeManagmentView/Employee/DeleteEmployeeWindow.xaml.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee
|
||||||
|
{
|
||||||
|
public partial class DeleteEmployeeWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private IEnumerable<EmployeeViewModel> _allEmployees; // Список сотрудников для фильтрации
|
||||||
|
|
||||||
|
public DeleteEmployeeWindow(IEmployeeLogic employeeLogic)
|
||||||
|
{
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadEmployees();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEmployees()
|
||||||
|
{
|
||||||
|
_allEmployees = _employeeLogic.GetFullList(); // Загрузка всех данных
|
||||||
|
EmployeesDataGrid.ItemsSource = _allEmployees;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (EmployeesDataGrid.SelectedItem is EmployeeViewModel selectedEmployee)
|
||||||
|
{
|
||||||
|
// Удаление сотрудника
|
||||||
|
_employeeLogic.Delete(selectedEmployee.Id);
|
||||||
|
MessageBox.Show("Сотрудник успешно удален!");
|
||||||
|
LoadEmployees(); // Перезагрузка данных после удаления
|
||||||
|
SearchTextBox.Text = string.Empty; // Очистка поля поиска
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Пожалуйста, выберите сотрудника для удаления.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string query = SearchTextBox.Text.ToLower();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
|
{
|
||||||
|
// Отображаем все записи
|
||||||
|
EmployeesDataGrid.ItemsSource = _allEmployees;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтрация по всем полям сущности
|
||||||
|
var filteredList = _allEmployees.Where(emp =>
|
||||||
|
(emp.NameJob?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(emp.PartTimeJob?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(emp.PhysicalPersonName?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(emp.StartJob.HasValue && emp.StartJob.Value.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(emp.EndJob.HasValue && emp.EndJob.Value.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
emp.Bid.ToString().Contains(query)
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
EmployeesDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
125
EmployeeManagmentView/Employee/EditEmployeeWindow.xaml
Normal file
125
EmployeeManagmentView/Employee/EditEmployeeWindow.xaml
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.EditEmployeeWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Редактирование сотрудника"
|
||||||
|
Height="600" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,-6">
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Редактирование сотрудника"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Основная сетка -->
|
||||||
|
<Grid Margin="0,70,0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<!-- Поиск -->
|
||||||
|
<RowDefinition Height="2*" />
|
||||||
|
<!-- Редактирование -->
|
||||||
|
<RowDefinition Height="5*" />
|
||||||
|
<!-- Кнопка сохранения -->
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Блок поиска -->
|
||||||
|
<Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0, 0, 0, 0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поле для поиска сотрудников -->
|
||||||
|
<Label Grid.Row="0" Grid.Column="0"
|
||||||
|
Content="Поиск сотрудника" Foreground="White" HorizontalAlignment="Center" Margin="0,10,0,10" VerticalContentAlignment="Center"/>
|
||||||
|
<TextBox x:Name="SearchTextBox" Grid.Row="0" Grid.Column="1"
|
||||||
|
Width="250" Height="30"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,10,0,10"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
ToolTip="Введите для поиска"
|
||||||
|
TextChanged="SearchTextBox_TextChanged"/>
|
||||||
|
|
||||||
|
<!-- Поле для выбора сотрудника -->
|
||||||
|
<Label Grid.Row="1" Grid.Column="0"
|
||||||
|
Content="Выберите сотрудника" Foreground="White" HorizontalAlignment="Center" Margin="0,10,0,10" VerticalContentAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="EmployeeComboBox" Grid.Row="1" Grid.Column="1"
|
||||||
|
Width="400" Height="30"
|
||||||
|
Margin="0,10,0,10"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
ToolTip="Выберите сотрудника"
|
||||||
|
SelectionChanged="EmployeeComboBox_SelectionChanged" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Блок редактирования -->
|
||||||
|
<Grid Grid.Row="1" Margin="0,0,0,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поля редактирования -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Название работы" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="JobNameTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите название работы"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Дата начала работы" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="StartJobPicker" Width="250" Height="40"
|
||||||
|
ToolTip="Выберите дату начала" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Дата окончания работы" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="EndJobPicker" Width="250" Height="40"
|
||||||
|
ToolTip="Выберите дату окончания" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Совместительство" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PartTimeTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Укажите частичную занятость"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Ставка" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="BidTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите ставку"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Физическое лицо" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="PhysicalPersonComboBox" Width="250" Height="40"
|
||||||
|
ToolTip="Выберите физическое лицо" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Кнопка сохранения -->
|
||||||
|
<Button Grid.Row="2" Content="Сохранить изменения"
|
||||||
|
Width="250" Height="40"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="SaveButton_Click"
|
||||||
|
HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
243
EmployeeManagmentView/Employee/EditEmployeeWindow.xaml.cs
Normal file
243
EmployeeManagmentView/Employee/EditEmployeeWindow.xaml.cs
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для EditEmployeeWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class EditEmployeeWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _physicalPersonLogic;
|
||||||
|
private List<EmployeeViewModel> _employees;
|
||||||
|
|
||||||
|
public EditEmployeeWindow(IEmployeeLogic employeeLogic, IPhisicalPersonLogic physicalPersonLogic)
|
||||||
|
{
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_physicalPersonLogic = physicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadEmployees();
|
||||||
|
LoadPhysicalPersons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEmployees()
|
||||||
|
{
|
||||||
|
_employees = _employeeLogic.GetFullList();
|
||||||
|
|
||||||
|
// Заполняем комбинированное свойство, если нужно
|
||||||
|
foreach (var employee in _employees)
|
||||||
|
{
|
||||||
|
var physicalPerson = _physicalPersonLogic.GetElement(employee.PhysicalPersonsId ?? 0);
|
||||||
|
employee.PhysicalPersonName = physicalPerson?.FullNameWithBirthday;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmployeeComboBox.ItemsSource = _employees;
|
||||||
|
EmployeeComboBox.DisplayMemberPath = "DisplayText"; // Используем новое свойство
|
||||||
|
EmployeeComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void LoadPhysicalPersons()
|
||||||
|
{
|
||||||
|
var physicalPersons = _physicalPersonLogic.GetFullList();
|
||||||
|
PhysicalPersonComboBox.ItemsSource = physicalPersons;
|
||||||
|
PhysicalPersonComboBox.DisplayMemberPath = "FullNameWithBirthday";
|
||||||
|
PhysicalPersonComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmployeeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (EmployeeComboBox.SelectedValue is int selectedEmployeeId)
|
||||||
|
{
|
||||||
|
LoadEmployee(selectedEmployeeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void LoadEmployee(int employeeId)
|
||||||
|
{
|
||||||
|
var employee = _employeeLogic.GetElement(employeeId);
|
||||||
|
if (employee != null)
|
||||||
|
{
|
||||||
|
JobNameTextBox.Text = employee.NameJob;
|
||||||
|
StartJobPicker.SelectedDate = employee.StartJob;
|
||||||
|
EndJobPicker.SelectedDate = employee.EndJob;
|
||||||
|
PartTimeTextBox.Text = employee.PartTimeJob;
|
||||||
|
BidTextBox.Text = employee.Bid.ToString();
|
||||||
|
PhysicalPersonComboBox.SelectedValue = employee.PhysicalPersonsId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var searchText = SearchTextBox.Text.ToLower();
|
||||||
|
var filteredEmployees = _employees
|
||||||
|
.Where(emp => emp.NameJob.ToLower().Contains(searchText) ||
|
||||||
|
emp.PhysicalPersonName?.ToLower().Contains(searchText) == true)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
EmployeeComboBox.ItemsSource = filteredEmployees;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
// Проверка обязательных полей
|
||||||
|
if (string.IsNullOrWhiteSpace(JobNameTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Название должности' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PartTimeTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Совместительство' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(BidTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Ставка' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StartJobPicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Начало работы' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EndJobPicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Конец работы' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhysicalPersonComboBox.SelectedItem == null)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Пол' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
if (EmployeeComboBox.SelectedValue is int selectedEmployeeId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var updatedEmployee = new EmployeeViewModel
|
||||||
|
{
|
||||||
|
Id = selectedEmployeeId,
|
||||||
|
NameJob = JobNameTextBox.Text,
|
||||||
|
StartJob = StartJobPicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
EndJob = EndJobPicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
PartTimeJob = PartTimeTextBox.Text,
|
||||||
|
Bid = float.Parse(BidTextBox.Text),
|
||||||
|
PhysicalPersonsId = PhysicalPersonComboBox.SelectedValue as int?
|
||||||
|
};
|
||||||
|
|
||||||
|
_employeeLogic.Update(updatedEmployee);
|
||||||
|
MessageBox.Show("Данные успешно обновлены!");
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите сотрудника перед сохранением!", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
EmployeeManagmentView/Employee/EmployeeManagementWindow.xaml
Normal file
51
EmployeeManagmentView/Employee/EmployeeManagementWindow.xaml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.EmployeeManagementWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Управление сотрудниками"
|
||||||
|
Height="400" Width="400"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Управление сотрудниками"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Стек кнопок -->
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<!-- Кнопка "Удаление сотрудника" -->
|
||||||
|
<Button Content="Удаление сотрудника"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click ="OpenDeleteEmployeeWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Добавление сотрудника" -->
|
||||||
|
<Button Content="Добавление сотрудника"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenAddEmployeeWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Редактирование сотрудника" -->
|
||||||
|
<Button Content="Редактирование сотрудника"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenEditEmployeeWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Просмотр сотрудника" -->
|
||||||
|
<Button Content="Просмотр сотрудников"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenViewEmployeesWindow"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
100
EmployeeManagmentView/Employee/EmployeeManagementWindow.xaml.cs
Normal file
100
EmployeeManagmentView/Employee/EmployeeManagementWindow.xaml.cs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentView.PhysicalPerson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для EmployeeManagementWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class EmployeeManagementWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
|
||||||
|
public EmployeeManagementWindow(IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic, ISalaryLogic salaryLogic, IVacationLogic vacationLogic)
|
||||||
|
{
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenAddEmployeeWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is AddEmployeeWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addWindow = new AddEmployeeWindow(_employeeLogic, _phisicalPersonLogic);
|
||||||
|
addWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenDeleteEmployeeWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is DeleteEmployeeWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteWindow = new DeleteEmployeeWindow(_employeeLogic);
|
||||||
|
deleteWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenEditEmployeeWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is EditEmployeeWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var editWindow = new EditEmployeeWindow(_employeeLogic, _phisicalPersonLogic);
|
||||||
|
editWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenViewEmployeesWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is ViewEmployeeWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewWindow = new ViewEmployeeWindow(_employeeLogic, _salaryLogic, _vacationLogic, _phisicalPersonLogic);
|
||||||
|
viewWindow.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
EmployeeManagmentView/Employee/Salary/AddSalaryWindow.xaml
Normal file
78
EmployeeManagmentView/Employee/Salary/AddSalaryWindow.xaml
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Salary.AddSalaryWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Добавление зарплаты"
|
||||||
|
Height="500" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<TextBlock Text="Добавление зарплаты"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<Grid Margin="0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поле для сотрудника -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Сотрудник" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="EmployeeComboBox" Width="400" Height="40"
|
||||||
|
Background="White" Margin="0,5"
|
||||||
|
ToolTip="Выберите сотрудника" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для количества часов -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Количество часов" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="HoursTextBox" Width="200" Height="40"
|
||||||
|
Margin="0,5" ToolTip="Введите количество часов"
|
||||||
|
PreviewTextInput="NumericTextBox_PreviewTextInput"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для ставки -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Цена за час" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PriceTextBox" Width="200" Height="40"
|
||||||
|
Margin="0,5" ToolTip="Введите ставку"
|
||||||
|
PreviewTextInput="DecimalTextBox_PreviewTextInput"
|
||||||
|
TextChanged="DecimalTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для премии -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Премия" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PremiumTextBox" Width="200" Height="40"
|
||||||
|
Margin="0,5" ToolTip="Введите премию (если есть)"
|
||||||
|
PreviewTextInput="DecimalTextBox_PreviewTextInput"
|
||||||
|
TextChanged="DecimalTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для даты -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Дата" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="DatePicker" Width="200" Height="40"
|
||||||
|
Margin="0,5" ToolTip="Выберите дату выплаты" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Button Grid.Row="4" Grid.ColumnSpan="2" Content="Сохранить"
|
||||||
|
Width="200" Height="40"
|
||||||
|
Background="#004890" Foreground="White"
|
||||||
|
Margin="0,10"
|
||||||
|
Click="SaveButton_Click" HorizontalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
228
EmployeeManagmentView/Employee/Salary/AddSalaryWindow.xaml.cs
Normal file
228
EmployeeManagmentView/Employee/Salary/AddSalaryWindow.xaml.cs
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Salary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для AddSalaryWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class AddSalaryWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private List<EmployeeViewModel> _employees;
|
||||||
|
|
||||||
|
public AddSalaryWindow(ISalaryLogic salaryLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadEmployees();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка на ввод только чисел и одной запятой
|
||||||
|
private void DecimalTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Разрешаем только цифры и запятую
|
||||||
|
e.Handled = !(char.IsDigit(e.Text, 0) || e.Text == ",");
|
||||||
|
|
||||||
|
// Проверка на количество запятых
|
||||||
|
if (e.Text == "," && textBox.Text.Contains(","))
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NumericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем ввод только цифр и запятой
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Ограничение на 2 знака после запятой
|
||||||
|
private void DecimalTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Проверяем наличие запятой
|
||||||
|
int commaIndex = currentText.IndexOf(',');
|
||||||
|
|
||||||
|
if (commaIndex != -1 && currentText.Length - commaIndex > 3)
|
||||||
|
{
|
||||||
|
// Обрезаем текст до двух знаков после запятой
|
||||||
|
textBox.Text = currentText.Substring(0, commaIndex + 3);
|
||||||
|
textBox.SelectionStart = textBox.Text.Length; // Устанавливаем курсор в конец текста
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEmployees()
|
||||||
|
{
|
||||||
|
_employees = _employeeLogic.GetFullList();
|
||||||
|
|
||||||
|
// Заполняем комбинированное свойство, если нужно
|
||||||
|
foreach (var employee in _employees)
|
||||||
|
{
|
||||||
|
var physicalPerson = _phisicalPersonLogic.GetElement(employee.PhysicalPersonsId ?? 0);
|
||||||
|
employee.PhysicalPersonName = physicalPerson?.FullNameWithBirthday;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmployeeComboBox.ItemsSource = _employees;
|
||||||
|
EmployeeComboBox.DisplayMemberPath = "DisplayText"; // Используем новое свойство
|
||||||
|
EmployeeComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
// Проверка обязательных полей
|
||||||
|
if (string.IsNullOrWhiteSpace(HoursTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Название должности' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PriceTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Совместительство' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PremiumTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Ставка' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Дата зарплаты' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EmployeeComboBox.SelectedItem == null)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Сотрудник' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var salary = new SalaryViewModel
|
||||||
|
{
|
||||||
|
CountHours = int.Parse(HoursTextBox.Text),
|
||||||
|
PriceHour = float.Parse(PriceTextBox.Text),
|
||||||
|
Premium = string.IsNullOrEmpty(PremiumTextBox.Text) ? null : float.Parse(PremiumTextBox.Text),
|
||||||
|
Date = DatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
EmployeeId = (int?)EmployeeComboBox.SelectedValue
|
||||||
|
};
|
||||||
|
|
||||||
|
_salaryLogic.Insert(salary);
|
||||||
|
MessageBox.Show("Зарплата успешно сохранена!");
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Salary.DeleteSalaryWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:EmployeeManagmentDataModels.Enums;assembly=EmployeeManagmentDataModels"
|
||||||
|
Title="Удаление зарплат"
|
||||||
|
Height="600" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Window.Resources>
|
||||||
|
<local:BooleanToSalaryConverter x:Key="BooleanToSalaryConverter" />
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список зарплат"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поле поиска -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица зарплат -->
|
||||||
|
<DataGrid x:Name="SalariesDataGrid"
|
||||||
|
Margin="20,100,20,80"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Часы работы" Binding="{Binding CountHours}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Цена за час" Binding="{Binding PriceHour, StringFormat={}{0:F2}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Премия" Binding="{Binding Premium, StringFormat={}{0:F2}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата" Binding="{Binding Date, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Вылачено" Binding="{Binding Passed, Converter={StaticResource BooleanToSalaryConverter}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Сотрудник" Binding="{Binding EmployeeName}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<!-- Кнопка добавления/редактирования -->
|
||||||
|
<Button Content="Удалить"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||||
|
Width="150" Height="40"
|
||||||
|
Margin="0,0,0,20"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="DeleteButton_Click" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,82 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Salary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для DeleteSalaryWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class DeleteSalaryWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private IEnumerable<SalaryViewModel> _allSalaries;
|
||||||
|
|
||||||
|
public DeleteSalaryWindow(ISalaryLogic salaryLogic)
|
||||||
|
{
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadSalaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSalaries()
|
||||||
|
{
|
||||||
|
_allSalaries = _salaryLogic.GetFullList(); // Загрузка всех данных
|
||||||
|
SalariesDataGrid.ItemsSource = _allSalaries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (SalariesDataGrid.SelectedItem is SalaryViewModel selectedSalary)
|
||||||
|
{
|
||||||
|
// Удаление зарплаты
|
||||||
|
_salaryLogic.Delete(selectedSalary.Id);
|
||||||
|
MessageBox.Show("Зарплата успешно удалена!");
|
||||||
|
LoadSalaries(); // Перезагрузка данных после удаления
|
||||||
|
SearchTextBox.Text = string.Empty; // Очистка поля поиска
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Пожалуйста, выберите запись для удаления.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string query = SearchTextBox.Text.ToLower();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
|
{
|
||||||
|
// Отображаем все записи
|
||||||
|
SalariesDataGrid.ItemsSource = _allSalaries;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтрация по всем полям сущности
|
||||||
|
var filteredList = _allSalaries.Where(sal =>
|
||||||
|
(sal.EmployeeName?.ToLower().Contains(query) ?? false) ||
|
||||||
|
sal.CountHours.ToString().Contains(query) ||
|
||||||
|
sal.PriceHour.ToString().Contains(query) ||
|
||||||
|
sal.Passed.ToString().ToLower().Contains(query) ||
|
||||||
|
(sal.Premium.HasValue && sal.Premium.Value.ToString().Contains(query)) ||
|
||||||
|
(sal.Date.HasValue && sal.Date.Value.ToString("dd.MM.yyyy").Contains(query))
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
SalariesDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
EmployeeManagmentView/Employee/Salary/EditSalaryWindow.xaml
Normal file
84
EmployeeManagmentView/Employee/Salary/EditSalaryWindow.xaml
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Salary.EditSalaryWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Редактирование зарплаты"
|
||||||
|
Height="500" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,0">
|
||||||
|
<TextBlock Text="Редактирование зарплаты"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Блок поиска и выбора зарплаты -->
|
||||||
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,70,0,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="0" Content="Поиск зарплаты" Foreground="White" HorizontalAlignment="Center" Margin="0,0,10,10" />
|
||||||
|
<TextBox x:Name="SearchTextBox" Grid.Row="0" Grid.Column="1" Width="250" Height="30"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите для поиска"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<Label Grid.Row="1" Grid.Column="0" Content="Выберите зарплату" Foreground="White" HorizontalAlignment="Center" Margin="0,10,10,10" />
|
||||||
|
<ComboBox x:Name="SalaryComboBox" Grid.Row="1" Grid.Column="1" Width="250" Height="30"
|
||||||
|
SelectionChanged="SalaryComboBox_SelectionChanged" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Блок редактирования зарплаты -->
|
||||||
|
<Grid Margin="0,150,0,10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Часы работы" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="CountHoursTextBox" Width="250" Height="40" Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
PreviewTextInput="NumericTextBox_PreviewTextInput"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Ставка за час" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PriceHourTextBox" Width="250" Height="40" Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
PreviewTextInput="DecimalTextBox_PreviewTextInput"
|
||||||
|
TextChanged="DecimalTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Премия" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PremiumTextBox" Width="250" Height="40" Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
PreviewTextInput="DecimalTextBox_PreviewTextInput"
|
||||||
|
TextChanged="DecimalTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Дата" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="DatePicker" Width="250" Height="40" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="10">
|
||||||
|
<Label Content="Зарплата выплачена" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<CheckBox x:Name="PassedCheckBox" Content="Выплачено" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Кнопка сохранения -->
|
||||||
|
<Button Grid.Row="4" Grid.ColumnSpan="2" Content="Сохранить изменения" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="SaveButton_Click" Margin="0,10,0,0"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
255
EmployeeManagmentView/Employee/Salary/EditSalaryWindow.xaml.cs
Normal file
255
EmployeeManagmentView/Employee/Salary/EditSalaryWindow.xaml.cs
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Salary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для EditSalaryWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class EditSalaryWindow : Window
|
||||||
|
{
|
||||||
|
private readonly ISalaryLogic _salaryLogic; // Логика для работы с зарплатами
|
||||||
|
private readonly IEmployeeLogic _employeeLogic; // Логика для работы с сотрудниками
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private List<SalaryViewModel> _salaries;
|
||||||
|
private List<EmployeeViewModel> _employees; // Список сотрудников
|
||||||
|
|
||||||
|
public EditSalaryWindow(ISalaryLogic salaryLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadSalaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSalaries()
|
||||||
|
{
|
||||||
|
_salaries = _salaryLogic.GetFullList();
|
||||||
|
SalaryComboBox.ItemsSource = _salaries;
|
||||||
|
SalaryComboBox.DisplayMemberPath = "DisplayName";
|
||||||
|
SalaryComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SalaryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (SalaryComboBox.SelectedValue is int selectedSalaryId)
|
||||||
|
{
|
||||||
|
LoadSalary(selectedSalaryId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSalary(int salaryId)
|
||||||
|
{
|
||||||
|
var salary = _salaryLogic.GetElement(salaryId);
|
||||||
|
if (salary != null)
|
||||||
|
{
|
||||||
|
CountHoursTextBox.Text = salary.CountHours.ToString();
|
||||||
|
PriceHourTextBox.Text = salary.PriceHour.ToString();
|
||||||
|
PremiumTextBox.Text = salary.Premium?.ToString() ?? string.Empty;
|
||||||
|
DatePicker.SelectedDate = salary.Date;
|
||||||
|
PassedCheckBox.IsChecked = salary.Passed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Зарплата не найдена", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var searchText = SearchTextBox.Text.ToLower();
|
||||||
|
var filteredSalaries = _salaries
|
||||||
|
.Where(sal => sal.EmployeeName.ToLower().Contains(searchText))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
SalaryComboBox.ItemsSource = filteredSalaries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка на ввод только чисел и одной запятой
|
||||||
|
private void DecimalTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Разрешаем только цифры и запятую
|
||||||
|
e.Handled = !(char.IsDigit(e.Text, 0) || e.Text == ",");
|
||||||
|
|
||||||
|
// Проверка на количество запятых
|
||||||
|
if (e.Text == "," && textBox.Text.Contains(","))
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NumericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем ввод только цифр и запятой
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Ограничение на 2 знака после запятой
|
||||||
|
private void DecimalTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Проверяем наличие запятой
|
||||||
|
int commaIndex = currentText.IndexOf(',');
|
||||||
|
|
||||||
|
if (commaIndex != -1 && currentText.Length - commaIndex > 3)
|
||||||
|
{
|
||||||
|
// Обрезаем текст до двух знаков после запятой
|
||||||
|
textBox.Text = currentText.Substring(0, commaIndex + 3);
|
||||||
|
textBox.SelectionStart = textBox.Text.Length; // Устанавливаем курсор в конец текста
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
// Проверка обязательных полей
|
||||||
|
if (string.IsNullOrWhiteSpace(CountHoursTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Название должности' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PriceHourTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Совместительство' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PremiumTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Ставка' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Дата зарплаты' не выбрано.");
|
||||||
|
}
|
||||||
|
if (isValid)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (SalaryComboBox.SelectedValue is int selectedSalaryId)
|
||||||
|
{
|
||||||
|
var updatedSalary = new SalaryViewModel
|
||||||
|
{
|
||||||
|
Id = selectedSalaryId,
|
||||||
|
CountHours = int.Parse(CountHoursTextBox.Text),
|
||||||
|
PriceHour = float.Parse(PriceHourTextBox.Text),
|
||||||
|
Premium = float.TryParse(PremiumTextBox.Text, out var premium) ? premium : (float?)null,
|
||||||
|
Date = DatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
Passed = PassedCheckBox.IsChecked ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
|
_salaryLogic.Update(updatedSalary);
|
||||||
|
|
||||||
|
MessageBox.Show("Зарплата успешно обновлена!");
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите зарплату перед сохранением!", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка при сохранении данных: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Salary.SalaryManagementWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Управление зарплатой"
|
||||||
|
Height="400" Width="400"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Управление зарплатой"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Стек кнопок -->
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<!-- Кнопка "Удаление зарплаты" -->
|
||||||
|
<Button Content="Удаление зарплаты"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="OpenDeleteSalaryWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Добавление зарплаты" -->
|
||||||
|
<Button Content="Добавление зарплаты"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenAddSalaryWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Редактирование зарплаты" -->
|
||||||
|
<Button Content="Редактирование зарплаты"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenEditSalaryWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Просмотр зарплат" -->
|
||||||
|
<Button Content="Просмотр зарплат"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenViewSalaryWindow"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,101 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentView.Employee.Vacation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Salary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для SalaryManagementWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class SalaryManagementWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
|
||||||
|
public SalaryManagementWindow(ISalaryLogic salaryLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenAddSalaryWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is AddSalaryWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addWindow = new AddSalaryWindow(_salaryLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
addWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenDeleteSalaryWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is DeleteSalaryWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteWindow = new DeleteSalaryWindow(_salaryLogic);
|
||||||
|
deleteWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenEditSalaryWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is EditSalaryWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var editWindow = new EditSalaryWindow(_salaryLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
editWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenViewSalaryWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is ViewSalaryWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewWindow = new ViewSalaryWindow(_salaryLogic);
|
||||||
|
viewWindow.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
EmployeeManagmentView/Employee/Salary/ViewSalaryWindow.xaml
Normal file
56
EmployeeManagmentView/Employee/Salary/ViewSalaryWindow.xaml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Salary.ViewSalaryWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:EmployeeManagmentDataModels.Enums;assembly=EmployeeManagmentDataModels"
|
||||||
|
Title="Список зарплат"
|
||||||
|
Height="600" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Window.Resources>
|
||||||
|
<local:BooleanToSalaryConverter x:Key="BooleanToSalaryConverter" />
|
||||||
|
</Window.Resources>
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список зарплат"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поле поиска -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица зарплат -->
|
||||||
|
<DataGrid x:Name="SalariesDataGrid"
|
||||||
|
Margin="20,100,20,80"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Часы работы" Binding="{Binding CountHours}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Цена за час" Binding="{Binding PriceHour, StringFormat={}{0:F2}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Премия" Binding="{Binding Premium, StringFormat={}{0:F2}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата" Binding="{Binding Date, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Оплачено" Binding="{Binding Passed, Converter={StaticResource BooleanToSalaryConverter}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Работник" Binding="{Binding EmployeeName}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<!-- Кнопка генерации отчета -->
|
||||||
|
<Button Content="Генерация отчета"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||||
|
Width="150" Height="40"
|
||||||
|
Margin="0,0,0,20"
|
||||||
|
Background="#004890"
|
||||||
|
Click="ExportToExcelButton_Click"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
|
|
180
EmployeeManagmentView/Employee/Salary/ViewSalaryWindow.xaml.cs
Normal file
180
EmployeeManagmentView/Employee/Salary/ViewSalaryWindow.xaml.cs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
using DocumentFormat.OpenXml.Packaging;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using DocumentFormat.OpenXml;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Salary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для ViewSalaryWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class ViewSalaryWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private IEnumerable<SalaryViewModel> _allSalaries;
|
||||||
|
|
||||||
|
public ViewSalaryWindow(ISalaryLogic salaryLogic)
|
||||||
|
{
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadSalaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSalaries()
|
||||||
|
{
|
||||||
|
_allSalaries = _salaryLogic.GetFullList(); // Загрузка всех данных
|
||||||
|
SalariesDataGrid.ItemsSource = _allSalaries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExportToExcelButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Получаем данные о зарплатах
|
||||||
|
var salaries = _salaryLogic.GetFullList();
|
||||||
|
|
||||||
|
if (salaries == null || !salaries.Any())
|
||||||
|
{
|
||||||
|
MessageBox.Show("Нет данных для экспорта.", "Внимание", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Открытие диалогового окна для сохранения файла
|
||||||
|
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||||||
|
{
|
||||||
|
Filter = "Excel файлы (*.xlsx)|*.xlsx", // фильтр для файлов .xlsx
|
||||||
|
Title = "Сохранить отчет об зарплатах", // заголовок окна
|
||||||
|
FileName = "Отчет_зарплат.xlsx" // имя по умолчанию
|
||||||
|
};
|
||||||
|
|
||||||
|
// Проверка, что пользователь выбрал путь и имя файла
|
||||||
|
if (saveFileDialog.ShowDialog() == true)
|
||||||
|
{
|
||||||
|
string filePath = saveFileDialog.FileName; // Путь и имя файла
|
||||||
|
GenerateExcelReport(filePath, salaries); // Генерация отчета
|
||||||
|
MessageBox.Show($"Отчет успешно сохранен: {filePath}", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка экспорта: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateExcelReport(string filePath, List<SalaryViewModel> salaries)
|
||||||
|
{
|
||||||
|
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
|
||||||
|
{
|
||||||
|
// Создаем Workbook
|
||||||
|
WorkbookPart workbookPart = document.AddWorkbookPart();
|
||||||
|
workbookPart.Workbook = new Workbook();
|
||||||
|
|
||||||
|
// Создаем Worksheet
|
||||||
|
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
|
||||||
|
worksheetPart.Worksheet = new Worksheet(new SheetData());
|
||||||
|
|
||||||
|
// Добавляем лист в Workbook
|
||||||
|
Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
|
||||||
|
Sheet sheet = new Sheet()
|
||||||
|
{
|
||||||
|
Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
|
||||||
|
SheetId = 1,
|
||||||
|
Name = "Зарплаты"
|
||||||
|
};
|
||||||
|
sheets.Append(sheet);
|
||||||
|
|
||||||
|
// Получаем SheetData
|
||||||
|
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
|
||||||
|
|
||||||
|
// Заполняем заголовки
|
||||||
|
Row headerRow = new Row();
|
||||||
|
headerRow.Append(
|
||||||
|
CreateTextCell("A", "ID"),
|
||||||
|
CreateTextCell("B", "Сотрудник"),
|
||||||
|
CreateTextCell("C", "Часы"),
|
||||||
|
CreateTextCell("D", "Ставка"),
|
||||||
|
CreateTextCell("E", "Премия"),
|
||||||
|
CreateTextCell("F", "Дата"),
|
||||||
|
CreateTextCell("G", "Статус оплаты") // Добавлен заголовок для Passed
|
||||||
|
);
|
||||||
|
sheetData.AppendChild(headerRow);
|
||||||
|
|
||||||
|
// Заполняем данные
|
||||||
|
foreach (var salary in salaries)
|
||||||
|
{
|
||||||
|
Row row = new Row();
|
||||||
|
row.Append(
|
||||||
|
CreateTextCell("A", salary.Id.ToString()),
|
||||||
|
CreateTextCell("B", salary.EmployeeName),
|
||||||
|
CreateTextCell("C", salary.CountHours.ToString()),
|
||||||
|
CreateTextCell("D", salary.PriceHour.ToString("F2")),
|
||||||
|
CreateTextCell("E", salary.Premium?.ToString("F2") ?? "0"),
|
||||||
|
CreateTextCell("F", salary.Date.Value.ToString("dd.MM.yyyy")),
|
||||||
|
CreateTextCell("G", salary.Passed ? "Заплачено" : "Не заплачено") // Используем поле Passed
|
||||||
|
);
|
||||||
|
sheetData.AppendChild(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
workbookPart.Workbook.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Метод для создания текстовой ячейки
|
||||||
|
private Cell CreateTextCell(string columnName, string text)
|
||||||
|
{
|
||||||
|
return new Cell
|
||||||
|
{
|
||||||
|
DataType = CellValues.String,
|
||||||
|
CellReference = columnName,
|
||||||
|
CellValue = new CellValue(text)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string query = SearchTextBox.Text.ToLower();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
|
{
|
||||||
|
// Отображаем все записи
|
||||||
|
SalariesDataGrid.ItemsSource = _allSalaries;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтрация по всем полям сущности
|
||||||
|
var filteredList = _allSalaries.Where(sal =>
|
||||||
|
(sal.EmployeeName?.ToLower().Contains(query) ?? false) ||
|
||||||
|
sal.CountHours.ToString().Contains(query) ||
|
||||||
|
sal.PriceHour.ToString().Contains(query) ||
|
||||||
|
(sal.Premium.HasValue && sal.Premium.Value.ToString().Contains(query)) ||
|
||||||
|
(sal.Date.HasValue && sal.Date.Value.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(sal.Passed ? "заплачено" : "не заплачено").Contains(query) // Добавлен фильтр для Passed
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
SalariesDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Vacation.AddVacationWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Добавление отпуска"
|
||||||
|
Height="450" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<TextBlock Text="Добавление отпуска"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<Grid Margin="0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поле для сотрудника -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Сотрудник" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="EmployeeComboBox" Width="400" Height="40"
|
||||||
|
Background="White" Margin="0,5"
|
||||||
|
ToolTip="Выберите сотрудника" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для начала отпуска -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Дата начала" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="StartDatePicker" Width="200" Height="40"
|
||||||
|
Margin="0,5" ToolTip="Выберите дату начала отпуска" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для окончания отпуска -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Дата окончания" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="EndDatePicker" Width="200" Height="40"
|
||||||
|
Margin="0,5" ToolTip="Выберите дату окончания отпуска" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Чекбокс для отметки пройденного отпуска -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Center" Margin="0,10">
|
||||||
|
<CheckBox x:Name="PassedCheckBox" Content="Отпуск завершен" Foreground="White"
|
||||||
|
FontSize="14" VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Button Grid.Row="3" Grid.ColumnSpan="2" Content="Сохранить"
|
||||||
|
Width="200" Height="40"
|
||||||
|
Background="#004890" Foreground="White"
|
||||||
|
Margin="0,10"
|
||||||
|
Click="SaveButton_Click" HorizontalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,172 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Vacation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для AddVacationWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class AddVacationWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private List<EmployeeViewModel> _employees;
|
||||||
|
|
||||||
|
public AddVacationWindow(IVacationLogic vacationLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadEmployees();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEmployees()
|
||||||
|
{
|
||||||
|
_employees = _employeeLogic.GetFullList();
|
||||||
|
|
||||||
|
// Заполняем комбинированное свойство, если нужно
|
||||||
|
foreach (var employee in _employees)
|
||||||
|
{
|
||||||
|
var physicalPerson = _phisicalPersonLogic.GetElement(employee.PhysicalPersonsId ?? 0);
|
||||||
|
employee.PhysicalPersonName = physicalPerson?.FullNameWithBirthday;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmployeeComboBox.ItemsSource = _employees;
|
||||||
|
EmployeeComboBox.DisplayMemberPath = "DisplayText"; // Используем новое свойство
|
||||||
|
EmployeeComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
|
||||||
|
if (!StartDatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Начало отпуска' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EndDatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Конец отпуска' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EmployeeComboBox.SelectedItem == null)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Сотрудник' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var vacation = new VacationViewModel
|
||||||
|
{
|
||||||
|
StartData = StartDatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
EndData = EndDatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
Passed = PassedCheckBox.IsChecked ?? false,
|
||||||
|
EmployeeId = (int?)EmployeeComboBox.SelectedValue
|
||||||
|
};
|
||||||
|
|
||||||
|
_vacationLogic.Insert(vacation);
|
||||||
|
MessageBox.Show("Отпуск успешно сохранен!");
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Vacation.DeleteVacationWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:EmployeeManagmentDataModels.Enums;assembly=EmployeeManagmentDataModels"
|
||||||
|
Title="Удаление отпуска"
|
||||||
|
Height="600" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Window.Resources>
|
||||||
|
<local:BooleanToVacationConverter x:Key="BooleanToVacationConverter" />
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список отпусков"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поле поиска -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица отпусков -->
|
||||||
|
<DataGrid x:Name="VacationsDataGrid"
|
||||||
|
Margin="20,100,20,80"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Дата начала" Binding="{Binding StartData, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата окончания" Binding="{Binding EndData, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Заврешен" Binding="{Binding Passed, Converter={StaticResource BooleanToVacationConverter}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Сотрудник" Binding="{Binding EmployeeName}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<!-- Удалить -->
|
||||||
|
<Button Content="Удалить"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||||
|
Width="150" Height="40"
|
||||||
|
Margin="0,0,0,20"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="DeleteButton_Click" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,79 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Vacation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для DeleteVacationWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class DeleteVacationWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
private IEnumerable<VacationViewModel> _allVacations;
|
||||||
|
|
||||||
|
public DeleteVacationWindow(IVacationLogic vacationLogic)
|
||||||
|
{
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadVacations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadVacations()
|
||||||
|
{
|
||||||
|
_allVacations = _vacationLogic.GetFullList(); // Загрузка всех данных
|
||||||
|
VacationsDataGrid.ItemsSource = _allVacations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (VacationsDataGrid.SelectedItem is VacationViewModel selectedVacation)
|
||||||
|
{
|
||||||
|
// Удаление отпуска
|
||||||
|
_vacationLogic.Delete(selectedVacation.Id);
|
||||||
|
MessageBox.Show("Отпуск успешно удален!");
|
||||||
|
LoadVacations(); // Перезагрузка данных после удаления
|
||||||
|
SearchTextBox.Text = string.Empty; // Очистка поля поиска
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Пожалуйста, выберите запись для удаления.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string query = SearchTextBox.Text.ToLower();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
|
{
|
||||||
|
// Отображаем все записи
|
||||||
|
VacationsDataGrid.ItemsSource = _allVacations;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтрация по всем полям сущности
|
||||||
|
var filteredList = _allVacations.Where(vac =>
|
||||||
|
(vac.EmployeeName?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(vac.StartData.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(vac.EndData.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(vac.Passed.ToString().ToLower().Contains(query))
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
VacationsDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Vacation.EditVacationWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Редактирование отпуска"
|
||||||
|
Height="450" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,0">
|
||||||
|
<TextBlock Text="Редактирование отпуска"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Блок поиска и выбора отпуска -->
|
||||||
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,70,0,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Label Grid.Row="0" Grid.Column="0" Content="Поиск отпуска" Foreground="White" HorizontalAlignment="Center" Margin="0,0,10,10" />
|
||||||
|
<TextBox x:Name="SearchTextBox" Grid.Row="0" Grid.Column="1" Width="250" Height="30"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите для поиска"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<Label Grid.Row="1" Grid.Column="0" Content="Выберите отпуск" Foreground="White" HorizontalAlignment="Center" Margin="0,10,10,10" />
|
||||||
|
<ComboBox x:Name="VacationComboBox" Grid.Row="1" Grid.Column="1" Width="250" Height="30"
|
||||||
|
SelectionChanged="VacationComboBox_SelectionChanged" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Блок редактирования отпуска -->
|
||||||
|
<Grid Margin="0,150,0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Дата начала" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="StartDatePicker" Width="250" Height="40" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Дата окончания" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="EndDatePicker" Width="250" Height="40" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Margin="10" HorizontalAlignment="Center">
|
||||||
|
<Label Content="Завершение отпуска" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<CheckBox x:Name="PassedCheckBox" Content="Завершено" Foreground="White" HorizontalAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Кнопка сохранения -->
|
||||||
|
<Button Grid.Row="4" Grid.ColumnSpan="2" Content="Сохранить изменения" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="SaveButton_Click" Margin="0,10,0,0"/>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,200 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Vacation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для EditVacationWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class EditVacationWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IVacationLogic _vacationLogic; // Логика для работы с отпусками
|
||||||
|
private readonly IEmployeeLogic _employeeLogic; // Логика для работы с сотрудниками
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private List<VacationViewModel> _vacations;
|
||||||
|
private List<EmployeeViewModel> _employees; // Список сотрудников
|
||||||
|
|
||||||
|
public EditVacationWindow(IVacationLogic vacationLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadVacations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadVacations()
|
||||||
|
{
|
||||||
|
_vacations = _vacationLogic.GetFullList();
|
||||||
|
VacationComboBox.ItemsSource = _vacations;
|
||||||
|
VacationComboBox.DisplayMemberPath = "DisplayName";
|
||||||
|
VacationComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VacationComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (VacationComboBox.SelectedValue is int selectedVacationId)
|
||||||
|
{
|
||||||
|
LoadVacation(selectedVacationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadVacation(int vacationId)
|
||||||
|
{
|
||||||
|
var vacation = _vacationLogic.GetElement(vacationId);
|
||||||
|
if (vacation != null)
|
||||||
|
{
|
||||||
|
StartDatePicker.SelectedDate = vacation.StartData;
|
||||||
|
EndDatePicker.SelectedDate = vacation.EndData;
|
||||||
|
PassedCheckBox.IsChecked = vacation.Passed;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Отпуск не найден", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var searchText = SearchTextBox.Text.ToLower();
|
||||||
|
var filteredVacations = _vacations
|
||||||
|
.Where(vac => vac.EmployeeName.ToLower().Contains(searchText))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
VacationComboBox.ItemsSource = filteredVacations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
|
||||||
|
if (!StartDatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Начало отпуска' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EndDatePicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Конец отпуска' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (VacationComboBox.SelectedValue is int selectedVacationId)
|
||||||
|
{
|
||||||
|
var updatedVacation = new VacationViewModel
|
||||||
|
{
|
||||||
|
Id = selectedVacationId,
|
||||||
|
StartData = StartDatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
EndData = EndDatePicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
Passed = PassedCheckBox.IsChecked ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
|
_vacationLogic.Update(updatedVacation);
|
||||||
|
|
||||||
|
MessageBox.Show("Отпуск успешно обновлен!");
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите отпуск перед сохранением!", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка при сохранении данных: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Vacation.VacationManagementWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Управление отпуском"
|
||||||
|
Height="400" Width="400"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Управление отпуском"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Стек кнопок -->
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<!-- Кнопка "Удаление отпуска" -->
|
||||||
|
<Button Content="Удаление отпуска"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="OpenDeleteVacationWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Добавление отпуска" -->
|
||||||
|
<Button Content="Добавление отпуска"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenAddVacationWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Редактирование отпуска" -->
|
||||||
|
<Button Content="Редактирование отпуска"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenEditVacationWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Просмотр отпусков" -->
|
||||||
|
<Button Content="Просмотр отпусков"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenViewVacationWindow"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
|
|
@ -0,0 +1,99 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Vacation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для VacationManagementWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class VacationManagementWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
|
||||||
|
public VacationManagementWindow(IVacationLogic vacationLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenAddVacationWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is AddVacationWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addWindow = new AddVacationWindow(_vacationLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
addWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenDeleteVacationWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is DeleteVacationWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteWindow = new DeleteVacationWindow(_vacationLogic);
|
||||||
|
deleteWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenEditVacationWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is EditVacationWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var editWindow = new EditVacationWindow(_vacationLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
editWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenViewVacationWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is ViewVacationWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewWindow = new ViewVacationWindow(_vacationLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
viewWindow.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.Vacation.ViewVacationWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:EmployeeManagmentDataModels.Enums;assembly=EmployeeManagmentDataModels"
|
||||||
|
Title="Управление отпусками"
|
||||||
|
Height="600" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Window.Resources>
|
||||||
|
<local:BooleanToVacationConverter x:Key="BooleanToVacationConverter" />
|
||||||
|
</Window.Resources>
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список отпусков"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поле поиска -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица отпусков -->
|
||||||
|
<DataGrid x:Name="VacationsDataGrid"
|
||||||
|
Margin="20,100,20,80"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Дата начала" Binding="{Binding StartData, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата окончания" Binding="{Binding EndData, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Заврешен" Binding="{Binding Passed, Converter={StaticResource BooleanToVacationConverter}}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Работник" Binding="{Binding EmployeeName}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<!-- Кнопка отчета -->
|
||||||
|
<Button Content="Генерация отчета"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||||
|
Width="150" Height="40"
|
||||||
|
Margin="0,0,0,20"
|
||||||
|
Click="ExportToExcelButton_Click"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,173 @@
|
|||||||
|
using DocumentFormat.OpenXml.Packaging;
|
||||||
|
using DocumentFormat.OpenXml.Spreadsheet;
|
||||||
|
using DocumentFormat.OpenXml;
|
||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee.Vacation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для ViewVacationWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class ViewVacationWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private IEnumerable<VacationViewModel> _allVacations;
|
||||||
|
private List<EmployeeViewModel> _employees;
|
||||||
|
|
||||||
|
public ViewVacationWindow(IVacationLogic vacationLogic, IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadVacations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadVacations()
|
||||||
|
{
|
||||||
|
_allVacations = _vacationLogic.GetFullList(); // Загрузка всех данных
|
||||||
|
VacationsDataGrid.ItemsSource = _allVacations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExportToExcelButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var vacations = _vacationLogic.GetFullList();
|
||||||
|
|
||||||
|
if (vacations == null || !vacations.Any())
|
||||||
|
{
|
||||||
|
MessageBox.Show("Нет данных для экспорта.", "Внимание", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Открытие диалогового окна для сохранения файла
|
||||||
|
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||||||
|
{
|
||||||
|
Filter = "Excel файлы (*.xlsx)|*.xlsx",
|
||||||
|
Title = "Сохранить отчет об отпусках",
|
||||||
|
FileName = "Отчет_отпуска.xlsx"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (saveFileDialog.ShowDialog() == true)
|
||||||
|
{
|
||||||
|
string filePath = saveFileDialog.FileName; // Путь и имя файла
|
||||||
|
GenerateExcelReport(filePath, vacations); // Генерация отчета
|
||||||
|
MessageBox.Show($"Отчет успешно сохранен: {filePath}", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка экспорта: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateExcelReport(string filePath, List<VacationViewModel> vacations)
|
||||||
|
{
|
||||||
|
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
|
||||||
|
{
|
||||||
|
// Создаем Workbook
|
||||||
|
WorkbookPart workbookPart = document.AddWorkbookPart();
|
||||||
|
workbookPart.Workbook = new Workbook();
|
||||||
|
|
||||||
|
// Создаем Worksheet
|
||||||
|
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
|
||||||
|
worksheetPart.Worksheet = new Worksheet(new SheetData());
|
||||||
|
|
||||||
|
// Добавляем лист в Workbook
|
||||||
|
Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
|
||||||
|
Sheet sheet = new Sheet()
|
||||||
|
{
|
||||||
|
Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
|
||||||
|
SheetId = 1,
|
||||||
|
Name = "Отпуска"
|
||||||
|
};
|
||||||
|
sheets.Append(sheet);
|
||||||
|
|
||||||
|
// Получаем SheetData
|
||||||
|
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
|
||||||
|
|
||||||
|
// Заполняем заголовки
|
||||||
|
Row headerRow = new Row();
|
||||||
|
headerRow.Append(
|
||||||
|
CreateTextCell("A", "ID"),
|
||||||
|
CreateTextCell("B", "Сотрудник"),
|
||||||
|
CreateTextCell("C", "Дата начала"),
|
||||||
|
CreateTextCell("D", "Дата окончания"),
|
||||||
|
CreateTextCell("E", "Статус")
|
||||||
|
);
|
||||||
|
sheetData.AppendChild(headerRow);
|
||||||
|
|
||||||
|
// Заполняем данные
|
||||||
|
foreach (var vacation in vacations)
|
||||||
|
{
|
||||||
|
Row row = new Row();
|
||||||
|
row.Append(
|
||||||
|
CreateTextCell("A", vacation.Id.ToString()),
|
||||||
|
CreateTextCell("B", vacation.EmployeeName),
|
||||||
|
CreateTextCell("C", vacation.StartData.ToString("dd.MM.yyyy")),
|
||||||
|
CreateTextCell("D", vacation.EndData.ToString("dd.MM.yyyy")),
|
||||||
|
CreateTextCell("E", vacation.Passed ? "Проведен" : "Не проведен")
|
||||||
|
);
|
||||||
|
sheetData.AppendChild(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
workbookPart.Workbook.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для создания текстовой ячейки
|
||||||
|
private Cell CreateTextCell(string columnName, string text)
|
||||||
|
{
|
||||||
|
return new Cell
|
||||||
|
{
|
||||||
|
DataType = CellValues.String,
|
||||||
|
CellReference = columnName,
|
||||||
|
CellValue = new CellValue(text)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string query = SearchTextBox.Text.ToLower();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
|
{
|
||||||
|
// Отображаем все записи
|
||||||
|
VacationsDataGrid.ItemsSource = _allVacations;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтрация по всем полям сущности
|
||||||
|
var filteredList = _allVacations.Where(vac =>
|
||||||
|
(vac.EmployeeName?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(vac.StartData.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(vac.EndData.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(vac.Passed.ToString().ToLower().Contains(query))
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
VacationsDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
61
EmployeeManagmentView/Employee/ViewEmployeeWindow.xaml
Normal file
61
EmployeeManagmentView/Employee/ViewEmployeeWindow.xaml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.Employee.ViewEmployeeWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Просмотр сотрудников"
|
||||||
|
Height="500" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список сотрудников"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поле поиска -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица сотрудников -->
|
||||||
|
<DataGrid x:Name="EmployeesDataGrid"
|
||||||
|
Margin="20,100,20,75"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Должность" Binding="{Binding NameJob}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата начала" Binding="{Binding StartJob, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата окончания" Binding="{Binding EndJob, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Частичная занятость" Binding="{Binding PartTimeJob}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Ставка" Binding="{Binding Bid}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Физическое лицо" Binding="{Binding PhysicalPersonName}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<Button Content="Работа с отпусками"
|
||||||
|
HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
||||||
|
Width="200" Height="40"
|
||||||
|
Margin="180,0,0,20"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="OpenVacationManagementWindow"/>
|
||||||
|
|
||||||
|
<Button Content="Работа с зарплатой"
|
||||||
|
HorizontalAlignment="Right" VerticalAlignment="Bottom"
|
||||||
|
Width="200" Height="40"
|
||||||
|
Margin="0,0,180,20"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="White"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="OpenSalaryManagementWindow"/>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
118
EmployeeManagmentView/Employee/ViewEmployeeWindow.xaml.cs
Normal file
118
EmployeeManagmentView/Employee/ViewEmployeeWindow.xaml.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentView.Employee.Salary;
|
||||||
|
using EmployeeManagmentView.Employee.Vacation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.Employee
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Логика взаимодействия для ViewEmployeeWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class ViewEmployeeWindow : Window
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private IEnumerable<EmployeeViewModel> _allEmployees; // Список сотрудников для фильтрации
|
||||||
|
private List<EmployeeViewModel> _employees;
|
||||||
|
|
||||||
|
public ViewEmployeeWindow(IEmployeeLogic employeeLogic, ISalaryLogic salaryLogic, IVacationLogic vacationLogic, IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadEmployees();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEmployees()
|
||||||
|
{
|
||||||
|
_allEmployees = _employeeLogic.GetFullList(); // Загрузка всех данных
|
||||||
|
EmployeesDataGrid.ItemsSource = _allEmployees;
|
||||||
|
|
||||||
|
_employees = _employeeLogic.GetFullList();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string query = SearchTextBox.Text.ToLower();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(query))
|
||||||
|
{
|
||||||
|
// Отображаем все записи
|
||||||
|
EmployeesDataGrid.ItemsSource = _allEmployees;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтрация по всем полям сущности
|
||||||
|
var filteredList = _allEmployees.Where(emp =>
|
||||||
|
(emp.NameJob?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(emp.PartTimeJob?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(emp.PhysicalPersonName?.ToLower().Contains(query) ?? false) ||
|
||||||
|
(emp.StartJob.HasValue && emp.StartJob.Value.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
(emp.EndJob.HasValue && emp.EndJob.Value.ToString("dd.MM.yyyy").Contains(query)) ||
|
||||||
|
emp.Bid.ToString().Contains(query)
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
EmployeesDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenSalaryManagementWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is SalaryManagementWindow)
|
||||||
|
{
|
||||||
|
// Если окно уже открыто, активируем его и ставим на передний план
|
||||||
|
window.Activate();
|
||||||
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
|
window.Topmost = true; // Ставим окно на передний план
|
||||||
|
window.Topmost = false; // Сразу снимаем флаг, чтобы окно не оставалось всегда наверху
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var salaryWindow = new SalaryManagementWindow(_salaryLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
salaryWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenVacationManagementWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is VacationManagementWindow)
|
||||||
|
{
|
||||||
|
// Если окно уже открыто, активируем его и ставим на передний план
|
||||||
|
window.Activate();
|
||||||
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
|
window.Topmost = true; // Ставим окно на передний план
|
||||||
|
window.Topmost = false; // Сразу снимаем флаг, чтобы окно не оставалось всегда наверху
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var vacationWindow = new VacationManagementWindow(_vacationLogic, _employeeLogic, _phisicalPersonLogic);
|
||||||
|
vacationWindow.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,4 +8,28 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.6.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentBusinessLogic\EmployeeManagmentBusinessLogic.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentContracts\EmployeeManagmentContracts.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataBaseImplement\EmployeeManagmentDataBaseImplement.csproj" />
|
||||||
|
<ProjectReference Include="..\EmployeeManagmentDataModels\EmployeeManagmentDataModels.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<Window x:Class="EmployeeManagmentView.EmployeesWindow"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
Title="Employees" Height="450" Width="800">
|
|
||||||
<Grid>
|
|
||||||
<TextBlock Text="Список сотрудников" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
||||||
</Grid>
|
|
||||||
</Window>
|
|
@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Data;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using System.Windows.Shapes;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentView
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Логика взаимодействия для EmployeesWindow.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class EmployeesWindow : Window
|
|
||||||
{
|
|
||||||
public EmployeesWindow()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +1,30 @@
|
|||||||
<Window x:Class="EmployeeManagmentView.MainWindow"
|
<Window x:Class="EmployeeManagmentView.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
Title="Отдел кадров УлГТУ" Height="450" Width="800" Background="#0D2D4F"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
MinWidth="400" MinHeight="300"
|
||||||
mc:Ignorable="d"
|
WindowStartupLocation="CenterScreen"
|
||||||
Title="Employee Management System"
|
MaxWidth="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}}"
|
||||||
Height="450" Width="800">
|
MaxHeight="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}}">
|
||||||
<Grid>
|
|
||||||
<StackPanel>
|
|
||||||
<TextBlock Text="Система управления сотрудниками"
|
|
||||||
FontSize="24"
|
|
||||||
FontWeight="Bold"
|
|
||||||
Margin="10"/>
|
|
||||||
|
|
||||||
<Button Content="Просмотр сотрудников"
|
|
||||||
Width="200"
|
<Grid>
|
||||||
Height="40"
|
<!-- Заголовок -->
|
||||||
Margin="10"
|
<TextBlock Text="Отдел кадров УлГТУ"
|
||||||
Click="ViewEmployees_Click"/>
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
<Button Content="Управление зарплатами"
|
FontSize="24" FontWeight="Bold"
|
||||||
Width="200"
|
Foreground="#FFFFFF" Margin="0,20,0,0" />
|
||||||
Height="40"
|
|
||||||
Margin="10"
|
<!-- Центральный StackPanel -->
|
||||||
Click="ManageSalaries_Click"/>
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,40">
|
||||||
<Button Content="Управление отпусками"
|
<!-- Кнопка 1 -->
|
||||||
Width="200"
|
<Button Content="Работа с сотрудниками" Width="200" Height="50" Margin="0,10"
|
||||||
Height="40"
|
Background="#004890" Foreground="#FFFFFF" FontSize="16"
|
||||||
Margin="10"
|
Style="{StaticResource RoundedButtonStyle}" Click="OpenEmployeeManagementWindow"/>
|
||||||
Click="ManageVacations_Click"/>
|
<!-- Кнопка 2 -->
|
||||||
|
<Button Content="Работа с физ. лицами" Width="200" Height="50" Margin="0,10"
|
||||||
|
Background="#004890" Foreground="#FFFFFF" FontSize="16"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}" Click="OpenPhysicalPersonManagementWindow"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
@ -1,45 +1,71 @@
|
|||||||
using System.Text;
|
using EmployeeManagmentBusinessLogic.BusinessLogic;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using EmployeeManagmentView.Employee;
|
||||||
|
using EmployeeManagmentView.PhysicalPerson;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Data;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using System.Windows.Navigation;
|
|
||||||
using System.Windows.Shapes;
|
|
||||||
|
|
||||||
namespace EmployeeManagmentView
|
namespace EmployeeManagmentView
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for MainWindow.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
public MainWindow()
|
|
||||||
|
private readonly IEmployeeLogic _employeeLogic;
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private readonly ISalaryLogic _salaryLogic;
|
||||||
|
private readonly IVacationLogic _vacationLogic;
|
||||||
|
|
||||||
|
// Constructor with Dependency Injection
|
||||||
|
public MainWindow(IEmployeeLogic employeeLogic, IPhisicalPersonLogic phisicalPersonLogic, ISalaryLogic salaryLogic, IVacationLogic vacationLogic)
|
||||||
{
|
{
|
||||||
|
_employeeLogic = employeeLogic;
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
_salaryLogic = salaryLogic;
|
||||||
|
_vacationLogic = vacationLogic;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ViewEmployees_Click(object sender, RoutedEventArgs e)
|
public MainWindow()
|
||||||
{
|
{
|
||||||
// Логика для открытия окна просмотра сотрудников
|
|
||||||
var employeesWindow = new EmployeesWindow();
|
|
||||||
employeesWindow.Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ManageSalaries_Click(object sender, RoutedEventArgs e)
|
public void OpenPhysicalPersonManagementWindow(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Логика для открытия окна управления зарплатами
|
foreach (Window window in Application.Current.Windows)
|
||||||
var salariesWindow = new SalariesWindow();
|
{
|
||||||
salariesWindow.Show();
|
if (window is PhysicalPersonManagementWindow)
|
||||||
|
{
|
||||||
|
// Если окно уже открыто, активируем его и ставим на передний план
|
||||||
|
window.Activate();
|
||||||
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
|
window.Topmost = true; // Ставим окно на передний план
|
||||||
|
window.Topmost = false; // Сразу снимаем флаг, чтобы окно не оставалось всегда наверху
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var physicalPersonWindow = new PhysicalPersonManagementWindow(_phisicalPersonLogic);
|
||||||
|
physicalPersonWindow.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ManageVacations_Click(object sender, RoutedEventArgs e)
|
public void OpenEmployeeManagementWindow(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Логика для открытия окна управления отпусками
|
foreach (Window window in Application.Current.Windows)
|
||||||
var vacationsWindow = new VacationsWindow();
|
{
|
||||||
vacationsWindow.Show();
|
if (window is EmployeeManagementWindow)
|
||||||
|
{
|
||||||
|
// Если окно уже открыто, активируем его и ставим на передний план
|
||||||
|
window.Activate();
|
||||||
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
|
window.Topmost = true; // Ставим окно на передний план
|
||||||
|
window.Topmost = false; // Сразу снимаем флаг, чтобы окно не оставалось всегда наверху
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var employeeWindow = new EmployeeManagementWindow(_employeeLogic, _phisicalPersonLogic, _salaryLogic, _vacationLogic);
|
||||||
|
employeeWindow.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,132 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.PhysicalPerson.AddPhysicalPersonWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||||
|
Title="Добавление физического лица"
|
||||||
|
Height="600" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Добавление физического лица"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Сетка для ввода данных в два столбца -->
|
||||||
|
<Grid Margin="0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поле для имени -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Имя" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="NameTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Введите имя" HorizontalAlignment="Center"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Поле для фамилии -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Фамилия" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="SurnameTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"
|
||||||
|
ToolTip="Введите фамилию" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для отчества -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Отчество" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PatronomicTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"
|
||||||
|
ToolTip="Введите отчество" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для выбора даты рождения -->
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Дата рождения" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="BirthdayPicker"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Выберите дату рождения" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Поле для выбора пола -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Пол" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="GenderComboBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Выберите пол"
|
||||||
|
Background="White" HorizontalAlignment="Center">
|
||||||
|
<ComboBoxItem Content="Мужчина"/>
|
||||||
|
<ComboBoxItem Content="Женщина"/>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для адреса -->
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Адрес" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="AddressTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Введите адрес" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Поле для телефона -->
|
||||||
|
<StackPanel Grid.Row="3" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Label Content="Телефон" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="TelephoneTextBox"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,5"
|
||||||
|
ToolTip="Введите номер телефона"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Foreground="Black"
|
||||||
|
PreviewTextInput="TelephoneTextBox_PreviewTextInput"
|
||||||
|
TextChanged="TelephoneTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Кнопка для добавления физического лица -->
|
||||||
|
<Button Grid.Row="4" Grid.ColumnSpan="2" Content="Добавить физическое лицо"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="SaveButton_Click"
|
||||||
|
Background="#004890" Foreground="#FFFFFF" HorizontalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,167 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.PhysicalPerson
|
||||||
|
{
|
||||||
|
public partial class AddPhysicalPersonWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
|
||||||
|
public AddPhysicalPersonWindow(IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
// Проверка обязательных полей
|
||||||
|
if (string.IsNullOrWhiteSpace(NameTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Имя' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(SurnameTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Фамилия' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PatronomicTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Отчество' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BirthdayPicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Дата рождения' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (GenderComboBox.SelectedItem == null)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Пол' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(AddressTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Адрес' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(TelephoneTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Телефон' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var model = new PhisicalPersonViewModel
|
||||||
|
{
|
||||||
|
Name = NameTextBox.Text,
|
||||||
|
Surname = SurnameTextBox.Text,
|
||||||
|
Patronymic = PatronomicTextBox.Text,
|
||||||
|
Birthday = BirthdayPicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
Gender = GenderComboBox.Text,
|
||||||
|
Address = AddressTextBox.Text,
|
||||||
|
Telephone = TelephoneTextBox.Text
|
||||||
|
};
|
||||||
|
|
||||||
|
_phisicalPersonLogic.Insert(model);
|
||||||
|
|
||||||
|
MessageBox.Show("Данные успешно сохранены!");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.PhysicalPerson.DeletePhysicalPersonWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Удаление физического лица"
|
||||||
|
Height="500" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список физических лиц для удаления"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поиск -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,60,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" />
|
||||||
|
|
||||||
|
<!-- Таблица для отображения -->
|
||||||
|
<DataGrid x:Name="PhysicalPersonsDataGrid"
|
||||||
|
Margin="20,100,20,80"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Фамилия" Binding="{Binding Surname}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Имя" Binding="{Binding Name}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Отчество" Binding="{Binding Patronymic}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата рождения" Binding="{Binding Birthday, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Пол" Binding="{Binding Gender}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Адрес" Binding="{Binding Address}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Телефон" Binding="{Binding Telephone}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<!-- Кнопка для удаления -->
|
||||||
|
<Button Content="Удалить"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
||||||
|
Width="100" Height="40"
|
||||||
|
Margin="0,0,0,20"
|
||||||
|
Background="#004890"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click="DeleteButton_Click"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,74 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.PhysicalPerson
|
||||||
|
{
|
||||||
|
public partial class DeletePhysicalPersonWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private IEnumerable<PhisicalPersonViewModel> _allPersons; // Храним все записи для фильтрации
|
||||||
|
|
||||||
|
public DeletePhysicalPersonWindow(IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadPhysicalPersons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadPhysicalPersons()
|
||||||
|
{
|
||||||
|
_allPersons = _phisicalPersonLogic.GetFullList();
|
||||||
|
PhysicalPersonsDataGrid.ItemsSource = _allPersons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (PhysicalPersonsDataGrid.SelectedItem != null)
|
||||||
|
{
|
||||||
|
var selectedPerson = PhysicalPersonsDataGrid.SelectedItem as PhisicalPersonViewModel;
|
||||||
|
if (selectedPerson != null)
|
||||||
|
{
|
||||||
|
_phisicalPersonLogic.Delete(selectedPerson.Id); // Используем Id для удаления
|
||||||
|
LoadPhysicalPersons(); // Перезагружаем список
|
||||||
|
MessageBox.Show("Данные успешно удалены!");
|
||||||
|
|
||||||
|
// Очистка поля поиска после удаления
|
||||||
|
SearchTextBox.Text = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Пожалуйста, выберите физическое лицо для удаления.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string searchQuery = SearchTextBox.Text.ToLower(); // Получаем текст для поиска
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(searchQuery))
|
||||||
|
{
|
||||||
|
// Если поле пустое, показываем все записи
|
||||||
|
PhysicalPersonsDataGrid.ItemsSource = _allPersons;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтруем записи по всем полям
|
||||||
|
var filteredList = _allPersons.Where(p =>
|
||||||
|
p.Name.ToLower().Contains(searchQuery) ||
|
||||||
|
p.Surname.ToLower().Contains(searchQuery) ||
|
||||||
|
p.Patronymic.ToLower().Contains(searchQuery) ||
|
||||||
|
p.Address.ToLower().Contains(searchQuery) || // Поиск по адресу
|
||||||
|
p.Telephone.Contains(searchQuery) || // Поиск по телефону
|
||||||
|
p.Gender.ToLower().Contains(searchQuery) || // Поиск по полу
|
||||||
|
p.Birthday.ToString("dd.MM.yyyy").Contains(searchQuery) // Поиск по дате рождения
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
PhysicalPersonsDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.PhysicalPerson.EditPhysicalPersonWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Редактирование физического лица"
|
||||||
|
Height="704" Width="600"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,-6">
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Редактирование физического лица"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Основная сетка -->
|
||||||
|
<Grid Margin="0,70,0,60">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<!-- Поиск -->
|
||||||
|
<RowDefinition Height="2*" />
|
||||||
|
<!-- Редактирование -->
|
||||||
|
<RowDefinition Height="5*" />
|
||||||
|
<!-- Кнопка сохранения -->
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Блок поиска -->
|
||||||
|
<Grid Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поле для поиска физического лица -->
|
||||||
|
<Label Grid.Row="0" Grid.Column="0"
|
||||||
|
Content="Поиск физического лица" Foreground="White" HorizontalAlignment="Center" Margin="0,10,0,10" VerticalContentAlignment="Center"/>
|
||||||
|
<TextBox x:Name="SearchTextBox" Grid.Row="0" Grid.Column="1"
|
||||||
|
Width="250" Height="30"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
Margin="0,10,0,10"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
ToolTip="Введите для поиска"
|
||||||
|
TextChanged="SearchTextBox_TextChanged"/>
|
||||||
|
|
||||||
|
<!-- Поле для выбора физического лица -->
|
||||||
|
<Label Grid.Row="1" Grid.Column="0"
|
||||||
|
Content="Выберите физическое лицо" Foreground="White" HorizontalAlignment="Center" Margin="0,10,0,10" VerticalContentAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="PhysicalPersonComboBox" Grid.Row="1" Grid.Column="1"
|
||||||
|
Width="400" Height="30"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,10,0,10"
|
||||||
|
ToolTip="Выберите физическое лицо"
|
||||||
|
SelectionChanged="PhysicalPersonComboBox_SelectionChanged" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Блок редактирования -->
|
||||||
|
<Grid Grid.Row="1" Margin="0,0,0,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- Поля редактирования -->
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Имя" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="NameTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите имя"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="0" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Фамилия" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="SurnameTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите фамилию"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="0" Margin="10" >
|
||||||
|
<Label Content="Отчество" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="PatronomicTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите отчество"
|
||||||
|
PreviewTextInput="NameTextBox_PreviewTextInput"
|
||||||
|
TextChanged="NameTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="1" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Дата рождения" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<DatePicker x:Name="BirthdayPicker" Width="250" Height="40"
|
||||||
|
ToolTip="Выберите дату рождения" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Пол" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<ComboBox x:Name="GenderComboBox" Width="250" Height="40" ToolTip="Выберите пол">
|
||||||
|
<ComboBoxItem Content="Мужчина" />
|
||||||
|
<ComboBoxItem Content="Женщина" />
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="2" Grid.Column="1" Margin="10">
|
||||||
|
<Label Content="Адрес" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="AddressTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите адрес" />
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Row="3" Grid.Column="0" Margin="10">
|
||||||
|
<Label Content="Телефон" Foreground="White" HorizontalAlignment="Center"/>
|
||||||
|
<TextBox x:Name="TelephoneTextBox" Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}" ToolTip="Введите номер телефона"
|
||||||
|
PreviewTextInput="TelephoneTextBox_PreviewTextInput"
|
||||||
|
TextChanged="TelephoneTextBox_TextChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Кнопка сохранения -->
|
||||||
|
<Button Grid.Row="2" Content="Сохранить изменения"
|
||||||
|
Width="250" Height="40"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="SaveButton_Click"
|
||||||
|
HorizontalAlignment="Center" Margin="0,10,0,0"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,235 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.PhysicalPerson
|
||||||
|
{
|
||||||
|
public partial class EditPhysicalPersonWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private List<PhisicalPersonViewModel> _physicalPersons;
|
||||||
|
|
||||||
|
public EditPhysicalPersonWindow(IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadPhysicalPersons();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Загрузка всех физ.лиц в ComboBox
|
||||||
|
private void LoadPhysicalPersons()
|
||||||
|
{
|
||||||
|
_physicalPersons = _phisicalPersonLogic.GetFullList();
|
||||||
|
PhysicalPersonComboBox.ItemsSource = _physicalPersons;
|
||||||
|
PhysicalPersonComboBox.DisplayMemberPath = "FullNameWithBirthday";
|
||||||
|
PhysicalPersonComboBox.SelectedValuePath = "Id";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Событие при выборе физ.лица
|
||||||
|
private void PhysicalPersonComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (PhysicalPersonComboBox.SelectedValue is int selectedPersonId)
|
||||||
|
{
|
||||||
|
LoadPerson(selectedPersonId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Загрузка данных выбранного физ.лица в поля
|
||||||
|
private void LoadPerson(int personId)
|
||||||
|
{
|
||||||
|
var person = _phisicalPersonLogic.GetElement(personId);
|
||||||
|
if (person != null)
|
||||||
|
{
|
||||||
|
NameTextBox.Text = person.Name;
|
||||||
|
SurnameTextBox.Text = person.Surname;
|
||||||
|
PatronomicTextBox.Text = person.Patronymic;
|
||||||
|
BirthdayPicker.SelectedDate = person.Birthday;
|
||||||
|
|
||||||
|
// Устанавливаем выбранное значение для GenderComboBox
|
||||||
|
foreach (ComboBoxItem item in GenderComboBox.Items)
|
||||||
|
{
|
||||||
|
if (item.Content.ToString() == person.Gender)
|
||||||
|
{
|
||||||
|
GenderComboBox.SelectedItem = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressTextBox.Text = person.Address;
|
||||||
|
TelephoneTextBox.Text = person.Telephone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
// Разрешаем только буквы
|
||||||
|
e.Handled = !char.IsLetter(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Получаем текущий текст
|
||||||
|
string currentText = textBox.Text;
|
||||||
|
|
||||||
|
// Если текст не пустой, преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
if (!string.IsNullOrEmpty(currentText))
|
||||||
|
{
|
||||||
|
// Разбиваем строку по пробелам, чтобы обрабатывать каждое слово отдельно
|
||||||
|
var words = currentText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
for (int i = 0; i < words.Length; i++)
|
||||||
|
{
|
||||||
|
// Преобразуем первую букву в заглавную, а остальные в строчные
|
||||||
|
words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Объединяем слова обратно в строку и обновляем текст
|
||||||
|
textBox.Text = string.Join(" ", words);
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец текста
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void TelephoneTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
e.Handled = !char.IsDigit(e.Text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TelephoneTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
// Удаляем все символы, кроме цифр
|
||||||
|
string rawInput = new string(textBox.Text.Where(char.IsDigit).ToArray());
|
||||||
|
|
||||||
|
// Добавляем "7" по умолчанию
|
||||||
|
if (!rawInput.StartsWith("7"))
|
||||||
|
rawInput = "7" + rawInput;
|
||||||
|
|
||||||
|
if (rawInput.Length > 11) rawInput = rawInput.Substring(0, 11);
|
||||||
|
|
||||||
|
// Форматируем как +7 (XXX) XXX-XX-XX
|
||||||
|
if (rawInput.Length <= 1)
|
||||||
|
textBox.Text = "+7 ";
|
||||||
|
else if (rawInput.Length <= 4)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1)}";
|
||||||
|
else if (rawInput.Length <= 7)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4)}";
|
||||||
|
else if (rawInput.Length <= 9)
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7)}";
|
||||||
|
else
|
||||||
|
textBox.Text = $"+7 ({rawInput.Substring(1, 3)}) {rawInput.Substring(4, 3)}-{rawInput.Substring(7, 2)}-{rawInput.Substring(9)}";
|
||||||
|
|
||||||
|
// Устанавливаем курсор в конец
|
||||||
|
textBox.SelectionStart = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Фильтрация списка физических лиц по всем полям
|
||||||
|
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var searchText = SearchTextBox.Text.ToLower();
|
||||||
|
var filteredPersons = _physicalPersons
|
||||||
|
.Where(p => p.Name.ToLower().Contains(searchText) ||
|
||||||
|
p.Surname.ToLower().Contains(searchText) ||
|
||||||
|
p.Patronymic.ToLower().Contains(searchText) ||
|
||||||
|
p.Gender.ToLower().Contains(searchText) ||
|
||||||
|
p.Address.ToLower().Contains(searchText) ||
|
||||||
|
p.Telephone.ToLower().Contains(searchText) ||
|
||||||
|
p.Birthday.ToString("dd.MM.yyyy").Contains(searchText) // Поиск по дате рождения
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
PhysicalPersonComboBox.ItemsSource = filteredPersons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
// Проверка обязательных полей
|
||||||
|
if (string.IsNullOrWhiteSpace(NameTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Имя' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(SurnameTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Фамилия' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(PatronomicTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Отчество' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BirthdayPicker.SelectedDate.HasValue)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Дата рождения' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (GenderComboBox.SelectedItem == null)
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Пол' не выбрано.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(AddressTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Адрес' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(TelephoneTextBox.Text))
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
MessageBox.Show("Поле 'Телефон' не заполнено.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Если все поля заполнены, продолжаем выполнение
|
||||||
|
if (isValid)
|
||||||
|
if (PhysicalPersonComboBox.SelectedValue is int selectedPersonId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var updatedPerson = new PhisicalPersonViewModel
|
||||||
|
{
|
||||||
|
Id = selectedPersonId,
|
||||||
|
Name = NameTextBox.Text,
|
||||||
|
Surname = SurnameTextBox.Text,
|
||||||
|
Patronymic = PatronomicTextBox.Text,
|
||||||
|
Birthday = BirthdayPicker.SelectedDate.Value.ToUniversalTime(),
|
||||||
|
Gender = GenderComboBox.Text,
|
||||||
|
Address = AddressTextBox.Text,
|
||||||
|
Telephone = TelephoneTextBox.Text
|
||||||
|
};
|
||||||
|
|
||||||
|
_phisicalPersonLogic.Update(updatedPerson);
|
||||||
|
MessageBox.Show("Данные успешно обновлены!");
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите физическое лицо перед сохранением!", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.PhysicalPerson.PhysicalPersonManagementWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Управление физическими лицами"
|
||||||
|
Height="400" Width="400"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Управление физическими лицами"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Стек кнопок -->
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<!-- Кнопка "Удаление физического лица" -->
|
||||||
|
<Button Content="Удаление физического лица"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Click ="OpenDeletePhysicalPersonWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Добавление физического лица" -->
|
||||||
|
<Button Content="Добавление физического лица"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenAddPhysicalPersonWindow" RenderTransformOrigin="0.402,0.626"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Редактирование физического лица" -->
|
||||||
|
<Button Content="Редактирование физического лица"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenEditPhysicalPersonWindow"/>
|
||||||
|
|
||||||
|
<!-- Кнопка "Просмотр физических лиц" -->
|
||||||
|
<Button Content="Просмотр физических лиц"
|
||||||
|
Width="250" Height="40"
|
||||||
|
Style="{StaticResource RoundedButtonStyle}"
|
||||||
|
Background="#004890" Foreground="#FFFFFF"
|
||||||
|
Click="OpenViewPhysicalPersonsWindow"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,76 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.PhysicalPerson
|
||||||
|
{
|
||||||
|
public partial class PhysicalPersonManagementWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
|
||||||
|
public PhysicalPersonManagementWindow(IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenAddPhysicalPersonWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is AddPhysicalPersonWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addWindow = new AddPhysicalPersonWindow(_phisicalPersonLogic);
|
||||||
|
addWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenDeletePhysicalPersonWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is DeletePhysicalPersonWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteWindow = new DeletePhysicalPersonWindow(_phisicalPersonLogic);
|
||||||
|
deleteWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenEditPhysicalPersonWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is EditPhysicalPersonWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var editWindow = new EditPhysicalPersonWindow(_phisicalPersonLogic);
|
||||||
|
editWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenViewPhysicalPersonsWindow(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Window window in Application.Current.Windows)
|
||||||
|
{
|
||||||
|
if (window is ViewPhysicalPersonsWindow existingWindow)
|
||||||
|
{
|
||||||
|
existingWindow.Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewWindow = new ViewPhysicalPersonsWindow(_phisicalPersonLogic);
|
||||||
|
viewWindow.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
<Window x:Class="EmployeeManagmentView.PhysicalPerson.ViewPhysicalPersonsWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Список физических лиц"
|
||||||
|
Height="500" Width="800"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#0D2D4F">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<!-- Заголовок окна -->
|
||||||
|
<TextBlock Text="Список физических лиц"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
|
FontSize="18" FontWeight="Bold"
|
||||||
|
Foreground="#FFFFFF"
|
||||||
|
Margin="0,20,0,0" />
|
||||||
|
|
||||||
|
<!-- Поиск -->
|
||||||
|
<TextBox x:Name="SearchTextBox"
|
||||||
|
Width="560"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="0,49,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Style="{StaticResource RoundedTextBoxStyle}"
|
||||||
|
TextChanged="SearchTextBox_TextChanged" Height="35" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Таблица для отображения -->
|
||||||
|
<DataGrid x:Name="PhysicalPersonsDataGrid"
|
||||||
|
Margin="20,100,20,20"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
Style="{StaticResource RoundedDataGridStyle}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="Фамилия" Binding="{Binding Surname}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Имя" Binding="{Binding Name}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Отчество" Binding="{Binding Patronymic}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Дата рождения" Binding="{Binding Birthday, StringFormat=dd.MM.yyyy}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Пол" Binding="{Binding Gender}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Адрес" Binding="{Binding Address}" Width="*" />
|
||||||
|
<DataGridTextColumn Header="Телефон" Binding="{Binding Telephone}" Width="*" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
@ -0,0 +1,52 @@
|
|||||||
|
using EmployeeManagmentContracts.BusinessLogicContracts;
|
||||||
|
using EmployeeManagmentContracts.ViewModels;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace EmployeeManagmentView.PhysicalPerson
|
||||||
|
{
|
||||||
|
public partial class ViewPhysicalPersonsWindow : Window
|
||||||
|
{
|
||||||
|
private readonly IPhisicalPersonLogic _phisicalPersonLogic;
|
||||||
|
private IEnumerable<PhisicalPersonViewModel> _allPersons; // Храним все записи для фильтрации
|
||||||
|
|
||||||
|
public ViewPhysicalPersonsWindow(IPhisicalPersonLogic phisicalPersonLogic)
|
||||||
|
{
|
||||||
|
_phisicalPersonLogic = phisicalPersonLogic;
|
||||||
|
InitializeComponent();
|
||||||
|
LoadPhysicalPersons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadPhysicalPersons()
|
||||||
|
{
|
||||||
|
_allPersons = _phisicalPersonLogic.GetFullList();
|
||||||
|
PhysicalPersonsDataGrid.ItemsSource = _allPersons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
string searchQuery = SearchTextBox.Text.ToLower(); // Получаем текст для поиска
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(searchQuery))
|
||||||
|
{
|
||||||
|
// Если поле пустое, показываем все записи
|
||||||
|
PhysicalPersonsDataGrid.ItemsSource = _allPersons;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Фильтруем записи по всем полям
|
||||||
|
var filteredList = _allPersons.Where(p =>
|
||||||
|
p.Name.ToLower().Contains(searchQuery) ||
|
||||||
|
p.Surname.ToLower().Contains(searchQuery) ||
|
||||||
|
p.Patronymic.ToLower().Contains(searchQuery) || // Поиск по ФИО
|
||||||
|
p.Address.ToLower().Contains(searchQuery) || // Поиск по адресу
|
||||||
|
p.Telephone.Contains(searchQuery) || // Поиск по телефону
|
||||||
|
p.Gender.ToLower().Contains(searchQuery) || // Поиск по полу
|
||||||
|
p.Birthday.ToString("dd.MM.yyyy").Contains(searchQuery) // Поиск по дате рождения
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
PhysicalPersonsDataGrid.ItemsSource = filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user