Compare commits

...

7 Commits
master ... Ver1

Author SHA1 Message Date
artiogf
9b91763678 Mail 2023-05-25 01:26:13 +04:00
artiogf
c0f13a287a PDf 2023-05-25 00:52:52 +04:00
artiogf
bea9a1b241 ClientApp 2023-05-20 03:26:15 +04:00
artiogf
9d55f25bcc RestApi 2023-05-19 23:29:13 +04:00
artiogf
8d59a6a221 main 2023-05-11 20:37:42 +04:00
artiogf
48fefe4fb7 Main 2023-04-28 22:53:56 +04:00
artiogf
bed8ee9b95 ISPOLNITEL_3_SUHNOSTI 2023-04-28 22:02:47 +04:00
200 changed files with 80689 additions and 280 deletions

View File

@ -3,13 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TourCompanyContracts", "TourCompanyContracts\TourCompanyContracts.csproj", "{1C9D15EE-1E71-459A-B41A-FEA3D8E54C09}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TourCompanyContracts", "TourCompanyContracts\TourCompanyContracts.csproj", "{1C9D15EE-1E71-459A-B41A-FEA3D8E54C09}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TourCompanyDataModels", "TourCompanyDataModels\TourCompanyDataModels.csproj", "{D207F1E7-0345-42EC-B132-22B02245EC8B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TourCompanyDataModels", "TourCompanyDataModels\TourCompanyDataModels.csproj", "{D207F1E7-0345-42EC-B132-22B02245EC8B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TourCompanyBusinessLogic", "TourCompanyBusinessLogic\TourCompanyBusinessLogic.csproj", "{BFE0F3CB-9786-4F6D-92FC-481FE679AD86}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TourCompanyBusinessLogic", "TourCompanyBusinessLogic\TourCompanyBusinessLogic.csproj", "{BFE0F3CB-9786-4F6D-92FC-481FE679AD86}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TourCompanyDatabaseImplement", "TourCompanyDatabaseImplement\TourCompanyDatabaseImplement.csproj", "{A4E4547E-B6F7-467F-AB69-2BB335684BA2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TourCompanyDatabaseImplement", "TourCompanyDatabaseImplement\TourCompanyDatabaseImplement.csproj", "{A4E4547E-B6F7-467F-AB69-2BB335684BA2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TourCompanyRestApi", "TourCompanyRestApi\TourCompanyRestApi.csproj", "{DDDAF740-7EA1-42BF-AD15-0F505B1E0D01}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TourCompanyClientApp", "TourCompanyClientApp\TourCompanyClientApp.csproj", "{29186D66-6708-498F-BFDF-2B7865D10E6F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -33,6 +37,14 @@ Global
{A4E4547E-B6F7-467F-AB69-2BB335684BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4E4547E-B6F7-467F-AB69-2BB335684BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4E4547E-B6F7-467F-AB69-2BB335684BA2}.Release|Any CPU.Build.0 = Release|Any CPU
{DDDAF740-7EA1-42BF-AD15-0F505B1E0D01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDDAF740-7EA1-42BF-AD15-0F505B1E0D01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDDAF740-7EA1-42BF-AD15-0F505B1E0D01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDDAF740-7EA1-42BF-AD15-0F505B1E0D01}.Release|Any CPU.Build.0 = Release|Any CPU
{29186D66-6708-498F-BFDF-2B7865D10E6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29186D66-6708-498F-BFDF-2B7865D10E6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29186D66-6708-498F-BFDF-2B7865D10E6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29186D66-6708-498F-BFDF-2B7865D10E6F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -13,7 +13,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class ExecurtionLogic : IExecurtionLogic
public class ExecurtionLogic : IExecurtionLogic
{
private readonly ILogger _logger;
private readonly IExecurtionStorage _execurtionStorage;

View File

@ -12,7 +12,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class GidLogic : IGidLogic
public class GidLogic : IGidLogic
{
private readonly ILogger _logger;
private readonly IGidStorage _gidStorage;
@ -23,7 +23,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
}
public List<GidViewModel>? ReadList(GidSearchModel? model)
{
_logger.LogInformation("ReadList. UserId:{UserId}. ExecurtionId:{ExecurtionId}. TripId:{TripId}. Id: { Id}", model?.UserId, model?.ExecurtionId, model?.TripId, model?.Id);
_logger.LogInformation("ReadList. Id: { Id}", model?.Id);
var list = model == null ? _gidStorage.GetFullList() : _gidStorage.GetFilteredList(model);
if (list == null)
{
@ -39,7 +39,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement.UserId:{UserId}. ExecurtionId:{ExecurtionId}. TripId:{TripId}. Id: { Id}", model.UserId, model.ExecurtionId, model.TripId, model.Id);
_logger.LogInformation("ReadElement. Id: { Id}", model.Id);
var element = _gidStorage.GetElement(model);
if (element == null)
{
@ -90,25 +90,10 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
return;
}
if (model.TripId == null)
{
throw new ArgumentNullException("нет внешнего ключа поездки", nameof(model.TripId));
}
if (model.UserId == null)
{
throw new ArgumentNullException("нет внешнего ключа пользователя", nameof(model.UserId));
}
if (model.ExecurtionId == null)
{
throw new ArgumentNullException("нет внешнего ключа экскурсии", nameof(model.ExecurtionId));
}
_logger.LogInformation("Gid. UserId:{UserId}. ExecurtionId:{ExecurtionId}. TripId:{TripId}. Id: { Id}", model.UserId, model.ExecurtionId, model.TripId, model.Id);
_logger.LogInformation("Gid. Id: { Id}", model.Id);
var element = _gidStorage.GetElement(new GidSearchModel
{
TripId = model.TripId,
UserId = model.UserId,
ExecurtionId = model.ExecurtionId
GidFIO = model.GidFIO
});
if (element != null && element.Id != model.Id)
{

View File

@ -12,7 +12,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class PlaceVisitLogic : IPlaceVisitLogic
public class PlaceVisitLogic : IPlaceVisitLogic
{
private readonly ILogger _logger;
private readonly IPlaceVisitStorage _placeVisitStorage;
@ -23,7 +23,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
}
public List<PlaceVisitViewModel>? ReadList(PlaceVisitSearchModel? model)
{
_logger.LogInformation("ReadList. UserId:{UserId}. TourGroupId:{TourGroupId}. Id: { Id}", model?.UserId, model?.TourGroupId, model?.Id);
_logger.LogInformation("ReadList. TourGroupId:{TourGroupId}. Id: { Id}", model?.TourGroupId, model?.Id);
var list = model == null ? _placeVisitStorage.GetFullList() : _placeVisitStorage.GetFilteredList(model);
if (list == null)
{
@ -39,7 +39,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement.UserId:{UserId}. TourGroupId:{TourGroupId}. Id: { Id}", model.UserId, model.TourGroupId, model.Id);
_logger.LogInformation("ReadElement. TourGroupId:{TourGroupId}. Id: { Id}", model.TourGroupId, model.Id);
var element = _placeVisitStorage.GetElement(model);
if (element == null)
{
@ -90,18 +90,13 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
return;
}
if (model.UserId == null)
{
throw new ArgumentNullException("нет внешнего ключа пользователя", nameof(model.UserId));
}
if (model.TourGroupId == null)
{
throw new ArgumentNullException("нет внешнего ключа тур группы", nameof(model.TourGroupId));
}
_logger.LogInformation("PlaceVisit. UserId:{UserId}. TourGroupId:{TourGroupId}. Id: { Id}", model.UserId, model.TourGroupId, model.Id);
_logger.LogInformation("PlaceVisit. TourGroupId:{TourGroupId}. Id: { Id}", model.TourGroupId, model.Id);
var element = _placeVisitStorage.GetElement(new PlaceVisitSearchModel
{
UserId = model.UserId,
TourGroupId = model.TourGroupId
});

View File

@ -3,11 +3,162 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TourCompanyBusinessLogic.OfficePackage;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
using TourCompanyContracts.BindingModels;
using TourCompanyContracts.BusinessLogicsContracts;
using TourCompanyContracts.SearchModels;
using TourCompanyContracts.StoragesContracts;
using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class ReportLogic //: IReportLogic
{
}
public class ReportLogic : IReportLogic
{
private readonly ITourStorage _tourStorage;
private readonly ITourGroupStorage _tourGroupStorage;
private readonly IExecurtionStorage _execurtionStorage;
private readonly IPlaceVisitStorage _placeVisitStorage;
private readonly AbstractSaveToExcelUser _saveToExcelUser;
private readonly AbstractSaveToWordUser _saveToWordUser;
private readonly AbstractSaveToPdfUser _saveToPdfUser;
public ReportLogic(ITourStorage tourStorage, ITourGroupStorage tourGroupStorage, IExecurtionStorage execurtionStorage, IPlaceVisitStorage placeVisitStorage, AbstractSaveToExcelUser saveToExcelUser, AbstractSaveToWordUser saveToWordUser, AbstractSaveToPdfUser saveToPdfUser)
{
_tourStorage = tourStorage;
_tourGroupStorage = tourGroupStorage;
_execurtionStorage = execurtionStorage;
_placeVisitStorage = placeVisitStorage;
_saveToExcelUser = saveToExcelUser;
_saveToWordUser = saveToWordUser;
_saveToPdfUser = saveToPdfUser;
}
public List<ReportTourPlaceVisitViewModel> GetTourPlaceVisit(ReportBindingModel model)
{
var tourGroups = _tourGroupStorage.GetFullList();
var placeVisits = _placeVisitStorage.GetFullList();
var list = new List<ReportTourPlaceVisitViewModel>();
foreach (TourViewModel tour in model.Tours)
{
var record = new ReportTourPlaceVisitViewModel
{
TourName = tour.TourName
};
foreach (TourGroupViewModel tourGroup in tourGroups)
{
if (tourGroup.TourGroupTours.ContainsKey(tour.Id))
{
foreach (PlaceVisitViewModel placeVisit in placeVisits)
{
if (placeVisit.TourGroupId == tourGroup.Id)
{
record.PlaceVisits.Add(placeVisit.PlaceVisitName);
}
}
}
}
list.Add(record);
}
return list;
}
public List<ReportTourViewModel> GetTours(ReportBindingModel model)
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
var tours = _tourStorage.GetFilteredList(new TourSearchModel
{
DateFrom = model.DateFrom,
DateTo = model.DateTo
});
var tourGroups = _tourGroupStorage.GetFullList();
var execurtions = _execurtionStorage.GetFullList();
var list = new List<ReportTourViewModel>();
foreach (TourGroupViewModel tourGroup in tourGroups)
{
foreach (ExecurtionViewModel execurtion in execurtions)
{
foreach (int tourTourGroup in tourGroup.TourGroupTours.Keys)
{
if (execurtion.ExecurtionTours.ContainsKey(tourTourGroup))
{
try
{
var tourname = tours.FirstOrDefault(x => x.Id == tourTourGroup)?.TourName ?? string.Empty;
if (!tourname.Equals(""))
{
list.Add(new ReportTourViewModel
{
TourName = tourname,
TourGroupName = tourGroup.TourGroupName,
ExecurtionName = execurtion.Purpose,
DateTour = tours.FirstOrDefault(x => x.Id == tourTourGroup).DateTour,
});
}
}
catch(Exception ex)
{
}
}
}
}
}
return list;
}
/*
public List<ReportTourViewModel>? GetTours(ReportBindingModel model)
{
return _tourStorage.GetFilteredList(new TourSearchModel
{
DateFrom = model.DateFrom,
DateTo = model.DateTo,
}).Select(x => new ReportTourViewModel
{
TourName = x.TourName,
DateTour = x.DateTour
}).ToList();
}
*/
public void SaveTourPlaceVisitToExcelFile(ReportBindingModel model)
{
_saveToExcelUser.CreateReport(new ExcelInfoUser
{
FileName = model.FileName,
Title = "Список занятий по интресам",
TourPlaceVisits = GetTourPlaceVisit(model)
});
}
public void SaveTourPlaceVisitToWordFile(ReportBindingModel model)
{
_saveToWordUser.CreateDoc(new WordInfoUser
{
FileName = model.FileName,
Title = "Список занятий по интресам",
TourPlaceVisits = GetTourPlaceVisit(model)
});
}
public void SaveToursToPdfFile(ReportBindingModel model)
{
_saveToPdfUser.CreateDoc(new PdfInfoUser
{
FileName = model.FileName,
Title = "Список туров",
DateFrom = DateTime.SpecifyKind(model.DateFrom!.Value, DateTimeKind.Utc),
DateTo = DateTime.SpecifyKind(model.DateTo!.Value, DateTimeKind.Utc),
Tours = GetTours(model)
});
}
}
}

View File

@ -12,7 +12,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class TourGroupLogic : ITourGroupLogic
public class TourGroupLogic : ITourGroupLogic
{
private readonly ILogger _logger;
private readonly ITourGroupStorage _tourGroupStorage;
@ -23,7 +23,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
}
public List<TourGroupViewModel>? ReadList(TourGroupSearchModel? model)
{
_logger.LogInformation("ReadList. UserId:{UserId}. Id: { Id}", model?.UserId, model?.Id);
_logger.LogInformation("ReadList. Id: { Id}", model?.Id);
var list = model == null ? _tourGroupStorage.GetFullList() : _tourGroupStorage.GetFilteredList(model);
if (list == null)
{
@ -39,7 +39,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement.UserId:{UserId}. Id: { Id}", model.UserId, model.Id);
_logger.LogInformation("ReadElement. Id: { Id}", model.Id);
var element = _tourGroupStorage.GetElement(model);
if (element == null)
{
@ -90,16 +90,10 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
return;
}
if (model.UserId == null)
{
throw new ArgumentNullException("нет внешнего ключа пользователя", nameof(model.UserId));
}
_logger.LogInformation("TourGroup. UserId:{UserId}. Id: { Id}", model.UserId, model.Id);
_logger.LogInformation("TourGroup. . Id: { Id}", model.Id);
var element = _tourGroupStorage.GetElement(new TourGroupSearchModel
{
UserId = model.UserId
TourGroupName = model.TourGroupName
});
if (element != null && element.Id != model.Id)
{

View File

@ -12,7 +12,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class TourLogic : ITourLogic
public class TourLogic : ITourLogic
{
private readonly ILogger _logger;
private readonly ITourStorage _tourStorage;

View File

@ -12,7 +12,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class TripLogic : ITripLogic
public class TripLogic : ITripLogic
{
private readonly ILogger _logger;
private readonly ITripStorage _tripStorage;
@ -23,7 +23,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
}
public List<TripViewModel>? ReadList(TripSearchModel? model)
{
_logger.LogInformation("ReadList. UserId:{UserId}. Id: { Id}", model?.UserId, model?.Id);
_logger.LogInformation("ReadList. Id: { Id}", model?.Id);
var list = model == null ? _tripStorage.GetFullList() : _tripStorage.GetFilteredList(model);
if (list == null)
{
@ -39,7 +39,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement.UserId:{UserId}. Id: { Id}", model.UserId, model.Id);
_logger.LogInformation("ReadElement. Id: { Id}", model.Id);
var element = _tripStorage.GetElement(model);
if (element == null)
{
@ -90,15 +90,11 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
return;
}
if (model.UserId == null)
{
throw new ArgumentNullException("нет внешнего ключа пользователя", nameof(model.UserId));
}
_logger.LogInformation("Trip. UserId:{UserId}. Id: { Id}", model.UserId, model.Id);
_logger.LogInformation("Trip. GidId:{GidId}. Id: { Id}", model.GidId, model.Id);
var element = _tripStorage.GetElement(new TripSearchModel
{
UserId = model.UserId
GidId = model.GidId
});
if (element != null && element.Id != model.Id)

View File

@ -12,7 +12,7 @@ using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.BusinessLogics
{
internal class UserLogic : IUserLogic
public class UserLogic : IUserLogic
{
private readonly ILogger _logger;
private readonly IUserStorage _userStorage;
@ -23,7 +23,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
}
public List<UserViewModel>? ReadList(UserSearchModel? model)
{
_logger.LogInformation("ReadList. FIO:{FIO}. Id: { Id}", model?.FIO, model?.Id);
_logger.LogInformation("ReadList. UserFIO:{UserFIO}. Id: { Id}", model?.UserFIO, model?.Id);
var list = model == null ? _userStorage.GetFullList() : _userStorage.GetFilteredList(model);
if (list == null)
{
@ -39,7 +39,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement.FIO:{FIO}. Id: { Id}", model.FIO, model.Id);
_logger.LogInformation("ReadElement.UserFIO:{UserFIO}. Id: { Id}", model.UserFIO, model.Id);
var element = _userStorage.GetElement(model);
if (element == null)
{
@ -72,7 +72,7 @@ namespace TourCompanyBusinessLogic.BusinessLogics
public bool Delete(UserBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. FIO:{FIO}. Id: { Id}", model.FIO, model.Id);
_logger.LogInformation("Delete. UserFIO:{UserFIO}. Id: { Id}", model.UserFIO, model.Id);
if (_userStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
@ -90,10 +90,10 @@ namespace TourCompanyBusinessLogic.BusinessLogics
{
return;
}
_logger.LogInformation("User. FIO:{FIO}. Id: { Id}", model.FIO, model.Id);
_logger.LogInformation("User. UserFIO:{UserFIO}. Id: { Id}", model.UserFIO, model.Id);
var element = _userStorage.GetElement(new UserSearchModel
{
FIO = model.FIO
UserFIO = model.UserFIO
});
if (element != null && element.Id != model.Id)
{

View File

@ -0,0 +1,69 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TourCompanyContracts.BindingModels;
namespace TourCompanyBusinessLogic.MailKit
{
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 ILogger _logger;
public AbstractMailWorker(ILogger<AbstractMailWorker> logger)
{
_logger = logger;
}
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.Path))
{
return;
}
_logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject);
await SendMailAsync(info);
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
}
}

View File

@ -0,0 +1,47 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TourCompanyContracts.BindingModels;
using TourCompanyContracts.StoragesContracts;
namespace TourCompanyBusinessLogic.MailKit
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker(ILogger<MailKitWorker> logger, IUserStorage userStorage) : base(logger) { }
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.Attachments.Add(new Attachment(info.Path));
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;
}
}
}
}

View File

@ -0,0 +1,93 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TourCompanyBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcelUser
{
/// <summary>
/// Создание отчета
/// </summary>
/// <param name="info"></param>
public void CreateReport(ExcelInfoUser 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 pc in info.TourPlaceVisits)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = pc.TourName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var placeVisit in pc.PlaceVisits)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = placeVisit,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
rowIndex++;
}
SaveExcel(info);
}
/// <summary>
/// Создание excel-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfoUser info);
/// <summary>
/// Добавляем новую ячейку в лист
/// </summary>
/// <param name="cellParameters"></param>
protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams);
/// <summary>
/// Объединение ячеек
/// </summary>
/// <param name="mergeParameters"></param>
protected abstract void MergeCells(ExcelMergeParameters excelParams);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveExcel(ExcelInfoUser info);
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
namespace TourCompanyBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdfUser
{
public void CreateDoc(PdfInfoUser info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center });
CreateParagraph(new PdfParagraph { Text = $"с {info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center });
CreateTable(new List<string> { "4cm", "4cm", "4cm", "6cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> {"Тур", "Тур Группа", "Экскурсия", "Дата" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var tour in info.Tours)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { tour.TourName,tour.TourGroupName, tour.ExecurtionName, tour.DateTour.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
SavePdf(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreatePdf(PdfInfoUser info);
/// <summary>
/// Создание параграфа с текстом
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// <summary>
/// Создание таблицы
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateTable(List<string> columns);
/// <summary>
/// Создание и заполнение строки
/// </summary>
/// <param name="rowParameters"></param>
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SavePdf(PdfInfoUser info);
}
}

View File

@ -0,0 +1,76 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TourCompanyBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWordUser
{
public void CreateDoc(WordInfoUser 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 tour in info.TourPlaceVisits)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (tour.TourName, new WordTextProperties { Size = "24", Bold=true,})},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
foreach (var placeVisit in tour.PlaceVisits)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (placeVisit, new WordTextProperties { Size = "20", Bold=false,})},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
}
SaveWord(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateWord(WordInfoUser info);
/// <summary>
/// Создание абзаца с текстом
/// </summary>
/// <param name="paragraph"></param>
/// <returns></returns>
protected abstract void CreateParagraph(WordParagraph paragraph);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveWord(WordInfoUser info);
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TourCompanyBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBroder
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TourCompanyBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Rigth
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TourCompanyBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,17 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
namespace TourCompanyBusinessLogic.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; }
}
}

View File

@ -0,0 +1,14 @@

using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfoUser
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportTourPlaceVisitViewModel> TourPlaceVisits { get; set; } = new();
}
}

View File

@ -0,0 +1,11 @@
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,17 @@
using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfoUser
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<ReportTourViewModel> Tours { get; set; } = new();
}
}

View File

@ -0,0 +1,13 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class PdfRowParameters
{
public List<string> Texts { get; set; } = new();
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using TourCompanyContracts.ViewModels;
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class WordInfoUser
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportTourPlaceVisitViewModel> TourPlaceVisits { get; set; } = new();
}
}

View File

@ -0,0 +1,9 @@
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class WordParagraph
{
public List<(string, WordTextProperties)> Texts { get; set; } = new();
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
namespace TourCompanyBusinessLogic.OfficePackage.HelperModels
{
public class WordTextProperties
{
public string Size { get; set; } = string.Empty;
public bool Bold { get; set; }
public WordJustificationType JustificationType { get; set; }
}
}

View File

@ -0,0 +1,291 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace TourCompanyBusinessLogic.OfficePackage.Implements
{
public class SaveToExcelUser : AbstractSaveToExcelUser
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
/// <summary>
/// Настройка стилей для файла
/// </summary>
/// <param name="workbookpart"></param>
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);
}
/// <summary>
/// Получение номера стиля из типа
/// </summary>
/// <param name="styleInfo"></param>
/// <returns></returns>
private static uint GetStyleValue(ExcelStyleInfoType styleInfo)
{
return styleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBroder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(ExcelInfoUser info)
{
_spreadsheetDocument = SpreadsheetDocument.Create(info.FileName, 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>();
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 void SaveExcel(ExcelInfoUser info)
{
if (_spreadsheetDocument == null)
{
return;
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Close();
}
}
}

View File

@ -0,0 +1,115 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using TourCompanyBusinessLogic.OfficePackage;
namespace TourCompanyBusinessLogic.OfficePackage.Implements
{
public class SaveToPdfUser : AbstractSaveToPdfUser
{
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.Rigth => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
/// <summary>
/// Создание стилей для документа
/// </summary>
/// <param name="document"></param>
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 CreatePdf(PdfInfoUser info)
{
_document = new Document();
DefineStyles(_document);
_section = _document.AddSection();
}
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.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
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 CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
row.Cells[i].AddParagraph(rowParameters.Texts[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.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override void SavePdf(PdfInfoUser info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(info.FileName);
}
}
}

View File

@ -0,0 +1,135 @@
using TourCompanyBusinessLogic.OfficePackage.HelperEnums;
using TourCompanyBusinessLogic.OfficePackage.HelperModels;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace TourCompanyBusinessLogic.OfficePackage.Implements
{
public class SaveToWordUser : AbstractSaveToWordUser
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
/// <summary>
/// Получение типа выравнивания
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static JustificationValues GetJustificationValues(WordJustificationType type)
{
return type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
/// <summary>
/// Настройки страницы
/// </summary>
/// <returns></returns>
private static SectionProperties CreateSectionProperties()
{
var properties = new SectionProperties();
var pageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
properties.AppendChild(pageSize);
return properties;
}
/// <summary>
/// Задание форматирования для абзаца
/// </summary>
/// <param name="paragraphProperties"></param>
/// <returns></returns>
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(WordInfoUser info)
{
_wordDocument = WordprocessingDocument.Create(info.FileName, 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 void SaveWord(WordInfoUser info)
{
if (_docBody == null || _wordDocument == null)
{
return;
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Close();
}
}
}

View File

@ -7,11 +7,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="PDFsharp-MigraDoc" Version="1.50.5147" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TourCompanyContracts\TourCompanyContracts.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="OfficePackage\HelperEnums\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using TourCompanyContracts.ViewModels;
namespace TourCompanyClientApp
{
public class APIClient
{
public static UserViewModel? User { get; set; } = null;
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="SmtpClientHost" value="smtp.gmail.com" />
<add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" />
<add key="MailLogin" value="asdqr647@gmail.com" />
<add key="MailPassword" value="nzxwolohajhfqmoe" />
</appSettings>
</configuration>

View File

@ -0,0 +1,608 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.IdentityModel.Tokens;
using System.Diagnostics;
using TourCompanyBusinessLogic.MailKit;
using TourCompanyClientApp.Models;
using TourCompanyContracts.BindingModels;
using TourCompanyContracts.BusinessLogicsContracts;
using TourCompanyContracts.SearchModels;
using TourCompanyContracts.ViewModels;
using TourCompanyDatabaseImplement.Models;
using TourCompanyDataModels.Enums;
using TourCompanyDataModels.Models;
using Newtonsoft.Json;
namespace TourCompanyClientApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IExecurtionLogic _execurtion;
private readonly ITourGroupLogic _tourGroup;
private readonly ITourLogic _tour;
private readonly IUserLogic _user;
private readonly IPlaceVisitLogic _placeVisitLogic;
private readonly IGidLogic _gid;
private readonly ITripLogic _trip;
private readonly IReportLogic _report;
private readonly AbstractMailWorker mailSender;
public HomeController(ILogger<HomeController> logger , IExecurtionLogic execurtion, ITourLogic tour, IUserLogic user, ITourGroupLogic tourGroup, IPlaceVisitLogic placeVisitLogic, IGidLogic gid, ITripLogic trip, AbstractMailWorker abstractMailWorker, IReportLogic report)
{
_logger = logger;
_execurtion = execurtion;
_tour = tour;
_user = user;
_tourGroup = tourGroup;
_placeVisitLogic = placeVisitLogic;
_gid = gid;
_trip = trip;
_report = report;
try
{
mailSender = abstractMailWorker;
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
});
}
catch (Exception ex)
{
logger?.LogError(ex, "Ошибка работы с почтой");
}
}
[HttpGet]
public IActionResult Index()
{
return View();
}
public IActionResult Tour()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(_tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id}));
}
[HttpGet]
public IActionResult Privacy()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.User);
}
[HttpPost]
public void Privacy(string login, string password, string fio)
{
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
_user.Update(new UserBindingModel
{
UserFIO = fio,
Email = login,
Password = password
});
APIClient.User.UserFIO = fio;
APIClient.User.Email = login;
APIClient.User.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 Enter()
{
return View();
}
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
throw new Exception("Введите логин и пароль");
}
APIClient.User = _user.ReadElement(new UserSearchModel { Email = login, Password = password });
if (APIClient.User == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
_user.Create(new UserBindingModel
{
UserFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
/// <summary>
/// tour
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult CreateTour()
{
return View();
}
[HttpPost]
public void CreateTour(string tourName, DateTime tourDate)
{
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
_tour.Create(new TourBindingModel
{
UserId = APIClient.User.Id,
TourName = tourName,
DateTour = tourDate
});
Response.Redirect("Index");
}
[HttpGet]
public IActionResult TourSetting(int id)
{
return View(_tour.ReadElement(new TourSearchModel { Id = id }));
}
[HttpPost]
public void UpdateTour(int id, string tourName, DateTime tourDate)
{
if (string.IsNullOrEmpty(tourName))
{
throw new Exception("Нет названия");
}
_tour.Update(new TourBindingModel
{
Id = id,
TourName = tourName,
DateTour = tourDate,
UserId = APIClient.User.Id,
});
Response.Redirect("/Home/Tour");
}
public void DeleteTour(int id)
{
_tour.Delete(new TourBindingModel
{
Id = id,
});
Response.Redirect("/Home/Tour");
}
/// <summary>
/// execurtions
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Execurtion()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(_execurtion.ReadList(null));
}
[HttpGet]
public IActionResult CreateExecurtion()
{
var list = _tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id });
var simpTour = list.Select(x => new { TourId = x.Id, TourName = x.TourName });
ViewBag.Tours = new MultiSelectList(simpTour, "TourId", "TourName");
return View();
}
[HttpPost]
public void CreateExecurtion(string purpose, DateTime dateExecurtion, int execurtionDuratation, int[] tours)
{
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
Dictionary<int, ITourModel> execurtionTours = new Dictionary<int, ITourModel>();
foreach (int id in tours)
{
execurtionTours.Add(id, _tour.ReadElement(new TourSearchModel { Id = id }));
}
_execurtion.Create(new ExecurtionBindingModel
{
Purpose = purpose,
DateExecurtion = dateExecurtion,
ExecurtionDuratation = execurtionDuratation,
UserId = APIClient.User.Id,
ExecurtionTours = execurtionTours
});
Response.Redirect("Index");
}
[HttpGet]
public IActionResult ExecurtionSetting(int id)
{
var execurtion = _execurtion.ReadElement(new ExecurtionSearchModel { Id = id });
var tours = _tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id }).Select(x => new { TourId = x.Id, TourName = x.TourName }).ToList();
var selectedTours = execurtion.ExecurtionTours.Select(x => x.Key).ToArray();
ViewBag.Tours = new MultiSelectList(tours, "TourId", "TourName", selectedTours);
return View(execurtion);
}
[HttpPost]
public void UpdateExecurtion(int idExecurtion, string purpose, int execurtionDuratation, DateTime dateExecurtion, int[] tours)
{
if (string.IsNullOrEmpty(purpose))
{
throw new Exception("Нет названия");
}
if (execurtionDuratation == null)
{
throw new Exception("Нет длительности экскурсии");
}
if (dateExecurtion == null)
{
throw new Exception("Нет даты");
}
Dictionary<int, ITourModel> execurtionTours = new Dictionary<int, ITourModel>();
foreach (int id in tours)
{
execurtionTours.Add(id, _tour.ReadElement(new TourSearchModel { Id = id }));
}
_execurtion.Update(new ExecurtionBindingModel
{
Id = idExecurtion,
Purpose = purpose,
ExecurtionDuratation = execurtionDuratation,
DateExecurtion = dateExecurtion,
ExecurtionTours = execurtionTours
});
Response.Redirect("/Home/Execurtion");
}
public void DeleteExecurtion(int id)
{
_execurtion.Delete(new ExecurtionBindingModel
{
Id = id,
});
Response.Redirect("/Home/Execurtion");
}
/// <summary>
/// Tour Group
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult TourGroup()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(_tourGroup.ReadList(null));
}
[HttpGet]
public IActionResult CreateTourGroup()
{
var list = _tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id });
var simpTour = list.Select(x => new { TourId = x.Id, TourName = x.TourName });
ViewBag.Tours = new MultiSelectList(simpTour, "TourId", "TourName");
return View();
}
[HttpPost]
public void CreateTourGroup(string tourGroupName, int type, int[] tours)
{
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
Dictionary<int, ITourModel> tourGroupTours = new Dictionary<int, ITourModel>();
foreach (int id in tours)
{
tourGroupTours.Add(id, _tour.ReadElement(new TourSearchModel { Id = id }));
}
_tourGroup.Create(new TourGroupBindingModel
{
TourGroupName = tourGroupName,
Type = (TourType)type,
UserId = APIClient.User.Id,
TourGroupTours = tourGroupTours
});
Response.Redirect("Index");
}
[HttpGet]
public IActionResult TourGroupSetting(int id)
{
var tourGroup = _tourGroup.ReadElement(new TourGroupSearchModel { Id = id });
var tours = _tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id }).Select(x => new { TourId = x.Id, TourName = x.TourName }).ToList();
var selectedTours = tourGroup.TourGroupTours.Select(x => x.Key).ToArray();
ViewBag.Tours = new MultiSelectList(tours, "TourId", "TourName", selectedTours);
return View(tourGroup);
}
[HttpPost]
public void UpdateTourGroup(int idTourGroup, string tourGroupName, int type, int[] tours)
{
if (string.IsNullOrEmpty(tourGroupName))
{
throw new Exception("Нет названия");
}
if (type == null)
{
throw new Exception("Нет типа");
}
Dictionary<int, ITourModel> tourGroupTours = new Dictionary<int, ITourModel>();
foreach (int id in tours)
{
tourGroupTours.Add(id, _tour.ReadElement(new TourSearchModel { Id = id }));
}
_tourGroup.Update(new TourGroupBindingModel
{
Id = idTourGroup,
TourGroupName = tourGroupName,
Type = (TourType)type,
TourGroupTours = tourGroupTours
});
Response.Redirect("/Home/TourGroup");
}
public void DeleteTourGroup(int id)
{
_tourGroup.Delete(new TourGroupBindingModel
{
Id = id,
});
Response.Redirect("/Home/TourGroup");
}
/// <summary>
/// Place Visit
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult PlaceVisit()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(_placeVisitLogic.ReadList(null));
}
[HttpGet]
public IActionResult CreatePlaceVisit()
{
ViewBag.TourGroups = _tourGroup.ReadList(null);
var list = _trip.ReadList(null);
var simpTrip = list.Select(x => new { TripId = x.Id, TripName = x.TripName});
ViewBag.Trips = new MultiSelectList(simpTrip, "TripId", "TripName");
return View();
}
[HttpPost]
public void CreatePlaceVisit(int tourGroup, string placeVisitName, DateTime datePlaceVisit, int[] trips)
{
var prod = _tourGroup.ReadElement(new TourGroupSearchModel { Id = tourGroup });
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
Dictionary<int, ITripModel> placeVisitTrips = new Dictionary<int, ITripModel>();
foreach (int id in trips)
{
placeVisitTrips.Add(id, _trip.ReadElement(new TripSearchModel { Id = id }));
}
_placeVisitLogic.Create(new PlaceVisitBindingModel
{
PlaceVisitName = placeVisitName,
DatePlaceVisit = datePlaceVisit,
TourGroupId = tourGroup,
TourGroupName = prod.TourGroupName,
UserId = APIClient.User.Id,
PlaceVisitTrips = placeVisitTrips
});
Response.Redirect("Index");
}
/// <summary>
/// Gid
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Gid()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(_gid.ReadList(null));
}
[HttpGet]
public IActionResult CreateGid()
{
var list = _execurtion.ReadList(null);
var simpExecurtion = list.Select(x => new { ExecurtionId = x.Id, Purpose = x.Purpose });
ViewBag.Execurtions = new MultiSelectList(simpExecurtion, "ExecurtionId", "Purpose");
return View();
}
[HttpPost]
public void CreateGid(int experion, string GidFio, int[] execurtions)
{
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
Dictionary<int, IExecurtionModel> gidExecurtions = new Dictionary<int, IExecurtionModel>();
foreach (int id in execurtions)
{
gidExecurtions.Add(id, _execurtion.ReadElement(new ExecurtionSearchModel { Id = id }));
}
_gid.Create(new GidBindingModel
{
Experion = experion,
GidFIO = GidFio,
UserId = APIClient.User.Id,
GidExecurtions = gidExecurtions
});
Response.Redirect("Index");
}
/// <summary>
/// Trip
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Trip()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(_trip.ReadList(null));
}
[HttpGet]
public IActionResult CreateTrip()
{
ViewBag.Gids = _gid.ReadList(null);
return View();
}
[HttpPost]
public void CreateTrip(int gid, string tripName, DateTime dateTrip)
{
var prod = _gid.ReadElement(new GidSearchModel { Id = gid });
if (APIClient.User == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
_trip.Create(new TripBindingModel
{
TripName = tripName,
DateTrip = dateTrip,
GidId = gid,
UserId = APIClient.User.Id,
GidFIO = prod.GidFIO
});
Response.Redirect("Index");
}
///
/// Отчёты
///
public IActionResult Report()
{
var list = _tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id });
var simpTour = list.Select(x => new { TourId = x.Id, TourName = x.TourName });
ViewBag.Tours = new MultiSelectList(simpTour, "TourId", "TourName");
return View();
}
public IActionResult GetPartial(int[] tours, string mode)
{
var list = tours.Select(x => _tour.ReadElement(new TourSearchModel { Id = x })).ToList();
if (mode.Equals("Excel"))
{
_report.SaveTourPlaceVisitToExcelFile
(new ReportBindingModel { FileName = $"C:\\Reports\\{APIClient.User.Email}-{DateTime.Now.ToString("dd/MM/yyyy")}.xlsx", Tours = list, UserId = APIClient.User.Id });
}
else
{
_report.SaveTourPlaceVisitToWordFile
(new ReportBindingModel { FileName = $"C:\\Reports\\{APIClient.User.Email}-{DateTime.Now.ToString("dd/MM/yyyy")}.docx", Tours = list, UserId = APIClient.User.Id });
}
var items = _report.GetTourPlaceVisit(new ReportBindingModel { Tours = list, UserId = APIClient.User.Id });
return PartialView("PlaceVisitPartial", items);
}
public IActionResult ReportPdf()
{
var list = _tour.ReadList(new TourSearchModel { UserId = APIClient.User.Id });
var simpTour = list.Select(x => new { TourId = x.Id, TourName = x.TourName });
ViewBag.Tours = new MultiSelectList(simpTour, "TourId", "TourName");
return View();
}
public IActionResult GetPartialForPDF(int[] tours, DateTime dateFrom, DateTime dateTo)
{
var _dateFrom = dateFrom;
var _dateTo = dateTo;
if (_dateFrom > _dateTo)
{
throw new Exception("Не верные даты");
}
string path = $"C:\\Reports\\{APIClient.User.UserFIO} от {_dateFrom.ToString("dd/MM/yyyy")}.pdf";
_report.SaveToursToPdfFile
(new ReportBindingModel
{
FileName = path,
DateFrom = _dateFrom,
DateTo = _dateTo,
UserId = APIClient.User.Id
});
var items = _report.GetTours(new ReportBindingModel { DateFrom = _dateFrom, DateTo = _dateTo, UserId = APIClient.User.Id });
mailSender.MailSendAsync(new MailSendInfoBindingModel
{
MailAddress = APIClient.User.Email,
Subject = $"Отчет от {dateFrom} по {dateTo}",
Path = path
});
return PartialView("TourPartial", items);
}
}
}

