Compare commits

...

3 Commits

Author SHA1 Message Date
c0fc48b7e4 Late night, come home
Work sucks, I know
She left me roses by the stairs
Surprises let me know she cares
2023-04-22 13:48:42 +04:00
ecfa871e1a Merge branch 'LabWork06_Hard' into LabWork07_Hard 2023-04-22 10:33:03 +04:00
1b57449e73 fix 2023-04-22 10:32:35 +04:00
27 changed files with 1253 additions and 199 deletions

166
LawFirm/LawFirm/FormMail.Designer.cs generated Normal file
View File

@ -0,0 +1,166 @@
namespace LawFirmView
{
partial class FormMail
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
label1 = new Label();
label2 = new Label();
textBoxHead = new TextBox();
textBoxBody = new TextBox();
buttonCancel = new Button();
buttonSave = new Button();
label3 = new Label();
labelHead = new Label();
labelBody = new Label();
labelFrom = new Label();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(539, 53);
label1.Name = "label1";
label1.Size = new Size(84, 20);
label1.TabIndex = 0;
label1.Text = "Заголовок:";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(539, 115);
label2.Name = "label2";
label2.Size = new Size(104, 20);
label2.TabIndex = 1;
label2.Text = "Текст письма:";
//
// textBoxHead
//
textBoxHead.Location = new Point(547, 85);
textBoxHead.Name = "textBoxHead";
textBoxHead.Size = new Size(318, 27);
textBoxHead.TabIndex = 3;
//
// textBoxBody
//
textBoxBody.Location = new Point(547, 138);
textBoxBody.Name = "textBoxBody";
textBoxBody.Size = new Size(318, 27);
textBoxBody.TabIndex = 4;
//
// buttonCancel
//
buttonCancel.Location = new Point(664, 230);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(771, 230);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(94, 29);
buttonSave.TabIndex = 6;
buttonSave.Text = "Отправить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(541, 9);
label3.Name = "label3";
label3.Size = new Size(82, 20);
label3.TabIndex = 7;
label3.Text = "Ваш ответ:";
//
// labelHead
//
labelHead.AutoSize = true;
labelHead.Location = new Point(12, 9);
labelHead.Name = "labelHead";
labelHead.Size = new Size(165, 20);
labelHead.TabIndex = 8;
labelHead.Text = "Заголовок сообщения";
//
// labelBody
//
labelBody.AutoSize = true;
labelBody.Location = new Point(12, 53);
labelBody.Name = "labelBody";
labelBody.Size = new Size(129, 20);
labelBody.TabIndex = 9;
labelBody.Text = "Текст сообщения";
//
// labelFrom
//
labelFrom.AutoSize = true;
labelFrom.Location = new Point(12, 234);
labelFrom.Name = "labelFrom";
labelFrom.Size = new Size(33, 20);
labelFrom.TabIndex = 10;
labelFrom.Text = "От: ";
//
// FormMail
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(877, 266);
Controls.Add(labelFrom);
Controls.Add(labelBody);
Controls.Add(labelHead);
Controls.Add(label3);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(textBoxBody);
Controls.Add(textBoxHead);
Controls.Add(label2);
Controls.Add(label1);
Name = "FormMail";
Text = "Ответ на письмо";
Load += FormMail_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label1;
private Label label2;
private TextBox textBoxHead;
private TextBox textBoxBody;
private Button buttonCancel;
private Button buttonSave;
private Label label3;
private Label labelHead;
private Label labelBody;
private Label labelFrom;
}
}

View File

