merge
This commit is contained in:
commit
9c61562368
@ -75,7 +75,7 @@ namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
model.PurchaseStatus = PurchaseStatus.Выдан;
|
||||
model.DatePurchase = DateTime.Now;
|
||||
CheckModel(model, false);
|
||||
if (_purchaseStorage.Update(model) == null)
|
||||
if (_purchaseStorage.Update(model, false) == null)
|
||||
{
|
||||
_logger.LogWarning("Change status operation failed");
|
||||
return false;
|
||||
|
@ -1,8 +1,15 @@
|
||||
|
||||
using HardwareShopBusinessLogic.MailWorker;
|
||||
using HardwareShopBusinessLogic.OfficePackage;
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperModels;
|
||||
using HardwareShopBusinessLogic.OfficePackage.Implements;
|
||||
using HardwareShopContracts.BindingModels;
|
||||
using HardwareShopContracts.SearchModels;
|
||||
using HardwareShopContracts.StoragesContracts;
|
||||
using HardwareShopContracts.ViewModels;
|
||||
using HardwareShopDatabaseImplement.Implements.Worker;
|
||||
using HardwareShopDatabaseImplement.Models.Worker;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
||||
namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
{
|
||||
@ -11,10 +18,21 @@ namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
|
||||
private readonly IPurchaseStorage _purchaseStorage;
|
||||
|
||||
public WorkerReportLogic(IPurchaseStorage purchaseStorage)
|
||||
{
|
||||
private readonly AbstractSaveToExcel _saveToExcel;
|
||||
|
||||
private readonly AbstractSaveToWord _saveToWord;
|
||||
|
||||
private readonly AbstractSaveToPdf _saveToPdf;
|
||||
|
||||
private readonly AbstractMailWorker _mailKitWorker;
|
||||
|
||||
public WorkerReportLogic(IPurchaseStorage purchaseStorage, AbstractMailWorker mailKitWorker, AbstractSaveToPdf saveToPdf, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord)
|
||||
{
|
||||
_purchaseStorage = purchaseStorage;
|
||||
_saveToExcel = saveToExcel;
|
||||
_saveToWord = saveToWord;
|
||||
_saveToPdf = saveToPdf;
|
||||
_mailKitWorker = mailKitWorker;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -25,8 +43,10 @@ namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
{
|
||||
var list = new List<ReportPurchaseComponentViewModel>();
|
||||
|
||||
foreach (var purchase in purchaseList)
|
||||
foreach (var p in purchaseList)
|
||||
{
|
||||
var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!;
|
||||
|
||||
var record = new ReportPurchaseComponentViewModel
|
||||
{
|
||||
Id = purchase.Id,
|
||||
@ -57,32 +77,34 @@ namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public List<ReportPurchaseViewModel> GetPurchase(ReportBindingModel model, UserBindingModel userModel)
|
||||
public List<ReportPurchaseViewModel> GetPurchase(ReportBindingModel model)
|
||||
{
|
||||
var list = new List<ReportPurchaseViewModel>();
|
||||
var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = userModel.Id });
|
||||
|
||||
foreach (var purchase in purchases)
|
||||
var purchases = _purchaseStorage.GetFilteredList(new PurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo, UserId = model.UserId });
|
||||
foreach (var p in purchases)
|
||||
{
|
||||
var record = new ReportPurchaseViewModel
|
||||
{
|
||||
Id = purchase.Id,
|
||||
Builds = new List<(string Build, int count, List<string>, List<(string Component, int count)>)>(),
|
||||
};
|
||||
var purchase = _purchaseStorage.GetElement(new() { Id = p.Id })!;
|
||||
List<string> commentList = new List<string>();
|
||||
List<string> componentList = new List<string>();
|
||||
foreach (var build in purchase.PurchaseBuilds)
|
||||
{
|
||||
List<string> commentList = new List<string>();
|
||||
foreach (var comment in build.Value.Item1.BuildComments)
|
||||
{
|
||||
commentList.Add(new(comment.Value.Text));
|
||||
}
|
||||
List<(string Component, int count)> componentList = new List<(string Component, int count)>();
|
||||
foreach (var component in build.Value.Item1.BuildComponents)
|
||||
{
|
||||
componentList.Add(new(component.Value.Item1.ComponentName, component.Value.Item2));
|
||||
componentList.Add(component.Value.Item1.ComponentName);
|
||||
}
|
||||
record.Builds.Add(new(build.Value.Item1.BuildName, build.Value.Item2, commentList, componentList));
|
||||
}
|
||||
var record = new ReportPurchaseViewModel
|
||||
{
|
||||
Id = purchase.Id,
|
||||
PurchaseDate = (DateTime)p.DatePurchase,
|
||||
PurchaseSum = p.Sum,
|
||||
Comments = commentList,
|
||||
Components = componentList.Distinct().ToList()
|
||||
};
|
||||
list.Add(record);
|
||||
}
|
||||
return list;
|
||||
@ -93,27 +115,59 @@ namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
/// Сохранение компонент с указаеним покупок в файл-Word
|
||||
/// </summary>
|
||||
/// <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)
|
||||
});
|
||||
|
||||
byte[] file = File.ReadAllBytes(model.FileName);
|
||||
File.Delete(model.FileName);
|
||||
return file;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение компонент с указаеним покупок в файл-Excel
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void SaveDishComponentToExcelFile(ReportBindingModel model)
|
||||
public byte[] SavePurchasesToExcelFile(ReportBindingModel model, List<PurchaseViewModel> purchases)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_saveToExcel.CreatePurchaseComponentReport(new ExcelInfo
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Список Компонентов",
|
||||
PurchaseComponent = GetPurchaseComponent(purchases)
|
||||
});
|
||||
byte[] file = File.ReadAllBytes(model.FileName);
|
||||
File.Delete(model.FileName);
|
||||
return file;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение отчёта по покупкам в файл-Pdf
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public void SaveOrdersToPdfFile(ReportBindingModel model)
|
||||
public void SendByMailPurchaseReport(ReportBindingModel model)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
byte[] file = _saveToPdf.GetPurchaseReportFile(new()
|
||||
{
|
||||
FileName = model.FileName,
|
||||
Title = "Отчет по покупкам",
|
||||
DateFrom = model.DateFrom,
|
||||
DateTo = model.DateTo,
|
||||
ReportPurchases = GetPurchase(model)
|
||||
});
|
||||
_mailKitWorker.MailSendAsync(new()
|
||||
{
|
||||
MailAddress = model.UserEmail,
|
||||
Subject = "Отчет по покупкам",
|
||||
Text = $"За период с {model.DateFrom.ToShortDateString()} " +
|
||||
$"по {model.DateTo.ToShortDateString()}.",
|
||||
File = file
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
|
||||
<PackageReference Include="MailKit" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -25,6 +25,8 @@ namespace HardwareShopBusinessLogic.MailWorker
|
||||
objMailMessage.Body = info.Text;
|
||||
objMailMessage.SubjectEncoding = Encoding.UTF8;
|
||||
objMailMessage.BodyEncoding = Encoding.UTF8;
|
||||
MemoryStream ms = new(info.File);
|
||||
objMailMessage.Attachments.Add(new Attachment(ms, "report.pdf", "application/pdf"));
|
||||
|
||||
objSmtpClient.UseDefaultCredentials = false;
|
||||
objSmtpClient.EnableSsl = true;
|
||||
|
@ -56,6 +56,85 @@ namespace HardwareShopBusinessLogic.OfficePackage
|
||||
SaveExcel(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создание отчета по сборкам в выбранных товарах
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
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>
|
||||
|
@ -0,0 +1,119 @@
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperEnums;
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperModels;
|
||||
using MigraDoc.Rendering;
|
||||
|
||||
namespace HardwareShopBusinessLogic.OfficePackage
|
||||
{
|
||||
public abstract class AbstractSaveToPdf
|
||||
{
|
||||
public byte[] GetPurchaseReportFile(PdfInfo 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> { "5cm", "5cm", "5cm", "5cm", "5cm" });
|
||||
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = new List<string> { "Покупка", "Дата покупки", "Цена", "Комментарии", "Комплектующие" },
|
||||
Style = "NormalTitle",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Center
|
||||
});
|
||||
|
||||
foreach (var record in info.ReportPurchases)
|
||||
{
|
||||
List<string> comments = record.Comments;
|
||||
List<string> components = record.Components;
|
||||
int recordHeight = Math.Max(comments.Count + 1, components.Count + 1);
|
||||
for (int i = 0; i < recordHeight; i++)
|
||||
{
|
||||
List<string> cellsData = new() { "", "", "", "", "" };
|
||||
if (i == 0)
|
||||
{
|
||||
cellsData[0] = record.Id.ToString();
|
||||
cellsData[1] = record.PurchaseDate.ToShortDateString();
|
||||
cellsData[2] = record.PurchaseSum.ToString("0.00") + " р.";
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = cellsData,
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Left
|
||||
});
|
||||
continue;
|
||||
}
|
||||
int k = i - 1;
|
||||
if (k < comments.Count)
|
||||
{
|
||||
cellsData[3] = comments[k];
|
||||
}
|
||||
if (k < components.Count)
|
||||
{
|
||||
cellsData[4] = components[k];
|
||||
}
|
||||
CreateRow(new PdfRowParameters
|
||||
{
|
||||
Texts = cellsData,
|
||||
Style = "Normal",
|
||||
ParagraphAlignment = PdfParagraphAlignmentType.Left
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return GetFile(info);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Создание doc-файла
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
protected abstract void CreatePdf(PdfInfo 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(PdfInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение отправляем файл
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
protected abstract byte[] GetFile(PdfInfo info);
|
||||
}
|
||||
}
|
@ -57,6 +57,81 @@ namespace HardwareShopBusinessLogic.OfficePackage
|
||||
SaveWord(info);
|
||||
}
|
||||
|
||||
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-файла
|
||||
/// </summary>
|
||||
|
@ -0,0 +1,11 @@
|
||||
namespace HardwareShopBusinessLogic.OfficePackage.HelperEnums
|
||||
{
|
||||
public enum PdfParagraphAlignmentType
|
||||
{
|
||||
Center,
|
||||
|
||||
Left,
|
||||
|
||||
Rigth
|
||||
}
|
||||
}
|
@ -9,5 +9,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
public List<ReportBuildGoodViewModel> BuildGood { get; set; } = new();
|
||||
|
||||
public List<ReportPurchaseComponentViewModel> PurchaseComponent { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
|
||||
using HardwareShopContracts.ViewModels;
|
||||
|
||||
namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
|
||||
{
|
||||
public class PdfInfo
|
||||
{
|
||||
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<ReportComponentsViewModel> ReportComponents { get; set; } = new();
|
||||
|
||||
public List<ReportPurchaseViewModel> ReportPurchases { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperEnums;
|
||||
|
||||
namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
|
||||
{
|
||||
public class PdfParagraph
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public string Style { get; set; } = string.Empty;
|
||||
|
||||
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperEnums;
|
||||
|
||||
namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
|
||||
{
|
||||
public class PdfRowParameters
|
||||
{
|
||||
public List<string> Texts { get; set; } = new();
|
||||
|
||||
public string Style { get; set; } = string.Empty;
|
||||
|
||||
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
|
||||
}
|
||||
}
|
@ -9,5 +9,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.HelperModels
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
public List<ReportBuildGoodViewModel> BuildGood { get; set; } = new();
|
||||
|
||||
public List<ReportPurchaseComponentViewModel> PurchaseComponent { get; set; } = new();
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperEnums;
|
||||
using HardwareShopBusinessLogic.OfficePackage.HelperModels;
|
||||
using MigraDoc.DocumentObjectModel;
|
||||
using MigraDoc.DocumentObjectModel.Tables;
|
||||
using MigraDoc.Rendering;
|
||||
|
||||
namespace HardwareShopBusinessLogic.OfficePackage.Implements
|
||||
{
|
||||
public class SaveToPdf : AbstractSaveToPdf
|
||||
{
|
||||
private Document? _document;
|
||||
|
||||
private Section? _section;
|
||||
|
||||
private Table? _table;
|
||||
|
||||
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
|
||||
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
|
||||
PdfParagraphAlignmentType.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(PdfInfo 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(PdfInfo info)
|
||||
{
|
||||
var renderer = new PdfDocumentRenderer(true)
|
||||
{
|
||||
Document = _document
|
||||
};
|
||||
renderer.RenderDocument();
|
||||
renderer.PdfDocument.Save(info.FileName);
|
||||
}
|
||||
|
||||
protected override byte[] GetFile(PdfInfo info)
|
||||
{
|
||||
SavePdf(info);
|
||||
byte[] file = File.ReadAllBytes(info.FileName);
|
||||
File.Delete(info.FileName);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
@ -111,7 +111,7 @@ namespace HardwareShopBusinessLogic.OfficePackage.Implements
|
||||
TableGrid tableGrid = new TableGrid();
|
||||
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);
|
||||
for (int i = 0; i < data.Count; ++i)
|
||||
|
@ -7,5 +7,7 @@
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
public byte[] File { get; set; } = Array.Empty<byte>();
|
||||
}
|
||||
}
|
@ -31,5 +31,11 @@ namespace HardwareShopContracts.BindingModels
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
|
||||
public List<PurchaseViewModel> Purchases
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = new();
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,14 @@
|
||||
{
|
||||
public class ReportBindingModel
|
||||
{
|
||||
public string UserEmail { get; set; } = string.Empty;
|
||||
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
|
||||
public DateTime DateFrom { get; set; }
|
||||
|
||||
public DateTime DateTo { get; set; }
|
||||
|
||||
public int UserId { get; set; }
|
||||
|
||||
public DateTime? DateFrom { get; set; }
|
||||
|
||||
public DateTime? DateTo { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -17,24 +17,24 @@ namespace HardwareShopContracts.BusinessLogicsContracts
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
List<ReportPurchaseViewModel> GetPurchase(ReportBindingModel model, UserBindingModel userModel);
|
||||
List<ReportPurchaseViewModel> GetPurchase(ReportBindingModel model);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение компонент с указаеним покупок в файл-Word
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveComponentsToWordFile(ReportBindingModel model);
|
||||
byte[] SavePurchasesToWordFile(ReportBindingModel model, List<PurchaseViewModel> purchases);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение компонент с указаеним покупок в файл-Excel
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveDishComponentToExcelFile(ReportBindingModel model);
|
||||
byte[] SavePurchasesToExcelFile(ReportBindingModel model, List<PurchaseViewModel> purchases);
|
||||
|
||||
/// <summary>
|
||||
/// Сохранение отчёта по покупкам в файл-Pdf
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SaveOrdersToPdfFile(ReportBindingModel model);
|
||||
void SendByMailPurchaseReport(ReportBindingModel model);
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
|
||||
public int? PurchaseId { get; set; }
|
||||
|
||||
public string? BuildName { get; set; } = string.Empty;
|
||||
|
||||
public int? UserId { get; set; }
|
||||
|
@ -11,7 +11,7 @@ namespace HardwareShopContracts.StoragesContracts
|
||||
List<PurchaseViewModel> GetReportFilteredList(PurchaseSearchModel model);
|
||||
PurchaseViewModel? GetElement(PurchaseSearchModel model);
|
||||
PurchaseViewModel? Insert(PurchaseBindingModel model);
|
||||
PurchaseViewModel? Update(PurchaseBindingModel model);
|
||||
PurchaseViewModel? Update(PurchaseBindingModel model, bool withParams = true);
|
||||
PurchaseViewModel? Delete(PurchaseBindingModel model);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,12 @@
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public List<(string Build, int count, List<string>, List<(string Component, int count)>)> Builds { get; set; } = new();
|
||||
public DateTime PurchaseDate { get; set; }
|
||||
|
||||
public double PurchaseSum { get; set; }
|
||||
|
||||
public List<string> Comments { get; set; } = new();
|
||||
|
||||
public List<string> Components { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -53,12 +53,14 @@ namespace HardwareShopDatabaseImplement.Implements.Worker
|
||||
return null;
|
||||
}
|
||||
using var context = new HardwareShopDatabase();
|
||||
return context.Builds
|
||||
var dadada = context.Builds
|
||||
.Include(x => x.Purchases)
|
||||
.ThenInclude(x => x.Purchase)
|
||||
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.BuildName) && x.BuildName == model.BuildName) ||
|
||||
(model.Id.HasValue && x.Id == model.Id))
|
||||
?.GetViewModel;
|
||||
return dadada;
|
||||
|
||||
}
|
||||
|
||||
public BuildViewModel? Insert(BuildBindingModel model)
|
||||
|
@ -80,6 +80,13 @@ namespace HardwareShopDatabaseImplement.Implements.Worker
|
||||
return context.Purchases
|
||||
.Include(x => x.Goods)
|
||||
.ThenInclude(x => x.Good)
|
||||
.Include(x => x.Builds)
|
||||
.ThenInclude(x => x.Build)
|
||||
.ThenInclude(x => x.Components)
|
||||
.ThenInclude(x => x.Component)
|
||||
.Include(x => x.Builds)
|
||||
.ThenInclude(x => x.Build)
|
||||
.ThenInclude(x => x.Comments)
|
||||
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
|
||||
?.GetViewModel;
|
||||
}
|
||||
@ -101,7 +108,7 @@ namespace HardwareShopDatabaseImplement.Implements.Worker
|
||||
?.GetViewModel;
|
||||
}
|
||||
|
||||
public PurchaseViewModel? Update(PurchaseBindingModel model)
|
||||
public PurchaseViewModel? Update(PurchaseBindingModel model, bool withParams = true)
|
||||
{
|
||||
using var context = new HardwareShopDatabase();
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
@ -117,6 +124,10 @@ namespace HardwareShopDatabaseImplement.Implements.Worker
|
||||
}
|
||||
purchase.Update(model);
|
||||
context.SaveChanges();
|
||||
if (!withParams) {
|
||||
transaction.Commit();
|
||||
return purchase.GetViewModel;
|
||||
}
|
||||
purchase.UpdateGoods(context, model);
|
||||
transaction.Commit();
|
||||
return purchase.GetViewModel;
|
||||
|
@ -3,7 +3,10 @@ using HardwareShopContracts.BindingModels;
|
||||
using HardwareShopContracts.BusinessLogicsContracts;
|
||||
using HardwareShopContracts.SearchModels;
|
||||
using HardwareShopContracts.ViewModels;
|
||||
using HardwareShopDatabaseImplement.Models.ManyToMany;
|
||||
using HardwareShopDatabaseImplement.Models.Storekeeper;
|
||||
using HardwareShopDatabaseImplement.Models.Worker;
|
||||
using HardwareShopDataModels.Enums;
|
||||
using HardwareShopDataModels.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel;
|
||||
@ -16,11 +19,14 @@ namespace HardwareShopRestApi.Controllers
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IBuildLogic _buildLogic;
|
||||
private readonly IPurchaseLogic _purchaseLogic;
|
||||
|
||||
public BuildController(IBuildLogic buildLogic, ILogger<UserController> logger)
|
||||
public BuildController(IBuildLogic buildLogic, IPurchaseLogic purchaseLogic, ILogger<UserController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_buildLogic = buildLogic;
|
||||
_purchaseLogic = purchaseLogic;
|
||||
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@ -56,6 +62,32 @@ namespace HardwareShopRestApi.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<Tuple<PurchaseViewModel, int>>? GetBuildPurchase(int buildId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _buildLogic.ReadElement(new() { Id = buildId });
|
||||
List<Tuple<PurchaseViewModel, int>> listPurchase = new List<Tuple<PurchaseViewModel, int>>();
|
||||
foreach (var item in result.BuildPurchases)
|
||||
{
|
||||
listPurchase.Add(Tuple.Create(new PurchaseViewModel
|
||||
{
|
||||
Id = item.Value.Item1.Id,
|
||||
Sum = item.Value.Item1.Sum,
|
||||
PurchaseStatus = item.Value.Item1.PurchaseStatus,
|
||||
}, item.Value.Item2));
|
||||
}
|
||||
return listPurchase;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка сборки");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Create(BuildBindingModel model)
|
||||
{
|
||||
@ -70,6 +102,7 @@ namespace HardwareShopRestApi.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public void Update(BuildBindingModel model)
|
||||
{
|
||||
@ -84,6 +117,137 @@ namespace HardwareShopRestApi.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public bool LinkPurchase(int buildId, int purchaseId, int count)
|
||||
{
|
||||
try
|
||||
{
|
||||
var build = GetBuild(buildId);//APIClient.GetRequest<BuildViewModel>($"api/build/getBuild?buildId={buildId}");
|
||||
var purchase = _purchaseLogic.ReadElement(new() { Id = purchaseId });
|
||||
if (purchase.PurchaseStatus == PurchaseStatus.Выдан) return false;
|
||||
if (build.BuildPurchases.ContainsKey(purchaseId))
|
||||
{
|
||||
|
||||
build.BuildPurchases[purchaseId] = (purchase, build.BuildPurchases[purchaseId].Item2 + count);
|
||||
}
|
||||
else
|
||||
{
|
||||
build.BuildPurchases.Add(purchaseId, (purchase as IPurchaseModel, count));
|
||||
}
|
||||
Update(new BuildBindingModel
|
||||
{
|
||||
Id = buildId,
|
||||
Price = build.Price,
|
||||
BuildName = build.BuildName,
|
||||
BuildPurchases = build.BuildPurchases
|
||||
});
|
||||
purchase.Sum = Calc(purchase.Id);
|
||||
_purchaseLogic.Update(new PurchaseBindingModel
|
||||
{
|
||||
Id = purchase.Id,
|
||||
Sum = purchase.Sum,
|
||||
PurchaseStatus = purchase.PurchaseStatus,
|
||||
PurchaseGoods = purchase.PurchaseGoods,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка обновления данных");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
private double Calc(int purchaseId)
|
||||
{
|
||||
var purchase = _purchaseLogic.ReadElement(new() { Id = purchaseId });
|
||||
double price = 0;
|
||||
foreach (var elem in purchase.PurchaseBuilds)
|
||||
{
|
||||
price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2);
|
||||
}
|
||||
foreach (var elem in purchase.PurchaseGoods)
|
||||
{
|
||||
price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2);
|
||||
}
|
||||
return Math.Round(price * 1.1, 2);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public bool DeleteLinkPurchase(int deleteBuildId, int deletePurchaseId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var build = GetBuild(deleteBuildId);//APIClient.GetRequest<BuildViewModel>($"api/build/getBuild?buildId={buildId}");
|
||||
var purchase = _purchaseLogic.ReadElement(new() { Id = deletePurchaseId });
|
||||
if (purchase.PurchaseStatus == PurchaseStatus.Выдан) return false;
|
||||
build.BuildPurchases.Remove(deletePurchaseId);//Add(purchaseId, (purchase as IPurchaseModel, count));
|
||||
|
||||
Update(new BuildBindingModel
|
||||
{
|
||||
Id = deleteBuildId,
|
||||
Price = build.Price,
|
||||
BuildName = build.BuildName,
|
||||
BuildPurchases = build.BuildPurchases
|
||||
});
|
||||
purchase.Sum = Calc(purchase.Id);
|
||||
_purchaseLogic.Update(new PurchaseBindingModel
|
||||
{
|
||||
Id = purchase.Id,
|
||||
Sum = purchase.Sum,
|
||||
PurchaseStatus = purchase.PurchaseStatus,
|
||||
DatePurchase = purchase.DatePurchase,
|
||||
PurchaseGoods = purchase.PurchaseGoods,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка обновления данных");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public bool UpdateLinkPurchase(int updateBuildId, int updatePurchaseId, int count)
|
||||
{
|
||||
try
|
||||
{
|
||||
var build = GetBuild(updateBuildId);//APIClient.GetRequest<BuildViewModel>($"api/build/getBuild?buildId={buildId}");
|
||||
var purchase = _purchaseLogic.ReadElement(new() { Id = updatePurchaseId });
|
||||
if (purchase.PurchaseStatus == PurchaseStatus.Выдан) return false;
|
||||
if (build.BuildPurchases.ContainsKey(updatePurchaseId))
|
||||
{
|
||||
build.BuildPurchases[updatePurchaseId] = (build.BuildPurchases[updatePurchaseId].Item1, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Update(new BuildBindingModel
|
||||
{
|
||||
Id = updateBuildId,
|
||||
Price = build.Price,
|
||||
BuildName = build.BuildName,
|
||||
BuildPurchases = build.BuildPurchases
|
||||
});
|
||||
purchase.Sum = Calc(purchase.Id);
|
||||
_purchaseLogic.Update(new PurchaseBindingModel
|
||||
{
|
||||
Id = purchase.Id,
|
||||
Sum = purchase.Sum,
|
||||
PurchaseStatus = purchase.PurchaseStatus,
|
||||
DatePurchase = purchase.DatePurchase,
|
||||
PurchaseGoods = purchase.PurchaseGoods,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка обновления данных");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void DeleteBuild(BuildBindingModel model)
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using HardwareShopContracts.BusinessLogicsContracts;
|
||||
using HardwareShopContracts.SearchModels;
|
||||
using HardwareShopContracts.ViewModels;
|
||||
using HardwareShopDatabaseImplement.Models.Storekeeper;
|
||||
using HardwareShopDataModels.Enums;
|
||||
using HardwareShopDataModels.Models;
|
||||
using HardwareShopRestApi.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -24,6 +25,30 @@ namespace HardwareShopRestApi.Controllers
|
||||
_purchaseLogic = purchaseLogic;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public Tuple<PurchaseViewModel, List<Tuple<GoodViewModel, int>>>? GetPurchaseUpdate(int purchaseId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var purchase = _purchaseLogic.ReadElement(new() { Id = purchaseId });
|
||||
if (purchase == null)
|
||||
return null;
|
||||
var tuple = Tuple.Create(purchase,
|
||||
purchase.PurchaseGoods.Select(x => Tuple.Create(new GoodViewModel
|
||||
{
|
||||
Id = x.Value.Item1.Id,
|
||||
GoodName = x.Value.Item1.GoodName,
|
||||
Price = x.Value.Item1.Price
|
||||
}, x.Value.Item2)).ToList());
|
||||
return tuple;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка получения покупки");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<PurchaseViewModel>? GetPurchases(int userId)
|
||||
{
|
||||
@ -39,11 +64,11 @@ namespace HardwareShopRestApi.Controllers
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public PurchaseViewModel? GetPurchase(int id)
|
||||
public PurchaseViewModel? GetPurchase(int purchaseId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _purchaseLogic.ReadElement(new() { Id = id });
|
||||
return _purchaseLogic.ReadElement(new() { Id = purchaseId });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -59,8 +84,7 @@ namespace HardwareShopRestApi.Controllers
|
||||
{
|
||||
for (int i = 0; i < model.PurchaseGoodsCounts.Count; i++)
|
||||
{
|
||||
model.PurchaseGoods.Add(model.ListPurchaseGoods[i].Id,
|
||||
(model.ListPurchaseGoods[i] as IGoodModel, model.PurchaseGoodsCounts[i]));
|
||||
model.PurchaseGoods.Add(model.ListPurchaseGoods[i].Id,(model.ListPurchaseGoods[i] as IGoodModel, model.PurchaseGoodsCounts[i]));
|
||||
}
|
||||
_purchaseLogic.Create(model);
|
||||
}
|
||||
@ -72,10 +96,34 @@ namespace HardwareShopRestApi.Controllers
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void UpdatePurchase(PurchaseBindingModel model)
|
||||
public void UpdateStatusPurchase(PurchaseBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var oldModel = _purchaseLogic.ReadElement(new() {
|
||||
Id = model.Id,
|
||||
});
|
||||
model.Sum = oldModel.Sum;
|
||||
_purchaseLogic.DeliveryPurchase(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка обновления данных товара");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void Update(PurchaseBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < model.PurchaseGoodsCounts.Count; i++)
|
||||
{
|
||||
model.PurchaseGoods.Add(model.ListPurchaseGoods[i].Id, (model.ListPurchaseGoods[i] as IGoodModel, model.PurchaseGoodsCounts[i]));
|
||||
}
|
||||
model.PurchaseBuilds = _purchaseLogic.ReadElement(new() { Id = model.Id }).PurchaseBuilds;
|
||||
model.Sum = Calc(model);
|
||||
_purchaseLogic.Update(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -85,6 +133,20 @@ namespace HardwareShopRestApi.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
private double Calc(PurchaseBindingModel purchase)
|
||||
{
|
||||
double price = 0;
|
||||
foreach (var elem in purchase.PurchaseBuilds)
|
||||
{
|
||||
price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2);
|
||||
}
|
||||
foreach (var elem in purchase.PurchaseGoods)
|
||||
{
|
||||
price += ((elem.Value.Item1?.Price ?? 0) * elem.Value.Item2);
|
||||
}
|
||||
return Math.Round(price * 1.1, 2);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void DeletePurchase(PurchaseBindingModel model)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using HardwareShopContracts.BindingModels;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using HardwareShopContracts.BindingModels;
|
||||
using HardwareShopContracts.BusinessLogicsContracts;
|
||||
using HardwareShopContracts.ViewModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -75,5 +76,55 @@ namespace HardwareShopRestApi.Controllers
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public byte[] BuildPurchaseReport(PurchaseBindingModel model, string format)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] file;
|
||||
switch (format)
|
||||
{
|
||||
case "docx":
|
||||
file = _reportWorkerLogic.SavePurchasesToWordFile(new ReportBindingModel { FileName = "temp.docx" }, model.Purchases);
|
||||
break;
|
||||
case "xlsx":
|
||||
file = _reportWorkerLogic.SavePurchasesToExcelFile(new ReportBindingModel { FileName = "temp.xlsx" }, model.Purchases);
|
||||
break;
|
||||
default:
|
||||
throw new FormatException("Неправильный формат файла");
|
||||
}
|
||||
return file;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка сохранения списка сборок по выбранным товарам");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public List<ReportPurchaseViewModel>? GetPurchaseReportData(ReportBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var report = _reportWorkerLogic.GetPurchase(model);
|
||||
return report;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Ошибка получения данных для отчёта");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void SendByMailPurchaseReport(ReportBindingModel reportModel)
|
||||
{
|
||||
_reportWorkerLogic.SendByMailPurchaseReport(reportModel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ builder.Services.AddTransient<IWorkerReportLogic, WorkerReportLogic>();
|
||||
builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>();
|
||||
builder.Services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
|
||||
|
||||
builder.Services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
|
||||
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
@ -46,5 +46,23 @@ namespace HardwareShopWorkerApp
|
||||
throw new Exception(result);
|
||||
}
|
||||
}
|
||||
|
||||
public static R? PostRequestWithResult<T, R>(string requestUrl, T model)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(model);
|
||||
var data = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = _client.PostAsync(requestUrl, data);
|
||||
|
||||
var result = response.Result.Content.ReadAsStringAsync().Result;
|
||||
if (response.Result.IsSuccessStatusCode)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<R>(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,15 @@
|
||||
using HardwareShopContracts.SearchModels;
|
||||
using HardwareShopContracts.ViewModels;
|
||||
using HardwareShopDatabaseImplement.Models;
|
||||
using HardwareShopDatabaseImplement.Models.ManyToMany;
|
||||
using HardwareShopDatabaseImplement.Models.Storekeeper;
|
||||
using HardwareShopDatabaseImplement.Models.Worker;
|
||||
using HardwareShopDataModels.Enums;
|
||||
using HardwareShopDataModels.Models;
|
||||
using HardwareShopWorkerApp.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipelines;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace HardwareShopWorkerApp.Controllers
|
||||
@ -143,6 +148,28 @@ namespace HardwareShopWorkerApp.Controllers
|
||||
Response.Redirect("Builds");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public void LinkBuildPurchase(int buildId, int purchaseId, int count)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
|
||||
}
|
||||
if (buildId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0");
|
||||
}
|
||||
if (purchaseId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор покупки не может быть ниже или равен 0");
|
||||
}
|
||||
if (count <= 0)
|
||||
{
|
||||
throw new Exception($"Количество сборок в покупке не может быть ниже или равен 0");
|
||||
}
|
||||
APIClient.GetRequest<bool>($"api/build/linkPurchase?buildId={buildId}&purchaseId={purchaseId}&count={count}");
|
||||
Response.Redirect($"LinkPurchase?buildId={buildId}");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void DeleteBuild(int deleteBuildId)
|
||||
@ -262,11 +289,6 @@ namespace HardwareShopWorkerApp.Controllers
|
||||
Response.Redirect("Comments");
|
||||
}
|
||||
|
||||
public IActionResult listComponents()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Purchases()
|
||||
{
|
||||
@ -298,6 +320,49 @@ namespace HardwareShopWorkerApp.Controllers
|
||||
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 int[]? ListComponents([FromBody] PurchaseBindingModel purchaseModel, [FromQuery] string format)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
if (string.IsNullOrEmpty(format))
|
||||
{
|
||||
throw new FormatException($"Неправильный формат файла: {format}");
|
||||
}
|
||||
byte[]? file = APIClient.PostRequestWithResult<PurchaseBindingModel, byte[]>($"api/report/buildpurchasereport?format={format}", purchaseModel);
|
||||
var array = file!.Select(b => (int)b).ToArray();
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
[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]
|
||||
public IActionResult CreatePurchase()
|
||||
{
|
||||
@ -324,10 +389,78 @@ namespace HardwareShopWorkerApp.Controllers
|
||||
APIClient.PostRequest("api/purchase/createpurchase", purchaseModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult WorkerReport()
|
||||
[HttpPost]
|
||||
public void UpdateStatusPurchase(int id, int status)
|
||||
{
|
||||
return View();
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
if (id <= 0)
|
||||
{
|
||||
throw new Exception("Некорректный идентификатор");
|
||||
}
|
||||
if (status <= 0)
|
||||
{
|
||||
throw new Exception("Некорректный статус");
|
||||
}
|
||||
APIClient.PostRequest("api/purchase/UpdateStatusPurchase", new PurchaseBindingModel
|
||||
{
|
||||
Id = id,
|
||||
PurchaseStatus = (PurchaseStatus)status
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void DeletePurchase(int purchaseId)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
if (purchaseId <= 0)
|
||||
{
|
||||
throw new Exception("Некорректный идентификатор");
|
||||
}
|
||||
var purchase = APIClient.GetRequest<PurchaseViewModel>($"api/purchase/getpurchase?purchaseId={purchaseId}");
|
||||
APIClient.PostRequest("api/purchase/DeletePurchase", new PurchaseBindingModel
|
||||
{
|
||||
Id = purchaseId,
|
||||
PurchaseStatus = purchase.PurchaseStatus
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult UpdatePurchase(int purchaseId)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
ViewBag.Goods = APIClient.GetRequest<List<GoodViewModel>>($"api/good/GetAllGoods");
|
||||
return View(purchaseId);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void UpdatePurchase([FromBody] PurchaseBindingModel purchaseModel)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
purchaseModel.UserId = APIClient.User.Id;
|
||||
APIClient.PostRequest("api/purchase/update", purchaseModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public Tuple<PurchaseViewModel, List<Tuple<GoodViewModel?, int>>>? GetPurchaseUpdate(int purchaseId)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
|
||||
}
|
||||
var result = APIClient.GetRequest<Tuple<PurchaseViewModel, List<Tuple<GoodViewModel?, int>>>?>($"api/purchase/getpurchaseupdate?purchaseId={purchaseId}");
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@ -347,9 +480,90 @@ namespace HardwareShopWorkerApp.Controllers
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult LinkPurchase()
|
||||
public IActionResult LinkPurchase(int buildId)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
if (buildId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0");
|
||||
}
|
||||
ViewBag.Purchase = APIClient.GetRequest<List<PurchaseViewModel>>($"api/purchase/getpurchases?userId={APIClient.User.Id}");
|
||||
return View(APIClient.GetRequest<List<Tuple<PurchaseViewModel, int>>>($"api/build/GetBuildPurchase?buildId={buildId}"));
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public void DeleteLinkPurchase(int deleteBuildId, int deletePurchaseId)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
|
||||
}
|
||||
if (deleteBuildId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0");
|
||||
}
|
||||
if (deletePurchaseId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор покупки не может быть ниже или равен 0");
|
||||
}
|
||||
APIClient.GetRequest<bool>($"api/build/deleteLinkPurchase?deleteBuildId={deleteBuildId}&deletePurchaseId={deletePurchaseId}");
|
||||
Response.Redirect($"LinkPurchase?buildId={deleteBuildId}");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public void UpdateLinkPurchase(int updateBuildId, int updatePurchaseId, int count)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
|
||||
}
|
||||
if (updateBuildId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор сборки не может быть ниже или равен 0");
|
||||
}
|
||||
if (updatePurchaseId <= 0)
|
||||
{
|
||||
throw new Exception($"Идентификтаор покупки не может быть ниже или равен 0");
|
||||
}
|
||||
APIClient.GetRequest<bool>($"api/build/UpdateLinkPurchase?updateBuildId={updateBuildId}&updatePurchaseId={updatePurchaseId}&count={count}");
|
||||
Response.Redirect($"LinkPurchase?buildId={updateBuildId}");
|
||||
}
|
||||
|
||||
public IActionResult WorkerReport()
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
return Redirect("~/Home/Enter");
|
||||
}
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public List<ReportPurchaseViewModel>? WorkerReport([FromBody] ReportBindingModel reportModel)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
return new();
|
||||
}
|
||||
reportModel.UserId = APIClient.User.Id;
|
||||
List<ReportPurchaseViewModel>? list = APIClient.PostRequestWithResult<ReportBindingModel, List<ReportPurchaseViewModel>>("api/report/getpurchasereportdata", reportModel);
|
||||
return list;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public void SendByMailPurchaseReport([FromBody] ReportBindingModel reportModel)
|
||||
{
|
||||
if (APIClient.User == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
reportModel.UserId = APIClient.User.Id;
|
||||
reportModel.UserEmail = APIClient.User.Email;
|
||||
APIClient.PostRequest("api/report/SendByMailPurchaseReport", reportModel);
|
||||
}
|
||||
}
|
||||
}
|
@ -55,9 +55,7 @@
|
||||
<button onclick="getBuild(@item.Id)" type="button" class="btn btn-primary btn-lg mb-5" data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button onclick="deleteComponent(@item.Id)" type="button" class="btn btn-danger">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
<a class="btn btn-primary btn-lg mb-5" asp-controller="Home" asp-action="LinkPurchase" asp-route-buildId="@item.Id"></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -24,6 +24,7 @@
|
||||
<th scope="col">Товар</th>
|
||||
<th scope="col">Количество</th>
|
||||
<th scope="col">Цена</th>
|
||||
<th scope="col">Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="result">
|
||||
@ -93,12 +94,21 @@
|
||||
|
||||
saveBtn.addEventListener("click", () => {
|
||||
console.log('try to add purchase')
|
||||
console.log(list)
|
||||
if (list.length == 0) {
|
||||
alert('failed add good. components are empty')
|
||||
return
|
||||
}
|
||||
let goods = []
|
||||
let counts = []
|
||||
list.forEach((x) => {
|
||||
goods.push(x.good);
|
||||
counts.push(parseInt(x.count))
|
||||
})
|
||||
console.log(JSON.stringify({
|
||||
"Sum": parseFloat(totalSum.value),
|
||||
"ListPurchaseGoods": goods, "PurchaseGoodsCounts": counts
|
||||
}));
|
||||
$.ajax(
|
||||
{
|
||||
url: `/Home/CreatePurchase`,
|
||||
@ -106,7 +116,7 @@
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
"Sum": parseFloat(totalSum.value),
|
||||
"ListPurchaseGoods": goods
|
||||
"ListPurchaseGoods": goods, "PurchaseGoodsCounts": counts
|
||||
})
|
||||
}
|
||||
).done(() => window.location.href = '/Home/Purchases')
|
||||
@ -115,12 +125,25 @@
|
||||
function reloadTable() {
|
||||
resultTable.innerHTML = ''
|
||||
let price = 0;
|
||||
let count = 0;
|
||||
list.forEach((elem) => {
|
||||
resultTable.innerHTML += `<tr><td>${elem.good.goodName}</td><td>${elem.count}</td><td>${Math.round(elem.good.price * elem.count * 100) / 100}</td><td> \
|
||||
<div> \
|
||||
<button onclick="deleteGood(${count})" type="button" class="btn btn-danger"> \
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> \
|
||||
</button> \
|
||||
</div><td/></tr>`
|
||||
count++;
|
||||
console.log(elem);
|
||||
resultTable.innerHTML += `<tr><td>${elem.good.goodName}</td><td>${elem.count}</td><td>${Math.round(elem.good.price * elem.count * 100) / 100}</td></tr>`
|
||||
price += elem.good.price * elem.count
|
||||
})
|
||||
totalSum.value = Math.round(price * 100) / 100
|
||||
totalSum.value = Math.round(price * 110) / 100
|
||||
console.log(totalSum.value);
|
||||
}
|
||||
|
||||
function deleteGood(id) {
|
||||
list = list.filter(value => value.good.goodName != resultTable.rows[id].cells[0].innerText)
|
||||
reloadTable()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -1,4 +1,184 @@
|
||||
|
||||
@using HardwareShopContracts.ViewModels;
|
||||
|
||||
@model List<Tuple<PurchaseViewModel, int>>
|
||||
@{
|
||||
ViewData["Title"] = "Привязка сборок";
|
||||
Layout = "~/Views/Shared/_LayoutWorker.cshtml";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Привязка сборок</h1>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
@{
|
||||
<p>
|
||||
<button type="button" onclick="getBuild()" class="btn btn-primary btn-lg mb-5" data-bs-toggle="modal" data-bs-target="#createModal">Добавить</button>
|
||||
</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.Item1.Id)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Item1.Sum)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Item1.PurchaseStatus)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Item2)
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<button onclick="getPurchase(@item.Item1.Id)" type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#updateModal">
|
||||
Изменить
|
||||
</button>
|
||||
<button onclick="getPurchase(@item.Item1.Id)" type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||
Удалить
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form method="get" asp-controller="home" asp-action="LinkBuildPurchase">
|
||||
<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">
|
||||
<div class="form-group">
|
||||
<label>Количество</label>
|
||||
<input type="number" class="form-control" required="required" name="count" />
|
||||
</div>
|
||||
<label class="form-label">Сборка</label>
|
||||
<select id="purchaseId" name="purchaseId" class="form-control" asp-items="@(new SelectList(@ViewBag.Purchase, "Id","Id"))"></select>
|
||||
</div>
|
||||
<input type="hidden" id="buildId" name="buildId" />
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||
<input type="submit" class="btn btn-primary" value="Сохранить">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form method="get" asp-controller="home" asp-action="DeleteLinkPurchase">
|
||||
<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">
|
||||
<div class="form-group">
|
||||
<h1>Вы уверенны что хотите удалить сборку?</h1>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id="deleteBuildId" name="deleteBuildId" />
|
||||
<input type="hidden" id="deletePurchaseId" name="deletePurchaseId" />
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||
<input type="submit" class="btn btn-primary" value="Удалить">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="updateModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form method="get" asp-controller="home" asp-action="UpdateLinkPurchase">
|
||||
<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">
|
||||
<div class="form-group">
|
||||
<label>Количество</label>
|
||||
<input type="number" class="form-control" required="required" name="count" />
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id="updateBuildId" name="updateBuildId" />
|
||||
<input type="hidden" id="updatePurchaseId" name="updatePurchaseId" />
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||
<input type="submit" class="btn btn-primary" value="Сохранить">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script>
|
||||
function getBuild() {
|
||||
let currentUrl = window.location.href;
|
||||
console.log(currentUrl);
|
||||
getURLParameter(currentUrl, 'buildId');
|
||||
let buildId = getURLParameter(currentUrl, 'buildId');
|
||||
console.log(buildId);
|
||||
$('#buildId').val(buildId);
|
||||
$('#deleteBuildId').val(buildId);
|
||||
$('#updateBuildId').val(buildId);
|
||||
var id = document.getElementById("updateBuildId");
|
||||
console.log(id.value);
|
||||
}
|
||||
|
||||
function getURLParameter(sUrl, sParam) {
|
||||
let sPageURL = sUrl.substring(sUrl.indexOf('?') + 1);
|
||||
let sURLVariables = sPageURL.split('&');
|
||||
for (let i = 0; i < sURLVariables.length; i++) {
|
||||
let sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] == sParam) {
|
||||
return sParameterName[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
function getPurchase(purchaseId) {
|
||||
getBuild();
|
||||
$('#deletePurchaseId').val(purchaseId);
|
||||
$('#updatePurchaseId').val(purchaseId);
|
||||
console.log(purchaseId);
|
||||
}
|
||||
</script>
|
||||
}
|
||||
@*
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "LinkPurchase";
|
||||
@ -78,4 +258,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>*@
|
@ -17,14 +17,13 @@
|
||||
<h2 class="display-4">Покупки</h2>
|
||||
<p>
|
||||
<a asp-controller="Home" asp-action="CreatePurchase" class="btn btn-primary mx-2">Добавить</a>
|
||||
<button type="button" class="btn btn-primary mx-2" id="delete">Удалить заказ</button>
|
||||
<button type="button" class="btn btn-primary mx-2" id="inwork">Выполняется</button>
|
||||
<button type="button" class="btn btn-primary mx-2" id="ready">Готов</button>
|
||||
<button type="button" class="btn btn-primary mx-2" id="delete">Удалить покупку</button>
|
||||
<button type="button" class="btn btn-primary mx-2" id="done">Выдан</button>
|
||||
<button type="button" class="btn btn-primary mx-2" id="update">Обновить</button>
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-center" name="id">
|
||||
<table class="table">
|
||||
<div class="text-center">
|
||||
<table class="table" id="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@ -100,10 +99,8 @@
|
||||
|
||||
var table = document.getElementById("table");
|
||||
var remove = document.getElementById("delete");
|
||||
var inwork = document.getElementById("inwork");
|
||||
var ready = document.getElementById("ready");
|
||||
var done = document.getElementById("done");
|
||||
var order = 0;
|
||||
var purchase = 0;
|
||||
for (var i = 1; i < table.rows.length; i++) {
|
||||
table.rows[i].onclick = function () {
|
||||
// remove the background from the previous selected row
|
||||
@ -114,46 +111,30 @@
|
||||
index = this.rowIndex;
|
||||
// add class selected to the row
|
||||
this.classList.toggle("selected");
|
||||
order = parseInt(this.cells[0].innerText);
|
||||
purchase = parseInt(this.cells[0].innerText);
|
||||
remove.addEventListener("click", () => {
|
||||
console.log('try to delete order')
|
||||
console.log('try to delete purchase')
|
||||
$.ajax(
|
||||
{
|
||||
url: `/Storekeeper/DeleteOrder`,
|
||||
url: `/Home/DeletePurchase`,
|
||||
type: 'POST',
|
||||
data: { id: order }
|
||||
data: { purchaseId: purchase }
|
||||
}
|
||||
)
|
||||
})
|
||||
inwork.addEventListener("click", () => {
|
||||
console.log('try to delete order')
|
||||
$.ajax(
|
||||
{
|
||||
url: `/Storekeeper/UpdateOrder`,
|
||||
type: 'POST',
|
||||
data: { id: order, status: 1 }
|
||||
}
|
||||
)
|
||||
})
|
||||
ready.addEventListener("click", () => {
|
||||
console.log('try to delete order')
|
||||
$.ajax(
|
||||
{
|
||||
url: `/Storekeeper/UpdateOrder`,
|
||||
type: 'POST',
|
||||
data: { id: order, status: 2 }
|
||||
}
|
||||
)
|
||||
).done(() => window.location.href = '/Home/Purchases')
|
||||
})
|
||||
done.addEventListener("click", () => {
|
||||
console.log('try to delete order')
|
||||
console.log('try to delete purchase')
|
||||
$.ajax(
|
||||
{
|
||||
url: `/Storekeeper/UpdateOrder`,
|
||||
url: `/Home/UpdateStatusPurchase`,
|
||||
type: 'POST',
|
||||
data: { id: order, status: 3 }
|
||||
data: { id: purchase, status: 1 }
|
||||
}
|
||||
)
|
||||
).done(() => window.location.href = '/Home/Purchases')
|
||||
})
|
||||
update.addEventListener("click", () => {
|
||||
console.log('try to update purchase')
|
||||
window.location.href = '/Home/UpdatePurchase?purchaseId=' + purchase
|
||||
})
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,242 @@
|
||||
@using HardwareShopContracts.ViewModels
|
||||
@model int
|
||||
@{
|
||||
ViewData["Title"] = "UpdatePurchase";
|
||||
Layout = "~/Views/Shared/_LayoutWorker.cshtml";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Редактирование покупки</h2>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<div class="col-sm-3">
|
||||
<label class="form-label">Цена</label>
|
||||
<input type="number" step="0.01" class="form-control" name="sum" id="sum" readonly min="0.01" value="0" required>
|
||||
</div>
|
||||
<h1 class="display-6">Товары</h1>
|
||||
<div class="d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary mx-2 mt-3" data-bs-toggle="modal" data-bs-target="#exampleModal">Добавить</button>
|
||||
<button type="button" class="btn btn-primary mx-2 mt-3">Удалить</button>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Товар</th>
|
||||
<th scope="col">Количество</th>
|
||||
<th scope="col">Цена</th>
|
||||
<th scope="col">Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="result">
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="col-sm-2 d-flex justify-content-evenly align-items-baseline">
|
||||
<button type="button" class="btn btn-primary mt-3 px-4" id="createpurchase">Сохранить</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="good" name="good" class="form-control" asp-items="@(new SelectList(@ViewBag.Goods, "Id", "GoodName"))"></select>
|
||||
<label class="form-label">Количество</label>
|
||||
<input type="number" class="form-control" name="count" id="count" min="1" value="1" required>
|
||||
</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="savegood">Сохранить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script>
|
||||
const purchaseId = @Model
|
||||
let list = [];
|
||||
let status;
|
||||
const submitGoodBtn = document.getElementById("savegood");
|
||||
//const editBtn = document.getElementById("editcomponent");
|
||||
const saveBtn = document.getElementById("createpurchase");
|
||||
const countElem = document.getElementById("count");
|
||||
const resultTable = document.getElementById("result");
|
||||
|
||||
submitGoodBtn.addEventListener("click", () => {
|
||||
console.log('try to add good')
|
||||
var count = $('#count').val();
|
||||
var good = $('#good').val();
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: `/Home/GetGood`,
|
||||
data: { Id: good },
|
||||
success: function (result) {
|
||||
let flag = false
|
||||
if (list.length > 0) {
|
||||
list.forEach((elem) => {
|
||||
if (elem.good.id === parseInt(result.id)) {
|
||||
console.log('good already added')
|
||||
flag = true
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!flag) list.push({ good: result, count: count })
|
||||
reloadTable()
|
||||
countElem.value = '1'
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
saveBtn.addEventListener("click", () => {
|
||||
console.log('try to add purchase')
|
||||
console.log(list)
|
||||
if (list.length == 0) {
|
||||
alert('failed add good. components are empty')
|
||||
return
|
||||
}
|
||||
let goods = []
|
||||
let counts = []
|
||||
list.forEach((x) => {
|
||||
goods.push(x.good);
|
||||
counts.push(parseInt(x.count))
|
||||
})
|
||||
console.log(JSON.stringify({
|
||||
"ListPurchaseGoods": goods, "PurchaseGoodsCounts": counts
|
||||
}));
|
||||
$.ajax(
|
||||
{
|
||||
url: `/Home/UpdatePurchase`,
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
"Id": purchaseId, "ListPurchaseGoods": goods, "PurchaseGoodsCounts": counts, "PurchaseStatus": status
|
||||
})
|
||||
}
|
||||
).done(() => window.location.href = '/Home/Purchases')
|
||||
.fail(function (xhr, textStatus, errorThrown) {
|
||||
alert(xhr.responseText);
|
||||
})
|
||||
})
|
||||
|
||||
function reloadTable() {
|
||||
resultTable.innerHTML = ''
|
||||
let price = 0;
|
||||
let count = 0;
|
||||
list.forEach((elem) => {
|
||||
resultTable.innerHTML += `<tr><td>${elem.good.goodName}</td><td>${elem.count}</td><td>${Math.round(elem.good.price * elem.count * 100) / 100}</td><td> \
|
||||
<div> \
|
||||
<button onclick="deleteGood(${count})" type="button" class="btn btn-danger"> \
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> \
|
||||
</button> \
|
||||
</div><td/></tr>`
|
||||
count++;
|
||||
console.log(elem);
|
||||
})
|
||||
}
|
||||
|
||||
function deleteGood(id) {
|
||||
list = list.filter(value => value.good.goodName != resultTable.rows[id].cells[0].innerText)
|
||||
reloadTable()
|
||||
}
|
||||
|
||||
function getPurchase() {
|
||||
if (purchaseId) {
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: "/Home/GetPurchaseUpdate",
|
||||
data: { purchaseId: purchaseId },
|
||||
success: function (result) {
|
||||
if (result) {
|
||||
console.log(result)
|
||||
status = result.item1.purchaseStatus
|
||||
result.item2.forEach(elem => {
|
||||
list.push({ good: elem.item1, count: elem.item2 })
|
||||
})
|
||||
reloadTable()
|
||||
}
|
||||
else
|
||||
alert("Ошибка получения товара")
|
||||
}
|
||||
})
|
||||
.fail(function (xhr, textStatus, errorThrown) {
|
||||
alert(xhr.responseText);
|
||||
})
|
||||
};
|
||||
}
|
||||
getPurchase();
|
||||
|
||||
</script>
|
||||
}
|
||||
|
||||
|
||||
@*<form class="d-flex justify-content-evenly">
|
||||
<div class=" col-sm-8">
|
||||
<div class="text-center">
|
||||
<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" 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">Сохранить</button>
|
||||
</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">
|
||||
<div>
|
||||
<label class="form-label">Товар</label>
|
||||
<select class="form-select">
|
||||
<option value="1">Товар 1</option>
|
||||
<option value="2">Товар 2</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Количество</label>
|
||||
<input type="number" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||
<button type="button" class="btn btn-primary">Сохранить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
*@
|
@ -3,13 +3,198 @@
|
||||
Layout = "~/Views/Shared/_LayoutWorker.cshtml";
|
||||
}
|
||||
|
||||
<form method="post" class="d-flex flex-column align-items-center">
|
||||
<div class="col-sm-3">
|
||||
<label class="form-label">С</label>
|
||||
<input type="date" class="form-control" name="dateFrom">
|
||||
<label class="form-label">По</label>
|
||||
<input type="date" class="form-control" name="dateTo">
|
||||
<h4 class="fw-bold">Отчет по покупкам</h4>
|
||||
|
||||
<div id="error-div-shell" class="error-div-shell">
|
||||
<div>
|
||||
<p id="error-p" class="error-p mb-2"></p>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-3 px-4">Вывод на страницу</button>
|
||||
<button type="submit" class="btn btn-primary mt-3 px-4">Отправить на почту</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<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 text-button mb-2">
|
||||
Показать
|
||||
</button>
|
||||
<button id="send-by-mail-button" class="button-primary text-button 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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@section Scripts
|
||||
{
|
||||
<script>
|
||||
const generateButton = document.getElementById("generate-button");
|
||||
const sendByMailButton = document.getElementById("send-by-mail-button");
|
||||
const dateFromInput = document.getElementById("date-from-input");
|
||||
const dateToInput = document.getElementById("date-to-input");
|
||||
const dateFromSpan = document.getElementById("date-from-span");
|
||||
const dateToSpan = document.getElementById("date-to-span");
|
||||
const tbody = document.getElementById("tbody");
|
||||
const errorP = document.getElementById("error-p");
|
||||
const errorDivShell = document.getElementById("error-div-shell");
|
||||
|
||||
// [Event listeners]
|
||||
|
||||
generateButton.addEventListener("click", () => {
|
||||
const dateFrom = new Date(dateFromInput.value);
|
||||
const dateTo = new Date(dateToInput.value);
|
||||
const reportModel = {
|
||||
"DateFrom": dateFrom,
|
||||
"DateTo": dateTo
|
||||
};
|
||||
if (!validate(reportModel)) {
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: "/home/WorkerReport",
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(reportModel)
|
||||
}).done((reportData) => {
|
||||
dateFromSpan.innerHTML = reportModel["DateFrom"].toLocaleDateString();
|
||||
dateToSpan.innerHTML = reportModel["DateTo"].toLocaleDateString();
|
||||
renderTable(reportData);
|
||||
});
|
||||
});
|
||||
|
||||
sendByMailButton.addEventListener("click", () => {
|
||||
const dateFrom = new Date(dateFromInput.value);
|
||||
const dateTo = new Date(dateToInput.value);
|
||||
const reportModel = {
|
||||
"DateFrom": dateFrom,
|
||||
"DateTo": dateTo
|
||||
};
|
||||
if (!validate(reportModel)) {
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: "/home/SendByMailPurchaseReport",
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(reportModel)
|
||||
}).done(() => {
|
||||
});
|
||||
});
|
||||
|
||||
dateFromInput.addEventListener("input", () => {
|
||||
errorDivShell.style.gridTemplateRows = "0fr";
|
||||
});
|
||||
|
||||
dateToInput.addEventListener("input", () => {
|
||||
errorDivShell.style.gridTemplateRows = "0fr";
|
||||
});
|
||||
|
||||
// ![Event listeners]
|
||||
|
||||
// [HTML gen]
|
||||
|
||||
const renderTable = function (reportData) {
|
||||
tbody.innerHTML = "";
|
||||
reportData.forEach((record) => {
|
||||
console.log(record);
|
||||
const comments = record.comments;
|
||||
const components = record.components;
|
||||
const recordHeight = Math.max(comments.length + 1, components.length + 1);
|
||||
for (let i = 0; i < recordHeight; i++) {
|
||||
let cellsData = ["", "", "", "", ""];
|
||||
if (i === 0) {
|
||||
cellsData[0] = record.id;
|
||||
cellsData[1] = getDate(record.purchaseDate);
|
||||
cellsData[2] = record.purchaseSum;
|
||||
createTableRow(cellsData);
|
||||
continue;
|
||||
}
|
||||
let k = i - 1;
|
||||
if (k < comments.length) {
|
||||
cellsData[3] = comments[k];
|
||||
}
|
||||
if (k < components.length) {
|
||||
cellsData[4] = components[k];
|
||||
}
|
||||
createTableRow(cellsData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const createTableRow = function (cellsData) {
|
||||
const tr = document.createElement('tr');
|
||||
tr.classList.add("table-row");
|
||||
tr.appendChild(createTableCell(cellsData[0])); // Purchase
|
||||
tr.appendChild(createTableCell(cellsData[1])); // DatePurchase
|
||||
tr.appendChild(createTableCell(cellsData[2])); // purchaseSum
|
||||
tr.appendChild(createTableCell(cellsData[3])); // Comments
|
||||
tr.appendChild(createTableCell(cellsData[4])); // Copmponent
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
|
||||
const createTableCell = function (cellText) {
|
||||
const td = document.createElement('td');
|
||||
td.innerHTML = cellText;
|
||||
return td;
|
||||
}
|
||||
|
||||
// ![HTML gen]
|
||||
|
||||
// [Other]
|
||||
|
||||
const validate = function (reportModel) {
|
||||
if (isNaN(reportModel["DateFrom"])) {
|
||||
errorDivShell.style.gridTemplateRows = "1fr";
|
||||
errorP.innerHTML = "Выберите начальную дату";
|
||||
return false;
|
||||
}
|
||||
if (isNaN(reportModel["DateTo"])) {
|
||||
errorDivShell.style.gridTemplateRows = "1fr";
|
||||
errorP.innerHTML = "Выберите конечную дату";
|
||||
return false;
|
||||
}
|
||||
if (reportModel["DateFrom"] >= reportModel["DateTo"]) {
|
||||
errorDivShell.style.gridTemplateRows = "1fr";
|
||||
errorP.innerHTML = "Начальная дата должна быть меньше конечной";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const getDate = function (iso) {
|
||||
const year = iso.substring(0, 4);
|
||||
const month = iso.substring(5, 7);
|
||||
const day = iso.substring(8, 10);
|
||||
const date = `${day}.${month}.${year}`;
|
||||
return date;
|
||||
}
|
||||
|
||||
// ![Other]
|
||||
|
||||
</script>
|
||||
}
|
@ -1,43 +1,33 @@
|
||||
@{
|
||||
ViewData["Title"] = "ListComponents";
|
||||
@using HardwareShopContracts.ViewModels
|
||||
@{
|
||||
ViewData["Title"] = "Получение списка";
|
||||
Layout = "~/Views/Shared/_LayoutWorker.cshtml";
|
||||
}
|
||||
|
||||
<form method="post" class="d-flex justify-content-evenly">
|
||||
<div class=" col-sm-8">
|
||||
<div class="text-center">
|
||||
<h2 class="display-4">Покупки</h2>
|
||||
<h1 class="display-4">Получение списка покупок</h1>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<h1 class="display-6">Выбранные покупки</h1>
|
||||
<div class="d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary mx-2 mt-3" data-bs-toggle="modal" data-bs-target="#exampleModal">Добавить покупку</button>
|
||||
</div>
|
||||
<div class="text-center" name="id">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Номер
|
||||
</th>
|
||||
<th>
|
||||
Дата оплаты
|
||||
</th>
|
||||
<th>
|
||||
Сумма
|
||||
</th>
|
||||
<th>
|
||||
Статус
|
||||
</th>
|
||||
<th scope="col">Покупка</th>
|
||||
<th scope="col">Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody id="result">
|
||||
</tbody>
|
||||
</table>
|
||||
<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="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="modal-dialog">
|
||||
@ -47,19 +37,117 @@
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div>
|
||||
<label class="form-label">Покупка</label>
|
||||
<select class="form-select">
|
||||
<option value="1">Покупка 1</option>
|
||||
<option value="2">Покупка 2</option>
|
||||
</select>
|
||||
</div>
|
||||
<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">Добавить</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="savepurchase">Сохранить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@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");
|
||||
|
||||
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('docx')
|
||||
})
|
||||
|
||||
saveExcelBtn.addEventListener("click", async () => {
|
||||
send('xlsx')
|
||||
})
|
||||
|
||||
function send(format) {
|
||||
console.log(`try to save in ${format} format`)
|
||||
if (list.length == 0) {
|
||||
alert('operation failed. purchases or filename are empty')
|
||||
return
|
||||
}
|
||||
$.ajax({
|
||||
url: `/Home/ListComponents?format=${format}`,
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ "Purchases" : list })
|
||||
}).done((file) => {
|
||||
let byteArray = new Uint8Array(file);
|
||||
saveFile(byteArray, format);
|
||||
})
|
||||
.fail(function(xhr, textStatus, errorThrown) {
|
||||
alert(xhr.responseText);
|
||||
})
|
||||
}
|
||||
|
||||
async function saveFile(bytes, format) {
|
||||
if (window.showSaveFilePicker) {
|
||||
const opts = {
|
||||
suggestedName: `listcomponents.${format}`,
|
||||
types: [{
|
||||
description: `${format} file`,
|
||||
accept:
|
||||
{
|
||||
[`text/${format}`]: [`.${format}`]
|
||||
},
|
||||
}],
|
||||
};
|
||||
const handle = await showSaveFilePicker(opts);
|
||||
const writable = await handle.createWritable();
|
||||
await writable.write(bytes);
|
||||
writable.close();
|
||||
alert('done')
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
}
|
Loading…
Reference in New Issue
Block a user