View File

@ -0,0 +1,9 @@
namespace TourCompanyClientApp.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@ -0,0 +1,53 @@
using TourCompanyBusinessLogic.BusinessLogics;
using TourCompanyBusinessLogic.MailKit;
using TourCompanyBusinessLogic.OfficePackage;
using TourCompanyBusinessLogic.OfficePackage.Implements;
using TourCompanyClientApp;
using TourCompanyContracts.BusinessLogicsContracts;
using TourCompanyContracts.StoragesContracts;
using TourCompanyDatabaseImplement.Implements;
using TourCompanyDatabaseImplement.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddTransient<IUserStorage, UserStorage>();
builder.Services.AddTransient<ITourStorage, TourStorage>();
builder.Services.AddTransient<IExecurtionStorage, ExecurtionStorage>();
builder.Services.AddTransient<ITourGroupStorage, TourGroupStorage>();
builder.Services.AddTransient<IPlaceVisitStorage, PlaceVisitStorage>();
builder.Services.AddTransient<IGidStorage, GidStorage>();
builder.Services.AddTransient<ITripStorage, TripStorage>();
builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddTransient<ITourLogic, TourLogic>();
builder.Services.AddTransient<IExecurtionLogic, ExecurtionLogic>();
builder.Services.AddTransient<ITourGroupLogic, TourGroupLogic>();
builder.Services.AddTransient<IPlaceVisitLogic, PlaceVisitLogic>();
builder.Services.AddTransient<IGidLogic, GidLogic>();
builder.Services.AddTransient<ITripLogic,TripLogic>();
builder.Services.AddTransient<IReportLogic, ReportLogic>();
builder.Services.AddTransient<AbstractSaveToExcelUser, SaveToExcelUser>();
builder.Services.AddTransient<AbstractSaveToWordUser, SaveToWordUser>();
builder.Services.AddTransient<AbstractSaveToPdfUser, SaveToPdfUser>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// 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();