@ -0,0 +1,81 @@
using LawFirmBusinessLogic.MailWorker;
using LawFirmContracts.BusinessLogicContracts;
using LawFirmContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LawFirmView
{
public partial class FormMail : Form
{
private readonly ILogger _logger;
private readonly AbstractMailWorker _mailWorker;
private readonly IMessageInfoLogic _logic;
private MessageInfoViewModel _message;
public string MessageId { get; set; } = string.Empty;
public FormMail(ILogger<FormMail> logger, AbstractMailWorker mailWorker, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_mailWorker = mailWorker;
_logic = logic;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void buttonSave_Click(object sender, EventArgs e)
{
_mailWorker.MailSendAsync(new()
{
MailAddress = _message.SenderName,
Subject = textBoxHead.Text,
Text = textBoxBody.Text,
});
_logic.Update(new()
{
MessageId = MessageId,
Reply = textBoxBody.Text,
IsReaded = true,
});
MessageBox.Show("Успешно отправлен ответ", "Отправлен ответ", MessageBoxButtons.OK);
DialogResult = DialogResult.OK;
Close();
}
private void FormMail_Load(object sender, EventArgs e)
{
try
{
_message = _logic.ReadElement(new() { MessageId = MessageId });
if (_message == null) throw new ArgumentNullException("Письма с таким Id не существует");
labelHead.Text = _message.Subject;
labelBody.Text = _message.Body;
labelFrom.Text = $"От: {_message.SenderName}";
if (_message.IsReaded is false)
{
_logic.Update(new() { MessageId = MessageId, IsReaded = true, Reply = _message.Reply });
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения собщения");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -29,6 +29,10 @@
private void InitializeComponent() private void InitializeComponent()
{ {
dataGridView = new DataGridView(); dataGridView = new DataGridView();
buttonPrevPage = new Button();
buttonNextPage = new Button();
labelPage = new Label();
buttonReply = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout(); SuspendLayout();
// //
@ -42,21 +46,69 @@
dataGridView.Size = new Size(776, 426); dataGridView.Size = new Size(776, 426);
dataGridView.TabIndex = 0; dataGridView.TabIndex = 0;
// //
// buttonPrevPage
//
buttonPrevPage.Location = new Point(594, 444);
buttonPrevPage.Name = "buttonPrevPage";
buttonPrevPage.Size = new Size(94, 29);
buttonPrevPage.TabIndex = 1;
buttonPrevPage.Text = "Пред.";
buttonPrevPage.UseVisualStyleBackColor = true;
buttonPrevPage.Click += buttonPrevPage_Click;
//
// buttonNextPage
//
buttonNextPage.Location = new Point(694, 444);
buttonNextPage.Name = "buttonNextPage";
buttonNextPage.Size = new Size(94, 29);
buttonNextPage.TabIndex = 2;
buttonNextPage.Text = "След.";
buttonNextPage.UseVisualStyleBackColor = true;
buttonNextPage.Click += buttonNextPage_Click;
//
// labelPage
//
labelPage.AutoSize = true;
labelPage.Location = new Point(462, 448);
labelPage.Name = "labelPage";
labelPage.Size = new Size(91, 20);
labelPage.TabIndex = 3;
labelPage.Text = "Страница: 0";
//
// buttonReply
//
buttonReply.Location = new Point(12, 444);
buttonReply.Name = "buttonReply";
buttonReply.Size = new Size(94, 29);
buttonReply.TabIndex = 4;
buttonReply.Text = "Ответить";
buttonReply.UseVisualStyleBackColor = true;
buttonReply.Click += buttonReply_Click;
//
// FormMails // FormMails
// //
AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450); ClientSize = new Size(800, 475);
Controls.Add(buttonReply);
Controls.Add(labelPage);
Controls.Add(buttonNextPage);
Controls.Add(buttonPrevPage);
Controls.Add(dataGridView); Controls.Add(dataGridView);
Name = "FormMails"; Name = "FormMails";
Text = "Письма"; Text = "Письма";
Load += FormMails_Load; Load += FormMails_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit(); ((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout();
} }
#endregion #endregion
private DataGridView dataGridView; private DataGridView dataGridView;
private Button buttonPrevPage;
private Button buttonNextPage;
private Label labelPage;
private Button buttonReply;
} }
} }

View File

@ -1,4 +1,6 @@
using LawFirmContracts.BusinessLogicContracts; using LawFirm;
using LawFirmContracts.BusinessLogicContracts;
using LawFirmContracts.ViewModels;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -16,19 +18,31 @@ namespace LawFirmView
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic; private readonly IMessageInfoLogic _logic;
private int currentPage = 1;
public int pageSize = 2;
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic) public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;
_logic = logic; _logic = logic;
buttonPrevPage.Enabled = false;
} }
private void FormMails_Load(object sender, EventArgs e) private void FormMails_Load(object sender, EventArgs e)
{
LoadMail();
}
private bool LoadMail()
{ {
try try
{ {
var list = _logic.ReadList(null); var list = _logic.ReadList(new()
{
Page = currentPage,
PageSize = pageSize,
});
if (list != null) if (list != null)
{ {
dataGridView.DataSource = list; dataGridView.DataSource = list;
@ -37,12 +51,61 @@ namespace LawFirmView
dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
} }
_logger.LogInformation("Загрузка писем"); _logger.LogInformation("Загрузка писем");
labelPage.Text = $"Страница: {currentPage}";
return true;
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка загрузки писем"); _logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error); MessageBoxIcon.Error);
return false;
}
}
private void buttonPrevPage_Click(object sender, EventArgs e)
{
if (currentPage == 1)
{
return;
}
currentPage--;
if (LoadMail())
{
buttonNextPage.Enabled = true;
if (currentPage == 1)
{
buttonPrevPage.Enabled = false;
}
}
}
private void buttonNextPage_Click(object sender, EventArgs e)
{
currentPage++;
if (!LoadMail() || ((List<MessageInfoViewModel>)dataGridView.DataSource).Count == 0)
{
currentPage--;
LoadMail();
buttonNextPage.Enabled = false;
}
else
{
buttonPrevPage.Enabled = true;
}
}
private void buttonReply_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMail));
if (service is FormMail form)
{
form.MessageId = (string)(dataGridView.SelectedRows[0].Cells["MessageId"].Value);
form.ShowDialog();
LoadMail();
}
} }
} }
} }

