Compare commits
30 Commits
main
...
stage2_ser
Author | SHA1 | Date | |
---|---|---|---|
4c72a6bcb7 | |||
f0cb77a254 | |||
c13a1b2a71 | |||
8afd4dd83d | |||
85551918e3 | |||
7745307e48 | |||
f468ca7603 | |||
4b81de1b6c | |||
b45b6a1f7c | |||
9bf9ca9874 | |||
506aac2e22 | |||
c48aa77d13 | |||
23f4584b8a | |||
9bcec875a0 | |||
ea69b16468 | |||
86804b33aa | |||
46ae5de04f | |||
6ee89f6397 | |||
6d1f93451c | |||
d7b655cdad | |||
f15adb2824 | |||
ea770727ca | |||
c35b78a8b7 | |||
e6f5ae0f17 | |||
929ff66750 | |||
e9db19f09b | |||
330fc031dc | |||
d0d6ce7400 | |||
b77b2a1408 | |||
bff0ac3cef |
8
12345678
Normal file
8
12345678
Normal file
@ -0,0 +1,8 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBdnP+MV4
|
||||
VwS1yecrAOXrzjAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIKR8odg9m0A3Wn1f
|
||||
AsD8bFrBr2c7U4gzr34WAPTOClvKAAAAoETF2SR1FCOl3OGFsy+vuQwfqp8qySZsswBKSu
|
||||
6YTNm65JWix/m2P3bO1mMSiiu6t0olwNQnXz7inHHf7YoIsOskkqMdD9/0wDgmrG/D9Wl1
|
||||
SEEsIZBNy5u0C4ufdifb6/4zTAMOGcIt8+w1G2jbPvnJ2ez/70aGOANYl6rzsQZS0IdS4X
|
||||
SADuP5bdG1Q2zaOj5+3bOivM0co10Vkx9hJG4=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
1
12345678.pub
Normal file
1
12345678.pub
Normal file
@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKR8odg9m0A3Wn1fAsD8bFrBr2c7U4gzr34WAPTOClvK rgismatullinm@yandex.ru
|
@ -3,7 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.6.33717.318
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStation", "ServiceStation\ServiceStation.csproj", "{3071CADC-9EED-4B15-A2AD-9B45C3C4A8EB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationDataModels", "ServiceStationDataModels\ServiceStationDataModels.csproj", "{431172B6-C074-45F3-8064-4D8D7F3F9FD2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationsDataBaseImplement", "ServiceStationsDataBaseImplement\ServiceStationsDataBaseImplement.csproj", "{71AAE393-32B8-4E7C-8EC2-C0D98F5E3FCF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationContracts", "ServiceStationContracts\ServiceStationContracts.csproj", "{6758A476-8AC7-4558-AC45-E2EDBAA71C59}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationBusinessLogic", "ServiceStationBusinessLogic\ServiceStationBusinessLogic.csproj", "{E3C21F43-152C-4770-88A9-0CF5B182E6AD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStationRestAPI", "ServiceStationRestAPI\ServiceStationRestAPI.csproj", "{6EA674DA-F458-4662-BBE5-7F5C45D5AE5C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceSourceExecutorApp", "ServiceStationExecutorApp\ServiceSourceExecutorApp.csproj", "{85655746-80E9-4B8B-A0B6-94DF0B7E9339}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -11,10 +21,30 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3071CADC-9EED-4B15-A2AD-9B45C3C4A8EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3071CADC-9EED-4B15-A2AD-9B45C3C4A8EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3071CADC-9EED-4B15-A2AD-9B45C3C4A8EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3071CADC-9EED-4B15-A2AD-9B45C3C4A8EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{431172B6-C074-45F3-8064-4D8D7F3F9FD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{431172B6-C074-45F3-8064-4D8D7F3F9FD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{431172B6-C074-45F3-8064-4D8D7F3F9FD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{431172B6-C074-45F3-8064-4D8D7F3F9FD2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{71AAE393-32B8-4E7C-8EC2-C0D98F5E3FCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{71AAE393-32B8-4E7C-8EC2-C0D98F5E3FCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{71AAE393-32B8-4E7C-8EC2-C0D98F5E3FCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71AAE393-32B8-4E7C-8EC2-C0D98F5E3FCF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6758A476-8AC7-4558-AC45-E2EDBAA71C59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6758A476-8AC7-4558-AC45-E2EDBAA71C59}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6758A476-8AC7-4558-AC45-E2EDBAA71C59}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6758A476-8AC7-4558-AC45-E2EDBAA71C59}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E3C21F43-152C-4770-88A9-0CF5B182E6AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E3C21F43-152C-4770-88A9-0CF5B182E6AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E3C21F43-152C-4770-88A9-0CF5B182E6AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E3C21F43-152C-4770-88A9-0CF5B182E6AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6EA674DA-F458-4662-BBE5-7F5C45D5AE5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6EA674DA-F458-4662-BBE5-7F5C45D5AE5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6EA674DA-F458-4662-BBE5-7F5C45D5AE5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6EA674DA-F458-4662-BBE5-7F5C45D5AE5C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{85655746-80E9-4B8B-A0B6-94DF0B7E9339}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{85655746-80E9-4B8B-A0B6-94DF0B7E9339}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{85655746-80E9-4B8B-A0B6-94DF0B7E9339}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{85655746-80E9-4B8B-A0B6-94DF0B7E9339}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1,7 +0,0 @@
|
||||
namespace ServiceStation
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using ServiceStationContracts.StorageContracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.BusinessLogic {
|
||||
public class ClientLogic : IClientLogic {
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IClientStorage _storage;
|
||||
|
||||
public ClientLogic(ILogger<IClientLogic> logger, IClientStorage storage) {
|
||||
_logger = logger;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public bool Create(ClientBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Insert(model) == null) {
|
||||
_logger.LogWarning("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Delete(ClientBindingModel model) {
|
||||
CheckModel(model, false);
|
||||
_logger.LogInformation($"Delete.Id:{model.Id}");
|
||||
if (_storage.Delete(model) == null) {
|
||||
_logger.LogWarning("Delete operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Update(ClientBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Update(model) == null) {
|
||||
_logger.LogWarning("Update operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public ClientViewModel? ReadElement(ClientSearchModel model) {
|
||||
if (model == null) {
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.Id:{model.Id}.login:{model.fio}");
|
||||
var element = _storage.GetElement(model);
|
||||
if (element == null) {
|
||||
_logger.LogWarning("ReadElement.Element not fount");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.find.Id:{element.Id}");
|
||||
return element;
|
||||
}
|
||||
|
||||
public List<ClientViewModel>? ReadList() {
|
||||
var list = _storage.GetFullList();
|
||||
if (list == null) {
|
||||
_logger.LogWarning("ReadList return null list");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadList.Count:{list.Count}");
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CheckModel(ClientBindingModel model, bool withParams = true) {
|
||||
if (string.IsNullOrEmpty((model.Id).ToString())) {
|
||||
throw new ArgumentNullException("Нет Id клиента", nameof(model.Id));
|
||||
}
|
||||
|
||||
if (!withParams) {
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.FIO)) {
|
||||
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.FIO));
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Client.Id:{model.Id}.FIO:{model.FIO}");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using ServiceStationContracts.StorageContracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.BusinessLogic {
|
||||
public class ExecutorLogic : IExecutorLogic {
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IExecutorStorage _storage;
|
||||
|
||||
public ExecutorLogic(ILogger<IExecutorLogic> logger, IExecutorStorage storage) {
|
||||
_logger = logger;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public bool Create(ExecutorBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Insert(model) == null) {
|
||||
_logger.LogWarning("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Delete(ExecutorBindingModel model) {
|
||||
CheckModel(model, false);
|
||||
_logger.LogInformation($"Delete.Id:{model.Id}");
|
||||
if (_storage.Delete(model) == null) {
|
||||
_logger.LogWarning("Delete operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Update(ExecutorBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Update(model) == null) {
|
||||
_logger.LogWarning("Update operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public ExecutorViewModel? ReadElement(ExecutorSearchModel model) {
|
||||
if (model == null) {
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.Id:{model.Id}.Email:{model.Email}");
|
||||
var element = _storage.GetElement(model);
|
||||
if (element == null) {
|
||||
_logger.LogWarning("ReadElement.Element not fount");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.Find.Id:{element.Id}");
|
||||
return element;
|
||||
}
|
||||
|
||||
public List<ExecutorViewModel>? ReadList() {
|
||||
var list = _storage.GetFullList();
|
||||
if (list == null) {
|
||||
_logger.LogWarning("ReadList return null list");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadList.Count:{list.Count}");
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CheckModel(ExecutorBindingModel model, bool withParams = true) {
|
||||
if (string.IsNullOrEmpty(model.Id.ToString())) {
|
||||
throw new ArgumentNullException("Нет номера исполнителя", nameof(model.Id));
|
||||
}
|
||||
if (!withParams) {
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty((model.Id).ToString())) {
|
||||
throw new ArgumentNullException("Нет Id исполнителя", nameof(model.Id));
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.Email)) {
|
||||
throw new ArgumentNullException("Нет почты исполнителя", nameof(model.Email));
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.Password)) {
|
||||
throw new ArgumentNullException("Нет пароля исполнителя", nameof(model.Password));
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.FIO)) {
|
||||
throw new ArgumentNullException("Нет ФИО исполнителя", nameof(model.FIO));
|
||||
}
|
||||
_logger.LogInformation($"Executor.Id:{model.Id}.Email:{model.Email}.Password:{model.Password}.FIO:{model.FIO}");
|
||||
|
||||
var element = _storage.GetElement(new ExecutorSearchModel { Email = model.Email });
|
||||
if (element != null && element.Id != model.Id) {
|
||||
throw new InvalidOperationException("Такая почта уже занята");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
using PdfSharp.Pdf;
|
||||
using ServiceStationBusinessLogic.OfficePackage;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using ServiceStationContracts.StorageContracts;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace ServiceStationBusinessLogic.BusinessLogic {
|
||||
public class ReportLogic : IReportLogic {
|
||||
|
||||
private readonly IWorkStorage _workStorage;
|
||||
private readonly ITaskStorage _taskStorage;
|
||||
private readonly IClientStorage _clientStorage;
|
||||
private readonly IWorkClientStorage _workClientStorage;
|
||||
|
||||
private readonly AbstractSaveToExcel _saveToExcel;
|
||||
private readonly AbstractSaveToPdf _saveToPdf;
|
||||
private readonly AbstractSaveToWord _saveToWord;
|
||||
|
||||
public ReportLogic(IWorkStorage workStorage, ITaskStorage taskStorage, IClientStorage clientStorage, IWorkClientStorage workClientStorage,
|
||||
AbstractSaveToExcel saveToExcel, AbstractSaveToPdf saveToPdf, AbstractSaveToWord saveToWord) {
|
||||
_workStorage = workStorage;
|
||||
_taskStorage = taskStorage;
|
||||
_clientStorage = clientStorage;
|
||||
_workClientStorage = workClientStorage;
|
||||
_saveToExcel = saveToExcel;
|
||||
_saveToPdf = saveToPdf;
|
||||
_saveToWord = saveToWord;
|
||||
}
|
||||
|
||||
public List<ReportClientsInWorksViewModel> GetClientListInWorks(ReportBindeingModel model) {
|
||||
List<ReportClientsInWorksViewModel> client_list_in_works = new();
|
||||
foreach (int id in model.ids) {
|
||||
var work = _workStorage.GetElement(new WorkSearchModel { Id = id }) ?? throw new Exception("Ошибка получения данных");
|
||||
|
||||
var record = new ReportClientsInWorksViewModel {
|
||||
WorkId = work.Id,
|
||||
Date = work.Date.ToShortDateString(),
|
||||
Price = work.Price,
|
||||
TotalCount = 0,
|
||||
_Clients = new()
|
||||
};
|
||||
|
||||
foreach (var client in work.ClientList) {
|
||||
|
||||
var work_client = _workClientStorage.GetElement(new WorkClientSearchModel { client_id = client.Key, work_id = id })
|
||||
?? throw new Exception("Ошибка получения данных");
|
||||
|
||||
record._Clients.Add(new(client.Key, client.Value.FIO, work_client.Point_count));
|
||||
record.TotalCount++;
|
||||
}
|
||||
client_list_in_works.Add(record);
|
||||
}
|
||||
return client_list_in_works;
|
||||
}
|
||||
|
||||
public byte[]? SaveToExcelFile(ReportBindeingModel model) {
|
||||
var document = _saveToExcel.CreateReport(new ExcelInfo {
|
||||
Title = "Список клиентов по выбранным работам",
|
||||
WorksClients = GetClientListInWorks(model)
|
||||
});
|
||||
return document;
|
||||
}
|
||||
|
||||
public PdfDocument SaveToPdfFile(ReportBindeingModel model) {
|
||||
|
||||
var works = _workStorage.GetFilteredList(new WorkSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo });
|
||||
|
||||
var record = new PdfInfo {
|
||||
Title = "Список работ и назначенных заданий",
|
||||
Date_From = model.DateFrom.ToShortDateString(),
|
||||
Date_To = model.DateTo.ToShortDateString(),
|
||||
WorkTask = new(),
|
||||
TotalCount = 0,
|
||||
};
|
||||
|
||||
foreach (var work in works) {
|
||||
var task = _taskStorage.GetElement(new TaskSearchModel { Id = work.TaskByWorkId }) ?? throw new Exception("Ошибка получения данных");
|
||||
record.WorkTask.Add(new(work.Id, work.Date.ToShortDateString(), work.Price, task.Id, task.Name));
|
||||
record.TotalCount++;
|
||||
}
|
||||
|
||||
var document = _saveToPdf.CreateDoc(record);
|
||||
return document;
|
||||
}
|
||||
|
||||
public byte[]? SaveToWordFile(ReportBindeingModel model) {
|
||||
var document = _saveToWord.CreateDoc(new WordInfo {
|
||||
Title = "Список клиентов по выбранным работам",
|
||||
WorksClients = GetClientListInWorks(model)
|
||||
});
|
||||
return document;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using ServiceStationContracts.StorageContracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.BusinessLogic {
|
||||
public class TaskLogic : ITaskLogic {
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly ITaskStorage _storage;
|
||||
|
||||
public TaskLogic(ILogger<ITaskLogic> logger, ITaskStorage storage) {
|
||||
_logger = logger;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public bool Create(TaskBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Insert(model) == null) {
|
||||
_logger.LogInformation("Insert operatin failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Update(TaskBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Update(model) == null) {
|
||||
_logger.LogWarning("Update operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Delete(TaskBindingModel model) {
|
||||
CheckModel(model);
|
||||
_logger.LogInformation($"Delete.Id:{model.Id}");
|
||||
if (_storage.Delete(model) == null) {
|
||||
_logger.LogWarning("Delete operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public TaskViewModel? ReadElement(TaskSearchModel model) {
|
||||
if (model == null) {
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.Id:{model.Id}");
|
||||
var element = _storage.GetElement(model);
|
||||
if (element == null) {
|
||||
_logger.LogWarning("ReadElement.Element not found");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.Find.Id:{element.Id}");
|
||||
return element;
|
||||
}
|
||||
|
||||
public List<TaskViewModel>? ReadList() {
|
||||
var list = _storage.GetFullList();
|
||||
if (list == null) {
|
||||
_logger.LogWarning("ReadList return null list");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadList.Count:{list.Count}");
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CheckModel (TaskBindingModel model, bool withParams = true) {
|
||||
if (string.IsNullOrEmpty(model.Id.ToString())) {
|
||||
throw new ArgumentNullException("Нет номера задачи", nameof(model.Id));
|
||||
}
|
||||
if (!withParams) {
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.Name)) {
|
||||
throw new ArgumentNullException("Нет номера модели", nameof(model.Name));
|
||||
}
|
||||
_logger.LogInformation($"Task.Id:{model.Id}.Name:{model.Name}");
|
||||
var task = _storage.GetElement(new TaskSearchModel { Name = model.Name });
|
||||
if (task != null && task.Id != model.Id) {
|
||||
throw new InvalidOperationException("Такая задача уже создана");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using ServiceStationContracts.HelperModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.StorageContracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.BusinessLogic
|
||||
{
|
||||
public class WorkClientLogic : IWorkClientLogic {
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IWorkClientStorage _storage;
|
||||
private readonly IWorkStorage _workStorage;
|
||||
private readonly IClientStorage _clientStorage;
|
||||
|
||||
public WorkClientLogic(ILogger<WorkClientLogic> logger, IWorkClientStorage storage, IWorkStorage workStorage, IClientStorage clientStorage) {
|
||||
_logger = logger;
|
||||
_storage = storage;
|
||||
_workStorage = workStorage;
|
||||
_clientStorage = clientStorage;
|
||||
}
|
||||
|
||||
public bool Add_Points(WorkClientModel model) {
|
||||
CheckModel(model);
|
||||
if (!_storage.Add_Points(model)) {
|
||||
_logger.LogWarning("Add_Points operatin failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<WorkClientModel>? ReadList(WorkClientSearchModel model) {
|
||||
_logger.LogInformation($"ReadList.client_id:{model.client_id}");
|
||||
var list = _storage.GetFilteredList(model);
|
||||
if (list == null) {
|
||||
_logger.LogWarning("ReadList return null list");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadList.Count:{list.Count}");
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CheckModel(WorkClientModel model) {
|
||||
if (model.Point_count < 0) {
|
||||
throw new ArgumentNullException("Нельзя ставить отрицательное количество баллов");
|
||||
}
|
||||
var work = _workStorage.GetElement(new ServiceStationContracts.SearchModels.WorkSearchModel { Id = model.Work_Id });
|
||||
var client = _clientStorage.GetElement(new ServiceStationContracts.SearchModels.ClientSearchModel { Id = model.Client_Id });
|
||||
|
||||
if (work == null || client == null) {
|
||||
throw new ArgumentNullException("Нет такой работы или такого клиента");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using ServiceStationContracts.StorageContracts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.BusinessLogic
|
||||
{
|
||||
public class WorkLogic : IWorkLogic {
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IWorkStorage _storage;
|
||||
|
||||
public WorkLogic(ILogger<IWorkLogic> logger, IWorkStorage storage) {
|
||||
_logger = logger;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public bool Create(WorkBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Insert(model) == null) {
|
||||
_logger.LogInformation("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Update(WorkBindingModel model) {
|
||||
CheckModel(model);
|
||||
if (_storage.Update(model) == null) {
|
||||
_logger.LogInformation("Insert operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Delete(WorkBindingModel model) {
|
||||
CheckModel(model, false);
|
||||
_logger.LogInformation($"Delete. Id:{model.Id}");
|
||||
if (_storage.Delete(model) == null) {
|
||||
_logger.LogWarning("Delete operation failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public WorkViewModel? ReadElement(WorkSearchModel model) {
|
||||
if (model == null) {
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.ID:{model.Id}");
|
||||
var element = _storage.GetElement(model);
|
||||
if (element == null) {
|
||||
_logger.LogWarning("ReadElement.Element not found");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadElement.Find.Id:{element.Id}");
|
||||
return element;
|
||||
}
|
||||
|
||||
public List<WorkViewModel>? ReadList(WorkSearchModel model) {
|
||||
_logger.LogInformation($"ReadList.ID:{model?.Id}");
|
||||
var list = model == null ? _storage.GetFullList() : _storage.GetFilteredList(model);
|
||||
if (list == null) {
|
||||
_logger.LogWarning("ReadList return null list");
|
||||
return null;
|
||||
}
|
||||
_logger.LogInformation($"ReadList.Count:{list.Count}");
|
||||
return list;
|
||||
}
|
||||
|
||||
private void CheckModel(WorkBindingModel model, bool withParams = true) {
|
||||
|
||||
if (string.IsNullOrEmpty(model.Id.ToString())) {
|
||||
throw new ArgumentNullException("Нет номера работы", nameof(model.Id));
|
||||
}
|
||||
if (!withParams) {
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.Date.ToString())) {
|
||||
model.Date = DateTime.Now;
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.Price.ToString())) {
|
||||
throw new ArgumentNullException("Стоимость работы должна быть боль 0", nameof(model.Price));
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.ExecutorId.ToString())) {
|
||||
throw new ArgumentNullException("Нет номера исполнителя", nameof(model.ExecutorId));
|
||||
}
|
||||
if (string.IsNullOrEmpty(model.TaskByWorkId.ToString())) {
|
||||
throw new ArgumentNullException("Нет номера задачи", nameof(model.TaskByWorkId));
|
||||
}
|
||||
if (model.ClientList.Count <= 0) {
|
||||
throw new ArgumentException("Работа не может быть без клиента", nameof(model.ClientList));
|
||||
}
|
||||
_logger.LogInformation($"Work.Id:{model.Id}.Date:{model.Date}.Price:{model.Price}.ExecutorId:{model.ExecutorId}.TaskId:{model.TaskByWorkId}." +
|
||||
$"ClientList.Count:{model.ClientList.Count}");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.MailKitWorker {
|
||||
public abstract class AbstractMailWorker {
|
||||
protected string _mailLogin = string.Empty;
|
||||
|
||||
protected string _mailPassword = string.Empty;
|
||||
|
||||
protected string _smtpClientHost = string.Empty;
|
||||
|
||||
protected int _smtpClientPort;
|
||||
|
||||
protected string _popHost = string.Empty;
|
||||
|
||||
protected int _popPort;
|
||||
|
||||
private readonly IClientLogic _clientLogic;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IClientLogic clientLogic) {
|
||||
_logger = logger;
|
||||
_clientLogic = clientLogic;
|
||||
}
|
||||
|
||||
public void MailConfig(MailConfigBindingModel config) {
|
||||
_mailLogin = config.MailLogin;
|
||||
_mailPassword = config.MailPassword;
|
||||
_smtpClientHost = config.SmtpClientHost;
|
||||
_smtpClientPort = config.SmtpClientPort;
|
||||
_popHost = config.PopHost;
|
||||
_popPort = config.PopPort;
|
||||
_logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, {popHost}, {popPort}", _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort);
|
||||
}
|
||||
|
||||
public async void MailSendAsync(MailSendInfoBindingModel info) {
|
||||
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject);
|
||||
await SendMailAsync(info);
|
||||
}
|
||||
|
||||
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.BusinessLogic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.MailKitWorker {
|
||||
public class MailKitWorker :AbstractMailWorker {
|
||||
public MailKitWorker(ILogger<MailKitWorker> logger,
|
||||
IClientLogic clientLogic) : base(logger, clientLogic) { }
|
||||
|
||||
protected override async Task SendMailAsync(MailSendInfoBindingModel info) {
|
||||
using var objMailMessage = new MailMessage();
|
||||
using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
|
||||
try {
|
||||
objMailMessage.From = new MailAddress(_mailLogin);
|
||||
objMailMessage.To.Add(new MailAddress(info.MailAddress));
|
||||
objMailMessage.Subject = info.Subject;
|
||||
objMailMessage.Body = info.Text;
|
||||
|
||||
Attachment attachment = new Attachment(new MemoryStream(info.document), name: "Report.pdf");
|
||||
if (attachment != null) {
|
||||
objMailMessage.Attachments.Add(attachment);
|
||||
}
|
||||
|
||||
objMailMessage.SubjectEncoding = Encoding.UTF8;
|
||||
objMailMessage.BodyEncoding = Encoding.UTF8;
|
||||
|
||||
objSmtpClient.UseDefaultCredentials = false;
|
||||
objSmtpClient.EnableSsl = true;
|
||||
objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
|
||||
objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
|
||||
|
||||
await Task.Run(() => objSmtpClient.Send(objMailMessage));
|
||||
}
|
||||
catch (Exception) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage
|
||||
{
|
||||
public abstract class AbstractSaveToExcel {
|
||||
public byte[]? CreateReport(ExcelInfo info) {
|
||||
CreateExcel(info);
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "A",
|
||||
RowIndex = 1,
|
||||
Text = info.Title,
|
||||
StyleInfo = ExcelStyleInfoType.Title
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = "A1",
|
||||
CellToName = "C1"
|
||||
});
|
||||
|
||||
uint rowIndex = 2;
|
||||
foreach (var work_client in info.WorksClients) {
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "A",
|
||||
RowIndex = rowIndex,
|
||||
Text = $"Номер работы: {work_client.WorkId}",
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "B",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"A{rowIndex}",
|
||||
CellToName = $"B{rowIndex}"
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "C",
|
||||
RowIndex = rowIndex,
|
||||
Text = $"Дата работы: {work_client.Date}",
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "D",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"C{rowIndex}",
|
||||
CellToName = $"D{rowIndex}"
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "E",
|
||||
RowIndex = rowIndex,
|
||||
Text = $"Стоимость: {work_client.Price}",
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "F",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.Text
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"E{rowIndex}",
|
||||
CellToName = $"F{rowIndex}"
|
||||
});
|
||||
|
||||
rowIndex++;
|
||||
foreach (var (client_id, client_fio, points) in work_client._Clients) {
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "B",
|
||||
RowIndex = rowIndex,
|
||||
Text = $"Номер клиента: {client_id}",
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "C",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"B{rowIndex}",
|
||||
CellToName = $"C{rowIndex}"
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "D",
|
||||
RowIndex = rowIndex,
|
||||
Text = $"ФИО клиента: {client_fio}",
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "E",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"D{rowIndex}",
|
||||
CellToName = $"E{rowIndex}"
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "F",
|
||||
Text = $"Баллов у клиента: {points}",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "G",
|
||||
RowIndex = rowIndex,
|
||||
StyleInfo = ExcelStyleInfoType.TextWithBorder
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"F{rowIndex}",
|
||||
CellToName = $"H{rowIndex}"
|
||||
});
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
InsertCellInWorksheet(new ExcelCellParameters {
|
||||
ColumnName = "A",
|
||||
RowIndex = rowIndex,
|
||||
Text = $"Итого: {work_client.TotalCount}",
|
||||
StyleInfo = ExcelStyleInfoType.Title
|
||||
});
|
||||
|
||||
MergeCells(new ExcelMergeParameters {
|
||||
CellFromName = $"A{rowIndex}",
|
||||
CellToName = $"B{rowIndex}"
|
||||
});
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
var document = SaveExcel(info);
|
||||
return document;
|
||||
}
|
||||
|
||||
// Создание excel-файла
|
||||
protected abstract void CreateExcel(ExcelInfo info);
|
||||
|
||||
// Добавляем новую ячейку в лист
|
||||
protected abstract void InsertCellInWorksheet(ExcelCellParameters excelCellParameters);
|
||||
|
||||
// Объединение ячеек
|
||||
protected abstract void MergeCells(ExcelMergeParameters mergeParameters);
|
||||
|
||||
// Сохранение файла
|
||||
protected abstract byte[]? SaveExcel(ExcelInfo info);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
using PdfSharp.Pdf;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage {
|
||||
public abstract class AbstractSaveToPdf {
|
||||
|
||||
public PdfDocument CreateDoc (PdfInfo info) {
|
||||
CreatePdf(info);
|
||||
|
||||
CreateParagraph(new PdfParagraph {
|
||||
Text = info.Title,
|
||||
Style = "NormalTitle",
|
||||
alignmentType = PdfParagraphAlignmentType.Center,
|
||||
});
|
||||
|
||||
CreateParagraph(new PdfParagraph {
|
||||
Text = $"С {info.Date_From} по {info.Date_To}",
|
||||
Style = "Normal",
|
||||
alignmentType = PdfParagraphAlignmentType.Right,
|
||||
});
|
||||
|
||||
CreateTable(new List<string> { "3cm", "4cm", "3cm", "2cm", "4cm" });
|
||||
|
||||
CreateRow(new PdfRowParameters {
|
||||
Text = new List<string> { "Номер работы", "Дата работы", "Стоимость", "Номер задачи", "Название задачи" },
|
||||
Style = "NormalTittle",
|
||||
alignmentType = PdfParagraphAlignmentType.Left,
|
||||
});
|
||||
|
||||
foreach (var rec in info.WorkTask) {
|
||||
CreateRow(new PdfRowParameters {
|
||||
Text = new List<string> {
|
||||
rec.work_id.ToString(),
|
||||
rec.work_date,
|
||||
rec.work_price.ToString(),
|
||||
rec.task_id.ToString(),
|
||||
rec.task_name.ToString()
|
||||
},
|
||||
Style = "Normal",
|
||||
alignmentType = PdfParagraphAlignmentType.Left,
|
||||
});
|
||||
}
|
||||
CreateParagraph(new PdfParagraph {
|
||||
Text = $"Итого: {info.TotalCount}",
|
||||
Style = "Normal",
|
||||
alignmentType = PdfParagraphAlignmentType.Right,
|
||||
});
|
||||
|
||||
var document = SavePdf(info);
|
||||
return document;
|
||||
}
|
||||
|
||||
// Создание документа
|
||||
protected abstract void CreatePdf(PdfInfo info);
|
||||
|
||||
// Создание параграфа с текстом
|
||||
protected abstract void CreateParagraph(PdfParagraph paragraph);
|
||||
|
||||
// Создание таблицы
|
||||
protected abstract void CreateTable(List<string> columns);
|
||||
|
||||
// Создание и заполнение строки
|
||||
protected abstract void CreateRow(PdfRowParameters rowParameters);
|
||||
|
||||
// Сохранение файла
|
||||
protected abstract PdfDocument SavePdf(PdfInfo info);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage {
|
||||
public abstract class AbstractSaveToWord {
|
||||
|
||||
public byte[]? CreateDoc(WordInfo info) {
|
||||
|
||||
CreateWord(info);
|
||||
|
||||
CreateParagraph(new WordParagraph {
|
||||
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24"})},
|
||||
TextProperties = new WordTextProperties {
|
||||
Size = "24",
|
||||
JustificationType = WordJustificationType.Center,
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var work_client in info.WorksClients) {
|
||||
CreateParagraph(new WordParagraph {
|
||||
Texts = new List<(string, WordTextProperties)> {($"Номера работы:{work_client.WorkId}/Дата:{work_client.Date}/" +
|
||||
$"Сумма:{work_client.Price}", new WordTextProperties {
|
||||
Bold = true, Size = "24"
|
||||
})},
|
||||
TextProperties = new WordTextProperties {
|
||||
Size = "24",
|
||||
JustificationType = WordJustificationType.Both
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var client in work_client._Clients) {
|
||||
CreateParagraph(new WordParagraph {
|
||||
Texts = new List<(string, WordTextProperties)> {($"Номер клиента:{client.client_id}/ФИО клиента:{client.client_fio}/Быллы:" +
|
||||
$"{client.points}",
|
||||
new WordTextProperties {
|
||||
Bold = false, Size = "24"
|
||||
})},
|
||||
TextProperties = new WordTextProperties {
|
||||
Size = "24",
|
||||
JustificationType = WordJustificationType.Both
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CreateParagraph(new WordParagraph {
|
||||
Texts = new List<(string, WordTextProperties)> {
|
||||
($"Итого:{work_client.TotalCount}", new WordTextProperties {
|
||||
Bold = true,
|
||||
Size = "24"
|
||||
})
|
||||
},
|
||||
TextProperties = new WordTextProperties {
|
||||
Size = "24",
|
||||
JustificationType = WordJustificationType.Both
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var doucment = SaveWord(info);
|
||||
return doucment;
|
||||
}
|
||||
|
||||
// Создание документа
|
||||
protected abstract void CreateWord(WordInfo info);
|
||||
|
||||
// Создание абзаца с текстом
|
||||
protected abstract void CreateParagraph(WordParagraph paragraph);
|
||||
|
||||
// Сохранение файла
|
||||
protected abstract byte[]? SaveWord(WordInfo info);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperEnums {
|
||||
public enum ExcelStyleInfoType {
|
||||
Title,
|
||||
Text,
|
||||
TextWithBorder
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperEnums {
|
||||
public enum PdfParagraphAlignmentType {
|
||||
Center,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperEnums {
|
||||
public enum WordJustificationType {
|
||||
Center,
|
||||
Both
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class ExcelCellParameters {
|
||||
public string ColumnName { get; set; } = string.Empty;
|
||||
|
||||
public uint RowIndex { get; set; }
|
||||
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public string CellReference => $"{ColumnName}{RowIndex}";
|
||||
|
||||
public ExcelStyleInfoType StyleInfo { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class ExcelInfo {
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public List<ReportClientsInWorksViewModel> WorksClients { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class ExcelMergeParameters {
|
||||
public string CellFromName { get; set; } = string.Empty;
|
||||
|
||||
public string CellToName { get; set; } = string.Empty;
|
||||
|
||||
public string Merge => $"{CellFromName}:{CellToName}";
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class PdfInfo {
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Date_From { get; set; } = string.Empty;
|
||||
public string Date_To { get; set;} = string.Empty;
|
||||
public List<(int work_id, string work_date, double work_price, int task_id, string task_name)> WorkTask { get; set; } = new();
|
||||
public int TotalCount { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class PdfParagraph {
|
||||
public string Text { get; set; } = string.Empty;
|
||||
public string Style { get; set; } = string.Empty;
|
||||
public PdfParagraphAlignmentType alignmentType { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class PdfRowParameters {
|
||||
public List<string> Text { get; set; } = new();
|
||||
public string Style { get; set; } = string.Empty;
|
||||
public PdfParagraphAlignmentType alignmentType { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class WordInfo {
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public List<ReportClientsInWorksViewModel> WorksClients { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class WordParagraph {
|
||||
public List<(string, WordTextProperties)> Texts { get; set; } = new();
|
||||
|
||||
public WordTextProperties? TextProperties { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.HelperModels {
|
||||
public class WordTextProperties {
|
||||
public string Size { get; set; } = string.Empty;
|
||||
|
||||
public bool Bold { get; set; }
|
||||
|
||||
public WordJustificationType JustificationType { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,267 @@
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||
using DocumentFormat.OpenXml.Office2013.Excel;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.Implements {
|
||||
public class SaveToExcel : AbstractSaveToExcel {
|
||||
private SpreadsheetDocument? _spreadsheetDocument;
|
||||
|
||||
private SharedStringTablePart? _shareStringPart;
|
||||
|
||||
private Worksheet? _worksheet;
|
||||
|
||||
private MemoryStream _mem = new MemoryStream();
|
||||
|
||||
// Настройка стилей для файла
|
||||
private static void CreateStyles(WorkbookPart workbookpart) {
|
||||
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
|
||||
sp.Stylesheet = new Stylesheet();
|
||||
|
||||
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
|
||||
|
||||
var fontUsual = new Font();
|
||||
fontUsual.Append(new FontSize() { Val = 12D });
|
||||
fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U });
|
||||
fontUsual.Append(new FontName() { Val = "Times New Roman" });
|
||||
fontUsual.Append(new FontFamilyNumbering() { Val = 2 });
|
||||
fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor });
|
||||
|
||||
var fontTitle = new Font();
|
||||
fontTitle.Append(new Bold());
|
||||
fontTitle.Append(new FontSize() { Val = 14D });
|
||||
fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Theme = 1U });
|
||||
fontTitle.Append(new FontName() { Val = "Times New Roman" });
|
||||
fontTitle.Append(new FontFamilyNumbering() { Val = 2 });
|
||||
fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor });
|
||||
|
||||
fonts.Append(fontUsual);
|
||||
fonts.Append(fontTitle);
|
||||
|
||||
var fills = new Fills() { Count = 2U };
|
||||
|
||||
var fill1 = new Fill();
|
||||
fill1.Append(new PatternFill() { PatternType = PatternValues.None });
|
||||
|
||||
var fill2 = new Fill();
|
||||
fill2.Append(new PatternFill() { PatternType = PatternValues.Gray125 });
|
||||
|
||||
fills.Append(fill1);
|
||||
fills.Append(fill2);
|
||||
|
||||
var borders = new Borders() { Count = 2U };
|
||||
|
||||
var borderNoBorder = new Border();
|
||||
borderNoBorder.Append(new LeftBorder());
|
||||
borderNoBorder.Append(new RightBorder());
|
||||
borderNoBorder.Append(new TopBorder());
|
||||
borderNoBorder.Append(new BottomBorder());
|
||||
borderNoBorder.Append(new DiagonalBorder());
|
||||
|
||||
var borderThin = new Border();
|
||||
|
||||
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
|
||||
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
|
||||
|
||||
var rightBorder = new RightBorder() { Style = BorderStyleValues.Thin };
|
||||
rightBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
|
||||
|
||||
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
|
||||
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
|
||||
|
||||
var bottomBorder = new BottomBorder() { Style = BorderStyleValues.Thin };
|
||||
bottomBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color() { Indexed = 64U });
|
||||
|
||||
borderThin.Append(leftBorder);
|
||||
borderThin.Append(rightBorder);
|
||||
borderThin.Append(topBorder);
|
||||
borderThin.Append(bottomBorder);
|
||||
borderThin.Append(new DiagonalBorder());
|
||||
|
||||
borders.Append(borderNoBorder);
|
||||
borders.Append(borderThin);
|
||||
|
||||
var cellStyleFormats = new CellStyleFormats() { Count = 1U };
|
||||
var cellFormatStyle = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U };
|
||||
|
||||
cellStyleFormats.Append(cellFormatStyle);
|
||||
|
||||
var cellFormats = new CellFormats() { Count = 3U };
|
||||
var cellFormatFont = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 0U, FormatId = 0U, ApplyFont = true };
|
||||
var cellFormatFontAndBorder = new CellFormat() { NumberFormatId = 0U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyFont = true, ApplyBorder = true };
|
||||
var cellFormatTitle = new CellFormat() { NumberFormatId = 0U, FontId = 1U, FillId = 0U, BorderId = 0U, FormatId = 0U, Alignment = new Alignment() { Vertical = VerticalAlignmentValues.Center, WrapText = true, Horizontal = HorizontalAlignmentValues.Center }, ApplyFont = true };
|
||||
|
||||
cellFormats.Append(cellFormatFont);
|
||||
cellFormats.Append(cellFormatFontAndBorder);
|
||||
cellFormats.Append(cellFormatTitle);
|
||||
|
||||
var cellStyles = new CellStyles() { Count = 1U };
|
||||
|
||||
cellStyles.Append(new CellStyle() { Name = "Normal", FormatId = 0U, BuiltinId = 0U });
|
||||
|
||||
var differentialFormats = new DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats() { Count = 0U };
|
||||
|
||||
var tableStyles = new TableStyles() { Count = 0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleLight16" };
|
||||
|
||||
var stylesheetExtensionList = new StylesheetExtensionList();
|
||||
|
||||
var stylesheetExtension1 = new StylesheetExtension() { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" };
|
||||
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
|
||||
stylesheetExtension1.Append(new SlicerStyles() { DefaultSlicerStyle = "SlicerStyleLight1" });
|
||||
|
||||
var stylesheetExtension2 = new StylesheetExtension() { Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}" };
|
||||
stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
|
||||
stylesheetExtension2.Append(new TimelineStyles() { DefaultTimelineStyle = "TimeSlicerStyleLight1" });
|
||||
|
||||
stylesheetExtensionList.Append(stylesheetExtension1);
|
||||
stylesheetExtensionList.Append(stylesheetExtension2);
|
||||
|
||||
sp.Stylesheet.Append(fonts);
|
||||
sp.Stylesheet.Append(fills);
|
||||
sp.Stylesheet.Append(borders);
|
||||
sp.Stylesheet.Append(cellStyleFormats);
|
||||
sp.Stylesheet.Append(cellFormats);
|
||||
sp.Stylesheet.Append(cellStyles);
|
||||
sp.Stylesheet.Append(differentialFormats);
|
||||
sp.Stylesheet.Append(tableStyles);
|
||||
sp.Stylesheet.Append(stylesheetExtensionList);
|
||||
}
|
||||
|
||||
// Получение номера стиля из типа
|
||||
private static uint GetStyleValue(ExcelStyleInfoType styleInfo) {
|
||||
return styleInfo switch {
|
||||
ExcelStyleInfoType.Title => 2U,
|
||||
ExcelStyleInfoType.TextWithBorder => 1U,
|
||||
ExcelStyleInfoType.Text => 0U,
|
||||
_ => 0U,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void CreateExcel(ExcelInfo info) {
|
||||
_spreadsheetDocument = SpreadsheetDocument.Create(_mem, SpreadsheetDocumentType.Workbook);
|
||||
// Создаем книгу (в ней хранятся листы)
|
||||
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
|
||||
workbookpart.Workbook = new Workbook();
|
||||
|
||||
CreateStyles(workbookpart);
|
||||
|
||||
// Получаем/создаем хранилище текстов для книги
|
||||
_shareStringPart = _spreadsheetDocument.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().Any()
|
||||
? _spreadsheetDocument.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
|
||||
: _spreadsheetDocument.WorkbookPart.AddNewPart<SharedStringTablePart>();
|
||||
|
||||
// Создаем SharedStringTable, если его нет
|
||||
if (_shareStringPart.SharedStringTable == null) {
|
||||
_shareStringPart.SharedStringTable = new SharedStringTable();
|
||||
}
|
||||
|
||||
// Создаем лист в книгу
|
||||
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
|
||||
worksheetPart.Worksheet = new Worksheet(new SheetData());
|
||||
|
||||
// Добавляем лист в книгу
|
||||
var sheets = _spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
|
||||
var sheet = new Sheet() {
|
||||
Id = _spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
|
||||
SheetId = 1,
|
||||
Name = "Лист"
|
||||
};
|
||||
sheets.Append(sheet);
|
||||
|
||||
_worksheet = worksheetPart.Worksheet;
|
||||
}
|
||||
|
||||
protected override void InsertCellInWorksheet(ExcelCellParameters excelParams) {
|
||||
if (_worksheet == null || _shareStringPart == null) {
|
||||
return;
|
||||
}
|
||||
var sheetData = _worksheet.GetFirstChild<SheetData>();
|
||||
if (sheetData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ищем строку, либо добавляем ее
|
||||
Row row;
|
||||
if (sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).Any()) {
|
||||
row = sheetData.Elements<Row>().Where(r => r.RowIndex! == excelParams.RowIndex).First();
|
||||
}
|
||||
else {
|
||||
row = new Row() { RowIndex = excelParams.RowIndex };
|
||||
sheetData.Append(row);
|
||||
}
|
||||
|
||||
// Ищем нужную ячейку
|
||||
Cell cell;
|
||||
if (row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).Any()) {
|
||||
cell = row.Elements<Cell>().Where(c => c.CellReference!.Value == excelParams.CellReference).First();
|
||||
}
|
||||
else {
|
||||
// Все ячейки должны быть последовательно друг за другом расположены
|
||||
// нужно определить, после какой вставлять
|
||||
Cell? refCell = null;
|
||||
foreach (Cell rowCell in row.Elements<Cell>()) {
|
||||
if (string.Compare(rowCell.CellReference!.Value, excelParams.CellReference, true) > 0) {
|
||||
refCell = rowCell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var newCell = new Cell() { CellReference = excelParams.CellReference };
|
||||
row.InsertBefore(newCell, refCell);
|
||||
|
||||
cell = newCell;
|
||||
}
|
||||
|
||||
// вставляем новый текст
|
||||
_shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new Text(excelParams.Text)));
|
||||
_shareStringPart.SharedStringTable.Save();
|
||||
|
||||
cell.CellValue = new CellValue((_shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count() - 1).ToString());
|
||||
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
|
||||
cell.StyleIndex = GetStyleValue(excelParams.StyleInfo);
|
||||
}
|
||||
|
||||
protected override void MergeCells(ExcelMergeParameters excelParams) {
|
||||
if (_worksheet == null) {
|
||||
return;
|
||||
}
|
||||
MergeCells mergeCells;
|
||||
|
||||
if (_worksheet.Elements<MergeCells>().Any()) {
|
||||
mergeCells = _worksheet.Elements<MergeCells>().First();
|
||||
}
|
||||
else {
|
||||
mergeCells = new MergeCells();
|
||||
|
||||
if (_worksheet.Elements<CustomSheetView>().Any()) {
|
||||
_worksheet.InsertAfter(mergeCells, _worksheet.Elements<CustomSheetView>().First());
|
||||
}
|
||||
else {
|
||||
_worksheet.InsertAfter(mergeCells, _worksheet.Elements<SheetData>().First());
|
||||
}
|
||||
}
|
||||
|
||||
var mergeCell = new MergeCell() {
|
||||
Reference = new StringValue(excelParams.Merge)
|
||||
};
|
||||
mergeCells.Append(mergeCell);
|
||||
}
|
||||
|
||||
protected override byte[]? SaveExcel(ExcelInfo info) {
|
||||
if (_spreadsheetDocument == null) {
|
||||
return null;
|
||||
}
|
||||
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
|
||||
_spreadsheetDocument.Dispose();
|
||||
return _mem.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
using MigraDoc.DocumentObjectModel;
|
||||
using MigraDoc.DocumentObjectModel.Tables;
|
||||
using MigraDoc.Rendering;
|
||||
using PdfSharp.Pdf;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.Implements {
|
||||
public class SaveToPdf : AbstractSaveToPdf {
|
||||
|
||||
private Document? _document;
|
||||
private Section? _section;
|
||||
private Table? _table;
|
||||
|
||||
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type) {
|
||||
return type switch {
|
||||
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
|
||||
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
|
||||
PdfParagraphAlignmentType.Right => ParagraphAlignment.Right,
|
||||
_ => ParagraphAlignment.Justify
|
||||
};
|
||||
}
|
||||
|
||||
// Создание стилей для документа
|
||||
private static void DefineStyles(Document document) {
|
||||
var style = document.Styles["Normal"];
|
||||
style.Font.Name = "Times New Roman";
|
||||
style.Font.Size = 14;
|
||||
style = document.Styles.AddStyle("NormalTitle", "Normal");
|
||||
style.Font.Bold = true;
|
||||
}
|
||||
|
||||
protected override void CreateParagraph(PdfParagraph pdfParagraph) {
|
||||
if (_section == null) {
|
||||
return;
|
||||
}
|
||||
var paragraph = _section.AddParagraph(pdfParagraph.Text);
|
||||
paragraph.Format.SpaceAfter = "1cm";
|
||||
paragraph.Format.Alignment = GetParagraphAlignment(pdfParagraph.alignmentType);
|
||||
paragraph.Style = pdfParagraph.Style;
|
||||
}
|
||||
|
||||
protected override void CreateRow(PdfRowParameters rowParameters) {
|
||||
if (_table == null) {
|
||||
return;
|
||||
}
|
||||
var row = _table.AddRow();
|
||||
for (int i = 0; i < rowParameters.Text.Count; ++i) {
|
||||
// заполнение ячейки (добавление параграфа в ячейку)
|
||||
row.Cells[i].AddParagraph(rowParameters.Text[i]);
|
||||
if (!string.IsNullOrEmpty(rowParameters.Style)) {
|
||||
row.Cells[i].Style = rowParameters.Style;
|
||||
}
|
||||
Unit borderWidth = 0.5;
|
||||
row.Cells[i].Borders.Left.Width = borderWidth;
|
||||
row.Cells[i].Borders.Right.Width = borderWidth;
|
||||
row.Cells[i].Borders.Top.Width = borderWidth;
|
||||
row.Cells[i].Borders.Bottom.Width = borderWidth;
|
||||
|
||||
row.Cells[i].Format.Alignment = GetParagraphAlignment(rowParameters.alignmentType);
|
||||
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreateTable(List<string> columns) {
|
||||
if (_document == null) {
|
||||
return;
|
||||
}
|
||||
_table = _document.LastSection.AddTable();
|
||||
foreach (var elem in columns) {
|
||||
_table.AddColumn(elem);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CreatePdf(PdfInfo info) {
|
||||
_document = new Document();
|
||||
DefineStyles(_document);
|
||||
// Ссылка нп первую секцию
|
||||
_section = _document.AddSection();
|
||||
}
|
||||
|
||||
protected override PdfDocument SavePdf(PdfInfo info) {
|
||||
var renderer = new PdfDocumentRenderer(true) {
|
||||
Document = _document,
|
||||
};
|
||||
renderer.RenderDocument();
|
||||
return renderer.PdfDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,115 @@
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using DocumentFormat.OpenXml;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperEnums;
|
||||
using ServiceStationBusinessLogic.OfficePackage.HelperModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationBusinessLogic.OfficePackage.Implements {
|
||||
public class SaveToWord : AbstractSaveToWord {
|
||||
private WordprocessingDocument? _wordDocument;
|
||||
|
||||
private Body? _docBody;
|
||||
|
||||
private MemoryStream _mem = new MemoryStream();
|
||||
|
||||
// Получение типа выравнивания
|
||||
private static JustificationValues GetJustificationValues(WordJustificationType type) {
|
||||
return type switch {
|
||||
WordJustificationType.Both => JustificationValues.Both,
|
||||
WordJustificationType.Center => JustificationValues.Center,
|
||||
_ => JustificationValues.Left,
|
||||
};
|
||||
}
|
||||
|
||||
// Настройки страницы
|
||||
private static SectionProperties CreateSectionProperties() {
|
||||
var properties = new SectionProperties();
|
||||
|
||||
var pageSize = new PageSize {
|
||||
Orient = PageOrientationValues.Portrait
|
||||
};
|
||||
|
||||
properties.AppendChild(pageSize);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
// Задание форматирования для абзаца
|
||||
private static ParagraphProperties? CreateParagraphProperties(WordTextProperties? paragraphProperties) {
|
||||
if (paragraphProperties == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var properties = new ParagraphProperties();
|
||||
|
||||
properties.AppendChild(new Justification() {
|
||||
Val = GetJustificationValues(paragraphProperties.JustificationType)
|
||||
});
|
||||
|
||||
properties.AppendChild(new SpacingBetweenLines {
|
||||
LineRule = LineSpacingRuleValues.Auto
|
||||
});
|
||||
|
||||
properties.AppendChild(new Indentation());
|
||||
|
||||
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
|
||||
if (!string.IsNullOrEmpty(paragraphProperties.Size)) {
|
||||
paragraphMarkRunProperties.AppendChild(new FontSize { Val = paragraphProperties.Size });
|
||||
}
|
||||
properties.AppendChild(paragraphMarkRunProperties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected override void CreateWord(WordInfo info) {
|
||||
_wordDocument = WordprocessingDocument.Create(_mem, WordprocessingDocumentType.Document);
|
||||
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
|
||||
mainPart.Document = new Document();
|
||||
_docBody = mainPart.Document.AppendChild(new Body());
|
||||
}
|
||||
|
||||
protected override void CreateParagraph(WordParagraph paragraph) {
|
||||
if (_docBody == null || paragraph == null) {
|
||||
return;
|
||||
}
|
||||
var docParagraph = new Paragraph();
|
||||
|
||||
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
|
||||
|
||||
foreach (var run in paragraph.Texts) {
|
||||
var docRun = new Run();
|
||||
|
||||
var properties = new RunProperties();
|
||||
properties.AppendChild(new FontSize { Val = run.Item2.Size });
|
||||
if (run.Item2.Bold) {
|
||||
properties.AppendChild(new Bold());
|
||||
}
|
||||
docRun.AppendChild(properties);
|
||||
|
||||
docRun.AppendChild(new Text { Text = run.Item1, Space = SpaceProcessingModeValues.Preserve });
|
||||
|
||||
docParagraph.AppendChild(docRun);
|
||||
}
|
||||
|
||||
_docBody.AppendChild(docParagraph);
|
||||
}
|
||||
|
||||
protected override byte[]? SaveWord(WordInfo info) {
|
||||
if (_docBody == null || _wordDocument == null) {
|
||||
return null;
|
||||
}
|
||||
_docBody.AppendChild(CreateSectionProperties());
|
||||
|
||||
_wordDocument.MainDocumentPart!.Document.Save();
|
||||
|
||||
_wordDocument.Dispose();
|
||||
|
||||
return _mem.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="MigraDocCore.DocumentObjectModel" Version="1.3.65" />
|
||||
<PackageReference Include="MigraDocCore.Rendering" Version="1.3.65" />
|
||||
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ServiceStationContracts\ServiceStationContracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,10 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels
|
||||
{
|
||||
public class ClientBindingModel : IClientModel {
|
||||
|
||||
public int Id { get; set; }
|
||||
public string FIO { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels
|
||||
{
|
||||
public class ExecutorBindingModel : IExecutorModel {
|
||||
|
||||
public int Id { get; set; }
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public string FIO { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels {
|
||||
public class MailConfigBindingModel {
|
||||
public string MailLogin { get; set; } = string.Empty;
|
||||
public string MailPassword { get; set; } = string.Empty;
|
||||
public string SmtpClientHost { get; set; } = string.Empty;
|
||||
public int SmtpClientPort { get; set; }
|
||||
public string PopHost { get; set; } = string.Empty;
|
||||
public int PopPort { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels {
|
||||
public class MailSendInfoBindingModel {
|
||||
public string MailAddress { get; set; } = string.Empty;
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public string Text { get; set; } = string.Empty;
|
||||
public byte[]? document { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels {
|
||||
public class ReportBindeingModel {
|
||||
public string EmailAddress { get; set; } = string.Empty;
|
||||
public DateTime DateFrom { get; set; }
|
||||
public DateTime DateTo { get; set; }
|
||||
|
||||
// Список выбранных работ
|
||||
public List<int> ids { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels {
|
||||
public class TaskBindingModel : ITaskModel {
|
||||
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public double Price { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels
|
||||
{
|
||||
public class WorkBindingModel : IWorkModel {
|
||||
|
||||
public int Id { get; set; }
|
||||
public DateTime Date { get; set; } = DateTime.Now;
|
||||
public double Price { get; set; }
|
||||
public int ExecutorId { get; set; }
|
||||
public int TaskByWorkId { get; set; }
|
||||
|
||||
public Dictionary<int, IClientModel> ClientList { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BindingModels {
|
||||
public class WorkFromWebBindingModel {
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public DateTime Date { get; set; } = DateTime.Now;
|
||||
|
||||
public double Price { get; set; }
|
||||
|
||||
public int ExecutorId { get; set; }
|
||||
|
||||
public int TaskId { get; set; }
|
||||
|
||||
public int[] client_ids { get; set; } = new int[0];
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
|
||||
namespace ServiceStationContracts.BusinessLogic
|
||||
{
|
||||
public interface IClientLogic
|
||||
{
|
||||
List<ClientViewModel>? ReadList();
|
||||
ClientViewModel? ReadElement(ClientSearchModel model);
|
||||
|
||||
bool Create(ClientBindingModel model);
|
||||
bool Update(ClientBindingModel model);
|
||||
bool Delete(ClientBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
|
||||
namespace ServiceStationContracts.BusinessLogic
|
||||
{
|
||||
public interface IExecutorLogic
|
||||
{
|
||||
List<ExecutorViewModel>? ReadList();
|
||||
ExecutorViewModel? ReadElement(ExecutorSearchModel model);
|
||||
|
||||
bool Create(ExecutorBindingModel model);
|
||||
bool Update(ExecutorBindingModel model);
|
||||
bool Delete(ExecutorBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using PdfSharp.Pdf;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BusinessLogic {
|
||||
public interface IReportLogic {
|
||||
List<ReportClientsInWorksViewModel> GetClientListInWorks(ReportBindeingModel model);
|
||||
|
||||
byte[]? SaveToWordFile(ReportBindeingModel model);
|
||||
byte[]? SaveToExcelFile(ReportBindeingModel model);
|
||||
PdfDocument SaveToPdfFile(ReportBindeingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BusinessLogic {
|
||||
public interface ITaskLogic {
|
||||
List<TaskViewModel>? ReadList();
|
||||
TaskViewModel? ReadElement(TaskSearchModel model);
|
||||
|
||||
bool Create(TaskBindingModel model);
|
||||
bool Update(TaskBindingModel model);
|
||||
bool Delete(TaskBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using ServiceStationContracts.HelperModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.BusinessLogic
|
||||
{
|
||||
public interface IWorkClientLogic {
|
||||
bool Add_Points(WorkClientModel model);
|
||||
List<WorkClientModel>? ReadList(WorkClientSearchModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
|
||||
namespace ServiceStationContracts.BusinessLogic
|
||||
{
|
||||
public interface IWorkLogic
|
||||
{
|
||||
List<WorkViewModel>? ReadList(WorkSearchModel model);
|
||||
WorkViewModel? ReadElement(WorkSearchModel model);
|
||||
|
||||
bool Create(WorkBindingModel model);
|
||||
bool Update(WorkBindingModel model);
|
||||
bool Delete(WorkBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.HelperModels
|
||||
{
|
||||
public class WorkClientModel
|
||||
{
|
||||
public int Work_Id { get; set; }
|
||||
public int Client_Id { get; set; }
|
||||
public int Point_count { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace ServiceStationContracts.SearchModels
|
||||
{
|
||||
public class ClientSearchModel
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? fio { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace ServiceStationContracts.SearchModels
|
||||
{
|
||||
public class ExecutorSearchModel
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? Password { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace ServiceStationContracts.SearchModels
|
||||
{
|
||||
public class TaskSearchModel
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.SearchModels {
|
||||
public class WorkClientSearchModel {
|
||||
public int client_id { get; set; }
|
||||
public int work_id { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
|
||||
namespace ServiceStationContracts.SearchModels
|
||||
{
|
||||
public class WorkSearchModel
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public DateTime? DateFrom { get; set; }
|
||||
public DateTime? DateTo { get; set; }
|
||||
public int? ExecutorId { get; set; }
|
||||
public int? TaskId { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ServiceStationDataModels\ServiceStationDataModels.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,21 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.StorageContracts
|
||||
{
|
||||
public interface IClientStorage
|
||||
{
|
||||
List<ClientViewModel>? GetFullList();
|
||||
ClientViewModel? GetElement(ClientSearchModel model);
|
||||
|
||||
ClientViewModel? Insert(ClientBindingModel model);
|
||||
ClientViewModel? Update(ClientBindingModel model);
|
||||
ClientViewModel? Delete(ClientBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.StorageContracts
|
||||
{
|
||||
public interface IExecutorStorage
|
||||
{
|
||||
List<ExecutorViewModel> GetFullList();
|
||||
ExecutorViewModel? GetElement(ExecutorSearchModel model);
|
||||
|
||||
ExecutorViewModel? Insert(ExecutorBindingModel model);
|
||||
ExecutorViewModel? Update(ExecutorBindingModel model);
|
||||
ExecutorViewModel? Delete(ExecutorBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.StorageContracts
|
||||
{
|
||||
public interface ITaskStorage
|
||||
{
|
||||
List<TaskViewModel> GetFullList();
|
||||
TaskViewModel? GetElement(TaskSearchModel model);
|
||||
|
||||
TaskViewModel? Insert(TaskBindingModel model);
|
||||
TaskViewModel? Update(TaskBindingModel model);
|
||||
TaskViewModel? Delete(TaskBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using ServiceStationContracts.HelperModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.StorageContracts
|
||||
{
|
||||
public interface IWorkClientStorage {
|
||||
bool Add_Points(WorkClientModel model);
|
||||
List<WorkClientModel>? GetFilteredList(WorkClientSearchModel model);
|
||||
|
||||
WorkClientModel? GetElement(WorkClientSearchModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.SearchModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.StorageContracts
|
||||
{
|
||||
public interface IWorkStorage
|
||||
{
|
||||
List<WorkViewModel> GetFullList();
|
||||
List<WorkViewModel> GetFilteredList(WorkSearchModel model);
|
||||
|
||||
WorkViewModel? GetElement(WorkSearchModel model);
|
||||
WorkViewModel? Insert(WorkBindingModel model);
|
||||
WorkViewModel? Update(WorkBindingModel model);
|
||||
WorkViewModel? Delete(WorkBindingModel model);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ServiceStationContracts.ViewModels
|
||||
{
|
||||
public class ClientViewModel : IClientModel, IEquatable<ClientViewModel>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("ФИО")]
|
||||
public string FIO { get; set; } = string.Empty;
|
||||
|
||||
public bool Equals(ClientViewModel? other) {
|
||||
if (other is null) {
|
||||
return false;
|
||||
}
|
||||
return this.Id == other.Id && this.FIO == other.FIO;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => Equals(obj as ClientViewModel);
|
||||
public override int GetHashCode() => (Id, FIO).GetHashCode();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ServiceStationContracts.ViewModels
|
||||
{
|
||||
public class ExecutorViewModel : IExecutorModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("Email")]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Пароль")]
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("ФИО исполнителя")]
|
||||
public string FIO { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationContracts.ViewModels {
|
||||
public class ReportClientsInWorksViewModel {
|
||||
public int WorkId { get; set; }
|
||||
public string Date { get; set; } = string.Empty;
|
||||
public double Price { get; set; }
|
||||
public int TotalCount { get; set; }
|
||||
public List<(int client_id, string client_fio, int points)> _Clients { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ServiceStationContracts.ViewModels
|
||||
{
|
||||
public class TaskViewModel : ITaskModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("Наименование задачи")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Стоимость задачи")]
|
||||
public double Price { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
using ServiceStationDataModels.Models;
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
|
||||
namespace ServiceStationContracts.ViewModels
|
||||
{
|
||||
public class WorkViewModel : IWorkModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("Дата")]
|
||||
public DateTime Date { get; set; } = DateTime.Now;
|
||||
|
||||
[DisplayName("Цена")]
|
||||
public double Price { get; set; }
|
||||
|
||||
public int ExecutorId { get; set; }
|
||||
|
||||
public int TaskByWorkId { get; set; }
|
||||
|
||||
[DisplayName("Задача")]
|
||||
public string TaskName { get; set; } = string.Empty;
|
||||
|
||||
[JsonIgnore]
|
||||
public Dictionary<int, IClientModel> ClientList { get; set; } = new();
|
||||
}
|
||||
}
|
7
ServiceStation/ServiceStationDataModels/IId.cs
Normal file
7
ServiceStation/ServiceStationDataModels/IId.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace ServiceStationDataModels.HelperInterfaces
|
||||
{
|
||||
public interface IId
|
||||
{
|
||||
int Id { get; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using ServiceStationDataModels.HelperInterfaces;
|
||||
|
||||
namespace ServiceStationDataModels.Models
|
||||
{
|
||||
public interface IClientModel : IId
|
||||
{
|
||||
string FIO { get; }
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using ServiceStationDataModels.HelperInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationDataModels.Models
|
||||
{
|
||||
public interface IExecutorModel : IId
|
||||
{
|
||||
string Email { get; }
|
||||
string Password { get; }
|
||||
string FIO { get; }
|
||||
}
|
||||
}
|
15
ServiceStation/ServiceStationDataModels/Models/ITaskModel.cs
Normal file
15
ServiceStation/ServiceStationDataModels/Models/ITaskModel.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using ServiceStationDataModels.HelperInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationDataModels.Models
|
||||
{
|
||||
public interface ITaskModel : IId
|
||||
{
|
||||
string Name { get; }
|
||||
double Price { get; }
|
||||
}
|
||||
}
|
20
ServiceStation/ServiceStationDataModels/Models/IWorkModel.cs
Normal file
20
ServiceStation/ServiceStationDataModels/Models/IWorkModel.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using ServiceStationDataModels.HelperInterfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ServiceStationDataModels.Models
|
||||
{
|
||||
public interface IWorkModel : IId
|
||||
{
|
||||
DateTime Date { get; }
|
||||
double Price { get; }
|
||||
int ExecutorId { get; }
|
||||
int TaskByWorkId { get; }
|
||||
|
||||
// ClientId, ClientModel
|
||||
Dictionary<int, IClientModel> ClientList { get; }
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
42
ServiceStation/ServiceStationExecutorApp/APIClient.cs
Normal file
42
ServiceStation/ServiceStationExecutorApp/APIClient.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using Newtonsoft.Json;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace ServiceSourceExecutorApp {
|
||||
public class APIClient {
|
||||
private static readonly HttpClient _client = new();
|
||||
public static ExecutorViewModel? executor { get; set; } = null;
|
||||
public static string port { get; set; } = string.Empty;
|
||||
|
||||
public static void Connect(IConfiguration configuration) {
|
||||
_client.BaseAddress = new Uri(configuration["IPAddress"]);
|
||||
port = _client.BaseAddress.Port.ToString();
|
||||
_client.DefaultRequestHeaders.Accept.Clear();
|
||||
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
}
|
||||
|
||||
public static T? GetRequest<T>(string requestUrl) {
|
||||
var response = _client.GetAsync(requestUrl);
|
||||
var result = response.Result.Content.ReadAsStringAsync().Result;
|
||||
if (response.Result.IsSuccessStatusCode) {
|
||||
return JsonConvert.DeserializeObject<T>(result);
|
||||
}
|
||||
else {
|
||||
throw new Exception(result);
|
||||
}
|
||||
}
|
||||
|
||||
public static void PostRequest<T>(string requestUrl, T model) {
|
||||
var json = JsonConvert.SerializeObject(model);
|
||||
var data = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = _client.PostAsync(requestUrl, data);
|
||||
|
||||
var result = response.Result.Content.ReadAsStringAsync().Result;
|
||||
if (!response.Result.IsSuccessStatusCode) {
|
||||
throw new Exception(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,300 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||
using Newtonsoft.Json;
|
||||
using ServiceSourceClientApp.Models;
|
||||
using ServiceSourceExecutorApp;
|
||||
using ServiceStationContracts.BindingModels;
|
||||
using ServiceStationContracts.HelperModels;
|
||||
using ServiceStationContracts.ViewModels;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ServiceSourceClientApp.Controllers {
|
||||
public class HomeController : Controller {
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
|
||||
public HomeController(ILogger<HomeController> logger) {
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Index() {
|
||||
if (APIClient.executor == null) {
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
|
||||
var view = APIClient.GetRequest<List<WorkViewModel>>($"api/Main/GetWorks?_executorId={APIClient.executor.Id}");
|
||||
return View(view);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Enter() {
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Enter(string email, string password) {
|
||||
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password)) {
|
||||
throw new Exception("Ââåäèòå ïî÷òó è ïàðîëü");
|
||||
}
|
||||
APIClient.executor = APIClient.GetRequest<ExecutorViewModel>($"api/main/Login?email={email}&password={password}");
|
||||
if (APIClient.executor == null) {
|
||||
throw new Exception("Íåâåðíûé àäðåñ ïî÷òû èëè ïàðîëü");
|
||||
}
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Register() {
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Register(string email, string password, string fio) {
|
||||
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio)) {
|
||||
throw new Exception("Ââåäèòå ïî÷òó, ïàðîëü è ÔÈÎ");
|
||||
}
|
||||
APIClient.PostRequest("api/Main/Register", new ExecutorBindingModel {
|
||||
Email = email,
|
||||
Password = password,
|
||||
FIO = fio
|
||||
});
|
||||
Response.Redirect("Enter");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Privacy() {
|
||||
if (APIClient.executor == null) {
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View(APIClient.executor);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Privacy(string email, string password, string fio) {
|
||||
if (APIClient.executor == null) {
|
||||
Response.Redirect("~/Home/Enter");
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio)) {
|
||||
throw new Exception("Ââåäèòå ïî÷òó, ïàðîëü è ÔÈÎ");
|
||||
}
|
||||
APIClient.PostRequest("api/Main/UpdateData", new ExecutorBindingModel {
|
||||
Id = APIClient.executor.Id,
|
||||
Email = email,
|
||||
Password = password,
|
||||
FIO = fio
|
||||
});
|
||||
|
||||
APIClient.executor.FIO = fio;
|
||||
APIClient.executor.Email = email;
|
||||
APIClient.executor.Password = password;
|
||||
Response.Redirect("Index");
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error() {
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult CreateWork() {
|
||||
ViewBag.Tasks = APIClient.GetRequest<List<TaskViewModel>>($"api/Main/GetTasks?");
|
||||
return View(APIClient.GetRequest<List<ClientViewModel>>($"api/Main/GetClients?"));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void CreateWork(int[] ids, int task) {
|
||||
if (APIClient.executor == null) {
|
||||
Response.Redirect("~/Home/Enter");
|
||||
return;
|
||||
}
|
||||
APIClient.PostRequest("api/Main/CreateWork", new WorkFromWebBindingModel {
|
||||
Price = Calc(task, ids.Length),
|
||||
ExecutorId = APIClient.executor.Id,
|
||||
TaskId = task,
|
||||
client_ids = ids
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult EditWork(int Id) {
|
||||
if (Id == 0) {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
var work_info = APIClient.GetRequest<List<List<string>>>($"api/Main/GetWork?_workId={Id}")
|
||||
?? throw new Exception("Îøèáêà ïîëó÷åíèÿ äàííûõ");
|
||||
|
||||
ViewBag.Tasks = APIClient.GetRequest<List<TaskViewModel>>($"api/Main/GetTasks?");
|
||||
|
||||
int task_load_id = JsonConvert.DeserializeObject<int>(work_info[0][0]);
|
||||
var task_load = APIClient.GetRequest<TaskViewModel>($"api/Main/GetTask?_taskId={task_load_id}")
|
||||
?? throw new Exception("Îøèáêà ïîëó÷åíèÿ äàííûõ");
|
||||
if (ViewBag.Tasks[0].Name != task_load.Name) {
|
||||
int index = 0;
|
||||
for (int i = 0; i < ViewBag.Tasks.Count; i++) {
|
||||
if (ViewBag.Tasks[i].Name == task_load.Name) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var tmp = ViewBag.Tasks[0];
|
||||
ViewBag.Tasks[0] = task_load;
|
||||
ViewBag.Tasks[index] = tmp;
|
||||
}
|
||||
|
||||
List<ClientViewModel> clients_list = new();
|
||||
|
||||
|
||||
foreach (var rec in work_info[1]) {
|
||||
var client = JsonConvert.DeserializeObject<ClientViewModel>(rec) ?? throw new Exception("Îøèáêà äåñåðèàëèçàöèè");
|
||||
clients_list.Add(client);
|
||||
}
|
||||
|
||||
var clients = APIClient.GetRequest<List<ClientViewModel>>($"api/Main/GetClients?")
|
||||
?? throw new Exception("Îøèáêà ïîëó÷åíèÿ äàííûõ");
|
||||
IEnumerable<ClientViewModel> result = clients.Except(clients_list);
|
||||
|
||||
List<ClientViewModel> new_client = new();
|
||||
foreach (var client in result) {
|
||||
new_client.Add(client);
|
||||
}
|
||||
|
||||
(int, List<ClientViewModel>, List<ClientViewModel>) tuple = (Id, clients_list, new_client);
|
||||
return View(tuple);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void EditWork(int[] ids, int task, int id) {
|
||||
if (APIClient.executor == null) {
|
||||
Response.Redirect("~/Home/Enter");
|
||||
return;
|
||||
}
|
||||
|
||||
APIClient.PostRequest("api/Main/UpdateWork", new WorkFromWebBindingModel {
|
||||
Id = id,
|
||||
Price = Calc(task, ids.Length),
|
||||
ExecutorId = APIClient.executor.Id,
|
||||
TaskId = task,
|
||||
client_ids = ids
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public double Calc(int task, int count) {
|
||||
var task_info = APIClient.GetRequest<TaskViewModel>($"api/Main/GetTask?_taskId={task}") ?? throw new Exception("Îøèáêà ïîëó÷åèÿ äàííûõ");
|
||||
return task_info.Price + 700 * count;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult DeleteWork(int id) {
|
||||
APIClient.PostRequest("api/Main/DeleteWork", new WorkBindingModel {
|
||||
Id = id,
|
||||
});
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Scoring () {
|
||||
if (APIClient.executor == null) {
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Scoring(int client, int work, int points) {
|
||||
APIClient.PostRequest("api/Main/AddClientPoints", new WorkClientModel {
|
||||
Client_Id = client,
|
||||
Work_Id = work,
|
||||
Point_count = points
|
||||
});
|
||||
Response.Redirect("Scoring");
|
||||
}
|
||||
|
||||
public JsonResult Client() {
|
||||
var clients = APIClient.GetRequest<List<ClientViewModel>>($"api/Main/GetClients?") ?? throw new Exception("Îøèáêà ïîëó÷åíèÿ äàííûõ");
|
||||
return new JsonResult(clients);
|
||||
}
|
||||
|
||||
public JsonResult Work(int id) {
|
||||
var work_clients_list = APIClient.GetRequest<List<WorkClientModel>>($"api/Main/GetWorkClients?_clientId={id}")
|
||||
?? throw new Exception("Îøèáêà ïîëóåíèÿ äàííûõ");
|
||||
List<WorkViewModel> works = new();
|
||||
foreach (var record in work_clients_list) {
|
||||
int work_id = record.Work_Id;
|
||||
var work = APIClient.GetRequest<WorkViewModel>($"api/Main/GetWorkView?_workId={work_id}")
|
||||
?? throw new Exception("Îøèáêà ïîëó÷åíèÿ äàííûõ");
|
||||
works.Add(work);
|
||||
}
|
||||
return new JsonResult(works);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Report() {
|
||||
if (APIClient.executor == null) {
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
var view = APIClient.GetRequest<List<WorkViewModel>>($"api/Main/GetWorks?_executorId={APIClient.executor.Id}");
|
||||
return View(view);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Report(DateTime DateFrom, DateTime DateTo) {
|
||||
if (DateTo == DateTime.MinValue || DateFrom > DateTo) {
|
||||
throw new Exception("Íåêîðåêòíî óêàçàí âðåìåííîé èíòåðâàë");
|
||||
}
|
||||
Response.Redirect($"ReportSearchDate?_datefrom={DateFrom}&_dateto={DateTo + DateTime.Now.TimeOfDay}");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult ReportSearchDate(string _datefrom, string _dateto) {
|
||||
var reports = APIClient.GetRequest<List<WorkViewModel>>($"api/Main/GerWorksDate?_start={_datefrom}&_end={_dateto}");
|
||||
(DateTime, DateTime, List<WorkViewModel>?) tuple = (DateTime.Parse(_datefrom), DateTime.Parse(_dateto), reports);
|
||||
return View(tuple);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult CreatePdfReport(string DateFrom, string DateTo) {
|
||||
APIClient.PostRequest("api/Main/SendReportPdfMail", new ReportBindeingModel {
|
||||
EmailAddress = APIClient.executor?.Email ?? throw new Exception("Îøèáêà ïîëó÷åíèÿ àäðåñà"),
|
||||
DateFrom = DateTime.Parse(DateFrom),
|
||||
DateTo = DateTime.Parse(DateTo)
|
||||
});
|
||||
return Redirect("Report");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult CreateWordReport(string ids) {
|
||||
|
||||
if (string.IsNullOrEmpty(ids)) {
|
||||
throw new Exception("Íåò âûáðàíûõ çàïèñåé");
|
||||
}
|
||||
|
||||
|
||||
var fileMemStream = APIClient.GetRequest<byte[]>($"api/Main/CreateWordReport?_ids={ids}");
|
||||
|
||||
if (fileMemStream == null) {
|
||||
throw new Exception("Îøèáêà ñîçäàíèÿ îò÷åòà");
|
||||
}
|
||||
|
||||
return File(fileMemStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "Report.docx");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult CreateExcelReport(string ids) {
|
||||
|
||||
if (string.IsNullOrEmpty(ids)) {
|
||||
throw new Exception("Íåò âûáðàíûõ çàïèñåé");
|
||||
}
|
||||
|
||||
var fileMemStream = APIClient.GetRequest<byte[]>($"api/Main/CreateXlsxReport?_ids={ids}");
|
||||
|
||||
if (fileMemStream == null) {
|
||||
throw new Exception("Îøèáêà ñîçäàíèÿ îò÷åòà");
|
||||
}
|
||||
|
||||
return File(fileMemStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
namespace ServiceSourceClientApp.Models {
|
||||
public class ErrorViewModel {
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
35
ServiceStation/ServiceStationExecutorApp/Program.cs
Normal file
35
ServiceStation/ServiceStationExecutorApp/Program.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using ServiceSourceExecutorApp;
|
||||
|
||||
namespace ServiceSourceClientApp {
|
||||
public class Program {
|
||||
public static void Main(string[] args) {
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddControllersWithViews();
|
||||
|
||||
var app = builder.Build();
|
||||
APIClient.Connect(builder.Configuration);
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment()) {
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:42598",
|
||||
"sslPort": 44386
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5139",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7205;http://localhost:5139",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ServiceStationContracts\ServiceStationContracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,144 @@
|
||||
@using ServiceStationContracts.ViewModels
|
||||
@{
|
||||
ViewData["Title"] = "CreateWork";
|
||||
}
|
||||
|
||||
@model List<ClientViewModel>
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Создать работу</h2>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Задача:</div>
|
||||
<div class="col-8">
|
||||
<select id="task" name="task" class="form-control" asp-items="@(new SelectList(ViewBag.Tasks, "Id", "Name"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Стоимость:</div>
|
||||
<div class="col-8">
|
||||
<input id="price" type="text" name="price" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-5">Выбрать клиентов в работу</h2>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
if (Model == null) {
|
||||
<h3 class="display-4">Авторизируйтесь</h3>
|
||||
return;
|
||||
}
|
||||
<div class="text-end">
|
||||
<button class="btn btn-outline-primary" id="btnCreate">Создать</button>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер клиента
|
||||
</th>
|
||||
<th>
|
||||
ФИО клиента
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input" id="Select_all" name="Select_all" /> Выбрать все
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model) {
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.FIO)
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input" id="Select_rec" name="Select_rec" value="@item.Id" />
|
||||
</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
<script>
|
||||
$('#task').on('change', function () {
|
||||
check();
|
||||
});
|
||||
$('.form-check-input').on('change', function () {
|
||||
check();
|
||||
});
|
||||
|
||||
check();
|
||||
|
||||
function check() {
|
||||
var task = $('#task').val();
|
||||
let checkboxes = document.getElementsByTagName('input');
|
||||
var count = 0;
|
||||
|
||||
$("input[name='Select_rec']:checked").each(function () {
|
||||
count++;
|
||||
});
|
||||
if (task && count >= 0) {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/Home/Calc',
|
||||
data: {task: task, count: count},
|
||||
success: function (result) {
|
||||
$('#price').val(result)
|
||||
},
|
||||
error: function () {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
$('#Select_all').on('click', function () {
|
||||
let checkboxes = document.getElementsByTagName('input');
|
||||
let val = null;
|
||||
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
if (checkboxes[i].type === 'checkbox') {
|
||||
if (val == null) {
|
||||
val = checkboxes[i].checked;
|
||||
}
|
||||
else {
|
||||
checkboxes[i].checked = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
check();
|
||||
|
||||
});
|
||||
$('#btnCreate').on('click', function () {
|
||||
let val = [];
|
||||
var task = $('#task').val();
|
||||
|
||||
$("input[name='Select_rec']:checked").each(function () {
|
||||
val.push($(this).val());
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/Home/CreateWork',
|
||||
data: {'ids':val, 'task': task},
|
||||
success: function () {
|
||||
window.location.href = "Index";
|
||||
},
|
||||
error: function () {
|
||||
window.location.href = "Index";
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
@ -0,0 +1,218 @@
|
||||
@using ServiceStationContracts.ViewModels
|
||||
@{
|
||||
ViewData["Title"] = "EditWork";
|
||||
}
|
||||
|
||||
@model (int, List<ClientViewModel>, List<ClientViewModel>)
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Редактировать работу №:@Model.Item1</h2>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Задача:</div>
|
||||
<div class="col-8">
|
||||
<select id="task" name="task" class="form-control" asp-items="@(new SelectList(ViewBag.Tasks, "Id", "Name"))"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Стоимость:</div>
|
||||
<div class="col-8">
|
||||
<input id="price" type="text" name="price" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-5">Клиенты в работе</h2>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
if (Model.Item2 == null) {
|
||||
<h3 class="display-4">Авторизируйтесь</h3>
|
||||
return;
|
||||
}
|
||||
<div class="text-end">
|
||||
<button class="btn btn-outline-primary" id="btnEdit">Сохранить изменения</button>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер клиента
|
||||
</th>
|
||||
<th>
|
||||
ФИО клиента
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input old" id="Select_all" name="Select_all" /> Выбрать все
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Item2) {
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.FIO)
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input old" id="Select_rec" name="Select_rec" value="@item.Id" />
|
||||
</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-5">Добавить новых клиентов</h2>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
if (Model.Item3 == null) {
|
||||
<h3 class="display-4">Авторизируйтесь</h3>
|
||||
return;
|
||||
}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер клиента
|
||||
</th>
|
||||
<th>
|
||||
ФИО клиента
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input new" id="Select_all_new" name="Select_all_new" /> Выбрать все
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Item3) {
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.FIO)
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input new" id="Select_rec_new" name="Select_rec_new" value="@item.Id" />
|
||||
</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#task').on('change', function () {
|
||||
check();
|
||||
});
|
||||
$('.form-check-input').on('change', function () {
|
||||
check();
|
||||
});
|
||||
|
||||
document.getElementById('Select_all').checked = true;
|
||||
checked_all();
|
||||
|
||||
check();
|
||||
|
||||
function check() {
|
||||
var task = $('#task').val();
|
||||
let checkboxes = document.getElementsByTagName('input');
|
||||
var count = 0;
|
||||
|
||||
$("input[name='Select_rec']:checked").each(function () {
|
||||
count++;
|
||||
});
|
||||
$("input[name='Select_rec_new']:checked").each(function () {
|
||||
count++;
|
||||
});
|
||||
if (task && count >= 0) {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/Home/Calc',
|
||||
data: { task: task, count: count },
|
||||
success: function (result) {
|
||||
$('#price').val(result)
|
||||
},
|
||||
error: function () {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function checked_all() {
|
||||
let checkboxes = document.querySelectorAll('.form-check-input.old');
|
||||
let val = null;
|
||||
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
if (val == null) {
|
||||
val = checkboxes[i].checked;
|
||||
}
|
||||
else {
|
||||
checkboxes[i].checked = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#Select_all').on('click', function () {
|
||||
checked_all();
|
||||
check();
|
||||
|
||||
});
|
||||
|
||||
$('#Select_all_new').on('click', function () {
|
||||
let checkboxes = document.querySelectorAll('.form-check-input.new');
|
||||
let val = null;
|
||||
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
if (checkboxes[i].type === 'checkbox') {
|
||||
if (val == null) {
|
||||
val = checkboxes[i].checked;
|
||||
}
|
||||
else {
|
||||
checkboxes[i].checked = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
check();
|
||||
});
|
||||
|
||||
$('#btnEdit').on('click', function () {
|
||||
let val = [];
|
||||
var task = $('#task').val();
|
||||
var id = $('#id').val();
|
||||
|
||||
$("input[name='Select_rec']:checked").each(function () {
|
||||
val.push($(this).val());
|
||||
});
|
||||
$("input[name='Select_rec_new']:checked").each(function () {
|
||||
val.push($(this).val());
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/Home/EditWork',
|
||||
data: { 'ids': val, 'task': task, 'id':@Model.Item1 },
|
||||
success: function () {
|
||||
window.location.href = "Index";
|
||||
},
|
||||
error: function () {
|
||||
window.location.href = "Index";
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
@ -0,0 +1,21 @@
|
||||
@{
|
||||
ViewData["Title"] = "Enter";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Вход в приложение</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Почта:</div>
|
||||
<div class="col-8"><input type="text" name="Email" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Пароль:</div>
|
||||
<div class="col-8"><input type="password" name="password" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,69 @@
|
||||
@using ServiceStationContracts.ViewModels
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
@model List<WorkViewModel>
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Список работ</h1>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
if (Model == null) {
|
||||
<h3 class="display-4">Авторизируйтесь</h3>
|
||||
return;
|
||||
}
|
||||
|
||||
<p>
|
||||
<a asp-action="CreateWork">Создать работу</a>
|
||||
</p>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер
|
||||
</th>
|
||||
<th>
|
||||
Дата работы
|
||||
</th>
|
||||
<th>
|
||||
Стоимость работы
|
||||
</th>
|
||||
<th>
|
||||
Номер задания
|
||||
</th>
|
||||
<th>
|
||||
Задание
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model) {
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Date)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Price)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.TaskByWorkId)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.TaskName)
|
||||
</th>
|
||||
<td>
|
||||
<a class="btn btn-primary btn-sm" asp-action="EditWork" style="background-color:orange" asp-route-ID=" @item.Id">Изменить</a>
|
||||
<a class="btn btn-primary btn-sm" asp-action="DeleteWork" style="background-color:red;" asp-route-ID="@item.Id">Удалить</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
@ -0,0 +1,27 @@
|
||||
@using ServiceStationContracts.ViewModels
|
||||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
@model ExecutorViewModel
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Личные данные</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Почта:</div>
|
||||
<div class="col-8"><input type="text" name="email" value="@Model.Email"/></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Пароль:</div>
|
||||
<div class="col-8"><input type="password" name="password" value="@Model.Password"/></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">ФИО:</div>
|
||||
<div class="col-8"><input type="text" name="fio" value="@Model.FIO"/></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,25 @@
|
||||
@{
|
||||
ViewData["Title"] = "Register";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Регистрация</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Почта:</div>
|
||||
<div class="col-8"><input type="text" name="Email" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Пароль:</div>
|
||||
<div class="col-8"><input type="password" name="password" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">ФИО:</div>
|
||||
<div class="col-8"><input type="text" name="fio" /></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,151 @@
|
||||
@using ServiceStationContracts.ViewModels
|
||||
@model List<WorkViewModel>
|
||||
@{
|
||||
ViewData["Title"] = "Report";
|
||||
}
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Отчёты</h1>
|
||||
</div>
|
||||
|
||||
<div class="text-start">
|
||||
<h2 class="display-5">Отчёт за период</h2>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<div class="align-content-center row mb-3">
|
||||
<div class="col-sm-auto">
|
||||
<label>С:</label>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input name="DateFrom" id="datefrom" type="date" />
|
||||
</div>
|
||||
<div class="col-sm-auto">
|
||||
<label>По:</label>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input name="DateTo" id="dateto" type="date" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Cформировать отчет" class="btn btn-sm btn-outline-danger m-2 p-2" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="text-start">
|
||||
<h2 class="display-5">Выбрать оплаты в отечет</h2>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
if (Model == null) {
|
||||
<h3 class="display-4">Авторизируйтесь</h3>
|
||||
return;
|
||||
}
|
||||
<div class="text-end">
|
||||
<button class="btn btn-sm btn-outline-danger m-2 p-2" id="btnFix">Cформировать отчет</button>
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<button class="btn btn-primary btn-sm" id="SaveWord" style="background-color:#335a95;">Экспорт отчета в .docx</button>
|
||||
<button class="btn btn-primary btn-sm 2" id="SaveExcel" style="background-color:#04713A;">Экспорт отчета в .xlsx</button>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер
|
||||
</th>
|
||||
<th>
|
||||
Дата работы
|
||||
</th>
|
||||
<th>
|
||||
Стоимость работы
|
||||
</th>
|
||||
<th>
|
||||
Номер задания
|
||||
</th>
|
||||
<th>
|
||||
Задание
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input" id="Select_all" name="Select_all" /> Выбрать все
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model) {
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Date)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Price)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.TaskByWorkId)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.TaskName)
|
||||
</th>
|
||||
<th>
|
||||
<input type="checkbox" class="form-check-input" id="Select_rec" name="Select_rec" value="@item.Id" />
|
||||
</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#Select_all').on('click', function () {
|
||||
let checkboxes = document.getElementsByTagName('input');
|
||||
let val = null;
|
||||
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
if (checkboxes[i].type === 'checkbox') {
|
||||
if (val == null) {
|
||||
val = checkboxes[i].checked;
|
||||
}
|
||||
else {
|
||||
checkboxes[i].checked = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#SaveWord').on('click', function () {
|
||||
let val = [];
|
||||
$("input[name='Select_rec']:checked").each(function () {
|
||||
val.push($(this).val());
|
||||
});
|
||||
|
||||
var str = '';
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
str += val[i] + '_'
|
||||
}
|
||||
location.href = '/Home/CreateWordReport?ids=' + str
|
||||
});
|
||||
|
||||
$('#SaveExcel').on('click', function () {
|
||||
debugger
|
||||
let val = [];
|
||||
$("input[name='Select_rec']:checked").each(function () {
|
||||
val.push($(this).val());
|
||||
});
|
||||
|
||||
var str = '';
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
str += val[i] + '_'
|
||||
}
|
||||
location.href = '/Home/CreateExcelReport?ids=' + str
|
||||
});
|
||||
</script>
|
@ -0,0 +1,82 @@
|
||||
@using ServiceStationContracts.ViewModels
|
||||
@model (DateTime, DateTime, List<WorkViewModel>)
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "ReportSearchDate";
|
||||
}
|
||||
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="row align-items-center mb-3">
|
||||
<div class="text-center">
|
||||
<label>Предпросмотр отчета:</label>
|
||||
</div>
|
||||
<div class="col-sm-auto">
|
||||
<label>С:</label>
|
||||
</div>
|
||||
<div class="col-sm-auto">
|
||||
<input name="DateFrom" id="datefrom" type="text" value="@Model.Item1.Date.ToString("d")" readonly />
|
||||
</div>
|
||||
<div class="col-sm-auto">
|
||||
<label>По:</label>
|
||||
</div>
|
||||
<div class="col-sm-auto">
|
||||
<input name="DateTo" id="dateto" type="text" value="@Model.Item2.Date.ToString("d")" readonly />
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<a class="btn btn-primary btn-sm" asp-action="CreatePdfReport" asp-route-DateFrom="@Model.Item1"
|
||||
asp-route-DateTo="@Model.Item2" style="background-color:#ad0d09;">отправить на Email отчет в .pdf</a>
|
||||
</div>
|
||||
</h1>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер
|
||||
</th>
|
||||
<th>
|
||||
Дата работы
|
||||
</th>
|
||||
<th>
|
||||
Стоимость работы
|
||||
</th>
|
||||
<th>
|
||||
Номер задания
|
||||
</th>
|
||||
<th>
|
||||
Задание
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Item3) {
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Id)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Date)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.Price)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.TaskByWorkId)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayFor(modelItem => item.TaskName)
|
||||
</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
@ -0,0 +1,68 @@
|
||||
@{
|
||||
ViewData["Title"] = "Scoring";
|
||||
}
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
|
||||
<div class="text-center">
|
||||
<h class="display-4">Выставление баллов клиентам за работу</h>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-4">Клиент:</div>
|
||||
<div class="col-8">
|
||||
<select id="client" name="client" class="form-control">
|
||||
<option>--Select Client--</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Работа:</div>
|
||||
<div class="col-8">
|
||||
<select id="work" name="work" class="form-control">
|
||||
<option>--Select Work--</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">Баллы:</div>
|
||||
<div class="col-8">
|
||||
<input id="points" type="text" name="points" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8"></div>
|
||||
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
GetClient();
|
||||
$('#client').change(function () {
|
||||
var id = $(this).val();
|
||||
$('#work').empty();
|
||||
$('#work').append('<Option>--Select Client--</Option>');
|
||||
$.ajax({
|
||||
url: '/Home/Work?id=' + id,
|
||||
success: function (result) {
|
||||
$.each(result, function (i, data) {
|
||||
$('#work').append('<Option value=' + data.id + '>' + 'work_id:' + data.id + '||' + data.taskName + '</Option>');
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function GetClient() {
|
||||
$.ajax({
|
||||
url: '/Home/Client',
|
||||
success: function (result) {
|
||||
$.each(result, function (i, data) {
|
||||
$('#client').append('<Option value=' + data.id + '>' + data.fio + '</Option>');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
@ -0,0 +1,25 @@
|
||||
@model ErrorViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - ServiceSourceExecutorApp</title>
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="~/ServiceSourceExecutorApp.styles.css" asp-append-version="true" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">СТО Руки-крюки (Исполнитель)</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
|
||||
<ul class="navbar-nav flex-grow-1">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Register">Регистрация</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Работы</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Scoring">Выставление баллов</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Report">Отчеты</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container">
|
||||
<main role="main" class="pb-3">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="border-top footer text-muted">
|
||||
<div class="container">
|
||||
© 2024 - ServiceSourceClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,48 @@
|
||||
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
for details on configuring this project to bundle and minify static web assets. */
|
||||
|
||||
a.navbar-brand {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0077cc;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
.border-bottom {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
button.accept-policy {
|
||||
font-size: 1rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
line-height: 60px;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
|
@ -0,0 +1,3 @@
|
||||
@using ServiceSourceClientApp
|
||||
@using ServiceSourceClientApp.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
11
ServiceStation/ServiceStationExecutorApp/appsettings.json
Normal file
11
ServiceStation/ServiceStationExecutorApp/appsettings.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
// порт -> Свойства/отладка/пользовательский ин./URL адресс
|
||||
"IPAddress": "http://localhost:5192/"
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-bottom: 60px;
|
||||
}
|
BIN
ServiceStation/ServiceStationExecutorApp/wwwroot/favicon.ico
Normal file
BIN
ServiceStation/ServiceStationExecutorApp/wwwroot/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,4 @@
|
||||
// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your JavaScript code.
|
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2021 Twitter, Inc.
|
||||
Copyright (c) 2011-2021 The Bootstrap Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
4997
ServiceStation/ServiceStationExecutorApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
vendored
Normal file
4997
ServiceStation/ServiceStationExecutorApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4996
ServiceStation/ServiceStationExecutorApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
vendored
Normal file
4996
ServiceStation/ServiceStationExecutorApp/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user