View File

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:14223",
"sslPort": 44395
}
},
"profiles": {
"TourCompanyClientApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7138;http://localhost:5217",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TourCompanyBusinessLogic\TourCompanyBusinessLogic.csproj" />
<ProjectReference Include="..\TourCompanyDatabaseImplement\TourCompanyDatabaseImplement.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,30 @@
@{
ViewData["Title"] = "CreateExecurtion";
}
<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="purpose" /></div>
</div>
<div class="row">
<div class="col-4">Дата экскурсии:</div>
<div class="col-8"><input type="datetime-local" name="dateExecurtion" /></div>
</div>
<div class="row">
<div class="col-4">Длительность экскурсии:</div>
<div class="col-8"><input type="number" name="execurtionDuratation" /></div>
</div>
<div class="row">
<div class="col-4">туры:</div>
<div class="col-8">
@Html.ListBox("tours", (MultiSelectList)ViewBag.Tours)
</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>

View File

@ -0,0 +1,26 @@
@{
ViewData["Title"] = "CreateGid";
}
<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="number" name="experion" /></div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8"><input type="text" name="GidFio" /></div>
</div>
<div class="row">
<div class="col-4">экускурсии:</div>
<div class="col-8">
@Html.ListBox("execurtions", (MultiSelectList)ViewBag.Execurtions)
</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>

View File

@ -0,0 +1,32 @@
@{
ViewData["Title"] = "CreatePlaceVisit";
}
<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="tourGroup" name="tourGroup" class="form-control" asp-items="@(new SelectList(@ViewBag.TourGroups,"Id", "TourGroupName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Место посещения:</div>
<div class="col-8"><input type="text" name="placeVisitName" id="placeVisitName" /></div>
</div>
<div class="row">
<div class="col-4">Дата посещения:</div>
<div class="col-8"><input type="datetime-local" id="datePlaceVisit" name="datePlaceVisit" /></div>
</div>
<div class="row">
<div class="col-4">поездки:</div>
<div class="col-8">
@Html.ListBox("trips", (MultiSelectList)ViewBag.Trips)
</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>

View File

@ -0,0 +1,20 @@
@{
ViewData["Title"] = "CreateTour";
}
<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="tourName" /></div>
</div>
<div class="row">
<div class="col-4">Дата тура:</div>
<div class="col-8"><input type="datetime-local" name="tourDate" /></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>

View File

@ -0,0 +1,26 @@
@{
ViewData["Title"] = "CreateTourGroup";
}
<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="tourGroupName" /></div>
</div>
<div class="row">
<div class="col-4">Тип группы:</div>
<div class="col-8"><input type="number" name="type" min="0" max="1"/></div>
</div>
<div class="row">
<div class="col-4">туры:</div>
<div class="col-8">
@Html.ListBox("tours", (MultiSelectList)ViewBag.Tours)
</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>

View File

@ -0,0 +1,26 @@
@{
ViewData["Title"] = "CreateTrip";
}
<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="gid" name="gid" class="form-control" asp-items="@(new SelectList(@ViewBag.Gids,"Id", "GidFIO"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Название Поездки:</div>
<div class="col-8"><input type="text" name="tripName" id="tripName" /></div>
</div>
<div class="row">
<div class="col-4">Дата поездки:</div>
<div class="col-8"><input type="datetime-local" id="dateTrip" name="dateTrip" /></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>

View File

@ -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="login" /></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>

View File

@ -0,0 +1,77 @@
@using TourCompanyContracts.ViewModels
@model List<ExecurtionViewModel>
@{
ViewData["Title"] = "Execurtion";
}
<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="CreateExecurtion">Создать Экскурсию</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Цель экскурсии
</th>
<th>
Дата экскурсии
</th>
<th>
длительность экскурсии
</th>
<th>
Туры
</th>
<th>
Действие
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.Purpose)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateExecurtion)
</td>
<td>
@Html.DisplayFor(modelItem => item.ExecurtionDuratation)
</td>
<td>
<select asp-items="@(new SelectList(item.ExecurtionTours,"Key", "Value.TourName"))"></select>
</td>
<td>
<a href="@Url.Action("ExecurtionSetting","Home", new {id=item.Id })"
class="btn btn-primary btn-lg">Update/Delete</a>
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,36 @@
@using TourCompanyContracts.ViewModels;
@model ExecurtionViewModel
@{
ViewData["Title"] = "Setting";
}
<div class="text-center">
<h2 class="display-4">@Model.Purpose</h2>
</div>
<form method="post" action="@Url.Action("UpdateExecurtion", "Home", new{idExecurtion=Model.Id, purpose="#purpose",execurtionDuratation="#execurtionDuratation", dateExecurtion="#dateExecurtion", tours="#tours"})">
<div class="row m-3">
<div class="col-8">
<input type="submit" value="Обновить" class="col-md-4 btn btn-primary" />
<input type="button" class="col-md-4 ms-auto btn btn-danger" value="Удалить" onclick="location.href='@Url.Action("DeleteExecurtion","Home", new {id=Model.Id })'" />
</div>
</div>
<div class="row m-3">
<div class="col-4">Цель экскурсии:</div>
<div class="col-8"><input type="text" name="purpose" id="purpose" value="@Model.Purpose" /></div>
</div>
<div class="row m-3">
<div class="col-4">Даты экскурсии:</div>
<div class="col-8"><input type="datetime-local" name="dateExecurtion" id="dateExecurtion" value="@Model.DateExecurtion" /></div>
</div>
<div class="row m-3">
<div class="col-4">Длительность экскурсии:</div>
<div class="col-8"><input type="number" id="execurtionDuratation" name="execurtionDuratation">@Model.ExecurtionDuratation/></div>
</div>
<div class="row">
<div class="col-4">Туры:</div>
<div class="col-8">
@Html.ListBox("tours", (MultiSelectList)ViewBag.Tours)
</div>
</div>
</form>