View File

@ -109,7 +109,7 @@ namespace LawFirm
services.AddTransient<FormImplementers>(); services.AddTransient<FormImplementers>();
services.AddTransient<FormImplementer>(); services.AddTransient<FormImplementer>();
services.AddTransient<FormMails>(); services.AddTransient<FormMails>();
services.AddTransient<FormMail>();
} }
} }

View File

@ -32,6 +32,17 @@ namespace LawFirmBusinessLogic.BusinessLogics
return true; return true;
} }
public MessageInfoViewModel? ReadElement(MessageInfoSearchModel model)
{
var message = _messageInfoStorage.GetElement(model);
if (message == null)
{
_logger.LogWarning("Read message operation failed");
return null;
}
return message;
}
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model) public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{ {
_logger.LogInformation("ReadList. MessageId:{MessageId}.ClientId:{ClientId} ", model?.MessageId, model?.ClientId); _logger.LogInformation("ReadList. MessageId:{MessageId}.ClientId:{ClientId} ", model?.MessageId, model?.ClientId);
@ -44,5 +55,15 @@ namespace LawFirmBusinessLogic.BusinessLogics
_logger.LogInformation("ReadList. Count:{Count}", list.Count); _logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list; return list;
} }
public bool Update(MessageInfoBindingModel model)
{
if (_messageInfoStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
} }
} }

View File

