формирование списка в ворде работает криво, но работает

This commit is contained in:
Николай 2023-05-17 22:19:18 +04:00
parent 41f189f0ee
commit 2bec90ed3d
13 changed files with 436 additions and 105 deletions

View File

@ -1,21 +1,30 @@
 
using HardwareShopBusinessLogic.OfficePackage;
using HardwareShopBusinessLogic.OfficePackage.HelperModels;
using HardwareShopBusinessLogic.OfficePackage.Implements;
using HardwareShopContracts.BindingModels; using HardwareShopContracts.BindingModels;
using HardwareShopContracts.SearchModels; using HardwareShopContracts.SearchModels;
using HardwareShopContracts.StoragesContracts; using HardwareShopContracts.StoragesContracts;
using HardwareShopContracts.ViewModels; using HardwareShopContracts.ViewModels;
using HardwareShopDatabaseImplement.Models.Worker;
namespace HardwareShopContracts.BusinessLogicsContracts namespace HardwareShopContracts.BusinessLogicsContracts
{ {
public class WorkerReportLogic : IWorkerReportLogic public class WorkerReportLogic : IWorkerReportLogic
{ {
private readonly IPurchaseStorage _purchaseStorage; private readonly IPurchaseStorage _purchaseStorage;
public WorkerReportLogic(IPurchaseStorage purchaseStorage) private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
public WorkerReportLogic(IPurchaseStorage purchaseStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord)
{ {
_purchaseStorage = purchaseStorage; _purchaseStorage = purchaseStorage;
} _saveToExcel = saveToExcel;
_saveToWord = saveToWord;
}
/// <summary> /// <summary>
/// Получение списка компонент с указанием, в каких покупках используются /// Получение списка компонент с указанием, в каких покупках используются
@ -25,9 +34,11 @@ namespace HardwareShopContracts.BusinessLogicsContracts
{ {
var list = new List<ReportPurchaseComponentViewModel>(); var list = new List<ReportPurchaseComponentViewModel>();
foreach (var purchase in purchaseList) foreach (var p in purchaseList)
{ {
var record = new ReportPurchaseComponentViewModel var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!;
var record = new ReportPurchaseComponentViewModel
{ {
Id = purchase.Id, Id = purchase.Id,
Builds = new List<(string Build, int count, List<(string Component, int count)>)>(), Builds = new List<(string Build, int count, List<(string Component, int count)>)>(),
@ -62,9 +73,10 @@ namespace HardwareShopContracts.BusinessLogicsContracts
var list = new List<ReportPurchaseViewModel>(); var list = new List<ReportPurchaseViewModel>();
var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = userModel.Id }); var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = userModel.Id });
foreach (var purchase in purchases) foreach (var p in purchases)
{ {
var record = new ReportPurchaseViewModel var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!;
var record = new ReportPurchaseViewModel
{ {
Id = purchase.Id, Id = purchase.Id,
Builds = new List<(string Build, int count, List<string>, List<(string Component, int count)>)>(), Builds = new List<(string Build, int count, List<string>, List<(string Component, int count)>)>(),
@ -89,23 +101,40 @@ namespace HardwareShopContracts.BusinessLogicsContracts
} }
/// <summary> /// <summary>
/// Сохранение компонент с указаеним покупок в файл-Word /// Сохранение компонент с указаеним покупок в файл-Word
/// </summary> /// </summary>
/// <param name="model"></param> /// <param name="model"></param>
public void SaveComponentsToWordFile(ReportBindingModel model) public byte[] SavePurchasesToWordFile(ReportBindingModel model, List<PurchaseViewModel> purchases)
{ {
throw new NotImplementedException(); _saveToWord.CreateBuildPurchaseReport(new WordInfo
} {
FileName = model.FileName,
Title = "Список Компонентов",
PurchaseComponent = GetPurchaseComponent(purchases)
});
/// <summary> byte[] file = File.ReadAllBytes(model.FileName);
/// Сохранение компонент с указаеним покупок в файл-Excel //File.Delete(model.FileName);
/// </summary> return file;
/// <param name="model"></param> }
public void SaveDishComponentToExcelFile(ReportBindingModel model)
{ /// <summary>
throw new NotImplementedException(); /// Сохранение компонент с указаеним покупок в файл-Excel
} /// </summary>
/// <param name="model"></param>
public byte[] SavePurchasesToExcelFile(ReportBindingModel model, List<PurchaseViewModel> purchases)
{
_saveToExcel.CreatePurchaseComponentReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список Компонентов",
PurchaseComponent = GetPurchaseComponent(purchases)
});
byte[] file = File.ReadAllBytes(model.FileName);
File.Delete(model.FileName);
return file;
}
/// <summary> /// <summary>
/// Сохранение отчёта по покупкам в файл-Pdf /// Сохранение отчёта по покупкам в файл-Pdf
@ -115,5 +144,5 @@ namespace HardwareShopContracts.BusinessLogicsContracts
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
} }

View File

@ -58,11 +58,90 @@ namespace HardwareShopBusinessLogic.OfficePackage
SaveExcel(info); SaveExcel(info);
} }
/// <summary> /// <summary>
/// Создание excel-файла /// Создание отчета по сборкам в выбранных товарах
/// </summary> /// </summary>
/// <param name="info"></param> /// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfo info); public void CreatePurchaseComponentReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "E1"
});
uint rowIndex = 2;
foreach (var bg in info.PurchaseComponent)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = bg.Id.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var build in bg.Builds)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = build.Build,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = build.count.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
foreach (var component in build.Item3)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "D",
RowIndex = rowIndex,
Text = component.Component,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "E",
RowIndex = rowIndex,
Text = component.count.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
}
rowIndex++;
}
SaveExcel(info);
}
/// <summary>
/// Создание excel-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfo info);
/// <summary> /// <summary>
/// Добавляем новую ячейку в лист /// Добавляем новую ячейку в лист