View File

@ -0,0 +1,63 @@
@using TourCompanyContracts.ViewModels
@model List<GidViewModel>
@{
ViewData["Title"] = "Gid";
}
<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="CreateGid">Создать Гида</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Опыт
</th>
<th>
ФИО
</th>
<th>
Экскурсии
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.Experion)
</td>
<td>
@Html.DisplayFor(modelItem => item.GidFIO)
</td>
<td>
<select asp-items="@(new SelectList(item.GidExecurtions,"Key", "Value.Purpose"))"></select>
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,8 @@
@{
ViewData["Title"] = "Index";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

View File

@ -0,0 +1,70 @@
@using TourCompanyContracts.ViewModels
@model List<PlaceVisitViewModel>
@{
ViewData["Title"] = "PlaceVisit";
}
<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="CreatePlaceVisit">Создать Места посещения</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>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.PlaceVisitName)
</td>
<td>
@Html.DisplayFor(modelItem => item.DatePlaceVisit)
</td>
<td>
@Html.DisplayFor(modelItem => item.TourGroupName)
</td>
<td>
<select asp-items="@(new SelectList(item.PlaceVisitTrips,"Key", "Value.TripName"))"></select>
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,28 @@
@using TourCompanyContracts.ViewModels
@model UserViewModel
@{
ViewData["Title"] = "Privacy Policy";
}
<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="login" 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.UserFIO" /></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>