@ -10,6 +10,7 @@ namespace LawFirmClientApp
{ {
private static readonly HttpClient _client = new(); private static readonly HttpClient _client = new();
public static ClientViewModel? Client { get; set; } = null; public static ClientViewModel? Client { get; set; } = null;
public static int CurrentPage { get; set; } = 0;
public static void Connect(IConfiguration configuration) public static void Connect(IConfiguration configuration)
{ {
_client.BaseAddress = new Uri(configuration["IPAddress"]); _client.BaseAddress = new Uri(configuration["IPAddress"]);

View File

@ -4,6 +4,7 @@ using LawFirmContracts.ViewModels;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
namespace LawFirmClientApp.Controllers namespace LawFirmClientApp.Controllers
{ {
@ -143,7 +144,45 @@ namespace LawFirmClientApp.Controllers
{ {
return Redirect("~/Home/Enter"); return Redirect("~/Home/Enter");
} }
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}")); APIClient.CurrentPage = 0;
return View();
}
[HttpGet]
public Tuple<string?, string?, bool, bool>? SwitchPage(bool isNext)
{
if (isNext)
{
APIClient.CurrentPage++;
}
else
{
if (APIClient.CurrentPage == 1)
{
return null;
}
APIClient.CurrentPage--;
}
var messages = APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client!.Id}&pageNum={APIClient.CurrentPage}");
if (isNext && (messages == null || messages.Count == 0))
{
APIClient.CurrentPage--;
return Tuple.Create<string?, string?, bool, bool>(null, null, APIClient.CurrentPage != 1, false);
}
StringBuilder htmlTable = new();
foreach (var mail in messages)
{
htmlTable.Append("<tr>" +
$"<td>{mail.DateDelivery}</td>" +
$"<td>{mail.Subject}</td>" +
$"<td>{mail.Body}</td>" +
"<td>" + (mail.IsReaded ? "Прочитано" : "Непрочитано") + "</td>" +
$"<td>{mail.Reply}</td>" +
"</tr>");
}
return Tuple.Create<string?, string?, bool, bool>(htmlTable.ToString(), APIClient.CurrentPage.ToString(), APIClient.CurrentPage != 1, true);
} }

View File

@ -1,29 +1,16 @@
@using LawFirmContracts.ViewModels @{
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails"; ViewData["Title"] = "Mails";
} }
<div class="text-center"> <div class="text-center">
<h1 class="display-4">Письма</h1> <h1 class="display-4">Письма</h1>
</div> </div>
<div class="text-center"> <div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th> <th>
Дата письма Дата
</th> </th>
<th> <th>
Заголовок Заголовок
@ -31,24 +18,62 @@
<th> <th>
Текст Текст
</th> </th>
<th>
Прочитано
</th>
<th>
Ответ
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody id="mails-table-body">
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.DateDelivery)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
@Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody> </tbody>
</table> </table>
} <ul class="pagination justify-content-center">
<li id="prev-page" class="page-item">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Предыдущее</span>
</a>
</li>
<li class="page-item">
<a id="current-page" class="page-link"></a>
</li>
<li id="next-page" class="page-item">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Следующее</span>
</a>
</li>
</ul>
</div> </div>
<script>
function onClicked(isNext) {
$.ajax({
method: "GET",
url: "/Home/SwitchPage",
data: { isNext: isNext },
success: function (result) {
if (result != null) {
if (result.item1 != null && result.item2 != null) {
$("#mails-table-body").html(result.item1);
$("#current-page").text(result.item2);
}
if (result.item3)
$("#prev-page").removeClass("page-item disabled");
else
$("#prev-page").addClass("page-item disabled");
if (result.item4)
$("#next-page").removeClass("page-item disabled");
else
$("#next-page").addClass("page-item disabled");
}
}
});
}
onClicked(true);
$("#prev-page").on('click', () => onClicked(false));
$("#next-page").on('click', () => onClicked(true));
</script>

View File

@ -20,5 +20,7 @@ namespace LawFirmContracts.BindingModels
public string Subject { get; set; } = string.Empty; public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty; public string Body { get; set; } = string.Empty;
public bool IsReaded { get; set; }
public string? Reply { get; set; }
} }
} }

View File

@ -13,5 +13,7 @@ namespace LawFirmContracts.BusinessLogicContracts
{ {
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model); List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model); bool Create(MessageInfoBindingModel model);
bool Update(MessageInfoBindingModel model);
MessageInfoViewModel? ReadElement(MessageInfoSearchModel model);
} }
} }

View File

@ -10,5 +10,7 @@ namespace LawFirmContracts.SearchModels
{ {
public int? ClientId { get; set; } public int? ClientId { get; set; }
public string? MessageId { get; set; } public string? MessageId { get; set; }
public int? Page { get; set; }
public int? PageSize { get; set; }
} }
} }

View File

@ -15,5 +15,6 @@ namespace LawFirmContracts.StorageContracts
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model); List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel model); MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model); MessageInfoViewModel? Insert(MessageInfoBindingModel model);
MessageInfoViewModel? Update(MessageInfoBindingModel model);
} }
} }

View File

@ -21,5 +21,9 @@ namespace LawFirmContracts.ViewModels
public string Subject { get; set; } = string.Empty; public string Subject { get; set; } = string.Empty;
[DisplayName("Текст")] [DisplayName("Текст")]
public string Body { get; set; } = string.Empty; public string Body { get; set; } = string.Empty;
[DisplayName("Прочитано")]
public bool IsReaded { get; set; }
[DisplayName("Ответ")]
public string? Reply { get; set; }
} }
} }

View File

@ -14,5 +14,7 @@ namespace LawFirmDataModels.Models
DateTime DateDelivery { get; } DateTime DateDelivery { get; }
string Subject { get; } string Subject { get; }
string Body { get; } string Body { get; }
public bool IsReaded { get; }
public string? Reply { get; }
} }
} }

View File