View File

@ -57,11 +57,86 @@ namespace HardwareShopBusinessLogic.OfficePackage
SaveWord(info); SaveWord(info);
} }
/// <summary> public void CreateBuildPurchaseReport(WordInfo info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24" }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
List<WordRow> rows = new List<WordRow>();
rows.Add(new WordRow
{
Rows = new List<(string, WordTextProperties)> {
("Покупки", new WordTextProperties { Size = "24", Bold = true }),
("Сборки", new WordTextProperties { Size = "24", Bold = true }),
("Количество", new WordTextProperties { Size = "24", Bold = true }),
("Компоненты", new WordTextProperties { Size = "24", Bold = true }),
("Количество", new WordTextProperties { Size = "24", Bold = true })
}
});
var reportRecords = info.PurchaseComponent;
foreach (var reportRecord in reportRecords)
{
rows.Add(new WordRow
{
Rows = new List<(string, WordTextProperties)>
{
(reportRecord.Id.ToString(), new WordTextProperties { }),
("", new WordTextProperties { }),
("", new WordTextProperties { }),
("", new WordTextProperties { }),
("", new WordTextProperties { })
}
});
for (int i = 0; i < reportRecord.Builds.Count; i++)
{
rows.Add(new WordRow
{
Rows = new List<(string, WordTextProperties)>
{
("", new WordTextProperties { }),
(reportRecord.Builds[i].Build, new WordTextProperties { }),
(reportRecord.Builds[i].count.ToString(), new WordTextProperties { }),
("", new WordTextProperties { }),
("", new WordTextProperties { })
}
});
for(int j = 0; j < reportRecord.Builds[i].Item3.Count; j++)
{
rows.Add(new WordRow
{
Rows = new List<(string, WordTextProperties)>
{
("", new WordTextProperties { }),
("", new WordTextProperties { }),
("", new WordTextProperties { }),
(reportRecord.Builds[i].Item3[j].Component, new WordTextProperties { }),
(reportRecord.Builds[i].Item3[j].count.ToString(), new WordTextProperties { })
}
});
}
}
}
CreateTable(rows);
SaveWord(info);
}
/// <summary>
/// Создание doc-файла /// Создание doc-файла
/// </summary> /// </summary>
/// <param name="info"></param> /// <param name="info"></param>
protected abstract void CreateWord(WordInfo info); protected abstract void CreateWord(WordInfo info);
/// <summary> /// <summary>
/// Создание таблицы /// Создание таблицы

View File

@ -9,5 +9,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
public string Title { get; set; } = string.Empty; public string Title { get; set; } = string.Empty;
public List<ReportBuildGoodViewModel> BuildGood { get; set; } = new(); public List<ReportBuildGoodViewModel> BuildGood { get; set; } = new();
}
public List<ReportPurchaseComponentViewModel> PurchaseComponent { get; set; } = new();
}
} }

View File

@ -9,5 +9,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
public string Title { get; set; } = string.Empty; public string Title { get; set; } = string.Empty;
public List<ReportBuildGoodViewModel> BuildGood { get; set; } = new(); public List<ReportBuildGoodViewModel> BuildGood { get; set; } = new();
}
public List<ReportPurchaseComponentViewModel> PurchaseComponent { get; set; } = new();
}
} }

View File

@ -111,7 +111,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.Implements
TableGrid tableGrid = new TableGrid(); TableGrid tableGrid = new TableGrid();
for (int j = 0; j < data[0].Rows.Count; ++j) for (int j = 0; j < data[0].Rows.Count; ++j)
{ {
tableGrid.AppendChild(new GridColumn() { Width = "3200" }); tableGrid.AppendChild(new GridColumn() { Width = "1600" });
} }
table.AppendChild(tableGrid); table.AppendChild(tableGrid);
for (int i = 0; i < data.Count; ++i) for (int i = 0; i < data.Count; ++i)

