я умер
This commit is contained in:
parent
1cda9ec164
commit
5348aa00c1
@ -11,6 +11,7 @@ using BeautySalonContracts.BindingModels;
|
||||
using BeautySalonContracts.SearchModels;
|
||||
using BeatySalonBusinesLogic.OfficePackage.HelperModels;
|
||||
using BeatySalonBusinesLogic.OfficePackage.Implements;
|
||||
using BeautySalonBusinesLogics.OfficePackage;
|
||||
|
||||
namespace BeautySalonBusinesLogic.BusinessLogics
|
||||
{
|
||||
@ -60,16 +61,16 @@ namespace BeautySalonBusinesLogic.BusinessLogics
|
||||
|
||||
public List<ReportServicesViewModel> GetServices(ReportServiceBindingModel model)
|
||||
{
|
||||
List<ReportServicesViewModel> r = _serviceStorage.GetFullList()
|
||||
.Select(x => new ReportServicesViewModel
|
||||
{
|
||||
Id = x.Id,
|
||||
ProcedureName = x.ServiceProcedures.Select(kv => kv.Value.Item1.ProcedureName).FirstOrDefault(),
|
||||
CosmeticName = x.ServiceCosmetics.Select(kv => kv.Value.Item1.CosmeticName).FirstOrDefault(),
|
||||
ServicePrice = x.ServiceProcedures.Sum(kv => kv.Value.Item1.ProcedurePrice) +
|
||||
x.ServiceCosmetics.Sum(kv => kv.Value.Item1.CosmeticPrice)
|
||||
}).ToList();
|
||||
return r;
|
||||
List<ReportServicesViewModel> r = _serviceStorage.GetFullList()
|
||||
.Select(x => new ReportServicesViewModel
|
||||
{
|
||||
Id = x.Id,
|
||||
Cosmetics = x.ServiceCosmetics,
|
||||
Procedures = x.ServiceProcedures,
|
||||
ServicePrice = x.ServiceProcedures.Sum(kv => kv.Value.Item1.ProcedurePrice) +
|
||||
x.ServiceCosmetics.Sum(kv => kv.Value.Item1.CosmeticPrice)
|
||||
}).ToList();
|
||||
return r;
|
||||
}
|
||||
|
||||
public void SaveCosmeticProceduresToWordFile(ReportBindingModel model)
|
||||
@ -93,7 +94,7 @@ namespace BeautySalonBusinesLogic.BusinessLogics
|
||||
|
||||
public void SaveServicesToPdfFile(ReportServiceBindingModel model)
|
||||
{
|
||||
_saveToPdf.CreateDoc(new PdfInfo
|
||||
_saveToPdf.CreateReport(new PdfInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Список услуг",
|
||||
|
@ -1,68 +1,123 @@
|
||||
using BeatySalonBusinesLogic.OfficePackage.HelperEnums;
|
||||
using BeatySalonBusinesLogic.OfficePackage.HelperModels;
|
||||
using BeautySalonContracts.ViewModels;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BeatySalonBusinesLogic.OfficePackage
|
||||
namespace BeautySalonBusinesLogics.OfficePackage
|
||||
{
|
||||
public abstract class AbstractSaveToPdfStorekeeper//services
|
||||
/// <summary>
|
||||
/// Абстрактный класс для создания отчета Pdf
|
||||
/// </summary>
|
||||
public abstract class AbstractSaveToPdfStorekeeper
|
||||
{
|
||||
public void CreateDoc(PdfInfo info)
|
||||
public void CreateReport(PdfInfo info)
|
||||
{
|
||||
// Создаем файл
|
||||
CreatePdf(info);
|
||||
|
||||
// Создаем заголовок
|
||||
CreateParagraph(new PdfParagraph
|
||||
{
|
||||
Text = info.Title,
|
||||
Style = "NormalTitle",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
Style = "NormalTitle"
|
||||
});
|
||||
|
||||
// Период выборки данных
|
||||
// "с XX.XX.XXXX по XX.XX.XXXX"
|
||||
CreateParagraph(new PdfParagraph
|
||||
{
|
||||
Text = $"с{info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}",
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
Text = $"С {info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}",
|
||||
Style = "Normal"
|
||||
});
|
||||
CreateTable(new List<string> { "2cm", "6cm", "3cm"});
|
||||
|
||||
// Создаем таблицу с тремя колонками
|
||||
CreateTable(new List<string> { "7cm", "4cm", "4cm" });
|
||||
|
||||
// Создаем заголовок таблицы
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { "Номер", "Процедура", "Косметика", "Сумма"},
|
||||
Texts = new List<string> { "Услуга", "Процедуры", "Косметика" },
|
||||
Style = "NormalTitle",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
});
|
||||
foreach (var service in info.Services)
|
||||
|
||||
// Записываем основную информацию
|
||||
foreach (var view in info.Services)
|
||||
{
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { service.Id.ToString(), service.ProcedureName, service.CosmeticName, service.ServicePrice.ToString()},
|
||||
Texts = new List<string> { view.ServiceName, "", "" },
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Left
|
||||
});
|
||||
|
||||
// Конвертируем из HashSet в List, чтобы можно было обращаться по индексу
|
||||
List<string> cosmetics = new List<string>();
|
||||
foreach (var item in view.Cosmetics)
|
||||
{
|
||||
var cosmeticModel = item.Value.Item1;
|
||||
cosmetics.Add(cosmeticModel.CosmeticName);
|
||||
}
|
||||
List<string> procedures = new List<string>();
|
||||
foreach (var item in view.Procedures)
|
||||
{
|
||||
var procedureModel = item.Value.Item1;
|
||||
procedures.Add(procedureModel.ProcedureName);
|
||||
}
|
||||
|
||||
// Записываем названия лекарств во 2 колонку
|
||||
// и названия лекарств в 3 колонку
|
||||
int maxLength = Math.Max(cosmetics.Count, procedures.Count);
|
||||
for (int i = 0; i < maxLength; i++)
|
||||
{
|
||||
string cosmetic = (i < cosmetics.Count) ? cosmetics[i] : "";
|
||||
string procedure = (i < procedures.Count) ? procedures[i] : "";
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { "", cosmetic, procedure },
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Left
|
||||
});
|
||||
}
|
||||
}
|
||||
CreateParagraph(new PdfParagraph
|
||||
{
|
||||
Text = $"Итого: {info.Services.Sum(x => x.ServicePrice)}\t",
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Right
|
||||
});
|
||||
|
||||
// Сохраняем файл
|
||||
SavePdf(info);
|
||||
}
|
||||
|
||||
//Создание файла
|
||||
/// <summary>
|
||||
/// Создать файл Pdf
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
protected abstract void CreatePdf(PdfInfo info);
|
||||
|
||||
//Создание параграфа
|
||||
/// <summary>
|
||||
/// Создать абзац с текстом
|
||||
/// </summary>
|
||||
/// <param name="paragraph"></param>
|
||||
protected abstract void CreateParagraph(PdfParagraph paragraph);
|
||||
|
||||
//Создание таблицы
|
||||
/// <summary>
|
||||
/// Создать таблицу
|
||||
/// </summary>
|
||||
/// <param name="columns"></param>
|
||||
protected abstract void CreateTable(List<string> columns);
|
||||
|
||||
//Создание и заполнение строки
|
||||
/// <summary>
|
||||
/// Создать и заполнить строку
|
||||
/// </summary>
|
||||
/// <param name="rowParameters"></param>
|
||||
protected abstract void CreateRow(PdfRowParameters rowParameters);
|
||||
|
||||
//Сохранение файла
|
||||
/// <summary>
|
||||
/// Сохранить файл Pdf
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
protected abstract void SavePdf(PdfInfo info);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BeautySalonBusinesLogics.OfficePackage;
|
||||
|
||||
namespace BeatySalonBusinesLogic.OfficePackage.Implements
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using BeautySalonContracts.ViewModels;
|
||||
using BeautySalonDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -11,8 +12,8 @@ namespace BeautySalonContracts.ViewModels
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string ServiceName { get; set; } = string.Empty;
|
||||
public string ProcedureName { get; set; } = string.Empty;
|
||||
public string CosmeticName { get; set; } = string.Empty;
|
||||
public Dictionary <int, (ICosmeticModel, int)> Cosmetics { get; set; } = new();
|
||||
public Dictionary <int, (IProcedureModel, int)> Procedures { get; set; } = new();
|
||||
public double ServicePrice { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ using System.Reflection.PortableExecutable;
|
||||
using CafeBusinessLogic.BusinessLogics;
|
||||
using BeautySalonBusinesLogic.BusinessLogics;
|
||||
using BeautySalonDatabaseImplement.Implements;
|
||||
using BeautySalonBusinesLogics.OfficePackage;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
@ -150,8 +150,6 @@ namespace StorekeeperWebApp.Controllers
|
||||
APIStorekeeper.Storekeeper = null;
|
||||
Response.Redirect("Enter");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Reports()
|
||||
{
|
||||
if (APIStorekeeper.Storekeeper == null)
|
||||
@ -188,85 +186,68 @@ namespace StorekeeperWebApp.Controllers
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void CreateReportWord(List<int> procedures, DateTime dateFrom, DateTime dateTo)
|
||||
public async Task<IActionResult> CreateReportWord(List<int> cosmetics, DateTime dateFrom, DateTime dateTo, [FromServices] IWebHostEnvironment hostingEnvironment)
|
||||
{
|
||||
if (APIStorekeeper.Storekeeper == null)
|
||||
{
|
||||
throw new Exception("Необходимо авторизоваться!");
|
||||
}
|
||||
if (dateFrom == DateTime.MinValue || dateTo == DateTime.MinValue)
|
||||
{
|
||||
throw new Exception("Введены не все данные!");
|
||||
}
|
||||
// Проверки ввода и авторизации
|
||||
|
||||
if (procedures == null || procedures.Count <= 0)
|
||||
{
|
||||
throw new Exception("Не выбраны рецепты!");
|
||||
}
|
||||
var fileName = $"Список процедур {DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.docx";
|
||||
var filePath = Path.Combine(hostingEnvironment.ContentRootPath, "Downloads", fileName);
|
||||
|
||||
_reportLogic.SaveCosmeticProceduresToWordFile(new ReportBindingModel
|
||||
{
|
||||
FileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\Downloads\Список процедур {DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.docx",
|
||||
FileName = filePath,
|
||||
DateFrom = dateFrom,
|
||||
DateTo = dateTo
|
||||
});
|
||||
|
||||
Response.Redirect("/Home/Reports");
|
||||
// Возвращаем файл для загрузки
|
||||
var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
|
||||
return File(fileBytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void CreateReportExcel(List<int> procedures, DateTime dateFrom, DateTime dateTo)
|
||||
public async Task<IActionResult> CreateReportExcel(List<int> cosmetics, DateTime dateFrom, DateTime dateTo, [FromServices] IWebHostEnvironment hostingEnvironment)
|
||||
{
|
||||
if (APIStorekeeper.Storekeeper == null)
|
||||
{
|
||||
throw new Exception("Необходимо авторизоваться!");
|
||||
}
|
||||
if (dateFrom == DateTime.MinValue || dateTo == DateTime.MinValue)
|
||||
{
|
||||
throw new Exception("Введены не все данные!");
|
||||
}
|
||||
// Проверки ввода и авторизации
|
||||
|
||||
if (procedures == null || procedures.Count <= 0)
|
||||
{
|
||||
throw new Exception("Не выбраны рецепты!");
|
||||
}
|
||||
var fileName = $"Список процедур {DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.xlsx";
|
||||
var filePath = Path.Combine(hostingEnvironment.ContentRootPath, "Downloads", fileName);
|
||||
|
||||
_reportLogic.SaveCosmeticProceduresToExcelFile(new ReportBindingModel
|
||||
{
|
||||
FileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\Downloads\Список процедур {DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.xlsx",
|
||||
FileName = filePath,
|
||||
DateFrom = dateFrom,
|
||||
DateTo = dateTo
|
||||
});
|
||||
|
||||
Response.Redirect("/Home/Reports");
|
||||
// Возвращаем файл для загрузки
|
||||
var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
|
||||
return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void CreateReportPdf(DateTime dateFrom, DateTime dateTo)
|
||||
public async Task<IActionResult> CreateReportPdf(DateTime dateFrom, DateTime dateTo, [FromServices] IWebHostEnvironment hostingEnvironment)
|
||||
{
|
||||
if (APIStorekeeper.Storekeeper == null)
|
||||
{
|
||||
throw new Exception("Необходимо авторизоваться!");
|
||||
}
|
||||
// Проверки авторизации и ввода
|
||||
|
||||
if (dateFrom == DateTime.MinValue || dateTo == DateTime.MinValue)
|
||||
{
|
||||
throw new Exception("Введены не все данные!");
|
||||
}
|
||||
var fileName = $"Список услуг {DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.pdf";
|
||||
var filePath = Path.Combine(hostingEnvironment.ContentRootPath, "Downloads", fileName);
|
||||
|
||||
_reportLogic.SaveServicesToPdfFile(new ReportServiceBindingModel
|
||||
{
|
||||
FileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\Downloads\Список услуг{DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss")}.xlsx",
|
||||
FileName = filePath,
|
||||
DateFrom = dateFrom,
|
||||
DateTo = dateTo,
|
||||
StorekeeperId = APIStorekeeper.Storekeeper.Id
|
||||
});
|
||||
|
||||
Response.Redirect("/Home/Reports");
|
||||
// Возвращаем файл для загрузки
|
||||
var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
|
||||
return File(fileBytes, "application/pdf", fileName);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void SendReport(IFormFile fileUpload)
|
||||
public async Task<IActionResult> SendReport(IFormFile fileUpload, [FromServices] IWebHostEnvironment hostingEnvironment)
|
||||
{
|
||||
if (APIStorekeeper.Storekeeper == null)
|
||||
{
|
||||
@ -279,10 +260,15 @@ namespace StorekeeperWebApp.Controllers
|
||||
}
|
||||
|
||||
// Путь до файла
|
||||
var uploadPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + @"\Downloads\";
|
||||
var uploadPath = Path.Combine(hostingEnvironment.ContentRootPath, "Downloads");
|
||||
var fileName = Path.GetFileName(fileUpload.FileName);
|
||||
var fullPath = Path.Combine(uploadPath, fileName);
|
||||
|
||||
using (var fileStream = new FileStream(fullPath, FileMode.Create))
|
||||
{
|
||||
await fileUpload.CopyToAsync(fileStream);
|
||||
}
|
||||
|
||||
_mailLogic.MailSendAsync(new MailSendInfoBindingModel
|
||||
{
|
||||
MailAddress = APIStorekeeper.Storekeeper.Email,
|
||||
@ -291,7 +277,7 @@ namespace StorekeeperWebApp.Controllers
|
||||
Path = fullPath
|
||||
});
|
||||
|
||||
Response.Redirect("/Home/Reports");
|
||||
return RedirectToAction("Reports", "Home");
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
|
@ -10,6 +10,7 @@ using System.Reflection.PortableExecutable;
|
||||
using CafeBusinessLogic.BusinessLogics;
|
||||
using BeautySalonBusinesLogic.BusinessLogics;
|
||||
using BeautySalonDatabaseImplement.Implements;
|
||||
using BeautySalonBusinesLogics.OfficePackage;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
@ -25,11 +25,8 @@
|
||||
<None Include="Views\Cosmetic\UpdateCosmetics.cshtml" />
|
||||
<None Include="Views\Home\Enter.cshtml" />
|
||||
<None Include="Views\Home\Index.cshtml" />
|
||||
<None Include="Views\Home\LaborCosts.cshtml" />
|
||||
<None Include="Views\Home\ListCosmetics.cshtml" />
|
||||
<None Include="Views\Home\Register.cshtml" />
|
||||
<None Include="Views\Home\Report.cshtml" />
|
||||
<None Include="Views\Home\Service.cshtml" />
|
||||
<None Include="Views\Home\Reports.cshtml" />
|
||||
<None Include="Views\Shared\Error.cshtml" />
|
||||
<None Include="Views\Shared\UpdateLaborCosts.cshtml" />
|
||||
<None Include="Views\Shared\_Layout.cshtml" />
|
||||
|
@ -1,51 +0,0 @@
|
||||
@using BeautySalonContracts.ViewModels
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Трудозатраты";
|
||||
}
|
||||
|
||||
<h4 class="fw-bold">Трудозатраты</h4>
|
||||
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between">
|
||||
<div class="d-flex mb-2 gap-1">
|
||||
<a asp-controller="LaborCosts" asp-action="Create" class="button-primary">
|
||||
Создать
|
||||
</a>
|
||||
<a id="update-button" class="button-primary">
|
||||
Обновить
|
||||
</a>
|
||||
<button id="delete-button" class="button-primary me-5">
|
||||
Удалить
|
||||
</button>
|
||||
</div>
|
||||
<div class="d-flex mb-2 gap-1">
|
||||
<div class="input-group" style="width: auto;">
|
||||
<input id="page-input" type="number" min="1" value="@ViewBag.Page" max="@ViewBag.NumberOfPages" class="form-control" style="max-width: 5em">
|
||||
<span class="input-group-text">/ @ViewBag.NumberOfPages</span>
|
||||
</div>
|
||||
<a href="/Home/Cars?page=@ViewBag.Page" id="go-button" class="button-primary">
|
||||
Перейти
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border">
|
||||
<table class="table mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Количество часов</th>
|
||||
<th>Количество специалистов</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ViewBag.LaborCosts)
|
||||
{
|
||||
<tr class="table-row" id="row-@item.Id">
|
||||
<td>@item.NumberHours</td>
|
||||
<td>@item.NumberSpecialists</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script src="~/js/laborcosts.js" asp-append-version="true"></script>
|
@ -1,52 +0,0 @@
|
||||
@{
|
||||
ViewData["Title"] = "Список косметики по процедурам";
|
||||
}
|
||||
|
||||
<h4 class="fw-bold">Список косметики по процедурам</h4>
|
||||
|
||||
@{
|
||||
if (ViewBag.IsAllowed == false)
|
||||
{
|
||||
<h3 class="display-4">Авторизируйтесь</h3>
|
||||
return;
|
||||
}
|
||||
|
||||
<div class="mb-2">
|
||||
<button id="word-button" class="button-primary">
|
||||
Word
|
||||
</button>
|
||||
<button id="excel-button" class="button-primary">
|
||||
Excel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="mb-0">Выбранные процедуры:</p>
|
||||
<div class="table-shell border">
|
||||
<table class="table mb-0">
|
||||
<thead class="table-head">
|
||||
<tr>
|
||||
<th>Наименование</th>
|
||||
<th>Стоимость</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
<tr>
|
||||
<td>Не выбрано</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p class="mb-0">Добавить процедуру:</p>
|
||||
<div class="d-flex gap-1 mb-2">
|
||||
<select class="form-select mb-0" id="procedure-select"></select>
|
||||
<button id="add-button" class="button-primary">
|
||||
Добавить
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script src="~/js/list.js" asp-append-version="true"></script>
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
@{
|
||||
ViewData["Title"] = "Report";
|
||||
}
|
||||
|
||||
<h4 class="fw-bold">Отчет по услугам</h4>
|
||||
|
||||
<div class="d-flex flex-wrap gap-1 align-items-end mb-2">
|
||||
<div class="mb-2">
|
||||
<p class="mb-0">Дата начала:</p>
|
||||
<input id="date-from-input" class="form-control" type="date" />
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<p class="mb-0">Дата конца:</p>
|
||||
<input id="date-to-input" class="form-control" type="date" />
|
||||
</div>
|
||||
<button id="generate-button" class="button-primary mb-2">
|
||||
Показать
|
||||
</button>
|
||||
<button id="send-by-mail-button" class="button-primary mb-2">
|
||||
На почту
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="mb-0">
|
||||
<span>За период с </span>
|
||||
<span id="date-from-span" class="fw-bold">...</span>
|
||||
<span> по </span>
|
||||
<span id="date-to-span" class="fw-bold">...</span>
|
||||
</p>
|
||||
<div class="table-shell mb-2 border">
|
||||
<table class="table mb-0">
|
||||
<thead class="table-head">
|
||||
<tr>
|
||||
<th>Дата создания</th>
|
||||
<th>Услуга</th>
|
||||
<th>Стоимость</th>
|
||||
<th>Бренд косметики</th>
|
||||
<th>Наименование</th>
|
||||
<th>Стоимость косметики</th>
|
||||
<th>Процедуры</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script src="~/js/report.js" asp-append-version="true"></script>
|
121
BeautySalonView/StaffMemberWebApp/Views/Home/Reports.cshtml
Normal file
121
BeautySalonView/StaffMemberWebApp/Views/Home/Reports.cshtml
Normal file
@ -0,0 +1,121 @@
|
||||
@using BeautySalonContracts.ViewModels
|
||||
@model List<ReportServicesViewModel>
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Отчеты";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Отчеты</h2>
|
||||
</div>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" style="margin-top: 50px">
|
||||
<!-- Сохранить отчеты в формате Word и Excel -->
|
||||
<div class="d-flex justify-content-between">
|
||||
<!-- Кнопка для сохранения отчета в формате Word -->
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-primary" formaction="@Url.Action("CreateReportWord", "Home")">Список процедур по косметике Word</button>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">Процедуры по косметике:</div>
|
||||
<div class="col-8">
|
||||
<select name="recipes" id="recipes" class="form-control" size="4" multiple>
|
||||
@foreach (var cosmetic in ViewBag.Cosmetics)
|
||||
{
|
||||
<option value="@cosmetic.Id">@cosmetic.Id - @cosmetic.CosmeticName</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Кнопка для сохранения отчета в формате Excel -->
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-primary" formaction="@Url.Action("CreateReportExcel", "Home")">Список процедур по косметике Excel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Временной период выборки данных -->
|
||||
<div class="d-flex justify-content-center" style="margin: 50px 0px 30px 0px">
|
||||
<div class="text-center">
|
||||
<label for="dateFrom">С</label>
|
||||
<input type="date" id="dateFrom" name="dateFrom" class="form-control d-inline-block w-auto">
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<label for="dateTo">по</label>
|
||||
<input type="date" id="dateTo" name="dateTo" class="form-control d-inline-block w-auto">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Действия для отчета в формате Pdf -->
|
||||
<div class="d-flex justify-content-between">
|
||||
<!-- Сохранить отчет в формате Pdf -->
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-primary" formaction="@Url.Action("CreateReportPdf", "Home")">Сведения об услугах Pdf</button>
|
||||
</div>
|
||||
|
||||
<!-- Отправить отчет на почту -->
|
||||
<div class="d-flex">
|
||||
<label for="fileUpload" class="d-block"></label>
|
||||
<input type="file" id="fileUpload" name="fileUpload" class="form-control-file d-inline-block w-auto">
|
||||
<button type="submit" class="btn btn-primary" formaction="@Url.Action("SendReport", "Home")">Отправить отчет на почту</button>
|
||||
</div>
|
||||
|
||||
<!-- Вывести отчет на форму -->
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-primary" formaction="@Url.Action("Reports", "Home")">Вывести отчет на форму</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Таблица для вывода отчета на форму -->
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Услуга</th>
|
||||
<th>Процедуры</th>
|
||||
<th>Косметика</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (Model == null || Model.Count <= 0)
|
||||
{
|
||||
<td class="text-center" colspan="3">Нет доступных данных</td>
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var record in Model)
|
||||
{
|
||||
<td>@record.ServiceName</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
||||
// Конвертируем из HashSet в List, чтобы можно было обращаться по индексу
|
||||
var cosmetics = new List<string>();
|
||||
foreach (var kvp in record.Cosmetics)
|
||||
{
|
||||
var cosmeticModel = kvp.Value.Item1;
|
||||
cosmetics.Add(cosmeticModel.CosmeticName);
|
||||
}
|
||||
var procedures = new List<string>();
|
||||
foreach (var kvp in record.Procedures)
|
||||
{
|
||||
var procedureModel = kvp.Value.Item1;
|
||||
cosmetics.Add(procedureModel.ProcedureName);
|
||||
}
|
||||
|
||||
|
||||
// Записываем названия лекарств во 2 колонку
|
||||
// и названия лекарств в 3 колонку
|
||||
int maxLength = Math.Max(cosmetics.Count, procedures.Count);
|
||||
for (int i = 0; i < maxLength; i++)
|
||||
{
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>@(i < cosmetics.Count ? cosmetics[i] : "")</td>
|
||||
<td>@(i < procedures.Count ? procedures[i] : "")</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
@ -1,55 +0,0 @@
|
||||
@using BeautySalonContracts.ViewModels
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Услуга";
|
||||
}
|
||||
|
||||
<h4 class="fw-bold">Услуги</h4>
|
||||
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between">
|
||||
<div class="d-flex mb-2 gap-1">
|
||||
<a asp-controller="Service" asp-action="Create" class="button-primary">
|
||||
Создать
|
||||
</a>
|
||||
<a id="update-button" class="button-primary">
|
||||
Обновить
|
||||
</a>
|
||||
<a id="bind-button" class="button-primary">
|
||||
Связать с косметикой
|
||||
</a>
|
||||
<button id="delete-button" class="button-primary me-5">
|
||||
Удалить
|
||||
</button>
|
||||
</div>
|
||||
<div class="d-flex mb-2 gap-1">
|
||||
<div class="input-group" style="width: auto;">
|
||||
<input id="page-input" type="number" min="1" value="@ViewBag.Page" max="@ViewBag.NumberOfPages" class="form-control" style="max-width: 5em">
|
||||
<span class="input-group-text">/ @ViewBag.NumberOfPages</span>
|
||||
</div>
|
||||
<a href="/Home/Cars?page=@ViewBag.Page" id="go-button" class="button-primary">
|
||||
Перейти
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border">
|
||||
<table class="table mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Наименование</th>
|
||||
<th>Стоимость</th>
|
||||
<th>Дата создания</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ViewBag.Service)
|
||||
{
|
||||
<tr class="table-row" id="row-@item.Id">
|
||||
<td>@item.ServiceName</td>
|
||||
<td>@item.ServicePrice</td>
|
||||
<td>@item.DateCreate</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script src="~/js/service.js" asp-append-version="true"></script>
|
Loading…
x
Reference in New Issue
Block a user