@ -3,6 +3,7 @@ using LawFirmContracts.SearchModels;
using LawFirmContracts.StorageContracts; using LawFirmContracts.StorageContracts;
using LawFirmContracts.ViewModels; using LawFirmContracts.ViewModels;
using LawFirmDatabaseImplement.Models; using LawFirmDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -27,10 +28,16 @@ namespace LawFirmDatabaseImplement.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{ {
using var context = new LawFirmDatabase(); using var context = new LawFirmDatabase();
return context.Messages var messages = context.Messages
.Where(x => x.ClientId == model.ClientId) .Where(x => (model.ClientId == null) || (x.ClientId == model.ClientId))
.Select(x => x.GetViewModel) .Select(x => x.GetViewModel);
.ToList();
if (!(model.Page.HasValue && model.PageSize.HasValue))
{
return messages.ToList();
}
return messages.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
} }
public List<MessageInfoViewModel> GetFullList() public List<MessageInfoViewModel> GetFullList()
@ -53,5 +60,17 @@ namespace LawFirmDatabaseImplement.Implements
context.SaveChanges(); context.SaveChanges();
return newMessage.GetViewModel; return newMessage.GetViewModel;
} }
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
using var context = new LawFirmDatabase();
var message = context.Messages.Include(x => x.Client).FirstOrDefault(x => x.MessageId.Equals(model.MessageId));
if (message != null)
{
message.Update(model);
context.SaveChanges();
}
return message?.GetViewModel;
}
} }
} }

View File

@ -18,16 +18,6 @@ namespace LawFirmDatabaseImplement.Implements
{ {
using var context = new LawFirmDatabase(); using var context = new LawFirmDatabase();
if (model.ImplementerId != null && model.Status != null)
{
return context.Orders
.Include(x => x.Document)
.Include(x => x.Client)
.Include(x => x.Implementer)
.FirstOrDefault(x => x.Status.Equals(model.Status) && x.ImplementerId.Equals(model.ImplementerId))?.GetViewModel;
}
return context.Orders return context.Orders
.Include(x => x.Document) .Include(x => x.Document)
.Include(x => x.Client) .Include(x => x.Client)

View File

@ -0,0 +1,381 @@
// <auto-generated />
using System;
using LawFirmDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace LawFirmDatabaseImplement.Migrations
{
[DbContext(typeof(LawFirmDatabase))]
[Migration("20230422091213_MessageInfoUpdate")]
partial class MessageInfoUpdate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Blank", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("BlankName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Blanks");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Document", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("DocumentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Documents");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.DocumentBlank", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("BlankId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("DocumentId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("BlankId");
b.HasIndex("DocumentId");
b.ToTable("DocumentBlanks");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.MessageInfo", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<bool>("IsReaded")
.HasColumnType("bit");
b.Property<string>("Reply")
.HasColumnType("nvarchar(max)");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int>("DocumentId")
.HasColumnType("int");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("DocumentId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Adress")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("MaxCountDocuments")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("OpeningDate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.ShopDocument", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("DocumentId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("DocumentId");
b.HasIndex("ShopId");
b.ToTable("ShopDocuments");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.DocumentBlank", b =>
{
b.HasOne("LawFirmDatabaseImplement.Models.Blank", "Blank")
.WithMany("DocumentBlanks")
.HasForeignKey("BlankId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LawFirmDatabaseImplement.Models.Document", "Document")
.WithMany("Blanks")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Blank");
b.Navigation("Document");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("LawFirmDatabaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Order", b =>
{
b.HasOne("LawFirmDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LawFirmDatabaseImplement.Models.Document", "Document")
.WithMany("Orders")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LawFirmDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.Navigation("Client");
b.Navigation("Document");
b.Navigation("Implementer");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.ShopDocument", b =>
{
b.HasOne("LawFirmDatabaseImplement.Models.Document", "Document")
.WithMany()
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LawFirmDatabaseImplement.Models.Shop", "Shop")
.WithMany("Documents")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Document");
b.Navigation("Shop");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Blank", b =>
{
b.Navigation("DocumentBlanks");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
b.Navigation("Orders");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Document", b =>
{
b.Navigation("Blanks");
b.Navigation("Orders");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("LawFirmDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Documents");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LawFirmDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class MessageInfoUpdate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsReaded",
table: "Messages",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "Reply",
table: "Messages",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsReaded",
table: "Messages");
migrationBuilder.DropColumn(
name: "Reply",
table: "Messages");
}
}
}

View File

@ -155,6 +155,12 @@ namespace LawFirmDatabaseImplement.Migrations
b.Property<DateTime>("DateDelivery") b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<bool>("IsReaded")
.HasColumnType("bit");
b.Property<string>("Reply")
.HasColumnType("nvarchar(max)");
b.Property<string>("SenderName") b.Property<string>("SenderName")
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");

View File

@ -26,6 +26,8 @@ namespace LawFirmDatabaseImplement.Models
public string Body { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty;
public virtual Client? Client { get; private set; } public virtual Client? Client { get; private set; }
public bool IsReaded { get; private set; }
public string? Reply { get; private set; }
public static MessageInfo? Create(MessageInfoBindingModel model) public static MessageInfo? Create(MessageInfoBindingModel model)
{ {
@ -41,9 +43,21 @@ namespace LawFirmDatabaseImplement.Models
MessageId = model.MessageId, MessageId = model.MessageId,
SenderName = model.SenderName, SenderName = model.SenderName,
DateDelivery = model.DateDelivery, DateDelivery = model.DateDelivery,
IsReaded = model.IsReaded,
Reply = model.Reply
}; };
} }
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
IsReaded = model.IsReaded;
}
public MessageInfoViewModel GetViewModel => new() public MessageInfoViewModel GetViewModel => new()
{ {
Body = Body, Body = Body,
@ -52,6 +66,8 @@ namespace LawFirmDatabaseImplement.Models
MessageId = MessageId, MessageId = MessageId,
SenderName = SenderName, SenderName = SenderName,
DateDelivery = DateDelivery, DateDelivery = DateDelivery,
Reply = Reply,
IsReaded = IsReaded,
}; };
} }

View File

@ -30,10 +30,15 @@ namespace LawFirmFileImplement.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{ {
return _source.Messages var messages = _source.Messages
.Where(x => x.ClientId == model.ClientId) .Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel) .Select(x => x.GetViewModel);
.ToList();
if (!(model.Page.HasValue && model.PageSize.HasValue))
{
return messages.ToList();
}
return messages.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
} }
public List<MessageInfoViewModel> GetFullList() public List<MessageInfoViewModel> GetFullList()
@ -54,5 +59,16 @@ namespace LawFirmFileImplement.Implements
_source.SaveMessages(); _source.SaveMessages();
return newMessage.GetViewModel; return newMessage.GetViewModel;
} }
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
var message = _source.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId));
if (message != null)
{
message.Update(model);
_source.SaveMessages();
}
return message?.GetViewModel;
}
} }
} }