View File

@ -31,5 +31,11 @@ namespace HardwareShopContracts.BindingModels
get; get;
set; set;
} = new(); } = new();
public List<PurchaseViewModel> Purchases
{
get;
set;
} = new();
} }
} }

View File

@ -23,18 +23,18 @@ namespace HardwareShopContracts.BusinessLogicsContracts
/// Сохранение компонент с указаеним покупок в файл-Word /// Сохранение компонент с указаеним покупок в файл-Word
/// </summary> /// </summary>
/// <param name="model"></param> /// <param name="model"></param>
void SaveComponentsToWordFile(ReportBindingModel model); byte[] SavePurchasesToWordFile(ReportBindingModel model, List<PurchaseViewModel> purchases);
/// <summary> /// <summary>
/// Сохранение компонент с указаеним покупок в файл-Excel /// Сохранение компонент с указаеним покупок в файл-Excel
/// </summary> /// </summary>
/// <param name="model"></param> /// <param name="model"></param>
void SaveDishComponentToExcelFile(ReportBindingModel model); byte[] SavePurchasesToExcelFile(ReportBindingModel model, List<PurchaseViewModel> purchases);
/// <summary> /// <summary>
/// Сохранение отчёта по покупкам в файл-Pdf /// Сохранение отчёта по покупкам в файл-Pdf
/// </summary> /// </summary>
/// <param name="model"></param> /// <param name="model"></param>
void SaveOrdersToPdfFile(ReportBindingModel model); void SaveOrdersToPdfFile(ReportBindingModel model);
} }
} }

View File

@ -82,6 +82,8 @@ namespace HardwareShopDatabaseImplement.Implements.Worker
.ThenInclude(x => x.Good) .ThenInclude(x => x.Good)
.Include(x => x.Builds) .Include(x => x.Builds)
.ThenInclude(x => x.Build) .ThenInclude(x => x.Build)
.ThenInclude(x => x.Components)
.ThenInclude(x => x.Component)
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel; ?.GetViewModel;
} }

View File

@ -42,5 +42,31 @@ namespace HardwareShopRestApi.Controllers
throw; throw;
} }
} }
}
[HttpPost]
public void BuildPurchaseReport(PurchaseBindingModel model, string format, string filename)
{
try
{
switch (format)
{
case "doc":
_reportWorkerLogic.SavePurchasesToWordFile(new ReportBindingModel { FileName = filename }, model.Purchases);
break;
case "excel":
_reportWorkerLogic.SavePurchasesToExcelFile(new ReportBindingModel { FileName = filename }, model.Purchases);
break;
default:
throw new FormatException("Неправильный формат файла");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения списка сборок по выбранным товарам");
throw;
}
}
}
} }

View File