View File

@ -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="login" /></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>

View File

@ -0,0 +1,23 @@
@{
ViewData["Title"] = "Report";
}
<form id="my_form" asp-action="Reports" method="get" data-ajax="true" data-ajax-method="get" data-ajax-update="#panel" data-ajax-mode='replace' data-ajax-url="@Url.Action("GetPartial","Home")">
<select id="mode" name="mode">
<option>Excel</option>
<option>Word</option>
</select>
<div class="row">
<div class="col-4">туры:</div>
<div class="col-8">
@Html.ListBox("tours", (MultiSelectList)ViewBag.Tours)
</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>
<div class="row pr-3 pl-3" id="panel">
@section scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ajax-unobtrusive/3.2.6/jquery.unobtrusive-ajax.min.js"></script>
}

View File

@ -0,0 +1,28 @@
@{
ViewData["Title"] = "ReportPdf";
}
<form id="my_form" asp-action="SendingEmail" method="get" data-ajax="true" data-ajax-method="get" data-ajax-update="#panel" data-ajax-mode='replace' data-ajax-url="@Url.Action("GetPartialForPDF","Home")">
div class="row">
<div class="col-4">От:</div>
<div class="col-8"><input type="datetime-local" name="dateFrom" /></div>
</div>
<div class="row">
<div class="col-4">До:</div>
<div class="col-8"><input type="datetime-local" name="dateTo" /></div>
</div>
</select>
<div class="row">
<div class="col-4">туры:</div>
<div class="col-8">
@Html.ListBox("tours", (MultiSelectList)ViewBag.Tours)
</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>
<div class="row pr-3 pl-3" id="panel">
@section scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ajax-unobtrusive/3.2.6/jquery.unobtrusive-ajax.min.js"></script>
}

