From 2dc771cdb5259dc010ee923a66c08215267e601f Mon Sep 17 00:00:00 2001 From: sardq Date: Thu, 30 May 2024 00:49:57 +0400 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D1=91=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/WorkerReportLogic.cs | 12 ++- .../OfficePackage/AbstractSaveToPdf.cs | 68 ++++++++++----- .../OfficePackage/AbstractSaveToWord.cs | 35 +++++--- .../IWorkerReportLogic.cs | 3 +- .../StoragesContracts/IWorkpieceStorage.cs | 1 + .../Implements/PlanProductionStorage.cs | 7 +- .../Implements/WorkpieceStorage.cs | 5 +- .../Controllers/HomeController.cs | 83 ++++++++++++++++--- Factory/FactoryWorkerApp/Program.cs | 15 ++++ .../Views/Home/GetByPlans.cshtml | 2 +- .../FactoryWorkerApp/Views/Home/Index.cshtml | 8 -- .../Views/Home/PlanProductions.cshtml | 7 +- .../Views/Home/ProductProductionReport.cshtml | 20 ++++- .../Views/Home/WorkpieceDateReport.cshtml | 16 ++-- .../Views/Home/WorkpieceTimeChoose.cshtml | 2 +- .../Views/Home/Workpieces.cshtml | 6 ++ Factory/FactoryWorkerApp/WorkerLogic.cs | 12 ++- Factory/FactoryWorkerApp/appsettings.json | 9 +- 18 files changed, 226 insertions(+), 85 deletions(-) diff --git a/Factory/FactoryBuisinessLogic/BusinessLogics/WorkerReportLogic.cs b/Factory/FactoryBuisinessLogic/BusinessLogics/WorkerReportLogic.cs index e7f1299..d3e8406 100644 --- a/Factory/FactoryBuisinessLogic/BusinessLogics/WorkerReportLogic.cs +++ b/Factory/FactoryBuisinessLogic/BusinessLogics/WorkerReportLogic.cs @@ -36,7 +36,10 @@ namespace FactoryBusinessLogic.BusinessLogics } return products; } - + public List GetWorkpieces(ClientSearchModel client, ReportBindingModel model) + { + return _workpieceStorage.GetTimeReport(client, model); + } public void SaveWorkpiecesToPdfFile(ClientSearchModel client, ReportBindingModel model) { _saveToPdf.CreateWorkerDoc(new WorkerPdfInfo @@ -45,15 +48,16 @@ namespace FactoryBusinessLogic.BusinessLogics Title = "Список заготовок", DateFrom = model.DateFrom!.Value, DateTo = model.DateTo!.Value, + Workpieces = GetWorkpieces(client, model) }); } - public void SaveProductsToExcelFile(ReportBindingModel model, List plans) + public void SaveProductsToExcelFile(ReportBindingModel model, List ids) { _saveToExcel.CreateWorkerReport(new WorkerExcelInfo { FileName = model.FileName, Title = "Список планов", - //PlanProductionProducts = GetProductsByPlanProduction(plans) + PlanProductionProducts = GetProductsByPlanProduction(ids) }); } public void SaveProudctsToWordFile(ReportBindingModel model, List ids) @@ -63,7 +67,7 @@ namespace FactoryBusinessLogic.BusinessLogics { FileName = model.FileName, Title = "Список планов", - //PlanProductionProducts = GetProductsByPlanProduction(plans) + PlanProductionProducts = GetProductsByPlanProduction(ids) }); } } diff --git a/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToPdf.cs b/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToPdf.cs index 3c46ad1..7ac555c 100644 --- a/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToPdf.cs +++ b/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToPdf.cs @@ -94,41 +94,63 @@ namespace FactoryBusinessLogic.OfficePackage Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Center }); - CreateTable(new List { "3cm", "5cm" }); - foreach (var report in info.Workpieces) + CreateTable(new List { "3cm", "5cm", "5cm" }); + CreateRow(new PdfRowParameters + { + Texts = new List { "Название изделия", "Этапы выполнения", "Станки" }, + Style = "NormalTitle", + ParagraphAlignment = PdfParagraphAlignmentType.Center + }); + foreach (var workpiece in info.Workpieces) { CreateRow(new PdfRowParameters { - Texts = new List { "Заготовка", "Станок" }, - Style = "NormalTitle", - ParagraphAlignment = PdfParagraphAlignmentType.Center - }); - CreateRow(new PdfRowParameters - { - Texts = new List { report.WorkpieceName, "" }, + Texts = new List + { + workpiece.WorkpieceName, + string.Empty, + string.Empty, + }, Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Left }); - foreach (var machinee in report.Machines) - CreateRow(new PdfRowParameters - { - Texts = new List { "", machinee }, - Style = "Normal", - ParagraphAlignment = PdfParagraphAlignmentType.Left - }); - CreateRow(new PdfRowParameters + var phaseNames = workpiece.ExecutionPhases.Select(x => x.ExecutionPhaseName).ToList(); + var machineNames = workpiece.Machines.Select(x => x.MachineName).ToList(); + + if (phaseNames.Count != machineNames.Count) + { + if (phaseNames.Count > machineNames.Count) + { + var diff = phaseNames.Count - machineNames.Count; + for (int i = 0; i < diff; i++) + { + machineNames.Add(string.Empty); + } + } + else + { + var diff = machineNames.Count - phaseNames.Count; + for (int i = 0; i < diff; i++) + { + phaseNames.Add(string.Empty); + } + } + } + var tupleList = machineNames.Zip(phaseNames, Tuple.Create); + foreach (var tuple in tupleList) { - Texts = new List { "", "Этап выполнения" }, - Style = "NormalTitle", - ParagraphAlignment = PdfParagraphAlignmentType.Center - }); - foreach (var phase in report.ExecutionPhases) CreateRow(new PdfRowParameters { - Texts = new List { "", phase }, + Texts = new List + { + string.Empty, + tuple.Item1, + tuple.Item2, + }, Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Left }); + } } SaveWorkerPdf(info); } diff --git a/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToWord.cs b/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToWord.cs index c0023da..cdb4e66 100644 --- a/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToWord.cs +++ b/Factory/FactoryBuisinessLogic/OfficePackage/AbstractSaveToWord.cs @@ -72,28 +72,37 @@ namespace FactoryBusinessLogic.OfficePackage }); foreach (var ppp in info.PlanProductionProducts) { - var t = ppp.Products; List<(string, WordTextProperties)> texts = new List<(string, WordTextProperties)> { (ppp.ProductionName, new WordTextProperties { Bold = true, Size = "24", }) }; - foreach (var product in ppp.Products) + CreateParagraph(new WordParagraph + { + Texts = texts, + TextProperties = new WordTextProperties + { + Size = "24", + JustificationType = WordJustificationType.Both + } + }); + foreach (var product in ppp.Products) { - StringBuilder stringBuilder = new StringBuilder(); + texts = new List<(string, WordTextProperties)>(); + StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(product.ProductName); stringBuilder.Append(" — "); stringBuilder.Append(product.Price.ToString()); texts.Add((stringBuilder.ToString(), new WordTextProperties { Size = "24" })); - } - CreateParagraph(new WordParagraph - { - Texts = texts, - TextProperties = new WordTextProperties - { - Size = "24", - JustificationType = WordJustificationType.Both - } - }); + CreateParagraph(new WordParagraph + { + Texts = texts, + TextProperties = new WordTextProperties + { + Size = "24", + JustificationType = WordJustificationType.Both + } + }); + } } SaveWorkerWord(info); } diff --git a/Factory/FactoryContracts/BusinessLogicsContracts/IWorkerReportLogic.cs b/Factory/FactoryContracts/BusinessLogicsContracts/IWorkerReportLogic.cs index 79258b9..a933521 100644 --- a/Factory/FactoryContracts/BusinessLogicsContracts/IWorkerReportLogic.cs +++ b/Factory/FactoryContracts/BusinessLogicsContracts/IWorkerReportLogic.cs @@ -7,7 +7,8 @@ namespace FactoryContracts.BusinessLogicsContracts public interface IWorkerReportLogic { List GetProductsByPlanProduction(List plans); - void SaveProudctsToWordFile(ReportBindingModel model, List plans); + List GetWorkpieces(ClientSearchModel client, ReportBindingModel model); + void SaveProudctsToWordFile(ReportBindingModel model, List plans); void SaveProductsToExcelFile(ReportBindingModel model, List plans); void SaveWorkpiecesToPdfFile(ClientSearchModel client, ReportBindingModel model); diff --git a/Factory/FactoryContracts/StoragesContracts/IWorkpieceStorage.cs b/Factory/FactoryContracts/StoragesContracts/IWorkpieceStorage.cs index 5e5dab4..e631d92 100644 --- a/Factory/FactoryContracts/StoragesContracts/IWorkpieceStorage.cs +++ b/Factory/FactoryContracts/StoragesContracts/IWorkpieceStorage.cs @@ -9,6 +9,7 @@ namespace FactoryContracts.StoragesContracts List GetFullList(); List GetFilteredList(WorkpieceSearchModel model); + List GetTimeReport(ClientSearchModel client, ReportBindingModel model); WorkpieceViewModel? GetElement(WorkpieceSearchModel model); diff --git a/Factory/FactoryDatabaseImplement/Implements/PlanProductionStorage.cs b/Factory/FactoryDatabaseImplement/Implements/PlanProductionStorage.cs index 8158c52..0cd4137 100644 --- a/Factory/FactoryDatabaseImplement/Implements/PlanProductionStorage.cs +++ b/Factory/FactoryDatabaseImplement/Implements/PlanProductionStorage.cs @@ -127,8 +127,9 @@ namespace FactoryDatabaseImplement.Implements { using var context = new FactoryDatabase(); return context.PlanProductions + .Distinct() .Where(plan => ids.Contains(plan.Id)) - .Select(plan => new PlanProductionProductReportViewModel() + .Select(plan => new PlanProductionProductReportViewModel() { ProductionName = plan.ProductionName, Products = context.WorkpieceProducts @@ -136,8 +137,8 @@ namespace FactoryDatabaseImplement.Implements .Include(x => x.Workpiece) .Where(product => plan.Id == product.Product.Id) .Select(x => x.Product.GetViewModel) - .ToList() - }) + .ToList() + }) .ToList(); } } diff --git a/Factory/FactoryDatabaseImplement/Implements/WorkpieceStorage.cs b/Factory/FactoryDatabaseImplement/Implements/WorkpieceStorage.cs index 447fe69..3e8569d 100644 --- a/Factory/FactoryDatabaseImplement/Implements/WorkpieceStorage.cs +++ b/Factory/FactoryDatabaseImplement/Implements/WorkpieceStorage.cs @@ -111,7 +111,8 @@ namespace FactoryDatabaseImplement.Implements .Include(x => x.Client) .Include(x => x.PlanProductions) .ThenInclude(x => x.PlanProduction) - .Select(x => new WorkpieceTimeReportViewModel + .Where(x => x.DateCreate <= model.DateTo && x.DateCreate >= model.DateFrom) + .Select(x => new WorkpieceTimeReportViewModel { WorkpieceName = x.WorkpieceName, Machines = context.PlanProductionWorkpieces @@ -119,7 +120,7 @@ namespace FactoryDatabaseImplement.Implements .Where(ppw => ppw.WorkpieceId == x.Id) .Select(ppw => ppw.PlanProduction.Machines .Where(m => m.PlanProductionId == ppw.PlanProductionId) - .Select(m => m.Machine.GetViewModel).ToList()).FirstOrDefault()!, + .Select(m => m.Machine.GetViewModel).ToList()).FirstOrDefault(), ExecutionPhases = context.ExecutionPhases .Where(ep => ep.PlanProductionId.HasValue) .Include(ep => ep.PlanProduction) diff --git a/Factory/FactoryWorkerApp/Controllers/HomeController.cs b/Factory/FactoryWorkerApp/Controllers/HomeController.cs index 5efce59..5b32edc 100644 --- a/Factory/FactoryWorkerApp/Controllers/HomeController.cs +++ b/Factory/FactoryWorkerApp/Controllers/HomeController.cs @@ -1,4 +1,5 @@ using DocumentFormat.OpenXml.Office2010.Excel; +using FactoryBuisinessLogic.MailWorker; using FactoryBusinessLogic.BusinessLogics; using FactoryContracts.BindingModels; using FactoryContracts.BusinessLogicsContracts; @@ -18,14 +19,16 @@ namespace FactoryWorkerApp.Controllers private readonly ILogger _logger; private readonly WorkerLogic _logic; private readonly IWorkerReportLogic _workerReportLogic; - private bool IsLoggedIn { get { return Client.user != null; } } + private readonly AbstractMailWorker _abstractMailWorker; + private bool IsLoggedIn { get { return Client.user != null; } } private int UserId { get { return Client.user!.Id; } } - public HomeController(ILogger logger, WorkerLogic logic, IWorkerReportLogic workerReportLogic) + public HomeController(ILogger logger, WorkerLogic logic, IWorkerReportLogic workerReportLogic, AbstractMailWorker abstractMailWorker) { _logger = logger; _logic = logic; - _workerReportLogic = workerReportLogic; + _workerReportLogic = workerReportLogic; + _abstractMailWorker = abstractMailWorker; } public IActionResult Index() @@ -238,7 +241,7 @@ namespace FactoryWorkerApp.Controllers { return Redirect("Index"); } - ViewBag.plans = _logic.GetPlanProductions(Client.user!.Id); + ViewBag.ids = _logic.GetPlanProductions(Client.user!.Id); return View(); } @@ -249,7 +252,8 @@ namespace FactoryWorkerApp.Controllers { return Redirect("Index"); } - var report = _workerReportLogic.GetProductsByPlanProduction(plans); + ViewBag.ids = plans; + var report = _workerReportLogic.GetProductsByPlanProduction(plans); return View(report); } @@ -288,13 +292,19 @@ namespace FactoryWorkerApp.Controllers var startDate = DateTime.Parse(startDateStr); var endDate = DateTime.Parse(endDateStr).AddDays(1); - var values = _logic.GetWorkpieceTime(startDate, endDate, Client.user.Id); - - ViewBag.StartDate = startDate; - ViewBag.EndDate = endDate; - - return View(values); + var reports = _workerReportLogic.GetWorkpieces( + new ClientSearchModel + { + Id = Client.user.Id + }, + new ReportBindingModel + { + DateFrom = startDate, + DateTo = endDate, + }); + return View(reports); + } [HttpGet] @@ -345,6 +355,55 @@ namespace FactoryWorkerApp.Controllers _logic.CreateExecutionPhase(model); return RedirectToAction("ExecutionPhases"); } + [HttpPost] + public IActionResult CreateWord(List ids) + { + _workerReportLogic.SaveProudctsToWordFile( + new ReportBindingModel + { + FileName = "D:\\temp\\report.docx" + }, + ids); + return PhysicalFile("D:\\temp\\report.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "Отчет по изделиям.docx"); + } + [HttpPost] + public IActionResult CreateExcel(List ids) + { + _workerReportLogic.SaveProductsToExcelFile( + new ReportBindingModel + { + FileName = "D:\\temp\\report.xlsx" + }, + ids); + return PhysicalFile("D:\\temp\\report.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Отчет по изделиям.xlsx"); + } + + [HttpPost] + public IActionResult SendMail() + { + var startDateStr = HttpContext.Session.GetString("StartDate"); + var endDateStr = HttpContext.Session.GetString("EndDate"); + var startDate = DateTime.Parse(startDateStr); + var endDate = DateTime.Parse(endDateStr).AddDays(1); + _workerReportLogic.SaveWorkpiecesToPdfFile( + new ClientSearchModel + { + Id = Client.user.Id + }, + new ReportBindingModel + { + DateFrom = startDate, + DateTo = endDate, + FileName = "D:\\temp\\report.pdf" + }); + _abstractMailWorker.MailSendAsync(new MailSendInfoBindingModel + { + MailAddress = Client.user.Email, + Subject = $"Отчет по заготовкам пользователя {Client.user.Login}", + Text = $"Отчет по заготовкам с {startDate.ToShortDateString()} по {endDate.ToShortDateString()}" + }); + return Redirect("Index"); + } } -} \ No newline at end of file +} diff --git a/Factory/FactoryWorkerApp/Program.cs b/Factory/FactoryWorkerApp/Program.cs index dbfcc84..353223b 100644 --- a/Factory/FactoryWorkerApp/Program.cs +++ b/Factory/FactoryWorkerApp/Program.cs @@ -5,6 +5,8 @@ using FactoryDatabaseImplement.Implements; using FactoryWorkerApp; using FactoryBusinessLogic.OfficePackage; using FactoryBusinessLogic.OfficePackage.Implements; +using FactoryBuisinessLogic.MailWorker; +using FactoryContracts.BindingModels; var builder = WebApplication.CreateBuilder(args); @@ -32,6 +34,8 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddSingleton(); + builder.Services.AddSession(options => { @@ -43,6 +47,17 @@ builder.Services.AddSession(options => var app = builder.Build(); +var mailSender = app.Services.GetService(); + +mailSender?.MailConfig(new MailConfigBindingModel +{ + MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty, + MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty, + SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty, + SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()), + PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty, + PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString()) +}); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { diff --git a/Factory/FactoryWorkerApp/Views/Home/GetByPlans.cshtml b/Factory/FactoryWorkerApp/Views/Home/GetByPlans.cshtml index f4242bc..2df7677 100644 --- a/Factory/FactoryWorkerApp/Views/Home/GetByPlans.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/GetByPlans.cshtml @@ -14,7 +14,7 @@
Выберите планы
Планы:
-
diff --git a/Factory/FactoryWorkerApp/Views/Home/Index.cshtml b/Factory/FactoryWorkerApp/Views/Home/Index.cshtml index 4dbe30d..e4c39d4 100644 --- a/Factory/FactoryWorkerApp/Views/Home/Index.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/Index.cshtml @@ -10,20 +10,12 @@
@{ - //if (Model == null) - //{ - //

Авторизируйтесь

- // return; - //}

Заготовки

Планы производства -

-

- Привязка планов производства к заготовкам

Этапы выполнения diff --git a/Factory/FactoryWorkerApp/Views/Home/PlanProductions.cshtml b/Factory/FactoryWorkerApp/Views/Home/PlanProductions.cshtml index fcf2d7f..e8e7349 100644 --- a/Factory/FactoryWorkerApp/Views/Home/PlanProductions.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/PlanProductions.cshtml @@ -11,15 +11,10 @@

@{ - if (Model == null) - { -

Авторизируйтесь

- return; - }

Создать план - + Привязка планов производства к заготовкам

diff --git a/Factory/FactoryWorkerApp/Views/Home/ProductProductionReport.cshtml b/Factory/FactoryWorkerApp/Views/Home/ProductProductionReport.cshtml index 01dd7d9..6d4de40 100644 --- a/Factory/FactoryWorkerApp/Views/Home/ProductProductionReport.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/ProductProductionReport.cshtml @@ -9,10 +9,26 @@

Список изделий по планам производств

-
+ +
+ +
-
+ +
+ +
diff --git a/Factory/FactoryWorkerApp/Views/Home/WorkpieceDateReport.cshtml b/Factory/FactoryWorkerApp/Views/Home/WorkpieceDateReport.cshtml index 2c81592..20c17b3 100644 --- a/Factory/FactoryWorkerApp/Views/Home/WorkpieceDateReport.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/WorkpieceDateReport.cshtml @@ -10,7 +10,9 @@

Список заготовок за период

- + + + @@ -24,23 +26,23 @@ - @foreach (var workpice in Model) + @foreach (var workpiece in Model) { - + diff --git a/Factory/FactoryWorkerApp/Views/Home/WorkpieceTimeChoose.cshtml b/Factory/FactoryWorkerApp/Views/Home/WorkpieceTimeChoose.cshtml index d4e58c4..03dc950 100644 --- a/Factory/FactoryWorkerApp/Views/Home/WorkpieceTimeChoose.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/WorkpieceTimeChoose.cshtml @@ -64,7 +64,7 @@ var formData = $('#TimeReportWeb').serialize(); $.post('/Home/TimeReportWeb', formData, function (response) { - window.location.href = '/Home/WorkpieceTimeReport'; + window.location.href = '/Home/WorkpieceDateReport'; }).fail(function () { alert('Произошла ошибка при создании отчета.'); }); diff --git a/Factory/FactoryWorkerApp/Views/Home/Workpieces.cshtml b/Factory/FactoryWorkerApp/Views/Home/Workpieces.cshtml index 8029374..005f7ba 100644 --- a/Factory/FactoryWorkerApp/Views/Home/Workpieces.cshtml +++ b/Factory/FactoryWorkerApp/Views/Home/Workpieces.cshtml @@ -33,6 +33,9 @@ + @@ -54,6 +57,9 @@ + diff --git a/Factory/FactoryWorkerApp/WorkerLogic.cs b/Factory/FactoryWorkerApp/WorkerLogic.cs index 1a16091..f260384 100644 --- a/Factory/FactoryWorkerApp/WorkerLogic.cs +++ b/Factory/FactoryWorkerApp/WorkerLogic.cs @@ -114,5 +114,15 @@ namespace FactoryWorkerApp { return _productLogic.ReadList(null); } - } + + public List? GetWorkpieceTime(DateTime? startDate, DateTime? endDate, int ClientId) + { + var workpieces = _workpieceLogic.ReadList(new() { DateFrom = startDate, DateTo = endDate, ClientId = ClientId }); + if (workpieces == null) + return new(); + List detailTimeReports = new List(); + + return detailTimeReports; + } + } } diff --git a/Factory/FactoryWorkerApp/appsettings.json b/Factory/FactoryWorkerApp/appsettings.json index eed7524..60e0a72 100644 --- a/Factory/FactoryWorkerApp/appsettings.json +++ b/Factory/FactoryWorkerApp/appsettings.json @@ -7,5 +7,12 @@ }, "AllowedHosts": "*", - "IPAddress": "http://localhost:5283/" + "IPAddress": "http://localhost:5283/", + + "SmtpClientHost": "smtp.gmail.com", + "SmtpClientPort": "587", + "PopHost": "pop.gmail.com", + "PopPort": "995", + "MailLogin": "labworker83@gmail.com", + "MailPassword": "wpxc drvx lhqb uqpe" }
@workpice.WorkpieceName@workpiece.WorkpieceName
    - @foreach (var machine in workpice.Machines) + @foreach (var machine in workpiece.Machines) { -
  • @machine
  • +
  • @machine.MachineName
  • }
    - @foreach (var phase in workpice.ExecutionPhases) + @foreach (var phase in workpiece.ExecutionPhases) { -
  • @phase
  • +
  • @phase.PlanProductionName
  • }
Цена + Дата + Изменить заготовку @Html.DisplayFor(modelItem => item.Cost) + @Html.DisplayFor(modelItem => item.DateCreate) + Изменить