@ -289,11 +289,6 @@ namespace HardwareShopWorkerApp.Controllers
Response.Redirect("Comments"); Response.Redirect("Comments");
} }
public IActionResult listComponents()
{
return View();
}
[HttpGet] [HttpGet]
public IActionResult Purchases() public IActionResult Purchases()
{ {
@ -325,6 +320,50 @@ namespace HardwareShopWorkerApp.Controllers
return result; return result;
} }
[HttpGet]
public IActionResult ListComponents()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
ViewBag.Purchases = APIClient.GetRequest<List<PurchaseViewModel>>($"api/purchase/getpurchases?userId={APIClient.User.Id}");
return View();
}
[HttpPost]
public void ListComponents([FromBody] PurchaseBindingModel goodModel, [FromQuery] string format, [FromQuery] string filename)
{
if (APIClient.User == null)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(format))
{
throw new FormatException($"Неправильный формат файла: {format}");
}
if (string.IsNullOrEmpty(filename))
{
throw new FormatException($"Неправильное название файла: {filename}");
}
APIClient.PostRequest($"api/report/buildpurchasereport?format={format}&filename=${filename}", goodModel);
}
[HttpGet]
public GoodViewModel? GetPurchase(int Id)
{
if (APIClient.User == null)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
var result = APIClient.GetRequest<GoodViewModel?>($"api/purchase/getpurchase?purchaseId={Id}");
if (result == null)
{
return default;
}
return result;
}
[HttpGet] [HttpGet]
public IActionResult CreatePurchase() public IActionResult CreatePurchase()
{ {

View File

@ -1,65 +1,136 @@
@{ @using HardwareShopContracts.ViewModels
ViewData["Title"] = "ListComponents"; @{
ViewData["Title"] = "Получение списка";
Layout = "~/Views/Shared/_LayoutWorker.cshtml"; Layout = "~/Views/Shared/_LayoutWorker.cshtml";
} }
<form method="post" class="d-flex justify-content-evenly"> <div class="text-center">
<div class=" col-sm-8"> <h1 class="display-4">Получение списка покупок</h1>
<div class="text-center"> </div>
<h2 class="display-4">Покупки</h2>
</div>
<div class="text-center" name="id">
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Дата оплаты
</th>
<th>
Сумма
</th>
<th>
Статус
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="text-center d-flex flex-column mt-5">
<button type="button" class="btn btn-primary btn-lg mb-5" data-bs-toggle="modal" data-bs-target="#exampleModal">Добавить</button>
<button type="button" class="btn btn-primary btn-lg mb-5">Удалить</button>
<button type="button" class="btn btn-primary btn-lg mb-5">Обновить</button>
<button type="button" class="btn btn-primary btn-lg mb-5">Сохранить в doc формате</button>
<button type="button" class="btn btn-primary btn-lg mb-5">Сохранить в xls формате</button>
</div>
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="d-flex flex-column align-items-center">
<div class="modal-dialog"> <h1 class="display-6">Выбранные покупки</h1>
<div class="modal-content"> <div class="d-flex justify-content-center">
<div class="modal-header"> <button type="button" class="btn btn-primary mx-2 mt-3" data-bs-toggle="modal" data-bs-target="#exampleModal">Добавить покупку</button>
<h5 class="modal-title" id="exampleModalLabel">Покупка</h5> </div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button> <table class="table">
</div> <thead>
<div class="modal-body"> <tr>
<div> <th scope="col">Покупка</th>
<label class="form-label">Покупка</label> <th scope="col">Действия</th>
<select class="form-select"> </tr>
<option value="1">Покупка 1</option> </thead>
<option value="2">Покупка 2</option> <tbody id="result">
</select> </tbody>
</div> </table>
</div> <div class="col-sm-3">
<div class="modal-footer"> <label class="form-label">Название файла</label>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button> <input type="text" class="form-control" name="filename" id="filename">
<button type="button" class="btn btn-primary">Добавить</button> </div>
</div> <div class="col d-flex justify-content-evenly align-items-baseline">
<button type="button" class="btn btn-primary btn-lg m-2" id="savedoc">Сохранить в doc-формате</button>
<button type="button" class="btn btn-primary btn-lg m-2" id="saveexcel">Сохранить в xls-формате</button>
</div>
</div>
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Покупка</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
<label class="form-label">Покупка</label>
<select id="purchase" name="purchase" class="form-control" asp-items="@(new SelectList(@ViewBag.Purchases, "Id", "Id"))"></select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="savepurchase">Сохранить</button>
</div> </div>
</div> </div>
</div> </div>
</form> </div>
@section Scripts
{
<script>
let list = [];
const submitPurchaseBtn = document.getElementById("savepurchase");
const resultTable = document.getElementById("result");
const saveDocBtn = document.getElementById("savedoc");
const saveExcelBtn = document.getElementById("saveexcel");
const filename = document.getElementById("filename");
submitPurchaseBtn.addEventListener("click", () => {
console.log('try to add purchase')
var purchase = $('#purchase').val();
if (purchase)
$.ajax({
method: "GET",
url: `/Home/GetPurchase`,
data: { Id: purchase },
success: function (result) {
let flag = false
if (list.length > 0) {
list.forEach((elem) => {
if (elem.id === parseInt(result.id)) {
console.log('purchase already added')
flag = true
}
})
}
if (!flag) list.push(result)
reloadTable()
}
}).fail(function(xhr, textStatus, errorThrown) {
alert(xhr.responseText);
})
})
saveDocBtn.addEventListener("click", async () => {
send('doc')
})
saveExcelBtn.addEventListener("click", async () => {
send('excel')
})
function send(format) {
console.log(`try to save in ${format} format`)
if (list.length == 0 || !filename.value || filename.value == '') {
alert('operation failed. purchases or filename are empty')
return
}
$.ajax({
url: `/Home/ListComponents?format=${format}&filename=${filename.value}`,
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ "Purchases" : list })
}).done(() => {
//let byteArray = new Uint8Array(file);
})
.fail(function(xhr, textStatus, errorThrown) {
alert(xhr.responseText);
})
}
function reloadTable() {
resultTable.innerHTML = ''
let count = 0;
list.forEach((elem) => {
resultTable.innerHTML += `<tr><td>${elem.id}</td><td> \
<div> \
<button onclick="deletePurchase(${count})" type="button" class="btn btn-danger"> \
<i class="fa fa-trash" aria-hidden="true"></i> \
</button> \
</div></td></tr>`
count++;
})
}
function deletePurchase(id) {
list = list.filter(value => value.id != resultTable.rows[id].cells[0].innerText)
reloadTable()
}
</script>
}