View File

@ -0,0 +1,65 @@
@using TourCompanyContracts.ViewModels
@model List<TourViewModel>
@{
ViewData["Title"] = "Tour";
}
<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="CreateTour">Создать тур</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Тур
</th>
<th>
Дата Тура
</th>
<th>
Действие над выбранным туром
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.TourName)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateTour)
</td>
<td>
<a href="@Url.Action("TourSetting","Home", new {id=item.Id })"
class="btn btn-primary btn-lg">Update/Delete</a>
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,71 @@
@using TourCompanyContracts.ViewModels
@model List<TourGroupViewModel>
@{
ViewData["Title"] = "TourGroup";
}
<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="CreateTourGroup">Создать Тур группу</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>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.TourGroupName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Type)
</td>
<td>
<select asp-items="@(new SelectList(item.TourGroupTours,"Key", "Value.TourName"))"></select>
</td>
<td>
<a href="@Url.Action("TourGroupSetting","Home", new {id=item.Id })"
class="btn btn-primary btn-lg">Update/Delete</a>
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,32 @@
@using TourCompanyContracts.ViewModels;
@model TourGroupViewModel
@{
ViewData["Title"] = "Setting";
}
<div class="text-center">
<h2 class="display-4">@Model.TourGroupName</h2>
</div>
<form method="post" action="@Url.Action("UpdateTourGroup", "Home", new{idTourGroup=Model.Id,tourGroupName="#tourGroupName",type="#type", tours="#tours"})">
<div class="row m-3">
<div class="col-8">
<input type="submit" value="Обновить" class="col-md-4 btn btn-primary" />
<input type="button" class="col-md-4 ms-auto btn btn-danger" value="Удалить" onclick="location.href='@Url.Action("DeleteTourGroup","Home", new {id=Model.Id })'" />
</div>
</div>
<div class="row m-3">
<div class="col-4">Название тур группы:</div>
<div class="col-8"><input type="text" name="tourGroupName" id="tourGroupName" value="@Model.TourGroupName" /></div>
</div>
<div class="row m-3">
<div class="col-4">Тип группы:</div>
<div class="col-8"><input type="number" min="0" max="1" id="type" name="type" rows="5">@Model.Type/></div>
</div>
<div class="row">
<div class="col-4">Туры:</div>
<div class="col-8">
@Html.ListBox("tours", (MultiSelectList)ViewBag.Tours)
</div>
</div>
</form>