View File

@ -23,6 +23,8 @@ namespace LawFirmFileImplement.Models
public string Subject { get; private set; } = string.Empty; public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty;
public bool IsReaded { get; private set; }
public string? Reply { get; private set; }
public static MessageInfo? Create(MessageInfoBindingModel model) public static MessageInfo? Create(MessageInfoBindingModel model)
{ {
@ -38,6 +40,8 @@ namespace LawFirmFileImplement.Models
MessageId = model.MessageId, MessageId = model.MessageId,
SenderName = model.SenderName, SenderName = model.SenderName,
DateDelivery = model.DateDelivery, DateDelivery = model.DateDelivery,
Reply = model.Reply,
IsReaded = model.IsReaded,
}; };
} }
@ -55,9 +59,21 @@ namespace LawFirmFileImplement.Models
MessageId = element.Attribute("MessageId")!.Value, MessageId = element.Attribute("MessageId")!.Value,
SenderName = element.Attribute("SenderName")!.Value, SenderName = element.Attribute("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value), DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value),
Reply = element.Attribute("Reply")!.Value,
IsReaded = Convert.ToBoolean(element.Attribute("IsReaded")!.Value),
}; };
} }
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
IsReaded = model.IsReaded;
}
public MessageInfoViewModel GetViewModel => new() public MessageInfoViewModel GetViewModel => new()
{ {
Body = Body, Body = Body,
@ -66,6 +82,8 @@ namespace LawFirmFileImplement.Models
MessageId = MessageId, MessageId = MessageId,
SenderName = SenderName, SenderName = SenderName,
DateDelivery = DateDelivery, DateDelivery = DateDelivery,
Reply = Reply,
IsReaded = IsReaded,
}; };
public XElement GetXElement => new("MessageInfo", public XElement GetXElement => new("MessageInfo",
@ -74,7 +92,9 @@ namespace LawFirmFileImplement.Models
new XAttribute("ClientId", ClientId), new XAttribute("ClientId", ClientId),
new XAttribute("MessageId", MessageId), new XAttribute("MessageId", MessageId),
new XAttribute("SenderName", SenderName), new XAttribute("SenderName", SenderName),
new XAttribute("DateDelivery", DateDelivery) new XAttribute("DateDelivery", DateDelivery),
new XAttribute("Reply", Reply),
new XAttribute("HasRead", IsReaded)
); );
} }
} }

