Compare commits

...

10 Commits

78 changed files with 6527 additions and 50 deletions

View File

@ -0,0 +1,23 @@
namespace ProjectLibrary.Entities
{
using ProjectLibrary.Entities.Enums;
public class Book
{
public int Id { get; private set; }
public string Author { get; private set; } = string.Empty;
public string Name { get; private set; } = string.Empty;
public BookType TypeBookID { get; set; } = BookType.None;
public static Book CreateEntity(int id, string author, string name, BookType typeBookID = BookType.None)
{
return new Book
{
Id = id,
Author = author ?? string.Empty,
Name = name ?? string.Empty,
TypeBookID = typeBookID
};
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Entites
{
public class Book_Orders
{
public int BookID { get; private set; }
public int OrderID { get; private set; }
public int Count { get; private set; }
public static Book_Orders CreateEntity(int orderID,int bookID, int count )
{
return new Book_Orders
{
BookID = bookID,
OrderID = orderID,
Count = count
};
}
}
}

View File

@ -0,0 +1,19 @@
namespace ProjectLibrary.Entites
{
public class Book_Library
{
public int BookID { get; private set; }
public int LibraryID { get; private set; }
public int Count { get; private set; }
public static Book_Library CreateEntity(int libraryID, int bookID, int count)
{
return new Book_Library
{
BookID = bookID,
LibraryID = libraryID,
Count = count
};
}
}
}

View File

@ -0,0 +1,11 @@
namespace ProjectLibrary.Entities.Enums
{
public enum BookStatus
{
None = 0,
Available = 1,
CheckedOut = 2,
Reserved = 3,
Lost = 4
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Entities.Enums
{
[Flags]
public enum BookType
{
None = 0,
Fiction = 1,
NonFiction = 2,
Science = 4,
History = 8,
Mystery = 16,
Fantasy = 32
}
}

View File

@ -0,0 +1,32 @@
using ProjectLibrary.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Entites
{
public class Library
{
public int Id { get; private set; }
public string Name { get; private set; } = string.Empty;
public string Address { get; private set; } = string.Empty;
public IEnumerable<Book_Library> BookLibrary
{
get;
private set;
}
public static Library CreateEntity(int id, string name, string address, IEnumerable<Book_Library> bookLibrary)
{
return new Library
{
Id = id,
Name = name ?? string.Empty,
Address = address ?? string.Empty,
BookLibrary = bookLibrary
};
}
}
}

View File

@ -0,0 +1,49 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using Microsoft.VisualBasic;
using ProjectLibrary.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Entites
{
public class Orders
{
public int Id { get; private set; }
public DateTime OrderDate { get; private set; }
public DateTime ReturnDate { get; private set; }
public int ReaderID { get; private set; }
public IEnumerable<Book_Orders> BookOrders
{
get;
private set;
} = [];
public static Orders CreateEntity(int id, DateTime returnDate, int readerID, IEnumerable<Book_Orders> bookOrders)
{
return new Orders
{
Id = id,
OrderDate = DateTime.Now,
ReturnDate = returnDate,
ReaderID = readerID,
BookOrders = bookOrders
};
}
public static Orders CreateEntity(TempBookOrders tempBookOrders, IEnumerable<Book_Orders> bookOrders)
{
return new Orders
{
Id = tempBookOrders.Id,
OrderDate = tempBookOrders.OrderDate,
ReturnDate = tempBookOrders.ReturnDate,
ReaderID = tempBookOrders.ReaderID,
BookOrders = bookOrders
};
}
}
}

View File

@ -0,0 +1,21 @@
namespace ProjectLibrary.Entities
{
public class Reader
{
public int Id { get; private set; }
public string Name { get; private set; } = string.Empty;
public int ReaderTicket { get; private set; }
public DateTime RegistrationDateRT { get; private set; } // Изменение на DateTime
public static Reader CreateEntity(int id, string name, int readerTicket)
{
return new Reader
{
Id = id,
Name = name ?? string.Empty,
ReaderTicket = readerTicket,
RegistrationDateRT = DateTime.Now
};
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Entites;
public class TempBookOrders
{
public int Id { get; set; }
public DateTime OrderDate { get; set; }
public DateTime ReturnDate { get; set; }
public int ReaderID { get; set; }
public int BookID { get; set; }
public int Count { get; set; }
}

View File

@ -0,0 +1,21 @@
namespace ProjectLibrary.Entites
{
public class TicketExtensions
{
public int Id { get; private set; }
public int ReaderID { get; private set; }
public DateTime LastUpdateDate { get; private set; }
public DateTime NextUpdateDate { get; private set; }
public static TicketExtensions CreateEntity(int id, int readerID, DateTime lastUpdateDate, DateTime nextUpdateDate)
{
return new TicketExtensions
{
Id = id,
ReaderID = readerID,
LastUpdateDate = lastUpdateDate,
NextUpdateDate = nextUpdateDate
};
}
}
}

View File

@ -1,39 +0,0 @@
namespace ProjectLibrary
{
partial class Form1
{
/// <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()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace ProjectLibrary
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

168
ProjectLibrary/FormLibrary.Designer.cs generated Normal file
View File

@ -0,0 +1,168 @@
namespace ProjectLibrary
{
partial class FormLibrary
{
/// <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()
{
menuStrip1 = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
книгаToolStripMenuItem = new ToolStripMenuItem();
читателиToolStripMenuItem = new ToolStripMenuItem();
библиотекиToolStripMenuItem = new ToolStripMenuItem();
операцииToolStripMenuItem = new ToolStripMenuItem();
обновлениеБилетаToolStripMenuItem = new ToolStripMenuItem();
заказатьКнигиToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
DocReportToolStripMenuItem = new ToolStripMenuItem();
bookReportToolStripMenuItem = new ToolStripMenuItem();
OrderDistributionToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.BackColor = Color.SlateGray;
menuStrip1.ImageScalingSize = new Size(20, 20);
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, операцииToolStripMenuItem, отчетыToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Padding = new Padding(6, 3, 0, 3);
menuStrip1.Size = new Size(832, 30);
menuStrip1.TabIndex = 0;
menuStrip1.Text = "menuStrip";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { книгаToolStripMenuItem, читателиToolStripMenuItem, библиотекиToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(117, 24);
справочникиToolStripMenuItem.Text = "Справочники";
//
// книгаToolStripMenuItem
//
книгаToolStripMenuItem.Name = "книгаToolStripMenuItem";
книгаToolStripMenuItem.Size = new Size(175, 26);
книгаToolStripMenuItem.Text = "Книга";
книгаToolStripMenuItem.Click += книгаToolStripMenuItem_Click;
//
// читателиToolStripMenuItem
//
читателиToolStripMenuItem.Name = "читателиToolStripMenuItem";
читателиToolStripMenuItem.Size = new Size(175, 26);
читателиToolStripMenuItem.Text = "Читатели";
читателиToolStripMenuItem.Click += читателиToolStripMenuItem_Click;
//
// библиотекиToolStripMenuItem
//
библиотекиToolStripMenuItem.Name = "библиотекиToolStripMenuItem";
библиотекиToolStripMenuItem.Size = new Size(175, 26);
библиотекиToolStripMenuItem.Text = "Библиотеки";
библиотекиToolStripMenuItem.Click += библиотекиToolStripMenuItem_Click;
//
// операцииToolStripMenuItem
//
операцииToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { обновлениеБилетаToolStripMenuItem, заказатьКнигиToolStripMenuItem });
операцииToolStripMenuItem.Name = "операцииToolStripMenuItem";
операцииToolStripMenuItem.Size = new Size(95, 24);
операцииToolStripMenuItem.Text = "Операции";
//
// обновлениеБилетаToolStripMenuItem
//
обновлениеБилетаToolStripMenuItem.Name = "обновлениеБилетаToolStripMenuItem";
обновлениеБилетаToolStripMenuItem.Size = new Size(232, 26);
обновлениеБилетаToolStripMenuItem.Text = "Обновление билета";
обновлениеБилетаToolStripMenuItem.Click += обновлениеБилетаToolStripMenuItem_Click;
//
// заказатьКнигиToolStripMenuItem
//
заказатьКнигиToolStripMenuItem.Name = аказатьКнигиToolStripMenuItem";
заказатьКнигиToolStripMenuItem.Size = new Size(232, 26);
заказатьКнигиToolStripMenuItem.Text = "Заказать книги";
заказатьКнигиToolStripMenuItem.Click += заказатьКнигиToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { DocReportToolStripMenuItem, bookReportToolStripMenuItem, OrderDistributionToolStripMenuItem });
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(73, 24);
отчетыToolStripMenuItem.Text = "Отчеты";
//
// DocReportToolStripMenuItem
//
DocReportToolStripMenuItem.Name = "DocReportToolStripMenuItem";
DocReportToolStripMenuItem.Size = new Size(294, 26);
DocReportToolStripMenuItem.Text = "Документ со справочниками";
DocReportToolStripMenuItem.Click += DocReportToolStripMenuItem_Click;
//
// bookReportToolStripMenuItem
//
bookReportToolStripMenuItem.Name = "bookReportToolStripMenuItem";
bookReportToolStripMenuItem.Size = new Size(294, 26);
bookReportToolStripMenuItem.Text = "Движение книг";
bookReportToolStripMenuItem.Click += BookReportToolStripMenuItem_Click;
//
// OrderDistributionToolStripMenuItem
//
OrderDistributionToolStripMenuItem.Name = "OrderDistributionToolStripMenuItem";
OrderDistributionToolStripMenuItem.Size = new Size(294, 26);
OrderDistributionToolStripMenuItem.Text = "Кол-во книг в библиотеках";
OrderDistributionToolStripMenuItem.Click += OrderDistributionToolStripMenuItem_Click;
//
// FormLibrary
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = SystemColors.ButtonHighlight;
BackgroundImage = Properties.Resources.Снимок_экрана_2024_11_19_132940;
ClientSize = new Size(832, 453);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "FormLibrary";
StartPosition = FormStartPosition.CenterScreen;
Text = "Библиотека";
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip1;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem книгаToolStripMenuItem;
private ToolStripMenuItem операцииToolStripMenuItem;
private ToolStripMenuItem обновлениеБилетаToolStripMenuItem;
private ToolStripMenuItem отчетыToolStripMenuItem;
private ToolStripMenuItem читателиToolStripMenuItem;
private ToolStripMenuItem библиотекиToolStripMenuItem;
private ToolStripMenuItem заказатьКнигиToolStripMenuItem;
private ToolStripMenuItem DocReportToolStripMenuItem;
private ToolStripMenuItem bookReportToolStripMenuItem;
private ToolStripMenuItem OrderDistributionToolStripMenuItem;
}
}

View File

@ -0,0 +1,111 @@
using Unity;
namespace ProjectLibrary
{
public partial class FormLibrary : Form
{
private readonly IUnityContainer _container;
public FormLibrary(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void ÷èòàòåëèToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FReaders>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void çàêàçàòüÊíèãèToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FOrders>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void êíèãàToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FBooks>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void áèáëèîòåêèToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FLibraries>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void îáíîâëåíèåÁèëåòàToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FTiclet_Extensions>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DocReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FDocReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void BookReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FBookReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void OrderDistributionToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<Forms.FOrderDistributionReport>().ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

136
ProjectLibrary/Forms/FBook.Designer.cs generated Normal file
View File

@ -0,0 +1,136 @@
namespace ProjectLibrary.Forms
{
partial class FBook
{
/// <summary>
/// Обязательная переменная конструктора
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Очистка всех используемых ресурсов
/// </summary>
/// <param name="disposing">true, если управляемые ресурсы нужно освободить; иначе false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором Windows Form Designer
/// <summary>
/// Требуемый метод для поддержки конструктора - не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
lblAuthor = new Label();
txtAuthor = new TextBox();
lblName = new Label();
txtName = new TextBox();
lblType = new Label();
btnSave = new Button();
buttonCancel_Click = new Button();
checkedListBox1 = new CheckedListBox();
SuspendLayout();
//
// lblAuthor
//
lblAuthor.AutoSize = true;
lblAuthor.Location = new Point(19, 25);
lblAuthor.Name = "lblAuthor";
lblAuthor.Size = new Size(54, 20);
lblAuthor.TabIndex = 2;
lblAuthor.Text = "Автор:";
//
// txtAuthor
//
txtAuthor.Location = new Point(105, 25);
txtAuthor.Name = "txtAuthor";
txtAuthor.Size = new Size(246, 27);
txtAuthor.TabIndex = 3;
//
// lblName
//
lblName.AutoSize = true;
lblName.Location = new Point(19, 65);
lblName.Name = "lblName";
lblName.Size = new Size(80, 20);
lblName.TabIndex = 4;
lblName.Text = "Название:";
//
// txtName
//
txtName.Location = new Point(105, 65);
txtName.Name = "txtName";
txtName.Size = new Size(246, 27);
txtName.TabIndex = 5;
//
// lblType
//
lblType.AutoSize = true;
lblType.Location = new Point(19, 105);
lblType.Name = "lblType";
lblType.Size = new Size(38, 20);
lblType.TabIndex = 6;
lblType.Text = "Тип:";
//
// btnSave
//
btnSave.Location = new Point(19, 266);
btnSave.Name = "btnSave";
btnSave.Size = new Size(100, 30);
btnSave.TabIndex = 10;
btnSave.Text = "Сохранить";
btnSave.UseVisualStyleBackColor = true;
btnSave.Click += btnSave_Click;
//
// buttonCancel_Click
//
buttonCancel_Click.Location = new Point(251, 266);
buttonCancel_Click.Name = "buttonCancel_Click";
buttonCancel_Click.Size = new Size(100, 30);
buttonCancel_Click.TabIndex = 11;
buttonCancel_Click.Text = "Отмена";
buttonCancel_Click.Click += ButtonCancel_Click;
//
// checkedListBox1
//
checkedListBox1.FormattingEnabled = true;
checkedListBox1.Location = new Point(105, 105);
checkedListBox1.Name = "checkedListBox1";
checkedListBox1.Size = new Size(246, 114);
checkedListBox1.TabIndex = 13;
//
// FBook
//
ClientSize = new Size(400, 300);
Controls.Add(checkedListBox1);
Controls.Add(buttonCancel_Click);
Controls.Add(lblAuthor);
Controls.Add(txtAuthor);
Controls.Add(lblName);
Controls.Add(txtName);
Controls.Add(lblType);
Controls.Add(btnSave);
Name = "FBook";
Text = "Книга";
ResumeLayout(false);
PerformLayout();
}
#endregion
private System.Windows.Forms.Label lblAuthor;
private System.Windows.Forms.TextBox txtAuthor;
private System.Windows.Forms.Label lblName;
private System.Windows.Forms.TextBox txtName;
private System.Windows.Forms.Label lblType;
private System.Windows.Forms.Button btnSave;
private Button buttonCancel_Click;
private CheckedListBox checkedListBox1;
}
}

View File

@ -0,0 +1,102 @@
using ProjectLibrary.Entities;
using ProjectLibrary.Entities.Enums;
using ProjectLibrary.Repositores;
using ProjectLibrary.Repositories;
namespace ProjectLibrary.Forms
{
public partial class FBook : Form
{
private readonly IBookRepository _bookRepository;
private int? _bookId;
public int Id
{
set
{
try
{
var book = _bookRepository.ReadBookById(value);
if (book == null)
{
throw new InvalidOperationException("Книга не найдена.");
}
txtAuthor.Text = book.Author;
txtName.Text = book.Name;
//checkedListBox1.SelectedItem = book.TypeBookID;
char[] listInd = Convert.ToString((int)book.TypeBookID, 2).ToCharArray();
for (int i = 0; i < listInd.Length; i++)
{
checkedListBox1.SetItemChecked(i, listInd[i]=='1');
}
_bookId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public FBook(IBookRepository bookRepository)
{
InitializeComponent();
_bookRepository = bookRepository ?? throw new ArgumentNullException(nameof(bookRepository));
foreach(var elem in Enum.GetValues(typeof(BookType)))
{
if (!elem.Equals(BookType.None)) checkedListBox1.Items.Add(elem);
}
}
private void btnSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(txtAuthor.Text) || string.IsNullOrWhiteSpace(txtName.Text))
{
throw new Exception("Имеются незаполненные поля.");
}
if (_bookId.HasValue)
{
_bookRepository.UpdateBook(CreateBook(_bookId.Value));
}
else
{
_bookRepository.CreateBook(CreateBook(0));
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private Book CreateBook(int bookId)
{
BookType selectedType = BookType.None;
foreach (var item in checkedListBox1.CheckedItems)
{
if (item is BookType type)
{
selectedType |= type; // Это должно работать, если тип является BookType
}
}
return Book.CreateEntity(bookId, txtAuthor.Text, txtName.Text, selectedType);
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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

@ -0,0 +1,142 @@
namespace ProjectLibrary.Forms
{
partial class FBookReport
{
/// <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();
label3 = new Label();
label4 = new Label();
textBoxFilePath = new TextBox();
dateTimePickerStartDate = new DateTimePicker();
dateTimePickerEndDate = new DateTimePicker();
buttonSelectFilePath = new Button();
buttonMakeReport = new Button();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(22, 20);
label1.Name = "label1";
label1.Size = new Size(112, 20);
label1.TabIndex = 0;
label1.Text = "Путь до файла:";
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(22, 84);
label3.Name = "label3";
label3.Size = new Size(97, 20);
label3.TabIndex = 2;
label3.Text = "Дата начала:";
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(22, 135);
label4.Name = "label4";
label4.Size = new Size(90, 20);
label4.TabIndex = 3;
label4.Text = "Дата конца:";
//
// textBoxFilePath
//
textBoxFilePath.Location = new Point(188, 20);
textBoxFilePath.Name = "textBoxFilePath";
textBoxFilePath.ReadOnly = true;
textBoxFilePath.Size = new Size(147, 27);
textBoxFilePath.TabIndex = 4;
//
// dateTimePickerStartDate
//
dateTimePickerStartDate.Location = new Point(188, 84);
dateTimePickerStartDate.Name = "dateTimePickerStartDate";
dateTimePickerStartDate.Size = new Size(181, 27);
dateTimePickerStartDate.TabIndex = 5;
//
// dateTimePickerEndDate
//
dateTimePickerEndDate.Location = new Point(188, 130);
dateTimePickerEndDate.Name = "dateTimePickerEndDate";
dateTimePickerEndDate.Size = new Size(181, 27);
dateTimePickerEndDate.TabIndex = 6;
//
// buttonSelectFilePath
//
buttonSelectFilePath.BackColor = SystemColors.Control;
buttonSelectFilePath.Location = new Point(341, 20);
buttonSelectFilePath.Name = "buttonSelectFilePath";
buttonSelectFilePath.Size = new Size(28, 29);
buttonSelectFilePath.TabIndex = 7;
buttonSelectFilePath.Text = "..";
buttonSelectFilePath.UseVisualStyleBackColor = false;
buttonSelectFilePath.Click += ButtonSelectFilePath_Click;
//
// buttonMakeReport
//
buttonMakeReport.BackColor = SystemColors.Control;
buttonMakeReport.Location = new Point(22, 191);
buttonMakeReport.Name = "buttonMakeReport";
buttonMakeReport.Size = new Size(347, 29);
buttonMakeReport.TabIndex = 9;
buttonMakeReport.Text = "Сформировать";
buttonMakeReport.UseVisualStyleBackColor = false;
buttonMakeReport.Click += ButtonMakeReport_Click;
//
// FBookReport
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(409, 262);
Controls.Add(buttonMakeReport);
Controls.Add(buttonSelectFilePath);
Controls.Add(dateTimePickerEndDate);
Controls.Add(dateTimePickerStartDate);
Controls.Add(textBoxFilePath);
Controls.Add(label4);
Controls.Add(label3);
Controls.Add(label1);
Name = "FBookReport";
Text = "Движение книг";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label1;
private Label label3;
private Label label4;
private TextBox textBoxFilePath;
private DateTimePicker dateTimePickerStartDate;
private DateTimePicker dateTimePickerEndDate;
private Button buttonSelectFilePath;
private Button buttonMakeReport;
}
}

View File

@ -0,0 +1,66 @@
using ProjectLibrary.Reports;
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;
using Unity;
namespace ProjectLibrary.Forms
{
public partial class FBookReport : Form
{
IUnityContainer _container;
public FBookReport(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void ButtonSelectFilePath_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
Filter = "Excel Files | *.xlsx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
return;
}
textBoxFilePath.Text = sfd.FileName;
}
private void ButtonMakeReport_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(textBoxFilePath.Text))
{
throw new Exception("Отсутствует имя файла для отчета");
}
if (dateTimePickerEndDate.Value <= dateTimePickerStartDate.Value)
{
throw new Exception("Дата начала должна быть раньше даты окончания");
}
if (_container.Resolve<TableReport>().CreateTable(textBoxFilePath.Text,
dateTimePickerStartDate.Value, dateTimePickerEndDate.Value))
{
MessageBox.Show("Документ сформирован", "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах", "Формирование документа",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при создании очета", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>

106
ProjectLibrary/Forms/FBooks.Designer.cs generated Normal file
View File

@ -0,0 +1,106 @@
namespace ProjectLibrary.Forms
{
partial class FBooks
{
/// <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()
{
dataGridViewBooks = new DataGridView();
buttonAdd = new Button();
buttonUpdate = new Button();
buttonRemove = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewBooks).BeginInit();
SuspendLayout();
//
// dataGridViewBooks
//
dataGridViewBooks.AllowUserToAddRows = false;
dataGridViewBooks.AllowUserToDeleteRows = false;
dataGridViewBooks.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewBooks.Location = new Point(10, 9);
dataGridViewBooks.Margin = new Padding(3, 2, 3, 2);
dataGridViewBooks.Name = "dataGridViewBooks";
dataGridViewBooks.ReadOnly = true;
dataGridViewBooks.RowHeadersWidth = 51;
dataGridViewBooks.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewBooks.Size = new Size(602, 254);
dataGridViewBooks.TabIndex = 8;
//
// buttonAdd
//
buttonAdd.Location = new Point(27, 267);
buttonAdd.Margin = new Padding(3, 2, 3, 2);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(161, 37);
buttonAdd.TabIndex = 9;
buttonAdd.Text = "Добавить";
buttonAdd.Click += buttonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(247, 267);
buttonUpdate.Margin = new Padding(3, 2, 3, 2);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(161, 37);
buttonUpdate.TabIndex = 10;
buttonUpdate.Text = "Изменить";
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonRemove
//
buttonRemove.Location = new Point(452, 267);
buttonRemove.Margin = new Padding(3, 2, 3, 2);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(161, 37);
buttonRemove.TabIndex = 11;
buttonRemove.Text = "Удалить";
buttonRemove.Click += buttonRemove_Click;
//
// FBooks
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(700, 338);
Controls.Add(dataGridViewBooks);
Controls.Add(buttonAdd);
Controls.Add(buttonUpdate);
Controls.Add(buttonRemove);
Margin = new Padding(3, 2, 3, 2);
Name = "FBooks";
Text = "FBooks";
Load += FBooks_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewBooks).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewBooks;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonRemove;
}
}

View File

@ -0,0 +1,122 @@
using ProjectLibrary.Repositores;
using Unity;
namespace ProjectLibrary.Forms
{
public partial class FBooks : Form
{
private readonly IUnityContainer _container;
private readonly IBookRepository _bookRepository;
public FBooks(IUnityContainer container, IBookRepository bookRepository)
{
InitializeComponent(); // Инициализация компонентов формы, включая DataGridView.
_container = container ?? throw new ArgumentNullException(nameof(container));
_bookRepository = bookRepository ?? throw new ArgumentNullException(nameof(bookRepository));
}
private void LoadList()
{
// Привязывает к DataGridView коллекцию книг, полученную из репозитория.
// Устанавливает источник данных DataGridView (dataGridViewBooks) как список объектов из ReadBooks().
dataGridViewBooks.DataSource = _bookRepository.ReadBooks();
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
// Проверяет, выбрана ли хотя бы одна строка в DataGridView.
if (dataGridViewBooks.SelectedRows.Count < 1)
{
// Если строка не выбрана, отображает сообщение об ошибке.
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
// Извлекает идентификатор (ID) из выбранной строки, используя значение ячейки столбца "Id".
id = Convert.ToInt32(dataGridViewBooks.SelectedRows[0].Cells["Id"].Value);
return true;
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
// Открывает форму добавления книги.
_container.Resolve<FBook>().ShowDialog();
// После добавления обновляет список записей в DataGridView.
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
// Получает ID выбранной строки из DataGridView.
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
// Открывает форму редактирования книги с указанным ID.
var form = _container.Resolve<FBook>();
form.Id = findId;
form.ShowDialog();
// После редактирования обновляет список записей в DataGridView.
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
// Получает ID выбранной строки из DataGridView.
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
// Подтверждение удаления записи.
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
// Удаляет запись через репозиторий.
_bookRepository.DeleteBook(findId);
// После удаления обновляет список записей в DataGridView.
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FBooks_Load(object sender, EventArgs e)
{
try
{
// При загрузке формы заполняет DataGridView данными из репозитория.
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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

@ -0,0 +1,100 @@
namespace ProjectLibrary.Forms
{
partial class FDocReport
{
/// <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()
{
checkBoxBooks = new CheckBox();
checkBoxReaders = new CheckBox();
checkBoxIncludeTicketExtensions = new CheckBox();
buttonCreate = new Button();
SuspendLayout();
//
// checkBoxBooks
//
checkBoxBooks.AutoSize = true;
checkBoxBooks.Location = new Point(54, 34);
checkBoxBooks.Name = "checkBoxBooks";
checkBoxBooks.Size = new Size(73, 24);
checkBoxBooks.TabIndex = 0;
checkBoxBooks.Text = "Книги";
checkBoxBooks.UseVisualStyleBackColor = true;
//
// checkBoxReaders
//
checkBoxReaders.AutoSize = true;
checkBoxReaders.Location = new Point(54, 101);
checkBoxReaders.Name = "checkBoxReaders";
checkBoxReaders.Size = new Size(95, 24);
checkBoxReaders.TabIndex = 1;
checkBoxReaders.Text = "Читатели";
checkBoxReaders.UseVisualStyleBackColor = true;
//
// checkBoxIncludeTicketExtensions
//
checkBoxIncludeTicketExtensions.AutoSize = true;
checkBoxIncludeTicketExtensions.Location = new Point(54, 170);
checkBoxIncludeTicketExtensions.Name = "checkBoxIncludeTicketExtensions";
checkBoxIncludeTicketExtensions.Size = new Size(114, 24);
checkBoxIncludeTicketExtensions.TabIndex = 2;
checkBoxIncludeTicketExtensions.Text = "Библиотеки";
checkBoxIncludeTicketExtensions.UseVisualStyleBackColor = true;
//
// buttonCreate
//
buttonCreate.BackColor = SystemColors.Control;
buttonCreate.Location = new Point(278, 101);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(133, 29);
buttonCreate.TabIndex = 3;
buttonCreate.Text = "Сформировать";
buttonCreate.UseVisualStyleBackColor = false;
buttonCreate.Click += ButtonCreate_Click;
//
// FormDocReport
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(484, 236);
Controls.Add(buttonCreate);
Controls.Add(checkBoxIncludeTicketExtensions);
Controls.Add(checkBoxReaders);
Controls.Add(checkBoxBooks);
Name = "FormDocReport";
Text = "Выгрузка справочников";
ResumeLayout(false);
PerformLayout();
}
#endregion
private CheckBox checkBoxBooks;
private CheckBox checkBoxReaders;
private CheckBox checkBoxIncludeTicketExtensions;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,58 @@
using ProjectLibrary.Reports;
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;
using Unity;
namespace ProjectLibrary.Forms;
public partial class FDocReport : Form
{
private readonly IUnityContainer _container;
public FDocReport(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void ButtonCreate_Click(object sender, EventArgs e)
{
try
{
if (!checkBoxBooks.Checked && !checkBoxReaders.Checked && !checkBoxIncludeTicketExtensions.Checked)
{
throw new Exception("Не выбран ни один справочник для выгрузки");
}
var sfd = new SaveFileDialog()
{
Filter = "Docx Files | *.docx"
};
if (sfd.ShowDialog() != DialogResult.OK)
{
throw new Exception("Не выбран файла для отчета");
}
if (_container.Resolve<DocReport>().CreateDoc(sfd.FileName, checkBoxBooks.Checked,
checkBoxReaders.Checked, checkBoxIncludeTicketExtensions.Checked))
{
MessageBox.Show("Документ сформирован", "Формирование документа",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах",
"Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при создании отчета", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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

@ -0,0 +1,105 @@
namespace ProjectLibrary.Forms
{
partial class FLibraries
{
/// <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()
{
dataGridViewOrders = new DataGridView();
buttonAdd = new Button();
buttonUpdate = new Button();
buttonRemove = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).BeginInit();
SuspendLayout();
//
// dataGridViewOrders
//
dataGridViewOrders.AllowUserToAddRows = false;
dataGridViewOrders.AllowUserToDeleteRows = false;
dataGridViewOrders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewOrders.Location = new Point(12, 11);
dataGridViewOrders.Margin = new Padding(3, 2, 3, 2);
dataGridViewOrders.Name = "dataGridViewOrders";
dataGridViewOrders.ReadOnly = true;
dataGridViewOrders.RowHeadersWidth = 51;
dataGridViewOrders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewOrders.Size = new Size(525, 225);
dataGridViewOrders.TabIndex = 8;
//
// buttonAdd
//
buttonAdd.Location = new Point(12, 251);
buttonAdd.Margin = new Padding(3, 2, 3, 2);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(88, 22);
buttonAdd.TabIndex = 9;
buttonAdd.Text = "Добавить";
buttonAdd.Click += buttonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(227, 251);
buttonUpdate.Margin = new Padding(3, 2, 3, 2);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(88, 22);
buttonUpdate.TabIndex = 10;
buttonUpdate.Text = "Изменить";
buttonUpdate.Click += buttonUpdate_Click;
//
// buttonRemove
//
buttonRemove.Location = new Point(450, 251);
buttonRemove.Margin = new Padding(3, 2, 3, 2);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(88, 22);
buttonRemove.TabIndex = 11;
buttonRemove.Text = "Удалить";
buttonRemove.Click += buttonRemove_Click;
//
// FLibraries
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(562, 283);
Controls.Add(dataGridViewOrders);
Controls.Add(buttonAdd);
Controls.Add(buttonUpdate);
Controls.Add(buttonRemove);
Name = "FLibraries";
Text = "FLibraries";
Load += FLibraries_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewOrders;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonRemove;
}
}

View File

@ -0,0 +1,102 @@
using ProjectLibrary.Repositories;
using Unity;
namespace ProjectLibrary.Forms
{
public partial class FLibraries : Form
{
private readonly IUnityContainer _container;
private readonly ILibraryRepository _libraryRepository;
public FLibraries(IUnityContainer container, ILibraryRepository libraryRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_libraryRepository = libraryRepository ?? throw new ArgumentNullException(nameof(libraryRepository));
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FLibrary>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FLibrary>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_libraryRepository.DeleteLibrary(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FLibraries_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridViewOrders.DataSource = _libraryRepository.ReadLibraries();
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewOrders.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewOrders.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>

132
ProjectLibrary/Forms/FLibrary.Designer.cs generated Normal file
View File

@ -0,0 +1,132 @@
namespace ProjectLibrary.Forms
{
partial class FLibrary
{
private System.ComponentModel.IContainer components = null;
private Label lblName;
private TextBox txtName;
private Label lblAddress;
private TextBox txtAddress;
private Button ButtonSave;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
lblName = new Label();
txtName = new TextBox();
lblAddress = new Label();
txtAddress = new TextBox();
ButtonSave = new Button();
buttonCancel_Click = new Button();
dataGridView = new DataGridView();
Book = new DataGridViewComboBoxColumn();
Count = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// lblName
//
lblName.AutoSize = true;
lblName.Location = new Point(20, 9);
lblName.Name = "lblName";
lblName.Size = new Size(62, 15);
lblName.TabIndex = 2;
lblName.Text = "Название:";
//
// txtName
//
txtName.Location = new Point(100, 12);
txtName.Name = "txtName";
txtName.Size = new Size(200, 23);
txtName.TabIndex = 3;
//
// lblAddress
//
lblAddress.AutoSize = true;
lblAddress.Location = new Point(20, 49);
lblAddress.Name = "lblAddress";
lblAddress.Size = new Size(43, 15);
lblAddress.TabIndex = 4;
lblAddress.Text = "Адрес:";
//
// txtAddress
//
txtAddress.Location = new Point(100, 49);
txtAddress.Name = "txtAddress";
txtAddress.Size = new Size(200, 23);
txtAddress.TabIndex = 5;
//
// ButtonSave
//
ButtonSave.Location = new Point(20, 224);
ButtonSave.Name = "ButtonSave";
ButtonSave.Size = new Size(100, 27);
ButtonSave.TabIndex = 14;
ButtonSave.Text = "Сохранить";
ButtonSave.Click += ButtonSave_Click;
//
// buttonCancel_Click
//
buttonCancel_Click.Location = new Point(200, 222);
buttonCancel_Click.Name = "buttonCancel_Click";
buttonCancel_Click.Size = new Size(100, 30);
buttonCancel_Click.TabIndex = 10;
buttonCancel_Click.Text = "Отмена";
buttonCancel_Click.Click += buttonCancel_Click_Click;
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { Book, Count });
dataGridView.Location = new Point(20, 93);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.Size = new Size(280, 123);
dataGridView.TabIndex = 13;
//
// Book
//
Book.HeaderText = "Book";
Book.MinimumWidth = 6;
Book.Name = "Book";
Book.SortMode = DataGridViewColumnSortMode.Automatic;
Book.Width = 125;
//
// Count
//
Count.HeaderText = "Count";
Count.MinimumWidth = 6;
Count.Name = "Count";
Count.Width = 125;
//
// FLibrary
//
ClientSize = new Size(400, 436);
Controls.Add(dataGridView);
Controls.Add(buttonCancel_Click);
Controls.Add(lblName);
Controls.Add(txtName);
Controls.Add(lblAddress);
Controls.Add(txtAddress);
Controls.Add(ButtonSave);
Name = "FLibrary";
Text = "Библиотека";
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
private Button buttonCancel_Click;
private DataGridView dataGridView;
private DataGridViewComboBoxColumn Book;
private DataGridViewTextBoxColumn Count;
}
}

View File

@ -0,0 +1,113 @@
using ProjectLibrary.Entites;
using ProjectLibrary.Repositores;
using ProjectLibrary.Repositories;
using ProjectLibrary.Repositories.Implementations;
using System.Windows.Forms;
namespace ProjectLibrary.Forms
{
public partial class FLibrary : Form
{
private readonly ILibraryRepository _libraryRepository;
private int? _orderId;
public int Id
{
set
{
try
{
var library = _libraryRepository.ReadLibraryById(value);
if (library == null)
{
throw new InvalidOperationException("Заказ не найден.");
}
txtName.Text = library.Name;
txtAddress.Text = library.Address;
SetListBooksToDataGrid(library.BookLibrary);
_orderId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public FLibrary(ILibraryRepository libraryRepository, IBookRepository bookRepository)
{
InitializeComponent();
_libraryRepository = libraryRepository ?? throw new ArgumentNullException(nameof(libraryRepository));
Book.DataSource = bookRepository.ReadBooks();
Book.DisplayMember = "Name";
Book.ValueMember = "Id";
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(txtName.Text) || string.IsNullOrWhiteSpace(txtAddress.Text))
{
throw new Exception("Не все поля заполнены.");
}
var library = Library.CreateEntity(
_orderId ?? 0,
txtName.Text,
txtAddress.Text,
CreateListBooksFromDataGrid()
);
if (_orderId.HasValue)
{
_libraryRepository.UpdateLibrary(library);
}
else
{
_libraryRepository.CreateLibrary(library);
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click_Click(object sender, EventArgs e)
{
Close();
}
private List<Book_Library> CreateListBooksFromDataGrid()
{
var list = new List<Book_Library>();
foreach (DataGridViewRow row in dataGridView.Rows)
{
if (row.Cells["Book"].Value == null || row.Cells["Count"].Value == null)
{
continue;
}
list.Add(Book_Library.CreateEntity(0, Convert.ToInt32(row.Cells["Book"].Value), Convert.ToInt32(row.Cells["Count"].Value)));
}
return list;
}
private void SetListBooksToDataGrid(IEnumerable<Book_Library> list)
{
int index = 0;
foreach (Book_Library elem in list)
{
dataGridView.Rows.Add();
dataGridView.Rows[index].Cells["Book"].Value = elem.BookID;
dataGridView.Rows[index].Cells["Count"].Value = elem.Count;
index++;
}
}
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>
<metadata name="Book.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Count.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

166
ProjectLibrary/Forms/FOrder.Designer.cs generated Normal file
View File

@ -0,0 +1,166 @@
namespace ProjectLibrary.Forms
{
partial class FOrder
{
private System.ComponentModel.IContainer components = null;
private Label lblOrderDate;
private Label lblReturnDate;
private Label lblReaderID;
private Label lblBookID;
private Button btnSave;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
lblOrderDate = new Label();
lblReturnDate = new Label();
lblReaderID = new Label();
lblBookID = new Label();
btnSave = new Button();
buttonCancel_Click = new Button();
comboBox = new ComboBox();
dataGridViewBook = new DataGridView();
dtpOrderDate = new DateTimePicker();
dtptxtReturnDate = new DateTimePicker();
Book = new DataGridViewComboBoxColumn();
ColumnCount = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)dataGridViewBook).BeginInit();
SuspendLayout();
//
// lblOrderDate
//
lblOrderDate.AutoSize = true;
lblOrderDate.Location = new Point(12, 25);
lblOrderDate.Name = "lblOrderDate";
lblOrderDate.Size = new Size(93, 20);
lblOrderDate.TabIndex = 2;
lblOrderDate.Text = "Дата заказа:";
//
// lblReturnDate
//
lblReturnDate.AutoSize = true;
lblReturnDate.Location = new Point(12, 65);
lblReturnDate.Name = "lblReturnDate";
lblReturnDate.Size = new Size(111, 20);
lblReturnDate.TabIndex = 4;
lblReturnDate.Text = "Дата возврата:";
//
// lblReaderID
//
lblReaderID.AutoSize = true;
lblReaderID.Location = new Point(12, 105);
lblReaderID.Name = "lblReaderID";
lblReaderID.Size = new Size(92, 20);
lblReaderID.TabIndex = 6;
lblReaderID.Text = "ID читателя:";
//
// lblBookID
//
lblBookID.AutoSize = true;
lblBookID.Location = new Point(12, 145);
lblBookID.Name = "lblBookID";
lblBookID.Size = new Size(71, 20);
lblBookID.TabIndex = 8;
lblBookID.Text = "ID книги:";
//
// btnSave
//
btnSave.Location = new Point(23, 238);
btnSave.Name = "btnSave";
btnSave.Size = new Size(100, 30);
btnSave.TabIndex = 10;
btnSave.Text = "Сохранить";
btnSave.Click += ButtonSave_Click;
//
// buttonCancel_Click
//
buttonCancel_Click.Location = new Point(327, 238);
buttonCancel_Click.Name = "buttonCancel_Click";
buttonCancel_Click.Size = new Size(100, 30);
buttonCancel_Click.TabIndex = 11;
buttonCancel_Click.Text = "Отмена";
buttonCancel_Click.Click += ButtonCancel_Click;
//
// comboBox
//
comboBox.Location = new Point(129, 108);
comboBox.Name = "comboBox";
comboBox.Size = new Size(298, 28);
comboBox.TabIndex = 0;
//
// dataGridViewBook
//
dataGridViewBook.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewBook.Columns.AddRange(new DataGridViewColumn[] { Book, ColumnCount });
dataGridViewBook.Location = new Point(129, 151);
dataGridViewBook.Name = "dataGridViewBook";
dataGridViewBook.RowHeadersWidth = 51;
dataGridViewBook.Size = new Size(298, 81);
dataGridViewBook.TabIndex = 12;
//
// dtpOrderDate
//
dtpOrderDate.Enabled = false;
dtpOrderDate.Location = new Point(129, 20);
dtpOrderDate.Name = "dtpOrderDate";
dtpOrderDate.Size = new Size(298, 27);
dtpOrderDate.TabIndex = 13;
//
// dtptxtReturnDate
//
dtptxtReturnDate.Location = new Point(129, 60);
dtptxtReturnDate.Name = "dtptxtReturnDate";
dtptxtReturnDate.Size = new Size(298, 27);
dtptxtReturnDate.TabIndex = 14;
//
// Book
//
Book.HeaderText = "Book";
Book.MinimumWidth = 6;
Book.Name = "Book";
Book.Width = 125;
//
// ColumnCount
//
ColumnCount.HeaderText = "Count";
ColumnCount.MinimumWidth = 6;
ColumnCount.Name = "ColumnCount";
ColumnCount.Width = 125;
//
// FOrder
//
ClientSize = new Size(455, 294);
Controls.Add(dtptxtReturnDate);
Controls.Add(dtpOrderDate);
Controls.Add(dataGridViewBook);
Controls.Add(comboBox);
Controls.Add(buttonCancel_Click);
Controls.Add(lblOrderDate);
Controls.Add(lblReturnDate);
Controls.Add(lblReaderID);
Controls.Add(lblBookID);
Controls.Add(btnSave);
Name = "FOrder";
Text = "Заказы";
((System.ComponentModel.ISupportInitialize)dataGridViewBook).EndInit();
ResumeLayout(false);
PerformLayout();
}
private Button buttonCancel_Click;
private ComboBox comboBox;
private DataGridView dataGridViewBook;
private DateTimePicker dtpOrderDate;
private DateTimePicker dtptxtReturnDate;
private DataGridViewComboBoxColumn Book;
private DataGridViewTextBoxColumn ColumnCount;
}
}

View File

@ -0,0 +1,73 @@
using ProjectLibrary.Repositories;
using ProjectLibrary.Entites;
using System.Xml.Linq;
using ProjectLibrary.Repositores;
using System.Windows.Forms;
namespace ProjectLibrary.Forms
{
public partial class FOrder : Form
{
private readonly IOrderRepository _orderRepository;
private readonly IBookRepository _bookRepository;
public FOrder(IOrderRepository orderRepository, IReaderRepository _readerRepository, IBookRepository bookRepository)
{
InitializeComponent();
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_bookRepository = bookRepository ?? throw new ArgumentNullException(nameof(_bookRepository));
comboBox.DataSource = _readerRepository.ReadReaders();
comboBox.DisplayMember = "Name";
comboBox.ValueMember = "Id";
Book.DataSource = bookRepository.ReadBooks();
Book.DisplayMember = "Name";
Book.ValueMember = "Id";
}
private List<Book_Orders> CreateListBooksFromDataGrid()
{
var list = new List<Book_Orders>();
foreach (DataGridViewRow row in dataGridViewBook.Rows)
{
if (row.Cells["Book"].Value == null)
{
continue;
}
list.Add(Book_Orders.CreateEntity(0, Convert.ToInt32(row.Cells["Book"].Value), Convert.ToInt32(row.Cells["ColumnCount"].Value)));
}
return list;
}
private void ButtonSave_Click(object sender, EventArgs e)
{
try
{
if (comboBox.SelectedItem == null)
{
throw new Exception("Не все поля заполнены.");
}
var order = Orders.CreateEntity(
0,
dtptxtReturnDate.Value,
Convert.ToInt32(comboBox.SelectedValue),
CreateListBooksFromDataGrid()
);
_orderRepository.CreateOrder(order);
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
Close();
}
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>
<metadata name="Book.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="ColumnCount.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,109 @@
namespace ProjectLibrary.Forms
{
partial class FOrderDistributionReport
{
/// <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()
{
buttonSelectFileName = new Button();
labelFileName = new Label();
label1 = new Label();
dateTimePicker = new DateTimePicker();
buttonCreate = new Button();
SuspendLayout();
//
// buttonSelectFileName
//
buttonSelectFileName.BackColor = SystemColors.Control;
buttonSelectFileName.Location = new Point(12, 23);
buttonSelectFileName.Name = "buttonSelectFileName";
buttonSelectFileName.Size = new Size(129, 29);
buttonSelectFileName.TabIndex = 0;
buttonSelectFileName.Text = "Выбрать";
buttonSelectFileName.UseVisualStyleBackColor = false;
buttonSelectFileName.Click += ButtonSelectFileName_Click;
//
// labelFileName
//
labelFileName.AutoSize = true;
labelFileName.Location = new Point(179, 27);
labelFileName.Name = "labelFileName";
labelFileName.Size = new Size(45, 20);
labelFileName.TabIndex = 1;
labelFileName.Text = "Файл";
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 81);
label1.Name = "label1";
label1.Size = new Size(44, 20);
label1.TabIndex = 2;
label1.Text = "Дата:";
//
// dateTimePicker
//
dateTimePicker.Location = new Point(179, 76);
dateTimePicker.Name = "dateTimePicker";
dateTimePicker.Size = new Size(183, 27);
dateTimePicker.TabIndex = 3;
//
// buttonCreate
//
buttonCreate.BackColor = SystemColors.Control;
buttonCreate.Location = new Point(12, 146);
buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(350, 29);
buttonCreate.TabIndex = 4;
buttonCreate.Text = "Сформировать";
buttonCreate.UseVisualStyleBackColor = false;
buttonCreate.Click += ButtonCreate_Click;
//
// FormOrderDistributionReport
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(395, 227);
Controls.Add(buttonCreate);
Controls.Add(dateTimePicker);
Controls.Add(label1);
Controls.Add(labelFileName);
Controls.Add(buttonSelectFileName);
Name = "FormOrderDistributionReport";
Text = "FormInvoiceDistributionReport";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonSelectFileName;
private Label labelFileName;
private Label label1;
private DateTimePicker dateTimePicker;
private Button buttonCreate;
}
}

View File

@ -0,0 +1,65 @@
using ProjectLibrary.Reports;
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;
using Unity;
namespace ProjectLibrary.Forms;
public partial class FOrderDistributionReport : Form
{
private string _fileName = string.Empty;
private readonly IUnityContainer _container;
public FOrderDistributionReport(IUnityContainer container)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
}
private void ButtonSelectFileName_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
Filter = "Pdf Files | *.pdf"
};
if (sfd.ShowDialog() == DialogResult.OK)
{
_fileName = sfd.FileName;
labelFileName.Text = Path.GetFileName(_fileName);
}
}
private void ButtonCreate_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(_fileName))
{
throw new Exception("Отсутствует имя файла для отчета");
}
if
(_container.Resolve<ChartReport>().CreateChart(_fileName, dateTimePicker.Value))
{
MessageBox.Show("Документ сформирован", "Формирование документа",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах",
"Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при создании очета", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>

89
ProjectLibrary/Forms/FOrders.Designer.cs generated Normal file
View File

@ -0,0 +1,89 @@
namespace ProjectLibrary.Forms
{
partial class FOrders
{
/// <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()
{
dataGridViewOrders = new DataGridView();
buttonAdd = new Button();
buttonRemove = new Button();
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).BeginInit();
SuspendLayout();
//
// dataGridViewOrders
//
dataGridViewOrders.AllowUserToAddRows = false;
dataGridViewOrders.AllowUserToDeleteRows = false;
dataGridViewOrders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridViewOrders.Location = new Point(11, 12);
dataGridViewOrders.Name = "dataGridViewOrders";
dataGridViewOrders.ReadOnly = true;
dataGridViewOrders.RowHeadersWidth = 51;
dataGridViewOrders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridViewOrders.Size = new Size(600, 300);
dataGridViewOrders.TabIndex = 4;
//
// buttonAdd
//
buttonAdd.Location = new Point(11, 332);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(101, 29);
buttonAdd.TabIndex = 5;
buttonAdd.Text = "Добавить";
buttonAdd.Click += buttonAdd_Click;
//
// buttonRemove
//
buttonRemove.Location = new Point(512, 332);
buttonRemove.Name = "buttonRemove";
buttonRemove.Size = new Size(101, 29);
buttonRemove.TabIndex = 7;
buttonRemove.Text = "Удалить";
buttonRemove.Click += buttonRemove_Click;
//
// FOrders
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(630, 412);
Controls.Add(dataGridViewOrders);
Controls.Add(buttonAdd);
Controls.Add(buttonRemove);
Name = "FOrders";
Text = "FOrders";
Load += FOrders_Load;
((System.ComponentModel.ISupportInitialize)dataGridViewOrders).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridViewOrders;
private Button buttonAdd;
private Button buttonRemove;
}
}

View File

@ -0,0 +1,84 @@
using ProjectLibrary.Repositories;
using Unity;
namespace ProjectLibrary.Forms
{
public partial class FOrders : Form
{
private readonly IUnityContainer _container;
private readonly IOrderRepository _orderRepository;
public FOrders(IUnityContainer container, IOrderRepository orderRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
}
private void LoadList()
{
dataGridViewOrders.DataSource = _orderRepository.ReadOrders();
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FOrder>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewOrders.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewOrders.SelectedRows[0].Cells["Id"].Value);
return true;
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_orderRepository.DeleteOrder(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FOrders_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>

98
ProjectLibrary/Forms/FReader.Designer.cs generated Normal file
View File

@ -0,0 +1,98 @@
namespace ProjectLibrary.Forms
{
partial class FReader
{
private System.ComponentModel.IContainer components = null;
private Label lblName;
private TextBox txtName;
private Label lblReaderTicket;
private TextBox txtReaderTicket;
private Button btnSave;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
lblName = new Label();
txtName = new TextBox();
lblReaderTicket = new Label();
txtReaderTicket = new TextBox();
btnSave = new Button();
buttonCancel_Click = new Button();
SuspendLayout();
//
// lblName
//
lblName.AutoSize = true;
lblName.Location = new Point(22, 22);
lblName.Name = "lblName";
lblName.Size = new Size(42, 20);
lblName.TabIndex = 2;
lblName.Text = "Имя:";
//
// txtName
//
txtName.Location = new Point(179, 22);
txtName.Name = "txtName";
txtName.Size = new Size(238, 27);
txtName.TabIndex = 3;
//
// lblReaderTicket
//
lblReaderTicket.AutoSize = true;
lblReaderTicket.Location = new Point(22, 62);
lblReaderTicket.Name = "lblReaderTicket";
lblReaderTicket.Size = new Size(151, 20);
lblReaderTicket.TabIndex = 4;
lblReaderTicket.Text = "Читательский билет:";
//
// txtReaderTicket
//
txtReaderTicket.Location = new Point(179, 62);
txtReaderTicket.Name = "txtReaderTicket";
txtReaderTicket.Size = new Size(238, 27);
txtReaderTicket.TabIndex = 5;
//
// btnSave
//
btnSave.Location = new Point(22, 111);
btnSave.Name = "btnSave";
btnSave.Size = new Size(100, 30);
btnSave.TabIndex = 8;
btnSave.Text = "Сохранить";
btnSave.Click += SaveBtn_Click;
//
// buttonCancel_Click
//
buttonCancel_Click.Location = new Point(317, 111);
buttonCancel_Click.Name = "buttonCancel_Click";
buttonCancel_Click.Size = new Size(100, 30);
buttonCancel_Click.TabIndex = 10;
buttonCancel_Click.Text = "Отмена";
buttonCancel_Click.Click += DiscardBtn_Click;
//
// FReader
//
ClientSize = new Size(438, 180);
Controls.Add(buttonCancel_Click);
Controls.Add(lblName);
Controls.Add(txtName);
Controls.Add(lblReaderTicket);
Controls.Add(txtReaderTicket);
Controls.Add(btnSave);
Name = "FReader";
Text = "Читатель";
ResumeLayout(false);
PerformLayout();
}
private Button buttonCancel_Click;
}
}

View File

@ -0,0 +1,88 @@
using System;
using System.Windows.Forms;
using ProjectLibrary.Entities;
using ProjectLibrary.Repositories;
namespace ProjectLibrary.Forms
{
public partial class FReader : Form
{
private readonly IReaderRepository _readerRepository;
private int? _readerId;
public int ID
{
set
{
try
{
var reader = _readerRepository.ReadReaderById(value);
if (reader == null)
{
throw new InvalidOperationException($"Reader with ID {value} not found.");
}
txtName.Text = reader.Name;
txtReaderTicket.Text = reader.ReaderTicket.ToString();
_readerId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "[ Error : wrong data ]", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
public FReader(IReaderRepository readerRepository)
{
InitializeComponent();
_readerRepository = readerRepository ?? throw new ArgumentNullException(nameof(readerRepository));
}
private void SaveBtn_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(txtName.Text) || string.IsNullOrWhiteSpace(txtReaderTicket.Text))
{
throw new Exception("[ Error : blank spaces were left, not enough information ]");
}
var reader = CreateReader();
if (_readerId.HasValue)
{
_readerRepository.UpdateReader(reader);
}
else
{
_readerRepository.CreateReader(reader);
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "[ Error : while saving ]", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DiscardBtn_Click(object sender, EventArgs e)
{
Close();
}
private Reader CreateReader()
{
return Reader.CreateEntity(
_readerId ?? 0,
txtName.Text,
int.Parse(txtReaderTicket.Text)
);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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

@ -0,0 +1,72 @@
namespace ProjectLibrary.Forms
{
partial class FReaders
{
private System.ComponentModel.IContainer components = null;
private DataGridView dataGridViewReaders;
private Button buttonAdd;
private Button buttonUpdate;
private Button buttonRemove;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.dataGridViewReaders = new DataGridView();
this.buttonAdd = new Button();
this.buttonUpdate = new Button();
this.buttonRemove = new Button();
this.SuspendLayout();
// dataGridViewReaders
this.dataGridViewReaders.AllowUserToAddRows = false;
this.dataGridViewReaders.AllowUserToDeleteRows = false;
this.dataGridViewReaders.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridViewReaders.Location = new System.Drawing.Point(20, 20);
this.dataGridViewReaders.Name = "dataGridViewReaders";
this.dataGridViewReaders.ReadOnly = true;
this.dataGridViewReaders.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
this.dataGridViewReaders.Size = new System.Drawing.Size(600, 300);
this.Controls.Add(this.dataGridViewReaders);
// buttonAdd
this.buttonAdd.Location = new System.Drawing.Point(20, 340);
this.buttonAdd.Name = "buttonAdd";
this.buttonAdd.Size = new System.Drawing.Size(100, 30);
this.buttonAdd.Text = "Добавить";
this.buttonAdd.Click += new EventHandler(this.ButtonAdd_Click);
this.Controls.Add(this.buttonAdd);
// buttonUpdate
this.buttonUpdate.Location = new System.Drawing.Point(140, 340);
this.buttonUpdate.Name = "buttonUpdate";
this.buttonUpdate.Size = new System.Drawing.Size(100, 30);
this.buttonUpdate.Text = "Изменить";
this.buttonUpdate.Click += new EventHandler(this.ButtonUpdate_Click);
this.Controls.Add(this.buttonUpdate);
// buttonRemove
this.buttonRemove.Location = new System.Drawing.Point(260, 340);
this.buttonRemove.Name = "buttonRemove";
this.buttonRemove.Size = new System.Drawing.Size(100, 30);
this.buttonRemove.Text = "Удалить";
this.buttonRemove.Click += new EventHandler(this.ButtonRemove_Click);
this.Controls.Add(this.buttonRemove);
// FReaders
this.ClientSize = new System.Drawing.Size(650, 400);
this.Name = "FReaders";
this.Text = "Список читателей";
this.Load += new EventHandler(this.FReaders_Load);
this.ResumeLayout(false);
}
}
}

View File

@ -0,0 +1,104 @@
using ProjectLibrary.Repositories;
using Unity;
using System;
using System.Windows.Forms;
namespace ProjectLibrary.Forms
{
public partial class FReaders : Form
{
private readonly IUnityContainer _container;
private readonly IReaderRepository _readerRepository;
public FReaders(IUnityContainer container, IReaderRepository readerRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_readerRepository = readerRepository ?? throw new ArgumentNullException(nameof(readerRepository));
}
private void LoadList()
{
dataGridViewReaders.DataSource = _readerRepository.ReadReaders();
}
private void FReaders_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FReader>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonRemove_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
if (MessageBox.Show("Удалить запись?", "Удаление", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
try
{
_readerRepository.DeleteReader(findId);
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при удалении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FReader>();
form.ID = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridViewReaders.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridViewReaders.SelectedRows[0].Cells["Id"].Value);
return true;
}
}
}

View File

@ -0,0 +1,120 @@
namespace ProjectLibrary.Forms
{
partial class FTicket_Extension
{
private System.ComponentModel.IContainer components = null;
private Label lblLastUpdateDate;
private DateTimePicker dtpLastUpdateDate;
private Label lblNextUpdateDate;
private DateTimePicker dtpNextUpdateDate;
private Button btnSave;
private Button btnCancel;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
lblLastUpdateDate = new Label();
dtpLastUpdateDate = new DateTimePicker();
lblNextUpdateDate = new Label();
dtpNextUpdateDate = new DateTimePicker();
btnSave = new Button();
btnCancel = new Button();
labelId = new Label();
comboBoxId = new ComboBox();
SuspendLayout();
//
// lblLastUpdateDate
//
lblLastUpdateDate.AutoSize = true;
lblLastUpdateDate.Location = new Point(20, 64);
lblLastUpdateDate.Name = "lblLastUpdateDate";
lblLastUpdateDate.Size = new Size(219, 20);
lblLastUpdateDate.TabIndex = 4;
lblLastUpdateDate.Text = "Дата последнего обновления:";
//
// dtpLastUpdateDate
//
dtpLastUpdateDate.Location = new Point(276, 59);
dtpLastUpdateDate.Name = "dtpLastUpdateDate";
dtpLastUpdateDate.Size = new Size(200, 27);
dtpLastUpdateDate.TabIndex = 5;
//
// lblNextUpdateDate
//
lblNextUpdateDate.AutoSize = true;
lblNextUpdateDate.Location = new Point(20, 104);
lblNextUpdateDate.Name = "lblNextUpdateDate";
lblNextUpdateDate.Size = new Size(223, 20);
lblNextUpdateDate.TabIndex = 6;
lblNextUpdateDate.Text = "Дата следующего обновления:";
//
// dtpNextUpdateDate
//
dtpNextUpdateDate.Location = new Point(276, 99);
dtpNextUpdateDate.Name = "dtpNextUpdateDate";
dtpNextUpdateDate.Size = new Size(200, 27);
dtpNextUpdateDate.TabIndex = 7;
//
// btnSave
//
btnSave.Location = new Point(140, 164);
btnSave.Name = "btnSave";
btnSave.Size = new Size(100, 30);
btnSave.TabIndex = 8;
btnSave.Text = "Сохранить";
btnSave.Click += btnSave_Click;
//
// btnCancel
//
btnCancel.Location = new Point(250, 164);
btnCancel.Name = "btnCancel";
btnCancel.Size = new Size(100, 30);
btnCancel.TabIndex = 9;
btnCancel.Text = "Отмена";
btnCancel.Click += btnCancel_Click;
//
// labelId
//
labelId.AutoSize = true;
labelId.Location = new Point(20, 19);
labelId.Name = "labelId";
labelId.Size = new Size(173, 20);
labelId.TabIndex = 10;
labelId.Text = "ID Читателского билета";
//
// comboBoxId
//
comboBoxId.Location = new Point(273, 16);
comboBoxId.Name = "comboBoxId";
comboBoxId.Size = new Size(203, 28);
comboBoxId.TabIndex = 11;
//
// FTicket_Extension
//
ClientSize = new Size(573, 250);
Controls.Add(comboBoxId);
Controls.Add(labelId);
Controls.Add(lblLastUpdateDate);
Controls.Add(dtpLastUpdateDate);
Controls.Add(lblNextUpdateDate);
Controls.Add(dtpNextUpdateDate);
Controls.Add(btnSave);
Controls.Add(btnCancel);
Name = "FTicket_Extension";
Text = "Продление билета";
ResumeLayout(false);
PerformLayout();
}
private Label labelId;
private ComboBox comboBoxId;
}
}

View File

@ -0,0 +1,83 @@
using ProjectLibrary.Entites;
using ProjectLibrary.Repositores;
using ProjectLibrary.Repositories;
namespace ProjectLibrary.Forms
{
public partial class FTicket_Extension : Form
{
private readonly ITicketExtensionsRepository _ticketExtensionsRepository;
private int? _extensionId;
public int Id
{
set
{
try
{
var ticket = _ticketExtensionsRepository.ReadTicketExtensionById(value);
if (ticket == null)
{
throw new InvalidOperationException("Заказ не найден.");
}
comboBoxId.SelectedItem = ticket.ReaderID;
dtpLastUpdateDate.Text = ticket.LastUpdateDate.ToString();
dtpNextUpdateDate.Text = ticket.NextUpdateDate.ToString();
_extensionId = value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public FTicket_Extension(ITicketExtensionsRepository ticketRepository, IReaderRepository readerRepository)
{
InitializeComponent();
_ticketExtensionsRepository = ticketRepository ?? throw new ArgumentNullException(nameof(ticketRepository));
readerRepository = readerRepository ?? throw new ArgumentNullException(nameof(readerRepository));
comboBoxId.DataSource = readerRepository.ReadReaders();
comboBoxId.DisplayMember = "Name"; // Предполагается, что у Reader есть свойство Name
comboBoxId.ValueMember = "Id"; // И свойство Id для идентификации
}
private void btnSave_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrWhiteSpace(dtpLastUpdateDate.Text) || string.IsNullOrWhiteSpace(dtpNextUpdateDate.Text) || comboBoxId.SelectedItem == null)
{
throw new Exception("Не все поля заполнены.");
}
var ticket = TicketExtensions.CreateEntity(
0,
(int)comboBoxId.SelectedValue!,
DateTime.Parse(dtpLastUpdateDate.Text),
DateTime.Parse(dtpNextUpdateDate.Text)
);
if (_extensionId.HasValue)
{
_ticketExtensionsRepository.UpdateTicketExtension(ticket);
}
else
{
_ticketExtensionsRepository.CreateTicketExtension(ticket);
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при сохранении данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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

@ -0,0 +1,92 @@
namespace ProjectLibrary.Forms
{
partial class FTiclet_Extensions
{
/// <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()
{
dataGridView = new DataGridView();
buttonAdd = new Button();
buttonUpdate = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(12, 11);
dataGridView.Margin = new Padding(3, 2, 3, 2);
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersWidth = 51;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(525, 225);
dataGridView.TabIndex = 8;
//
// buttonAdd
//
buttonAdd.Location = new Point(12, 251);
buttonAdd.Margin = new Padding(3, 2, 3, 2);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(88, 22);
buttonAdd.TabIndex = 9;
buttonAdd.Text = "Добавить";
buttonAdd.Click += buttonAdd_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(227, 251);
buttonUpdate.Margin = new Padding(3, 2, 3, 2);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(88, 22);
buttonUpdate.TabIndex = 10;
buttonUpdate.Text = "Изменить";
buttonUpdate.Click += buttonUpdate_Click;
//
// FTiclet_Extensions
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(569, 293);
Controls.Add(dataGridView);
Controls.Add(buttonAdd);
Controls.Add(buttonUpdate);
Name = "FTiclet_Extensions";
Text = "FTiclet_Extensions";
Load += FTiclet_Extensions_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpdate;
}
}

View File

@ -0,0 +1,79 @@
using ProjectLibrary.Repositores;
using ProjectLibrary.Repositories;
using Unity;
namespace ProjectLibrary.Forms
{
public partial class FTiclet_Extensions : Form
{
private readonly IUnityContainer _container;
private readonly ITicketExtensionsRepository _ticketRepository;
public FTiclet_Extensions(IUnityContainer container, ITicketExtensionsRepository ticketRepository)
{
InitializeComponent();
_container = container ?? throw new ArgumentNullException(nameof(container));
_ticketRepository = ticketRepository ?? throw new ArgumentNullException(nameof(ticketRepository));
}
private void buttonAdd_Click(object sender, EventArgs e)
{
try
{
_container.Resolve<FTicket_Extension>().ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при добавлении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (!TryGetIdentifierFromSelectedRow(out var findId))
{
return;
}
try
{
var form = _container.Resolve<FTicket_Extension>();
form.Id = findId;
form.ShowDialog();
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при изменении", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void FTiclet_Extensions_Load(object sender, EventArgs e)
{
try
{
LoadList();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка при загрузке", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadList()
{
dataGridView.DataSource = _ticketRepository.ReadTicketExtensions();
}
private bool TryGetIdentifierFromSelectedRow(out int id)
{
id = 0;
if (dataGridView.SelectedRows.Count < 1)
{
MessageBox.Show("Нет выбранной записи", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["ReaderID"].Value);
return true;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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

@ -1,3 +1,13 @@
using ProjectLibrary.Repositories.Implementations;
using ProjectLibrary.Repositories;
using Unity;
using ProjectLibrary.Repositores;
using ProjectLibrary.Repositores.Implementations;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Serilog;
using Unity.Microsoft.Logging;
namespace ProjectLibrary
{
internal static class Program
@ -11,7 +21,35 @@ namespace ProjectLibrary
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
Application.Run(CreateContainer().Resolve<FormLibrary>());
}
private static IUnityContainer CreateContainer()
{
var container = new UnityContainer();
container.AddExtension(new LoggingExtension(CreateLoggerFactory()));
// Ðåãèñòðàöèÿ ðåïîçèòîðèåâ
container.RegisterType<IBookRepository, BookRepository>();
container.RegisterType<ILibraryRepository, LibraryRepository>();
container.RegisterType<IReaderRepository, ReaderRepository>();
container.RegisterType<IOrderRepository, OrderRepository>();
container.RegisterType<ITicketExtensionsRepository, TicketExtensionsRepository>();
container.RegisterType<IConnectionString, ConnectionString>();
return container;
}
private static LoggerFactory CreateLoggerFactory()
{
var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build())
.CreateLogger());
return loggerFactory;
}
}
}

View File

@ -8,4 +8,42 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Npgsql" Version="9.0.1" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="Serilog" Version="4.1.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.4" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Unity" Version="5.11.10" />
<PackageReference Include="Unity.Microsoft.Logging" Version="5.11.1" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ProjectLibrary.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProjectLibrary.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Снимок_экрана_2024_11_19_132940 {
get {
object obj = ResourceManager.GetObject("Снимок экрана 2024-11-19 132940", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Снимок экрана 2024-11-19 132940" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Снимок экрана 2024-11-19 132940.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -0,0 +1,46 @@
using Microsoft.Extensions.Logging;
using ProjectLibrary.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Reports;
public class ChartReport
{
private readonly IOrderRepository _orderRepository;
private readonly ILogger<ChartReport> _logger;
public ChartReport(IOrderRepository orderRepository, ILogger<ChartReport> logger)
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateChart(string filePath, DateTime dateTime)
{
try
{
new PdfBuilder(filePath)
.AddHeader("Количество книг в библиотеках")
.AddPieChart("Библиотеки", GetData(dateTime))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<(string Caption, double Value)> GetData(DateTime dateTime)
{
return _orderRepository
.ReadOrders()
.Where(x => x.OrderDate.Date == dateTime.Date)
.GroupBy(x => x.BookOrders.First(y => y.OrderID == x.Id).BookID , (key, group) => new { ID = key, Count = group.Sum(y => y.BookOrders.First(z => z.OrderID == y.Id).Count) })
.Select(x => (x.ID.ToString(), (double)x.Count))
.ToList();
}
}

View File

@ -0,0 +1,88 @@
using Microsoft.Extensions.Logging;
using ProjectLibrary.Repositores;
using ProjectLibrary.Repositories;
using ProjectLibrary.Repositories.Implementations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Reports;
public class DocReport
{
private readonly IBookRepository _bookRepository;
private readonly IReaderRepository _readerRepository;
private readonly ITicketExtensionsRepository _ticketExtensionsRepository;
private readonly ILogger<DocReport> _logger;
public DocReport(IBookRepository bookRepository, IReaderRepository readerRepository,
ITicketExtensionsRepository ticketExtensionsRepository, ILogger<DocReport> logger)
{
_bookRepository = bookRepository ?? throw new ArgumentNullException(nameof(bookRepository));
_readerRepository = readerRepository ?? throw new ArgumentNullException(nameof(readerRepository));
_ticketExtensionsRepository = ticketExtensionsRepository ?? throw new ArgumentNullException(nameof(ticketExtensionsRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateDoc(string filePath, bool includeBooks, bool includeReaders, bool includeTicketExtensions)
{
try
{
var builder = new WordBuilder(filePath).AddHeader("Документ со справочниками");
if (includeBooks)
{
builder.AddParagraph("Книги").AddTable([2400, 2400, 1200], GetBooks());
}
if (includeReaders)
{
builder.AddParagraph("Читатели").AddTable([2400, 1200, 1200], GetReaders());
}
if (includeTicketExtensions)
{
builder.AddParagraph("Библиотеки").AddTable([2400, 2400, 2400], GetTicketExtensions());
}
builder.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetBooks()
{
return [
["Автор", "Название", "Тип книги"],
.. _bookRepository
.ReadBooks()
.Select(x => new string[] { x.Author, x.Name, x.TypeBookID.ToString()}),
];
}
private List<string[]> GetReaders()
{
return [
["ФИО читателя", "Билет читателя", "Дата регистрации"],
.. _readerRepository
.ReadReaders()
.Select(x => new string[] { x.Name, x.ReaderTicket.ToString(), x.RegistrationDateRT.ToString()}),
];
}
private List<string[]> GetTicketExtensions()
{
return [
["ID Читателя", "Последняя дата обновления", "Следующая дата обновления"],
.. _ticketExtensionsRepository
.ReadTicketExtensions()
.Select(x => new string[] {x.ReaderID.ToString(), x.LastUpdateDate.ToString(), x.NextUpdateDate.ToString()}),
];
}
}

View File

@ -0,0 +1,308 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Reports;
public class ExcelBuilder
{
private readonly string _filePath;
private readonly SheetData _sheetData;
private readonly MergeCells _mergeCells;
private readonly Columns _columns;
private uint _rowIndex = 0;
public ExcelBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_sheetData = new SheetData();
_mergeCells = new MergeCells();
_columns = new Columns();
_rowIndex = 1;
}
public ExcelBuilder AddHeader(string header, int startIndex, int count)
{
CreateCell(startIndex, _rowIndex, header, StyleIndex.BoldTextWithoutBorder);
for (int i = startIndex + 1; i < startIndex + count; ++i)
{
CreateCell(i, _rowIndex, "", StyleIndex.SimpleTextWithoutBorder);
}
_mergeCells.Append(new MergeCell()
{
Reference = new StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}")
});
_rowIndex++;
return this;
}
public ExcelBuilder AddParagraph(string text, int columnIndex)
{
CreateCell(columnIndex, _rowIndex++, text, StyleIndex.SimpleTextWithoutBorder);
return this;
}
public ExcelBuilder AddTable(int[] columnsWidths, List<string[]> data)
{
if (columnsWidths == null || columnsWidths.Length == 0)
{
throw new ArgumentNullException(nameof(columnsWidths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != columnsWidths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
uint counter = 1;
int coef = 2;
_columns.Append(columnsWidths.Select(x => new Column
{
Min = counter,
Max = counter++,
Width = x * coef,
CustomWidth = true
}));
for (var j = 0; j < data.First().Length; ++j)
{
CreateCell(j, _rowIndex, data.First()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
for (var i = 1; i < data.Count - 1; ++i)
{
for (var j = 0; j < data[i].Length; ++j)
{
CreateCell(j, _rowIndex, data[i][j], StyleIndex.SimpleTextWithBorder);
}
_rowIndex++;
}
for (var j = 0; j < data.Last().Length; ++j)
{
CreateCell(j, _rowIndex, data.Last()[j], StyleIndex.BoldTextWithBorder);
}
_rowIndex++;
return this;
}
public void Build()
{
using var spreadsheetDocument = SpreadsheetDocument.Create(_filePath, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
GenerateStyle(workbookpart);
workbookpart.Workbook = new Workbook();
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
if (_columns.HasChildren)
{
worksheetPart.Worksheet.Append(_columns);
}
worksheetPart.Worksheet.Append(_sheetData);
var sheets = spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист 1"
};
sheets.Append(sheet);
if (_mergeCells.HasChildren)
{
worksheetPart.Worksheet.InsertAfter(_mergeCells, worksheetPart.Worksheet.Elements<SheetData>().First());
}
}
private static void GenerateStyle(WorkbookPart workbookPart)
{
var workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
workbookStylesPart.Stylesheet = new Stylesheet();
var fonts = new Fonts()
{
Count = 2,
KnownFonts = BooleanValue.FromBoolean(true)
};
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme()
{
Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor)
}
});
fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font
{
FontSize = new FontSize() { Val = 11 },
FontName = new FontName() { Val = "Calibri" },
Bold = new Bold(),
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
FontScheme = new FontScheme()
{
Val = new EnumValue<FontSchemeValues>(FontSchemeValues.Minor)
}
});
workbookStylesPart.Stylesheet.Append(fonts);
// Default Fill
var fills = new Fills() { Count = 1 };
fills.Append(new Fill
{
PatternFill = new PatternFill()
{
PatternType = new EnumValue<PatternValues>(PatternValues.None)
}
});
workbookStylesPart.Stylesheet.Append(fills);
// Default Border
var borders = new Borders() { Count = 2 };
borders.Append(new Border
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
borders.Append(new Border
{
LeftBorder = new LeftBorder() { Style = BorderStyleValues.Medium },
RightBorder = new RightBorder() { Style = BorderStyleValues.Medium },
TopBorder = new TopBorder() { Style = BorderStyleValues.Medium },
BottomBorder = new BottomBorder() { Style = BorderStyleValues.Medium },
DiagonalBorder = new DiagonalBorder() { Style = BorderStyleValues.Medium },
});
workbookStylesPart.Stylesheet.Append(borders);
// Default cell format and a date cell format
var cellFormats = new CellFormats() { Count = 4 };
cellFormats.Append(new CellFormat
{
NumberFormatId = 0,
FormatId = 0,
FontId = 0,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 1,
FormatId = 0,
FontId = 0,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 2,
FormatId = 0,
FontId = 1,
BorderId = 0,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
cellFormats.Append(new CellFormat
{
NumberFormatId = 3,
FormatId = 0,
FontId = 1,
BorderId = 1,
FillId = 0,
Alignment = new Alignment()
{
Horizontal = HorizontalAlignmentValues.Left,
Vertical = VerticalAlignmentValues.Center,
WrapText = true
}
});
workbookStylesPart.Stylesheet.Append(cellFormats);
}
private enum StyleIndex
{
SimpleTextWithoutBorder = 0,
SimpleTextWithBorder = 1,
BoldTextWithoutBorder = 2,
BoldTextWithBorder = 3
}
private void CreateCell(int columnIndex, uint rowIndex, string text, StyleIndex styleIndex)
{
var columnName = GetExcelColumnName(columnIndex);
var cellReference = columnName + rowIndex;
var row = _sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex! == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
_sheetData.Append(row);
}
var newCell = row.Elements<Cell>().FirstOrDefault(c => c.CellReference != null && c.CellReference.Value == columnName + rowIndex);
if (newCell == null)
{
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellReference?.Value != null && cell.CellReference.Value.Length == cellReference.Length)
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
}
newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
}
newCell.CellValue = new CellValue(text);
newCell.DataType = CellValues.String;
newCell.StyleIndex = (uint)styleIndex;
}
private static string GetExcelColumnName(int columnNumber)
{
columnNumber += 1;
int dividend = columnNumber;
string columnName = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() +
columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
}

View File

@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using MigraDoc.Rendering;
namespace ProjectLibrary.Reports;
public class PdfBuilder
{
private readonly string _filePath;
private readonly Document _document;
public PdfBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_document = new Document();
DefineStyles();
}
public PdfBuilder AddHeader(string header)
{
_document.AddSection().AddParagraph(header, "NormalBold");
return this;
}
public PdfBuilder AddPieChart(string title, List<(string Caption, double Value)> data)
{
if (data == null || data.Count == 0)
{
return this;
}
var chart = new Chart(ChartType.Pie2D);
var series = chart.SeriesCollection.AddSeries();
series.Add(data.Select(x => x.Value).ToArray());
var xseries = chart.XValues.AddXSeries();
xseries.Add(data.Select(x => x.Caption).ToArray());
chart.DataLabel.Type = DataLabelType.Percent;
chart.DataLabel.Position = DataLabelPosition.OutsideEnd;
chart.Width = Unit.FromCentimeter(16);
chart.Height = Unit.FromCentimeter(12);
chart.TopArea.AddParagraph(title);
chart.XAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.HasMajorGridlines = true;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
chart.TopArea.AddLegend();
_document.LastSection.Add(chart);
return this;
}
public void Build()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(_filePath);
}
private void DefineStyles()
{
var headerStyle = _document.AddStyle("NormalBold", "Normal");
headerStyle.Font.Bold = true;
headerStyle.Font.Size = 14;
}
}

View File

@ -0,0 +1,66 @@
using Microsoft.Extensions.Logging;
using ProjectLibrary.Entities;
using ProjectLibrary.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Reports;
public class TableReport
{
private readonly IOrderRepository _orderRepository;
private readonly ILogger<TableReport> _logger;
internal static readonly string[] item = ["Id заказа","Дата заказа", "Дата возврата", "Книга", "Количество"];
public TableReport(IOrderRepository orderRepository, ILogger<TableReport> logger)
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public bool CreateTable(string filePath, DateTime startDate, DateTime endDate)
{
try
{
new ExcelBuilder(filePath)
.AddHeader("Сводка по движению книг", 0, 5)
.AddParagraph("за период", 0)
.AddTable([10, 10, 10, 15, 15], GetData(startDate, endDate))
.Build();
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при формировании документа");
return false;
}
}
private List<string[]> GetData(DateTime startDate, DateTime endDate)
{
var data = _orderRepository
.ReadOrders()
.Where(x => x.OrderDate >= startDate && x.OrderDate <= endDate && x.BookOrders.Any(y => y.OrderID == x.Id))
.Select(x => new
{
x.Id,
DateOrder = x.OrderDate,
DateReturn = x.ReturnDate,
Book = (int?)x.BookOrders.First(y => y.OrderID == x.Id).BookID,
Count = (int?)x.BookOrders.First(y => y.OrderID == x.Id).Count
})
.OrderBy(x => x.DateOrder);
return
new List<string[]>() { item }
.Union(
data
.Select(x => new string[] { x.Id.ToString(), x.DateOrder.ToString(), x.DateReturn.ToString(),
x.Book?.ToString() ?? string.Empty, x.Count?.ToString() ?? string.Empty}))
.Union([["Всего", "", "", "", data.Sum(x => x.Count ?? 0).ToString()]])
.ToList();
}
}

View File

@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace ProjectLibrary.Reports;
public class WordBuilder
{
private readonly string _filePath;
private readonly Document _document;
private readonly Body _body;
public WordBuilder(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_filePath = filePath;
_document = new Document();
_body = _document.AppendChild(new Body());
}
public WordBuilder AddHeader(string header)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.PrependChild(new RunProperties());
run.RunProperties.AddChild(new Bold());
run.AppendChild(new Text(header));
return this;
}
public WordBuilder AddParagraph(string text)
{
var paragraph = _body.AppendChild(new Paragraph());
var run = paragraph.AppendChild(new Run());
run.AppendChild(new Text(text));
return this;
}
public WordBuilder AddTable(int[] widths, List<string[]> data)
{
if (widths == null || widths.Length == 0)
{
throw new ArgumentNullException(nameof(widths));
}
if (data == null || data.Count == 0)
{
throw new ArgumentNullException(nameof(data));
}
if (data.Any(x => x.Length != widths.Length))
{
throw new InvalidOperationException("widths.Length != data.Length");
}
var table = new Table();
table.AppendChild(new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 12 })));
// Заголовок
var tr = new TableRow();
for (var j = 0; j < widths.Length; ++j)
{
tr.Append(new TableCell(new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }),
new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j])))));
}
table.Append(tr);
// Данные
table.Append(data.Skip(1).Select(x => new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y))))))));
_body.Append(table);
return this;
}
public void Build()
{
using var wordDocument = WordprocessingDocument.Create(_filePath,
WordprocessingDocumentType.Document);
var mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = _document;
}
}

View File

@ -0,0 +1,13 @@
namespace ProjectLibrary.Repositores
{
using ProjectLibrary.Entities;
public interface IBookRepository
{
IEnumerable<Book> ReadBooks();
Book ReadBookById(int id);
void CreateBook(Book book);
void UpdateBook(Book book);
void DeleteBook(int id);
}
}

View File

@ -0,0 +1,6 @@
namespace ProjectLibrary.Repositores;
public interface IConnectionString
{
public string ConnectionString { get; }
}

View File

@ -0,0 +1,14 @@
namespace ProjectLibrary.Repositories
{
using ProjectLibrary.Entites;
using ProjectLibrary.Entities;
public interface ILibraryRepository
{
IEnumerable<Library> ReadLibraries();
Library ReadLibraryById(int id);
void CreateLibrary(Library library);
void UpdateLibrary(Library library);
void DeleteLibrary(int id);
}
}

View File

@ -0,0 +1,12 @@
namespace ProjectLibrary.Repositories
{
using ProjectLibrary.Entites;
public interface IOrderRepository
{
IEnumerable<Orders> ReadOrders();
Orders ReadOrderById(int id);
void CreateOrder(Orders order);
void DeleteOrder(int id);
}
}

View File

@ -0,0 +1,14 @@
namespace ProjectLibrary.Repositories
{
using ProjectLibrary.Entities;
using System.Collections.Generic;
public interface IReaderRepository
{
Reader ReadReaderById(int id);
void CreateReader(Reader reader);
void UpdateReader(Reader reader);
void DeleteReader(int id);
List<Reader> ReadReaders();
}
}

View File

@ -0,0 +1,11 @@
using ProjectLibrary.Entites;
namespace ProjectLibrary.Repositores;
public interface ITicketExtensionsRepository
{
TicketExtensions ReadTicketExtensionById(int id);
List<TicketExtensions> ReadTicketExtensions();
void CreateTicketExtension(TicketExtensions ticketExtension);
void UpdateTicketExtension(TicketExtensions ticketExtension);
}

View File

@ -0,0 +1,145 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectLibrary.Entities;
using ProjectLibrary.Entities.Enums;
using ProjectLibrary.Repositories;
using Dapper;
using ProjectLibrary.Repositores;
namespace ProjectLibrary.Repositories.Implementations
{
public class BookRepository : IBookRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<BookRepository> _logger;
public BookRepository(IConnectionString connectionString, ILogger<BookRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
// Добавление книги
public void CreateBook(Book book)
{
_logger.LogInformation("Добавление книги");
_logger.LogDebug("Книга: {json}", JsonConvert.SerializeObject(book));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Book (Author, Name, TypeBookID)
VALUES (@Author, @Name, @TypeBookID)";
connection.Execute(queryInsert, book);
_logger.LogInformation("Книга успешно добавлена");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении книги");
throw;
}
}
// Обновление информации о книге
public void UpdateBook(Book book)
{
_logger.LogInformation("Редактирование книги");
_logger.LogDebug("Книга: {json}", JsonConvert.SerializeObject(book));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Book
SET
Author = @Author,
Name = @Name,
TypeBookID = @TypeBookID
WHERE ID = @ID";
connection.Execute(queryUpdate, book);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании книги");
throw;
}
}
// Удаление книги
public void DeleteBook(int id)
{
_logger.LogInformation("Удаление книги с Id={id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Book
WHERE ID = @id";
var affectedRows = connection.Execute(queryDelete, new { id });
if (affectedRows > 0)
{
_logger.LogInformation("Книга с Id={id} успешно удалена", id);
}
else
{
_logger.LogWarning("Книга с Id={id} не найдена для удаления", id);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении книги с Id={id}", id);
throw;
}
}
// Получение книги по ID
public Book ReadBookById(int id)
{
_logger.LogInformation("Получение книги по Id={id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Book
WHERE ID = @id";
var book = connection.QueryFirstOrDefault<Book>(querySelect, new { id });
if (book != null)
{
_logger.LogDebug("Найдена книга: {json}", JsonConvert.SerializeObject(book));
}
else
{
_logger.LogWarning("Книга с Id={id} не найдена", id);
}
return book;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при получении книги с Id={id}", id);
throw;
}
}
// Получение всех книг
public IEnumerable<Book> ReadBooks()
{
_logger.LogInformation("Получение всех книг");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Book";
var books = connection.Query<Book>(querySelect);
_logger.LogDebug("Полученные книги: {json}", JsonConvert.SerializeObject(books));
return books;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при получении списка книг");
throw;
}
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLibrary.Repositores.Implementations;
public class ConnectionString : IConnectionString
{
string IConnectionString.ConnectionString => "Host=127.0.0.1;Port=5432;Username=postgres;Database=labsofdatabase;Password=3565;";
}

View File

@ -0,0 +1,202 @@
using ProjectLibrary.Entities;
using Dapper;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using ProjectLibrary.Repositores;
using ProjectLibrary.Entites;
namespace ProjectLibrary.Repositories.Implementations
{
public class LibraryRepository : ILibraryRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<LibraryRepository> _logger;
public LibraryRepository(IConnectionString connectionString, ILogger<LibraryRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
public void CreateLibrary(Library library)
{
_logger.LogInformation("Добавление новой библиотеки");
_logger.LogDebug("Библиотека: {json}", JsonConvert.SerializeObject(library));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open(); // открываем соединение
using var transaction = connection.BeginTransaction(); // начинаем транзакцию
var queryInsert = @"
INSERT INTO Library (Name, Address)
VALUES (@Name, @Address);
SELECT MAX(Id) FROM LIBRARY";
var libraryID = connection.QueryFirst<int>(queryInsert, library, transaction); // добавляем в транзакцию запросы,
var querySubInsert = @"INSERT INTO BOOK_LIBRARY (BOOKID, LIBRARYID, COUNT)
VALUES (@BOOKID, @LIBRARYID, @COUNT) ";
foreach (var elem in library.BookLibrary)
{
connection.Execute(querySubInsert, new
{
elem.BookID,
libraryID,
elem.Count
}, transaction); // добавляем в транзакцию запросы, качество параметра
}
transaction.Commit(); // отправляем транзакцию и она выполняет все положенные в неё запросы
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении библиотеки");
throw;
}
}
public void UpdateLibrary(Library library)
{
_logger.LogInformation("Редактирование библиотеки");
_logger.LogDebug("Библиотека: {json}", JsonConvert.SerializeObject(library));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var queryUpdate = @"
UPDATE Library
SET
Name = @Name,
Address = @Address
WHERE ID = @ID";
connection.Execute(queryUpdate, library, transaction);
var querySubUpdate = @"
UPDATE BOOK_LIBRARY
SET
BOOKID = @BOOKID,
COUNT = @COUNT
WHERE ID = @id";
var querySubInsert = @"INSERT INTO BOOK_LIBRARY (BookID, LibraryID, Count)
VALUES (@BookID, @Id, @Count) ";
int ind = 0;
List<int> listId = connection.Query<int>("Select Id From BOOK_LIBRARY Where LIBRARYID = @id", new { library.Id }).ToList();
foreach (var elem in library.BookLibrary)
{
if (ind > listId.Count-1)
{
connection.Execute(querySubInsert, new
{
elem.BookID,
library.Id,
elem.Count
}, transaction);
continue;
}
int id = listId[ind];
connection.Execute(querySubUpdate, new
{
id,
elem.BookID,
elem.Count
}, transaction);
ind++;
}
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании библиотеки");
throw;
}
}
public void DeleteLibrary(int id)
{
_logger.LogInformation("Удаление библиотеки");
_logger.LogDebug("ID библиотеки: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var querySubDelete = @"
DELETE FROM Book_Library
WHERE LibraryID = @id";
connection.Execute(querySubDelete, new { id }, transaction);
var queryDelete = @"
DELETE FROM Library
WHERE ID = @id";
connection.Execute(queryDelete, new { id }, transaction);
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении библиотеки");
throw;
}
}
public Library ReadLibraryById(int id)
{
_logger.LogInformation("Получение библиотеки по идентификатору");
_logger.LogDebug("ID библиотеки: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Library
WHERE ID = @id";
var library = connection.QueryFirstOrDefault<Library>(querySelect, new { id });
library = Library.CreateEntity(id, library.Name, library.Address, ReadBookLibraryById(id));
_logger.LogDebug("Найденная библиотека: {json}", JsonConvert.SerializeObject(library));
return library;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске библиотеки");
throw;
}
}
public IEnumerable<Library> ReadLibraries()
{
_logger.LogInformation("Получение всех библиотек");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Library";
var libraries = connection.Query<Library>(querySelect);
_logger.LogDebug("Полученные библиотеки: {json}", JsonConvert.SerializeObject(libraries));
return libraries;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении библиотек");
throw;
}
}
public IEnumerable<Book_Library> ReadBookLibraryById(int id)
{
_logger.LogInformation("Получение всех библиотек");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Book_Library WHERE LibraryID = @id";
var libraries = connection.Query<Book_Library>(querySelect, new { id });
_logger.LogDebug("Полученные библиотеки: {json}", JsonConvert.SerializeObject(libraries));
return libraries;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении библиотек");
throw;
}
}
}
}

View File

@ -0,0 +1,133 @@
using ProjectLibrary.Entities;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using Dapper;
using System.Collections.Generic;
using ProjectLibrary.Repositories;
using System.Transactions;
using System.Data.Common;
using ProjectLibrary.Entites;
using ProjectLibrary.Repositores;
using Unity;
namespace ProjectLibrary.Repositories.Implementations
{
public class OrderRepository : IOrderRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<OrderRepository> _logger;
public OrderRepository(IConnectionString connectionString, ILogger<OrderRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
// Добавление нового заказа
public void CreateOrder(Orders order)
{
_logger.LogInformation("Добавление нового заказа");
_logger.LogDebug("Заказ: {json}", JsonConvert.SerializeObject(order));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
// Вставляем сам заказ в таблицу Orders
var queryInsertOrder = @"
INSERT INTO Orders (OrderDate, ReturnDate, ReaderID)
VALUES (@OrderDate, @ReturnDate, @ReaderID);
SELECT MAX(Id) FROM Orders"; // Возвращаем ID вставленного заказа
var orderId = connection.QueryFirst<int>(queryInsertOrder, order, transaction);
// Вставляем ассоциации книг с заказом в таблицу Book_Orders
foreach (var bookId in order.BookOrders) // Предполагается, что Order.BookOrders содержит список ID книг
{
var queryInsertBookOrder = @"
INSERT INTO Book_Orders (BookID, OrderID, Count)
VALUES (@BookID, @OrderID, @Count)";
connection.Execute(queryInsertBookOrder, new { bookId.BookID, orderId, bookId.Count }, transaction);
}
transaction.Commit();
_logger.LogInformation("Заказ успешно добавлен с ID={OrderId}", orderId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении заказа");
throw;
}
}
// Удаление заказа
public void DeleteOrder(int id)
{
_logger.LogInformation("Удаление объекта");
_logger.LogDebug("Объект: {id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
connection.Open();
using var transaction = connection.BeginTransaction();
var querySubDelete = @"
DELETE FROM Book_Orders
WHERE OrderId=@id";
connection.Execute(querySubDelete, new { id }, transaction);
var queryDelete = @"
DELETE FROM Orders
WHERE Id=@id";
connection.Execute(queryDelete, new { id }, transaction);
transaction.Commit();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении объекта");
throw;
}
}
// Получение заказа по ID
public Orders ReadOrderById(int id)
{
_logger.LogInformation("Получение заказа по ID={id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelectOrder = "SELECT * FROM Orders WHERE ID = @id";
var order = connection.QueryFirstOrDefault<Orders>(querySelectOrder, new { id });
_logger.LogDebug("Найден заказ: {json}", JsonConvert.SerializeObject(order));
return order;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при получении заказа с ID={id}", id);
throw;
}
}
// Получение всех заказов
public IEnumerable<Orders> ReadOrders()
{
_logger.LogInformation("Получение всех объектов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"SELECT ord.*, bo.BookId, bo.Count
FROM Orders ord
INNER JOIN Book_Orders bo ON bo.orderId = ord.Id";
var order = connection.Query<TempBookOrders>(querySelect);
_logger.LogDebug("Получ енные объекты: {json}", JsonConvert.SerializeObject(order));
return order.GroupBy(x => x.Id, y => y,
(key, value) => Orders.CreateEntity(value.First(),
value.Select(z => Book_Orders.CreateEntity(z.Id, z.BookID, z.Count)))).ToList();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении объектов");
throw;
}
}
}
}

View File

@ -0,0 +1,159 @@
using ProjectLibrary.Entities;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using Dapper;
using System.Collections.Generic;
using ProjectLibrary.Repositores;
namespace ProjectLibrary.Repositories
{
public class ReaderRepository : IReaderRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<ReaderRepository> _logger;
public ReaderRepository(IConnectionString connectionString, ILogger<ReaderRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
// Добавление нового читателя
public void CreateReader(Reader reader)
{
_logger.LogInformation("Добавление читателя");
_logger.LogDebug("Читатель: {json}", JsonConvert.SerializeObject(reader));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Reader (Name, ReaderTicket, RegistrationDateRT) -- Используем правильные названия столбцов из вашей таблицы
VALUES (@Name, @ReaderTicket, @RegistrationDateRT)";
connection.Execute(queryInsert, reader);
_logger.LogInformation("Читатель успешно добавлен");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении читателя");
throw;
}
}
// Обновление информации о читателе
public void UpdateReader(Reader reader)
{
_logger.LogInformation("Редактирование читателя");
_logger.LogDebug("Читатель: {json}", JsonConvert.SerializeObject(reader));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Reader -- Используем правильное имя таблицы
SET
Name = @Name, -- Используем правильные названия столбцов
ReaderTicket = @ReaderTicket,
RegistrationDateRT = @RegistrationDateRT
WHERE ID = @ID";
var affectedRows = connection.Execute(queryUpdate, new
{
Name = reader.Name,
ReaderTicket = reader.ReaderTicket,
RegistrationDateRT = reader.RegistrationDateRT,
ID = reader.Id
});
if (affectedRows > 0)
{
_logger.LogInformation("Читатель успешно обновлен");
}
else
{
_logger.LogWarning("Читатель с ID={Id} не найден для обновления", reader.Id);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании читателя");
throw;
}
}
// Удаление читателя
public void DeleteReader(int id)
{
_logger.LogInformation("Удаление читателя с ID={id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryDelete = @"
DELETE FROM Reader -- Используем правильное имя таблицы
WHERE ID = @id";
var affectedRows = connection.Execute(queryDelete, new { id });
if (affectedRows > 0)
{
_logger.LogInformation("Читатель с ID={id} успешно удален", id);
}
else
{
_logger.LogWarning("Читатель с ID={id} не найден для удаления", id);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при удалении читателя с ID={id}", id);
throw;
}
}
// Получение читателя по ID
public Reader ReadReaderById(int id)
{
_logger.LogInformation("Получение читателя по ID={id}", id);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = @"
SELECT * FROM Reader -- Используем правильное имя таблицы
WHERE ID = @id";
var reader = connection.QueryFirstOrDefault<Reader>(querySelect, new { id });
if (reader != null)
{
_logger.LogDebug("Найден читатель: {json}", JsonConvert.SerializeObject(reader));
}
else
{
_logger.LogWarning("Читатель с ID={id} не найден", id);
}
return reader;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при поиске читателя");
throw;
}
}
// Получение всех читателей
public List<Reader> ReadReaders()
{
_logger.LogInformation("Получение всех читателей");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Reader"; // Используем правильное имя таблицы
var readers = connection.Query<Reader>(querySelect).ToList();
_logger.LogDebug("Полученные читатели: {json}", JsonConvert.SerializeObject(readers));
return readers;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при чтении списка читателей");
throw;
}
}
}
}

View File

@ -0,0 +1,128 @@
using ProjectLibrary.Entities;
using ProjectLibrary.Repositories;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Npgsql;
using Dapper;
using System;
using System.Collections.Generic;
using System.Linq;
using ProjectLibrary.Entites;
using ProjectLibrary.Repositores;
namespace ProjectLibrary.Repositories.Implementations
{
public class TicketExtensionsRepository : ITicketExtensionsRepository
{
private readonly IConnectionString _connectionString;
private readonly ILogger<TicketExtensionsRepository> _logger;
public TicketExtensionsRepository(IConnectionString connectionString, ILogger<TicketExtensionsRepository> logger)
{
_connectionString = connectionString;
_logger = logger;
}
// Создание новой записи о продлении билета
public void CreateTicketExtension(TicketExtensions ticketExtension)
{
_logger.LogInformation("Добавление нового продления билета для читателя с ID={ReaderID}", ticketExtension.ReaderID);
_logger.LogDebug("Данные продления: {json}", JsonConvert.SerializeObject(ticketExtension));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryInsert = @"
INSERT INTO Ticket_Extensions (ReaderID, LastUpdateDate, NextUpdateDate)
VALUES (@ReaderID, @LastUpdateDate, @NextUpdateDate)";
connection.Execute(queryInsert, ticketExtension);
_logger.LogInformation("Продление билета успешно добавлено для читателя с ID={ReaderID}", ticketExtension.ReaderID);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении продления билета");
throw;
}
}
// Обновление информации о продлении билета
public void UpdateTicketExtension(TicketExtensions ticketExtension)
{
_logger.LogInformation("Редактирование продления билета для читателя с ID={ReaderID}", ticketExtension.ReaderID);
_logger.LogDebug("Данные продления: {json}", JsonConvert.SerializeObject(ticketExtension));
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var queryUpdate = @"
UPDATE Ticket_Extensions
SET LastUpdateDate = @LastUpdateDate, NextUpdateDate = @NextUpdateDate
WHERE ReaderID = @ReaderID";
var affectedRows = connection.Execute(queryUpdate, ticketExtension);
if (affectedRows > 0)
{
_logger.LogInformation("Продление билета успешно обновлено для читателя с ID={ReaderID}", ticketExtension.ReaderID);
}
else
{
_logger.LogWarning("Продление билета для читателя с ID={ReaderID} не найдено для обновления", ticketExtension.ReaderID);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при редактировании продления билета");
throw;
}
}
// Получение продления билета по ID читателя
public TicketExtensions ReadTicketExtensionById(int readerId)
{
_logger.LogInformation("Получение продления билета для читателя с ID={readerId}", readerId);
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Ticket_Extensions WHERE ReaderID = @readerId";
var ticketExtension = connection.QueryFirstOrDefault<TicketExtensions>(querySelect, new { readerId });
if (ticketExtension != null)
{
_logger.LogDebug("Найдено продление билета: {json}", JsonConvert.SerializeObject(ticketExtension));
}
else
{
_logger.LogWarning("Продление билета для читателя с ID={readerId} не найдено", readerId);
}
return ticketExtension;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при получении продления билета с ID={readerId}", readerId);
throw;
}
}
// Получение всех продлений билетов
public List<TicketExtensions> ReadTicketExtensions()
{
_logger.LogInformation("Получение всех продлений билетов");
try
{
using var connection = new NpgsqlConnection(_connectionString.ConnectionString);
var querySelect = "SELECT * FROM Ticket_Extensions";
var ticketExtensions = connection.Query<TicketExtensions>(querySelect).ToList();
_logger.LogDebug("Полученные продления билетов: {json}", JsonConvert.SerializeObject(ticketExtensions));
return ticketExtensions;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при получении списка продлений билетов");
throw;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 KiB

View File

@ -0,0 +1,15 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs.txt",
"rollingInterval": "Day"
}
}
]
}
}