View File

@ -0,0 +1,48 @@
@using TourCompanyContracts.ViewModels;
@model List<ReportTourViewModel>
<div class="text-center">
@{
<table class="table">
<thead>
<tr>
<th>
тур
</th>
<th>
тур группа
</th>
<th>
экскурсия
</th>
<th>
Дата создания экс
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.TourName)
</td>
<td>
@Html.DisplayFor(modelItem => item.TourGroupName)
</td>
<td>
@Html.DisplayFor(modelItem => item.ExecurtionName)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateTour)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,24 @@
@using TourCompanyContracts.ViewModels
@model TourViewModel
@{
ViewData["Title"] = "Setting";
}
<div class="text-center">
<h2 class="display-4">@Model.TourName</h2>
</div>
<form method="post" action="@Url.Action("UpdateTour", "Home", new{id=Model.Id,tourName="#tourName",tourDate="#tourDate"})">
<div class="row m-3">
<div class="col-8">
<input type="submit" value="Обновить" class="col-md-4 btn btn-primary" />
<input type="button" class="col-md-4 ms-auto btn btn-danger" value="Удалить" onclick="location.href='@Url.Action("DeleteTour","Home", new {id=Model.Id })'" />
</div>
</div>
<div class="row m-3">
<div class="col-4">Название:</div>
<div class="col-8"><input type="text" name="tourName" id="tourName" value="@Model.TourName" /></div>
</div>
<div class="row m-3">
<div class="col-4">Дата Тура:</div>
<div class="col-8"><input type="datetime-local" id="tourDate" name="tourDate" value="@Model.DateTour" /></div>
</div>
</form>