View File

@ -30,15 +30,29 @@ namespace LawFirmListImplements.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{ {
List<MessageInfoViewModel> result = new(); List<MessageInfoViewModel> messages = new();
foreach (var item in _source.Messages) foreach (var item in _source.Messages)
{ {
if (item.ClientId.HasValue && item.ClientId == model.ClientId) if (item.ClientId == model.ClientId)
{ {
result.Add(item.GetViewModel); messages.Add(item.GetViewModel);
} }
} }
return result;
if (!(model.Page.HasValue && model.PageSize.HasValue))
{
return messages;
}
if (model.Page * model.PageSize >= messages.Count)
{
return null;
}
List<MessageInfoViewModel> filterMessages = new();
for (var i = (model.Page.Value - 1) * model.PageSize.Value; i < model.Page.Value * model.PageSize.Value; i++)
{
filterMessages.Add(messages[i]);
}
return filterMessages;
} }
public List<MessageInfoViewModel> GetFullList() public List<MessageInfoViewModel> GetFullList()
@ -61,5 +75,18 @@ namespace LawFirmListImplements.Implements
_source.Messages.Add(newMessage); _source.Messages.Add(newMessage);
return newMessage.GetViewModel; return newMessage.GetViewModel;
} }
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
foreach (var message in _source.Messages)
{
if (message.MessageId.Equals(model.MessageId))
{
message.Update(model);
return message.GetViewModel;
}
}
return null;
}
} }
} }

View File

@ -22,6 +22,8 @@ namespace LawFirmListImplements.Models
public string Subject { get; private set; } = string.Empty; public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty;
public bool IsReaded { get; private set; }
public string? Reply { get; private set; }
public static MessageInfo? Create(MessageInfoBindingModel model) public static MessageInfo? Create(MessageInfoBindingModel model)
{ {
@ -37,9 +39,21 @@ namespace LawFirmListImplements.Models
MessageId = model.MessageId, MessageId = model.MessageId,
SenderName = model.SenderName, SenderName = model.SenderName,
DateDelivery = model.DateDelivery, DateDelivery = model.DateDelivery,
Reply = model.Reply,
IsReaded = model.IsReaded,
}; };
} }
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
IsReaded = model.IsReaded;
}
public MessageInfoViewModel GetViewModel => new() public MessageInfoViewModel GetViewModel => new()
{ {
Body = Body, Body = Body,
@ -48,6 +62,8 @@ namespace LawFirmListImplements.Models
MessageId = MessageId, MessageId = MessageId,
SenderName = SenderName, SenderName = SenderName,
DateDelivery = DateDelivery, DateDelivery = DateDelivery,
Reply = Reply,
IsReaded = IsReaded,
}; };
} }

View File

@ -13,6 +13,7 @@ namespace LawFirmRestApi.Controllers
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; private readonly IClientLogic _logic;
private readonly IMessageInfoLogic _mailLogic; private readonly IMessageInfoLogic _mailLogic;
public int pageSize = 2;
public ClientController(IClientLogic logic, IMessageInfoLogic mailLogic, ILogger<ClientController> logger) public ClientController(IClientLogic logic, IMessageInfoLogic mailLogic, ILogger<ClientController> logger)
{ {
@ -65,13 +66,15 @@ namespace LawFirmRestApi.Controllers
} }
[HttpGet] [HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId) public List<MessageInfoViewModel>? GetMessages(int clientId, int pageNum)
{ {
try try
{ {
return _mailLogic.ReadList(new MessageInfoSearchModel return _mailLogic.ReadList(new()
{ {
ClientId = clientId ClientId = clientId,
Page = pageNum,
PageSize = pageSize
}); });
} }
catch (Exception ex) catch (Exception ex)