View File

@ -0,0 +1,63 @@
@using TourCompanyContracts.ViewModels
@model List<TripViewModel>
@{
ViewData["Title"] = "Trip";
}
<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="CreateTrip">Создать поездку</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Поездка
</th>
<th>
Дата Поездки
</th>
<th>
Гид
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.TripName)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateTrip)
</td>
<td>
@Html.DisplayFor(modelItem => item.GidFIO)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -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>

View File

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - TourCompanyClientApp</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="~/TourCompanyClientApp.styles.css" asp-append-version="true" />
<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>
</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">TourCompanyClientApp</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 justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Tour">Тур</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Execurtion">Экскурсия</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="TourGroup">ТурГруппа</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Report">Отчеты Word Excel</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="ReportPdf">Отчеты Pdf</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="PlaceVisit">Места посещения</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Gid">Гиды</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Trip">Поездки</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="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Register">Регистрация</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">
&copy; 2023 - TourCompanyClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,48 @@
/* Please see documentation at https://docs.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;
}

View File

@ -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>

View File

@ -0,0 +1,3 @@
@using TourCompanyClientApp
@using TourCompanyClientApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,11 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"IPAddress": "http://localhost:5149/"
}

View File

@ -0,0 +1,18 @@
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
html {
position: relative;
min-height: 100%;
}
body {
margin-bottom: 60px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,4 @@
// Please see documentation at https://docs.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.

View File

@ -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.

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

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

View File

@ -0,0 +1,427 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr /* rtl:ignore */;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,424 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr ;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */

File diff suppressed because one or more lines are too long

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

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

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

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