This commit is contained in:
gg12 darfren 2024-05-08 10:36:59 +04:00
commit f755c2d575
143 changed files with 80027 additions and 82 deletions

View File

@ -25,13 +25,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IceCreamShopDatabaseImpleme
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IceCreamShopRestApi", "IceCreamShopRestApi\IceCreamShopRestApi.csproj", "{1C55C6B6-9F97-4004-8F45-5B7E3F1C780C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IceCreamShopRestApi", "IceCreamShopRestApi\IceCreamShopRestApi.csproj", "{1C55C6B6-9F97-4004-8F45-5B7E3F1C780C}"
ProjectSection(ProjectDependencies) = postProject
{6E71A941-D9B0-47F8-A180-78D544754C4F} = {6E71A941-D9B0-47F8-A180-78D544754C4F}
{CAF716C0-0F6F-43C2-B6F6-903AA9D96FC5} = {CAF716C0-0F6F-43C2-B6F6-903AA9D96FC5}
EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IceCreamShopClientApp", "IceCreamShopClientApp\IceCreamShopClientApp.csproj", "{4B0891A8-0755-4F61-B631-1030F6772792}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IceCreamShopClientApp", "IceCreamShopClientApp\IceCreamShopClientApp.csproj", "{4B0891A8-0755-4F61-B631-1030F6772792}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IceCreamShopsApp", "IceCreamShopsApp\IceCreamShopsApp.csproj", "{D7D67DD9-7206-4121-B5BF-0A5044442D88}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -74,6 +72,10 @@ Global
{4B0891A8-0755-4F61-B631-1030F6772792}.Debug|Any CPU.Build.0 = Debug|Any CPU {4B0891A8-0755-4F61-B631-1030F6772792}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B0891A8-0755-4F61-B631-1030F6772792}.Release|Any CPU.ActiveCfg = Release|Any CPU {4B0891A8-0755-4F61-B631-1030F6772792}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B0891A8-0755-4F61-B631-1030F6772792}.Release|Any CPU.Build.0 = Release|Any CPU {4B0891A8-0755-4F61-B631-1030F6772792}.Release|Any CPU.Build.0 = Release|Any CPU
{D7D67DD9-7206-4121-B5BF-0A5044442D88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7D67DD9-7206-4121-B5BF-0A5044442D88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7D67DD9-7206-4121-B5BF-0A5044442D88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7D67DD9-7206-4121-B5BF-0A5044442D88}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -22,6 +22,251 @@
#region Windows Form Designer generated code #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();
ToolStripMenu = new ToolStripMenuItem();
КомпонентыStripMenuItem = new ToolStripMenuItem();
МороженноеStripMenuItem = new ToolStripMenuItem();
клиентыToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem1 = new ToolStripMenuItem();
поставкиToolStripMenuItem1 = new ToolStripMenuItem();
товарыToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
списокМороженногоToolStripMenuItem = new ToolStripMenuItem();
компонентыПоМороженнымToolStripMenuItem = new ToolStripMenuItem();
списокЗаказовToolStripMenuItem = new ToolStripMenuItem();
списокМагазиновToolStripMenuItem = new ToolStripMenuItem();
мороженноеПоМагазинамToolStripMenuItem = new ToolStripMenuItem();
заказыПоДатамToolStripMenuItem = new ToolStripMenuItem();
магазиныToolStripMenuItem = new ToolStripMenuItem();
поставкиToolStripMenuItem = new ToolStripMenuItem();
продажиToolStripMenuItem = new ToolStripMenuItem();
DataGridView = new DataGridView();
CreateOrderButton = new Button();
TakeInWorkButton = new Button();
ReadyButton = new Button();
IssuedButton = new Button();
RefreshButton = new Button();
menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.ImageScalingSize = new Size(20, 20);
menuStrip1.Items.AddRange(new ToolStripItem[] { ToolStripMenu, отчетыToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Padding = new Padding(6, 3, 0, 3);
menuStrip1.Size = new Size(1296, 30);
menuStrip1.TabIndex = 0;
menuStrip1.Text = "menuStrip1";
//
// ToolStripMenu
//
ToolStripMenu.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыStripMenuItem, МороженноеStripMenuItem, клиентыToolStripMenuItem, магазиныToolStripMenuItem1, поставкиToolStripMenuItem1, товарыToolStripMenuItem });
ToolStripMenu.Name = "ToolStripMenu";
ToolStripMenu.Size = new Size(117, 24);
ToolStripMenu.Text = "Справочники";
//
// КомпонентыStripMenuItem
//
КомпонентыStripMenuItem.Name = "КомпонентыStripMenuItem";
КомпонентыStripMenuItem.Size = new Size(224, 26);
КомпонентыStripMenuItem.Text = "Компоненты";
КомпонентыStripMenuItem.Click += КомпонентыStripMenuItem_Click;
//
// МороженноеStripMenuItem
//
МороженноеStripMenuItem.Name = "МороженноеStripMenuItem";
МороженноеStripMenuItem.Size = new Size(224, 26);
МороженноеStripMenuItem.Text = "Мороженное";
МороженноеStripMenuItem.Click += МороженноеStripMenuItem_Click;
//
// клиентыToolStripMenuItem
//
клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
клиентыToolStripMenuItem.Size = new Size(224, 26);
клиентыToolStripMenuItem.Text = "Клиенты";
клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click;
//
// магазиныToolStripMenuItem1
//
магазиныToolStripMenuItem1.Name = агазиныToolStripMenuItem1";
магазиныToolStripMenuItem1.Size = new Size(224, 26);
магазиныToolStripMenuItem1.Text = "Магазины";
магазиныToolStripMenuItem1.Click += магазиныToolStripMenuItem_Click;
//
// поставкиToolStripMenuItem1
//
поставкиToolStripMenuItem1.Name = "поставкиToolStripMenuItem1";
поставкиToolStripMenuItem1.Size = new Size(224, 26);
поставкиToolStripMenuItem1.Text = "Поставки";
поставкиToolStripMenuItem1.Click += поставкиToolStripMenuItem_Click;
//
// товарыToolStripMenuItem
//
товарыToolStripMenuItem.Name = оварыToolStripMenuItem";
товарыToolStripMenuItem.Size = new Size(224, 26);
товарыToolStripMenuItem.Text = "Товары";
товарыToolStripMenuItem.Click += продажиToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { списокМороженногоToolStripMenuItem, компонентыПоМороженнымToolStripMenuItem, списокЗаказовToolStripMenuItem, списокМагазиновToolStripMenuItem, мороженноеПоМагазинамToolStripMenuItem, заказыПоДатамToolStripMenuItem });
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(73, 24);
отчетыToolStripMenuItem.Text = "Отчеты";
//
// списокМороженногоToolStripMenuItem
//
списокМороженногоToolStripMenuItem.Name = "списокМороженногоToolStripMenuItem";
списокМороженногоToolStripMenuItem.Size = new Size(305, 26);
списокМороженногоToolStripMenuItem.Text = "Список мороженного";
списокМороженногоToolStripMenuItem.Click += списокМороженногоToolStripMenuItem_Click;
//
// компонентыПоМороженнымToolStripMenuItem
//
компонентыПоМороженнымToolStripMenuItem.Name = омпонентыПоМороженнымToolStripMenuItem";
компонентыПоМороженнымToolStripMenuItem.Size = new Size(305, 26);
компонентыПоМороженнымToolStripMenuItem.Text = "Компоненты по мороженным";
компонентыПоМороженнымToolStripMenuItem.Click += компонентыПоМороженнымToolStripMenuItem_Click;
//
// списокЗаказовToolStripMenuItem
//
списокЗаказовToolStripMenuItem.Name = "списокЗаказовToolStripMenuItem";
списокЗаказовToolStripMenuItem.Size = new Size(305, 26);
списокЗаказовToolStripMenuItem.Text = "Список заказов";
списокЗаказовToolStripMenuItem.Click += списокЗаказовToolStripMenuItem_Click;
//
// списокМагазиновToolStripMenuItem
//
списокМагазиновToolStripMenuItem.Name = "списокМагазиновToolStripMenuItem";
списокМагазиновToolStripMenuItem.Size = new Size(305, 26);
списокМагазиновToolStripMenuItem.Text = "Список магазинов";
списокМагазиновToolStripMenuItem.Click += списокМагазиновToolStripMenuItem_Click;
//
// мороженноеПоМагазинамToolStripMenuItem
//
мороженноеПоМагазинамToolStripMenuItem.Name = ороженноеПоМагазинамToolStripMenuItem";
мороженноеПоМагазинамToolStripMenuItem.Size = new Size(305, 26);
мороженноеПоМагазинамToolStripMenuItem.Text = "Мороженное по магазинам";
мороженноеПоМагазинамToolStripMenuItem.Click += мороженноеПоМагазинамToolStripMenuItem_Click;
//
// заказыПоДатамToolStripMenuItem
//
заказыПоДатамToolStripMenuItem.Name = аказыПоДатамToolStripMenuItem";
заказыПоДатамToolStripMenuItem.Size = new Size(305, 26);
заказыПоДатамToolStripMenuItem.Text = "Заказы по датам";
заказыПоДатамToolStripMenuItem.Click += заказыПоДатамToolStripMenuItem_Click;
//
// магазиныToolStripMenuItem
//
магазиныToolStripMenuItem.Name = агазиныToolStripMenuItem";
магазиныToolStripMenuItem.Size = new Size(186, 26);
магазиныToolStripMenuItem.Text = "Магазины";
магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click;
//
// поставкиToolStripMenuItem
//
поставкиToolStripMenuItem.Name = "поставкиToolStripMenuItem";
поставкиToolStripMenuItem.Size = new Size(186, 26);
поставкиToolStripMenuItem.Text = "Поставки";
поставкиToolStripMenuItem.Click += поставкиToolStripMenuItem_Click;
//
// продажиToolStripMenuItem
//
продажиToolStripMenuItem.Name = "продажиToolStripMenuItem";
продажиToolStripMenuItem.Size = new Size(186, 26);
продажиToolStripMenuItem.Text = "Продажи";
продажиToolStripMenuItem.Click += продажиToolStripMenuItem_Click;
//
// DataGridView
//
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.Location = new Point(11, 31);
DataGridView.Name = "DataGridView";
DataGridView.RowHeadersWidth = 51;
DataGridView.Size = new Size(1007, 407);
DataGridView.TabIndex = 1;
//
// CreateOrderButton
//
CreateOrderButton.Location = new Point(1025, 31);
CreateOrderButton.Name = "CreateOrderButton";
CreateOrderButton.Size = new Size(259, 29);
CreateOrderButton.TabIndex = 2;
CreateOrderButton.Text = "Создать заказ";
CreateOrderButton.UseVisualStyleBackColor = true;
CreateOrderButton.Click += CreateOrderButton_Click;
//
// TakeInWorkButton
//
TakeInWorkButton.Location = new Point(1025, 67);
TakeInWorkButton.Name = "TakeInWorkButton";
TakeInWorkButton.Size = new Size(259, 29);
TakeInWorkButton.TabIndex = 3;
TakeInWorkButton.Text = "Отдать заказ в работу";
TakeInWorkButton.UseVisualStyleBackColor = true;
TakeInWorkButton.Click += TakeInWorkButton_Click;
//
// ReadyButton
//
ReadyButton.Location = new Point(1025, 101);
ReadyButton.Name = "ReadyButton";
ReadyButton.Size = new Size(259, 29);
ReadyButton.TabIndex = 4;
ReadyButton.Text = "Заказ готов";
ReadyButton.UseVisualStyleBackColor = true;
ReadyButton.Click += ReadyButton_Click;
//
// IssuedButton
//
IssuedButton.Location = new Point(1025, 136);
IssuedButton.Name = "IssuedButton";
IssuedButton.Size = new Size(259, 29);
IssuedButton.TabIndex = 5;
IssuedButton.Text = "Заказ выдан";
IssuedButton.UseVisualStyleBackColor = true;
IssuedButton.Click += IssuedButton_Click;
//
// RefreshButton
//
RefreshButton.Location = new Point(1025, 171);
RefreshButton.Name = "RefreshButton";
RefreshButton.Size = new Size(259, 29);
RefreshButton.TabIndex = 6;
RefreshButton.Text = "Обновить";
RefreshButton.UseVisualStyleBackColor = true;
RefreshButton.Click += RefreshButton_Click;
//
// MainForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1296, 451);
Controls.Add(RefreshButton);
Controls.Add(IssuedButton);
Controls.Add(ReadyButton);
Controls.Add(TakeInWorkButton);
Controls.Add(CreateOrderButton);
Controls.Add(DataGridView);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "MainForm";
Text = "Форма главная";
Load += MainForm_Load;
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)DataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
/// <summary> /// <summary>
/// Required method for Designer support - do not modify /// Required method for Designer support - do not modify
/// the contents of this method with the code editor. /// the contents of this method with the code editor.
@ -202,7 +447,17 @@
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 продажиToolStripMenuItem;
private ToolStripMenuItem списокМагазиновToolStripMenuItem;
private ToolStripMenuItem мороженноеПоМагазинамToolStripMenuItem;
private ToolStripMenuItem заказыПоДатамToolStripMenuItem;
private ToolStripMenuItem клиентыToolStripMenuItem; private ToolStripMenuItem клиентыToolStripMenuItem;
private ToolStripMenuItem магазиныToolStripMenuItem1;
private ToolStripMenuItem поставкиToolStripMenuItem1;
private ToolStripMenuItem товарыToolStripMenuItem;
}
private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripMenuItem исполнителиToolStripMenuItem;
private ToolStripMenuItem запускРаботToolStripMenuItem; private ToolStripMenuItem запускРаботToolStripMenuItem;
} }

View File

@ -189,6 +189,33 @@ Program.ServiceProvider?.GetService(typeof(OrderForm));
LoadData(); LoadData();
} }
private void магазиныToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(ShopsForm));
if (service is ShopsForm form)
{
form.ShowDialog();
}
}
private void поставкиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(SupplyForm));
if (service is SupplyForm form)
{
form.ShowDialog();
}
}
private void продажиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(SellForm));
if (service is SellForm form)
{
form.ShowDialog();
}
}
private void списокМороженногоToolStripMenuItem_Click(object sender, EventArgs e) private void списокМороженногоToolStripMenuItem_Click(object sender, EventArgs e)
{ {
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" }; using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
@ -226,6 +253,40 @@ Program.ServiceProvider?.GetService(typeof(ReportOrdersForm));
} }
private void списокМагазиновToolStripMenuItem_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SaveShopsToWordFile(new ReportBindingModel
{
FileName = dialog.FileName
});
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
private void мороженноеПоМагазинамToolStripMenuItem_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(ReportShopsIceCreamsForm));
if (service is ReportShopsIceCreamsForm form)
{
form.ShowDialog();
}
}
private void заказыПоДатамToolStripMenuItem_Click(object sender, EventArgs e)
{
var service =
Program.ServiceProvider?.GetService(typeof(ReportDateOrdersForm));
if (service is ReportDateOrdersForm form)
{
form.ShowDialog();
}
}
private void клиентыToolStripMenuItem_Click(object sender, EventArgs e) private void клиентыToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = var service =

View File

@ -36,6 +36,8 @@ namespace IceCreamShop
option.AddNLog("nlog.config"); option.AddNLog("nlog.config");
}); });
services.AddTransient<IComponentStorage, ComponentStorage>(); services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IShopLogic, ShopLogic>();
services.AddTransient<IShopStorage, ShopStorage>();
services.AddTransient<IOrderStorage, OrderStorage>(); services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IIceCreamStorage, IceCreamStorage>(); services.AddTransient<IIceCreamStorage, IceCreamStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>(); services.AddTransient<IComponentLogic, ComponentLogic>();
@ -57,6 +59,12 @@ namespace IceCreamShop
services.AddTransient<ClientsForm>(); services.AddTransient<ClientsForm>();
services.AddTransient<IceCreamComponentForm>(); services.AddTransient<IceCreamComponentForm>();
services.AddTransient<IceCreamsForm>(); services.AddTransient<IceCreamsForm>();
services.AddTransient<ShopForm>();
services.AddTransient<ShopsForm>();
services.AddTransient<SupplyForm>();
services.AddTransient<SellForm>();
services.AddTransient<ReportShopsIceCreamsForm>();
services.AddTransient<ReportDateOrdersForm>();
services.AddTransient<ReportIceCreamComponentForm>(); services.AddTransient<ReportIceCreamComponentForm>();
services.AddTransient<ReportOrdersForm>(); services.AddTransient<ReportOrdersForm>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); services.AddTransient<AbstractSaveToExcel, SaveToExcel>();

View File

@ -0,0 +1,82 @@
namespace IceCreamShop
{
partial class ReportDateOrdersForm
{
/// <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()
{
panel = new Panel();
MakeButton = new Button();
ToPdfButton = new Button();
SuspendLayout();
//
// panel
//
panel.Location = new Point(12, 71);
panel.Name = "panel";
panel.Size = new Size(776, 367);
panel.TabIndex = 0;
//
// MakeButton
//
MakeButton.Location = new Point(12, 36);
MakeButton.Name = "MakeButton";
MakeButton.Size = new Size(131, 29);
MakeButton.TabIndex = 1;
MakeButton.Text = "Сформировать";
MakeButton.UseVisualStyleBackColor = true;
MakeButton.Click += MakeButton_Click;
//
// ToPdfButton
//
ToPdfButton.Location = new Point(149, 36);
ToPdfButton.Name = "ToPdfButton";
ToPdfButton.Size = new Size(94, 29);
ToPdfButton.TabIndex = 2;
ToPdfButton.Text = "В PDF";
ToPdfButton.UseVisualStyleBackColor = true;
ToPdfButton.Click += ToPdfButton_Click;
//
// ReportDateOrdersForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(ToPdfButton);
Controls.Add(MakeButton);
Controls.Add(panel);
Name = "ReportDateOrdersForm";
Text = "Заказы по датам";
ResumeLayout(false);
}
#endregion
private Panel panel;
private Button MakeButton;
private Button ToPdfButton;
}
}

View File

@ -0,0 +1,77 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IceCreamShop
{
public partial class ReportDateOrdersForm : Form
{
private readonly ReportViewer reportViewer;
private readonly ILogger _logger;
private readonly IReportLogic _logic;
public ReportDateOrdersForm(ILogger<ReportDateOrdersForm> logger, IReportLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
reportViewer = new ReportViewer
{
Dock = DockStyle.Fill
};
reportViewer.LocalReport.LoadReportDefinition(new FileStream("ReportOrdersByDate.rdlc", FileMode.Open));
panel.Controls.Add(reportViewer);
}
private void MakeButton_Click(object sender, EventArgs e)
{
try
{
var dataSource = _logic.GetDatesOrders();
var source = new ReportDataSource("DataSetOrders", dataSource);
reportViewer.LocalReport.DataSources.Clear();
reportViewer.LocalReport.DataSources.Add(source);
reportViewer.RefreshReport();
_logger.LogInformation("Загрузка списка заказов на весь период по датам");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка заказов на период");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ToPdfButton_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "pdf|*.pdf" };
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
_logic.SaveDatesOrdersToPdfFile(new ReportBindingModel
{
FileName = dialog.FileName
});
_logger.LogInformation("Сохранение списка заказов на весь период по датам");
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
_logger.LogError(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,400 @@
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<Body>
<ReportItems>
<Textbox Name="TextboxTitle">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Заказы</Value>
<Style>
<FontSize>16pt</FontSize>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Center</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>0.24cm</Top>
<Height>1cm</Height>
<Width>21cm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
<VerticalAlign>Middle</VerticalAlign>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
<Tablix Name="Tablix1">
<TablixBody>
<TablixColumns>
<TablixColumn>
<Width>3cm</Width>
</TablixColumn>
<TablixColumn>
<Width>3cm</Width>
</TablixColumn>
<TablixColumn>
<Width>7cm</Width>
</TablixColumn>
</TablixColumns>
<TablixRows>
<TablixRow>
<Height>0.6cm</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textbox1">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Дата</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox1</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox3">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Количество</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox3</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox2">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Сумма</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox2</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
<TablixRow>
<Height>0.6cm</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="DateOfOrders">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!DateOfOrders.Value</Value>
<Style>
<Format>d</Format>
</Style>
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>DateOfOrders</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Count">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Count.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Count</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Sum">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Sum.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Sum</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
</TablixRows>
</TablixBody>
<TablixColumnHierarchy>
<TablixMembers>
<TablixMember />
<TablixMember />
<TablixMember />
</TablixMembers>
</TablixColumnHierarchy>
<TablixRowHierarchy>
<TablixMembers>
<TablixMember>
<KeepWithGroup>After</KeepWithGroup>
</TablixMember>
<TablixMember>
<Group Name="Подробности" />
</TablixMember>
</TablixMembers>
</TablixRowHierarchy>
<DataSetName>DataSetOrders</DataSetName>
<Top>2.72391cm</Top>
<Left>0.55245cm</Left>
<Height>1.2cm</Height>
<Width>13cm</Width>
<ZIndex>1</ZIndex>
<Style>
<Border>
<Style>Double</Style>
</Border>
</Style>
</Tablix>
<Textbox Name="TextboxTotalSum">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Всего:</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Right</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>4.24cm</Top>
<Left>8.55245cm</Left>
<Height>0.6cm</Height>
<Width>2.5cm</Width>
<ZIndex>2</ZIndex>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
<Textbox Name="SumTotal">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Sum(Fields!Sum.Value, "DataSetOrders")</Value>
<Style>
<FontWeight>Bold</FontWeight>
</Style>
</TextRun>
</TextRuns>
<Style>
<TextAlign>Right</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>4.24cm</Top>
<Left>11.05245cm</Left>
<Height>0.6cm</Height>
<Width>2.5cm</Width>
<ZIndex>3</ZIndex>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</ReportItems>
<Height>2in</Height>
<Style />
</Body>
<Width>8.26772in</Width>
<Page>
<PageHeight>29.7cm</PageHeight>
<PageWidth>21cm</PageWidth>
<LeftMargin>2cm</LeftMargin>
<RightMargin>2cm</RightMargin>
<TopMargin>2cm</TopMargin>
<BottomMargin>2cm</BottomMargin>
<ColumnSpacing>0.13cm</ColumnSpacing>
<Style />
</Page>
<AutoRefresh>0</AutoRefresh>
<DataSources>
<DataSource Name="IceCreamShopContractsViewModels">
<ConnectionProperties>
<DataProvider>System.Data.DataSet</DataProvider>
<ConnectString>/* Local Connection */</ConnectString>
</ConnectionProperties>
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="DataSetOrders">
<Query>
<DataSourceName>IceCreamShopContractsViewModels</DataSourceName>
<CommandText>/* Local Query */</CommandText>
</Query>
<Fields>
<Field Name="DateOfOrders">
<DataField>DateOfOrders</DataField>
<rd:TypeName>System.DateTime</rd:TypeName>
</Field>
<Field Name="Count">
<DataField>Count</DataField>
<rd:TypeName>System.Decimal</rd:TypeName>
</Field>
<Field Name="Sum">
<DataField>Sum</DataField>
<rd:TypeName>System.Double</rd:TypeName>
</Field>
</Fields>
<rd:DataSetInfo>
<rd:DataSetName>IceCreamShopContracts.ViewModels</rd:DataSetName>
<rd:TableName>ReportDateOrdersViewModel</rd:TableName>
<rd:ObjectDataSourceType>IceCreamShopContracts.ViewModels.ReportDateOrdersViewModel, IceCreamShopContracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</rd:ObjectDataSourceType>
</rd:DataSetInfo>
</DataSet>
</DataSets>
<rd:ReportUnitType>Cm</rd:ReportUnitType>
<rd:ReportID>cd561cee-f04c-45db-850e-4c793555accd</rd:ReportID>
</Report>

View File

@ -0,0 +1,103 @@
namespace IceCreamShop
{
partial class ReportShopsIceCreamsForm
{
/// <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();
ShopColumn = new DataGridViewTextBoxColumn();
IceCreamColumn = new DataGridViewTextBoxColumn();
CountColumn = new DataGridViewTextBoxColumn();
SaveButton = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ShopColumn, IceCreamColumn, CountColumn });
dataGridView.Location = new Point(12, 64);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 29;
dataGridView.Size = new Size(682, 374);
dataGridView.TabIndex = 0;
//
// ShopColumn
//
ShopColumn.HeaderText = "Магазин";
ShopColumn.MinimumWidth = 6;
ShopColumn.Name = "ShopColumn";
ShopColumn.Width = 250;
//
// IceCreamColumn
//
IceCreamColumn.HeaderText = "Мороженное";
IceCreamColumn.MinimumWidth = 6;
IceCreamColumn.Name = "IceCreamColumn";
IceCreamColumn.Width = 250;
//
// CountColumn
//
CountColumn.HeaderText = "Количество";
CountColumn.MinimumWidth = 6;
CountColumn.Name = "CountColumn";
CountColumn.Width = 125;
//
// SaveButton
//
SaveButton.Location = new Point(12, 29);
SaveButton.Name = "SaveButton";
SaveButton.Size = new Size(108, 29);
SaveButton.TabIndex = 1;
SaveButton.Text = "Сохранить в";
SaveButton.UseVisualStyleBackColor = true;
SaveButton.Click += SaveButton_Click_1;
//
// ReportShopsIceCreamsForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(702, 450);
Controls.Add(SaveButton);
Controls.Add(dataGridView);
Name = "ReportShopsIceCreamsForm";
Text = "Мороженное по магазинам";
Load += ReportShopsIceCreamsForm_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button SaveButton;
private DataGridViewTextBoxColumn ShopColumn;
private DataGridViewTextBoxColumn IceCreamColumn;
private DataGridViewTextBoxColumn CountColumn;
}
}

View File

@ -0,0 +1,93 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IceCreamShop
{
public partial class ReportShopsIceCreamsForm : Form
{
private readonly ILogger _logger;
private readonly IReportLogic _logic;
public ReportShopsIceCreamsForm(ILogger<ReportShopsIceCreamsForm>
logger, IReportLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void ReportShopsIceCreamsForm_Load(object sender, EventArgs e)
{
try
{
var dict = _logic.GetShopsIceCreams();
if (dict != null)
{
dataGridView.Rows.Clear();
foreach (var elem in dict)
{
dataGridView.Rows.Add(new object[] { elem.ShopName,
"", "" });
foreach (var listElem in elem.IceCreams)
{
dataGridView.Rows.Add(new object[] { "",
listElem.Item1, listElem.Item2 });
}
dataGridView.Rows.Add(new object[] { "Итого", "",
elem.TotalCount });
dataGridView.Rows.Add(Array.Empty<object>());
}
}
_logger.LogInformation("Загрузка списка мороженных по магазинам");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки списка мороженных по магазинам");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void SaveButton_Click_1(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog
{
Filter = "xlsx|*.xlsx"
};
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
_logic.SaveShopsIceCreamsToExcelFile(new
ReportBindingModel
{
FileName = dialog.FileName
});
_logger.LogInformation("Сохранение списка мороженных по магазинам");
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения списка мороженных по магазинам");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}
}

View File

@ -0,0 +1,129 @@
<?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="ShopColumn.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="IceCreamColumn.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="CountColumn.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,117 @@
namespace IceCreamShop
{
partial class SellForm
{
/// <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()
{
IceCreamComboBox = new ComboBox();
IceCreamLabel = new Label();
CountLabel = new Label();
CountTextBox = new TextBox();
SaveButton = new Button();
CancelButton = new Button();
SuspendLayout();
//
// IceCreamComboBox
//
IceCreamComboBox.FormattingEnabled = true;
IceCreamComboBox.Location = new Point(99, 12);
IceCreamComboBox.Name = "IceCreamComboBox";
IceCreamComboBox.Size = new Size(121, 23);
IceCreamComboBox.TabIndex = 0;
//
// IceCreamLabel
//
IceCreamLabel.AutoSize = true;
IceCreamLabel.Location = new Point(12, 20);
IceCreamLabel.Name = "IceCreamLabel";
IceCreamLabel.Size = new Size(81, 15);
IceCreamLabel.TabIndex = 1;
IceCreamLabel.Text = "Мороженное";
//
// CountLabel
//
CountLabel.AutoSize = true;
CountLabel.Location = new Point(21, 49);
CountLabel.Name = "CountLabel";
CountLabel.Size = new Size(72, 15);
CountLabel.TabIndex = 2;
CountLabel.Text = "Количество";
//
// CountTextBox
//
CountTextBox.Location = new Point(99, 41);
CountTextBox.Name = "CountTextBox";
CountTextBox.Size = new Size(121, 23);
CountTextBox.TabIndex = 3;
//
// SaveButton
//
SaveButton.Location = new Point(64, 73);
SaveButton.Name = "SaveButton";
SaveButton.Size = new Size(75, 23);
SaveButton.TabIndex = 4;
SaveButton.Text = "Сохранить";
SaveButton.UseVisualStyleBackColor = true;
SaveButton.Click += SaveButton_Click;
//
// CancelButton
//
CancelButton.Location = new Point(145, 73);
CancelButton.Name = "CancelButton";
CancelButton.Size = new Size(75, 23);
CancelButton.TabIndex = 5;
CancelButton.Text = "Отмена";
CancelButton.UseVisualStyleBackColor = true;
//
// SellForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(224, 108);
Controls.Add(CancelButton);
Controls.Add(SaveButton);
Controls.Add(CountTextBox);
Controls.Add(CountLabel);
Controls.Add(IceCreamLabel);
Controls.Add(IceCreamComboBox);
Name = "SellForm";
Text = "Форма продажи";
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox IceCreamComboBox;
private Label IceCreamLabel;
private Label CountLabel;
private TextBox CountTextBox;
private Button SaveButton;
private Button CancelButton;
}
}

View File

@ -0,0 +1,117 @@
using IceCreamShopContracts.BusinessLogicsContracts;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IceCreamShop
{
public partial class SellForm : Form
{
private readonly List<IceCreamViewModel>? _iceCreamList;
IShopLogic _shopLogic;
IIceCreamLogic _iceCreamLogic;
public SellForm(IIceCreamLogic iceCreamLogic, IShopLogic shopLogic)
{
InitializeComponent();
_shopLogic = shopLogic;
_iceCreamLogic = iceCreamLogic;
_iceCreamList = iceCreamLogic.ReadList(null);
if (_iceCreamList != null)
{
IceCreamComboBox.DisplayMember = "IceCreamName";
IceCreamComboBox.ValueMember = "Id";
IceCreamComboBox.DataSource = _iceCreamList;
IceCreamComboBox.SelectedItem = null;
}
}
public int IceCreamId
{
get
{
return
Convert.ToInt32(IceCreamComboBox.SelectedValue);
}
set
{
IceCreamComboBox.SelectedValue = value;
}
}
public IIceCreamModel? IceCreamModel
{
get
{
if (_iceCreamList == null)
{
return null;
}
foreach (var elem in _iceCreamList)
{
if (elem.Id == IceCreamId)
{
return elem;
}
}
return null;
}
}
public int Count
{
get { return Convert.ToInt32(CountTextBox.Text); }
set
{ CountTextBox.Text = value.ToString(); }
}
private void SaveButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(CountTextBox.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (IceCreamComboBox.SelectedValue == null)
{
MessageBox.Show("Выберите мороженное", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
int count = Convert.ToInt32(CountTextBox.Text);
bool res = _shopLogic.MakeSell(
_iceCreamLogic.ReadElement(new() { Id = Convert.ToInt32(IceCreamComboBox.SelectedValue) }),
count
);
if (!res)
{
throw new Exception("Ошибка при продаже.");
}
MessageBox.Show("Продажа прошла успешно");
DialogResult = DialogResult.OK;
Close();
}
catch (Exception err)
{
MessageBox.Show("Ошибка продажи");
return;
}
}
}
}

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,220 @@
namespace IceCreamShop
{
partial class ShopForm
{
/// <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()
{
DateTimePicker = new DateTimePicker();
NameTextBox = new TextBox();
AddressTextBox = new TextBox();
NameLabel = new Label();
AdressLabel = new Label();
DateLabel = new Label();
SaveButton = new Button();
CancelButton = new Button();
DataGridView = new DataGridView();
Column1 = new DataGridViewTextBoxColumn();
Название = new DataGridViewTextBoxColumn();
Цена = new DataGridViewTextBoxColumn();
Количество = new DataGridViewTextBoxColumn();
CapacityUpDown = new NumericUpDown();
CapacityLabel = new Label();
((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)CapacityUpDown).BeginInit();
SuspendLayout();
//
// DateTimePicker
//
DateTimePicker.Location = new Point(85, 70);
DateTimePicker.Name = "DateTimePicker";
DateTimePicker.Size = new Size(318, 23);
DateTimePicker.TabIndex = 0;
//
// NameTextBox
//
NameTextBox.Location = new Point(85, 12);
NameTextBox.Name = "NameTextBox";
NameTextBox.Size = new Size(318, 23);
NameTextBox.TabIndex = 1;
//
// AddressTextBox
//
AddressTextBox.Location = new Point(85, 41);
AddressTextBox.Name = "AddressTextBox";
AddressTextBox.Size = new Size(318, 23);
AddressTextBox.TabIndex = 2;
//
// NameLabel
//
NameLabel.AutoSize = true;
NameLabel.Location = new Point(12, 15);
NameLabel.Name = "NameLabel";
NameLabel.Size = new Size(59, 15);
NameLabel.TabIndex = 3;
NameLabel.Text = "Название";
//
// AdressLabel
//
AdressLabel.AutoSize = true;
AdressLabel.Location = new Point(12, 44);
AdressLabel.Name = "AdressLabel";
AdressLabel.Size = new Size(40, 15);
AdressLabel.TabIndex = 4;
AdressLabel.Text = "Адрес";
//
// DateLabel
//
DateLabel.AutoSize = true;
DateLabel.Location = new Point(12, 76);
DateLabel.Name = "DateLabel";
DateLabel.Size = new Size(32, 15);
DateLabel.TabIndex = 5;
DateLabel.Text = "Дата";
//
// SaveButton
//
SaveButton.Location = new Point(247, 284);
SaveButton.Name = "SaveButton";
SaveButton.Size = new Size(75, 23);
SaveButton.TabIndex = 6;
SaveButton.Text = "Сохранить";
SaveButton.UseVisualStyleBackColor = true;
SaveButton.Click += SaveButton_Click;
//
// CancelButton
//
CancelButton.Location = new Point(328, 284);
CancelButton.Name = "CancelButton";
CancelButton.Size = new Size(75, 23);
CancelButton.TabIndex = 7;
CancelButton.Text = "Отмена";
CancelButton.UseVisualStyleBackColor = true;
CancelButton.Click += CancelButton_Click;
//
// DataGridView
//
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.Columns.AddRange(new DataGridViewColumn[] { Column1, Название, Цена, Количество });
DataGridView.Location = new Point(12, 128);
DataGridView.Name = "DataGridView";
DataGridView.RowHeadersWidth = 51;
DataGridView.Size = new Size(391, 150);
DataGridView.TabIndex = 8;
//
// Column1
//
Column1.HeaderText = "Column1";
Column1.MinimumWidth = 6;
Column1.Name = "Column1";
Column1.Visible = false;
Column1.Width = 125;
//
// Название
//
Название.HeaderText = "Название";
Название.MinimumWidth = 6;
Название.Name = "Название";
Название.ReadOnly = true;
Название.Width = 150;
//
// Цена
//
Цена.HeaderText = "Цена";
Цена.MinimumWidth = 6;
Цена.Name = "Цена";
Цена.ReadOnly = true;
Цена.Width = 125;
//
// Количество
//
Количество.HeaderText = "Количество";
Количество.MinimumWidth = 6;
Количество.Name = "Количество";
Количество.ReadOnly = true;
Количество.Width = 125;
//
// CapacityUpDown
//
CapacityUpDown.Location = new Point(98, 99);
CapacityUpDown.Maximum = new decimal(new int[] { 10000, 0, 0, 0 });
CapacityUpDown.Name = "CapacityUpDown";
CapacityUpDown.Size = new Size(120, 23);
CapacityUpDown.TabIndex = 9;
//
// CapacityLabel
//
CapacityLabel.AutoSize = true;
CapacityLabel.Location = new Point(12, 107);
CapacityLabel.Name = "CapacityLabel";
CapacityLabel.Size = new Size(80, 15);
CapacityLabel.TabIndex = 10;
CapacityLabel.Text = "Вместимость";
//
// ShopForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(411, 315);
Controls.Add(CapacityLabel);
Controls.Add(CapacityUpDown);
Controls.Add(DataGridView);
Controls.Add(CancelButton);
Controls.Add(SaveButton);
Controls.Add(DateLabel);
Controls.Add(AdressLabel);
Controls.Add(NameLabel);
Controls.Add(AddressTextBox);
Controls.Add(NameTextBox);
Controls.Add(DateTimePicker);
Name = "ShopForm";
Text = "Форма магазина";
Load += ShopForm_Load;
((System.ComponentModel.ISupportInitialize)DataGridView).EndInit();
((System.ComponentModel.ISupportInitialize)CapacityUpDown).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private DateTimePicker DateTimePicker;
private TextBox NameTextBox;
private TextBox AddressTextBox;
private Label NameLabel;
private Label AdressLabel;
private Label DateLabel;
private Button SaveButton;
private Button CancelButton;
private DataGridView DataGridView;
private DataGridViewTextBoxColumn Column1;
private DataGridViewTextBoxColumn Название;
private DataGridViewTextBoxColumn Цена;
private DataGridViewTextBoxColumn Количество;
private NumericUpDown CapacityUpDown;
private Label CapacityLabel;
}
}

View File

@ -0,0 +1,126 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.BusinessLogicsContracts;
using IceCreamShopContracts.SearchModels;
using IceCreamShopDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IceCreamShop
{
public partial class ShopForm : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
public int? _id;
private Dictionary<int, (IIceCreamModel, int)> _iceCreams;
public ShopForm(ILogger<ShopForm> logger, IShopLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void ShopForm_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка магазина");
try
{
var shop = _logic.ReadElement(new ShopSearchModel { Id = _id });
if (shop != null)
{
NameTextBox.Text = shop.ShopName;
AddressTextBox.Text = shop.Address;
DateTimePicker.Text = shop.DateOpen.ToString();
CapacityUpDown.Value = shop.MaxCapacity;
_iceCreams = shop.ShopIceCreams ?? new Dictionary<int, (IIceCreamModel, int)>();
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка товаров магазина");
try
{
if (_iceCreams != null)
{
foreach (var iceCream in _iceCreams)
{
DataGridView.Rows.Add(new object[] { iceCream.Key, iceCream.Value.Item1.IceCreamName, iceCream.Value.Item1.Price, iceCream.Value.Item2 });
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки изделий магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void CancelButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void SaveButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(NameTextBox.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(AddressTextBox.Text))
{
MessageBox.Show("Заполните адрес", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение магазина");
try
{
var model = new ShopBindingModel
{
Id = _id ?? 0,
ShopName = NameTextBox.Text,
Address = AddressTextBox.Text,
DateOpen = DateTimePicker.Value.Date,
MaxCapacity = Convert.ToInt32(CapacityUpDown.Value),
ShopIceCreams = null
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения магазина");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,132 @@
<?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="Column1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Название.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Цена.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Количество.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -0,0 +1,124 @@
namespace IceCreamShop
{
partial class ShopsForm
{
/// <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();
AddButton = new Button();
UpdateButton = new Button();
RefreshButton = new Button();
DeleteButton = new Button();
((System.ComponentModel.ISupportInitialize)DataGridView).BeginInit();
SuspendLayout();
//
// DataGridView
//
DataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
DataGridView.Location = new Point(14, 16);
DataGridView.Margin = new Padding(3, 4, 3, 4);
DataGridView.Name = "DataGridView";
DataGridView.RowHeadersWidth = 51;
DataGridView.Size = new Size(449, 499);
DataGridView.TabIndex = 0;
//
// AddButton
//
AddButton.Location = new Point(470, 16);
AddButton.Margin = new Padding(3, 4, 3, 4);
AddButton.Name = "AddButton";
AddButton.Size = new Size(130, 31);
AddButton.TabIndex = 1;
AddButton.Text = "Добавить";
AddButton.UseVisualStyleBackColor = true;
AddButton.Click += AddButton_Click;
//
// UpdateButton
//
UpdateButton.Location = new Point(470, 55);
UpdateButton.Margin = new Padding(3, 4, 3, 4);
UpdateButton.Name = "UpdateButton";
UpdateButton.Size = new Size(130, 31);
UpdateButton.TabIndex = 2;
UpdateButton.Text = "Изменить";
UpdateButton.UseVisualStyleBackColor = true;
UpdateButton.Click += UpdateButton_Click;
//
// RefreshButton
//
RefreshButton.Location = new Point(470, 93);
RefreshButton.Margin = new Padding(3, 4, 3, 4);
RefreshButton.Name = "RefreshButton";
RefreshButton.Size = new Size(130, 31);
RefreshButton.TabIndex = 3;
RefreshButton.Text = "Обновить";
RefreshButton.UseVisualStyleBackColor = true;
RefreshButton.Click += RefreshButton_Click;
//
// DeleteButton
//
DeleteButton.Location = new Point(470, 132);
DeleteButton.Margin = new Padding(3, 4, 3, 4);
DeleteButton.Name = "DeleteButton";
DeleteButton.Size = new Size(130, 31);
DeleteButton.TabIndex = 4;
DeleteButton.Text = "Удалить";
DeleteButton.UseVisualStyleBackColor = true;
DeleteButton.Click += DeleteButton_Click;
//
// ShopsForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(616, 537);
Controls.Add(DeleteButton);
Controls.Add(RefreshButton);
Controls.Add(UpdateButton);
Controls.Add(AddButton);
Controls.Add(DataGridView);
Margin = new Padding(3, 4, 3, 4);
Name = "ShopsForm";
Text = "Форма магазинов";
Load += ShopsForm_Load;
((System.ComponentModel.ISupportInitialize)DataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView DataGridView;
private Button AddButton;
private Button UpdateButton;
private Button RefreshButton;
private Button DeleteButton;
private DataGridViewTextBoxColumn Column1;
private DataGridViewTextBoxColumn Column2;
private DataGridViewTextBoxColumn Column3;
private DataGridViewTextBoxColumn Column4;
private DataGridViewTextBoxColumn Column5;
}
}

View File

@ -0,0 +1,118 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IceCreamShop
{
public partial class ShopsForm : Form
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
public ShopsForm(ILogger<ShopsForm> logger, IShopLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
DataGridView.DataSource = list;
DataGridView.Columns["Id"].Visible = false;
DataGridView.Columns["ShopName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
DataGridView.Columns["Address"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
DataGridView.Columns["DateOpen"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
DataGridView.Columns["ShopIceCreams"].Visible = false;
}
_logger.LogInformation("Загрузка магазинов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки магазинов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ShopsForm_Load(object sender, EventArgs e)
{
LoadData();
}
private void AddButton_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(ShopForm));
if (service is ShopForm form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void UpdateButton_Click(object sender, EventArgs e)
{
if (DataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(ShopForm));
if (service is ShopForm form)
{
var tmp = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);
form._id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void RefreshButton_Click(object sender, EventArgs e)
{
LoadData();
}
private void DeleteButton_Click(object sender, EventArgs e)
{
if (DataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(DataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление магазина");
try
{
if (!_logic.Delete(new ShopBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(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,111 @@
namespace IceCreamShop
{
partial class SupplyForm
{
/// <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()
{
ShopComboBox = new ComboBox();
IceCreamComboBox = new ComboBox();
CountTextBox = new TextBox();
SaveButton = new Button();
CancelButton = new Button();
SuspendLayout();
//
// ShopComboBox
//
ShopComboBox.FormattingEnabled = true;
ShopComboBox.Location = new Point(14, 16);
ShopComboBox.Margin = new Padding(3, 4, 3, 4);
ShopComboBox.Name = "ShopComboBox";
ShopComboBox.Size = new Size(378, 28);
ShopComboBox.TabIndex = 0;
//
// IceCreamComboBox
//
IceCreamComboBox.FormattingEnabled = true;
IceCreamComboBox.Location = new Point(14, 55);
IceCreamComboBox.Margin = new Padding(3, 4, 3, 4);
IceCreamComboBox.Name = "IceCreamComboBox";
IceCreamComboBox.Size = new Size(378, 28);
IceCreamComboBox.TabIndex = 1;
//
// CountTextBox
//
CountTextBox.Location = new Point(14, 93);
CountTextBox.Margin = new Padding(3, 4, 3, 4);
CountTextBox.Name = "CountTextBox";
CountTextBox.Size = new Size(378, 27);
CountTextBox.TabIndex = 2;
//
// SaveButton
//
SaveButton.Location = new Point(214, 132);
SaveButton.Margin = new Padding(3, 4, 3, 4);
SaveButton.Name = "SaveButton";
SaveButton.Size = new Size(86, 31);
SaveButton.TabIndex = 3;
SaveButton.Text = "Сохранить";
SaveButton.UseVisualStyleBackColor = true;
SaveButton.Click += SaveButton_Click;
//
// CancelButton
//
CancelButton.Location = new Point(306, 132);
CancelButton.Margin = new Padding(3, 4, 3, 4);
CancelButton.Name = "CancelButton";
CancelButton.Size = new Size(86, 31);
CancelButton.TabIndex = 4;
CancelButton.Text = "Отмена";
CancelButton.UseVisualStyleBackColor = true;
CancelButton.Click += CancelButton_Click;
//
// SupplyForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(406, 181);
Controls.Add(CancelButton);
Controls.Add(SaveButton);
Controls.Add(CountTextBox);
Controls.Add(IceCreamComboBox);
Controls.Add(ShopComboBox);
Margin = new Padding(3, 4, 3, 4);
Name = "SupplyForm";
Text = "Форма поставок";
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox ShopComboBox;
private ComboBox IceCreamComboBox;
private TextBox CountTextBox;
private Button SaveButton;
private Button CancelButton;
}
}

View File

@ -0,0 +1,153 @@
using IceCreamShopBusinessLogic.BusinessLogic;
using IceCreamShopContracts.BusinessLogicsContracts;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IceCreamShop
{
public partial class SupplyForm : Form
{
private readonly List<IceCreamViewModel>? _iceCreamList;
private readonly List<ShopViewModel>? _shopsList;
IShopLogic _shopLogic;
IIceCreamLogic _iceCreamLogic;
public int ShopId
{
get
{
return
Convert.ToInt32(ShopComboBox.SelectedValue);
}
set
{
ShopComboBox.SelectedValue = value;
}
}
public int IceCreamId
{
get
{
return
Convert.ToInt32(IceCreamComboBox.SelectedValue);
}
set
{
IceCreamComboBox.SelectedValue = value;
}
}
public IIceCreamModel? IceCreamModel
{
get
{
if (_iceCreamList == null)
{
return null;
}
foreach (var elem in _iceCreamList)
{
if (elem.Id == IceCreamId)
{
return elem;
}
}
return null;
}
}
public int Count
{
get { return Convert.ToInt32(CountTextBox.Text); }
set
{ CountTextBox.Text = value.ToString(); }
}
public SupplyForm(IIceCreamLogic iceCreamLogic, IShopLogic shopLogic)
{
InitializeComponent();
_shopLogic = shopLogic;
_iceCreamLogic = iceCreamLogic;
_iceCreamList = iceCreamLogic.ReadList(null);
_shopsList = shopLogic.ReadList(null);
if (_iceCreamList != null)
{
IceCreamComboBox.DisplayMember = "IceCreamName";
IceCreamComboBox.ValueMember = "Id";
IceCreamComboBox.DataSource = _iceCreamList;
IceCreamComboBox.SelectedItem = null;
}
if (_shopsList != null)
{
ShopComboBox.DisplayMember = "ShopName";
ShopComboBox.ValueMember = "Id";
ShopComboBox.DataSource = _shopsList;
ShopComboBox.SelectedItem = null;
}
}
private void SaveButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(CountTextBox.Text))
{
MessageBox.Show("Заполните поле Количество", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (IceCreamComboBox.SelectedValue == null)
{
MessageBox.Show("Выберите мороженное", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (ShopComboBox.SelectedValue == null)
{
MessageBox.Show("Выберите магазин", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
int count = Convert.ToInt32(CountTextBox.Text);
bool res = _shopLogic.MakeSupply(
new ShopSearchModel() { Id = Convert.ToInt32(ShopComboBox.SelectedValue) },
_iceCreamLogic.ReadElement(new() { Id = Convert.ToInt32(IceCreamComboBox.SelectedValue) }),
count
);
if (!res)
{
throw new Exception("Ошибка при пополнении. Дополнительная информация в логах");
}
MessageBox.Show("Пополнение прошло успешно");
DialogResult = DialogResult.OK;
Close();
}
catch (Exception err)
{
MessageBox.Show("Ошибка пополнения");
return;
}
}
private void CancelButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
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

@ -5,6 +5,7 @@ using IceCreamShopContracts.StoragesContracts;
using IceCreamShopContracts.ViewModels; using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels; using IceCreamShopDataModels;
using IceCreamShopDataModels.Enums; using IceCreamShopDataModels.Enums;
using IceCreamShopDataModels.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -18,12 +19,18 @@ namespace IceCreamShopBusinessLogic.BusinessLogic
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly IShopLogic _shopLogic;
private readonly IIceCreamStorage _iceCreamStorage;
static readonly object locker = new object(); static readonly object locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) public OrderLogic(IOrderStorage orderStorage, IShopStorage shopStorage, IShopLogic shopLogic, IIceCreamStorage iceCreamStorage, ILogger<OrderLogic> logger)
{ {
_logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
_shopStorage = shopStorage;
_logger = logger;
_shopLogic = shopLogic;
_iceCreamStorage = iceCreamStorage;
} }
public OrderViewModel? ReadElement(OrderSearchModel model) public OrderViewModel? ReadElement(OrderSearchModel model)
{ {
@ -69,6 +76,65 @@ namespace IceCreamShopBusinessLogic.BusinessLogic
return true; return true;
} }
public bool CheckSupply(IIceCreamModel iceCream, int count)
{
if (count <= 0)
{
_logger.LogWarning("Check then supply operation error. IceCream count < 0.");
return false;
}
int sumCapacity = 0;
int sumCount = 0;
sumCapacity = _shopStorage.GetFullList().Select(x => x.MaxCapacity).Sum();
sumCount = _shopStorage.GetFullList().Select(x => x.ShopIceCreams.Select(y => y.Value.Item2).Sum()).Sum();
int freeSpace = sumCapacity - sumCount;
if (freeSpace - count < 0)
{
_logger.LogWarning("Check then supply operation error. There's no place for new IceCream in shops.");
return false;
}
foreach (var shop in _shopStorage.GetFullList())
{
freeSpace = shop.MaxCapacity;
foreach (var doc in shop.ShopIceCreams)
{
freeSpace -= doc.Value.Item2;
}
if (freeSpace == 0)
{
continue;
}
if (freeSpace - count >= 0)
{
if (_shopLogic.MakeSupply(new() { Id = shop.Id }, iceCream, count))
count = 0;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (freeSpace - count < 0)
{
if (_shopLogic.MakeSupply(new() { Id = shop.Id }, iceCream, freeSpace))
count -= freeSpace;
else
{
_logger.LogWarning("Supply error");
return false;
}
}
if (count <= 0)
{
return true;
}
}
return false;
}
public bool ChangeStatus(OrderBindingModel model, OrderStatus status) public bool ChangeStatus(OrderBindingModel model, OrderStatus status)
{ {
CheckModel(model, false); CheckModel(model, false);
@ -83,6 +149,20 @@ namespace IceCreamShopBusinessLogic.BusinessLogic
_logger.LogWarning("Status change operation failed"); _logger.LogWarning("Status change operation failed");
throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный");
} }
if(element.Status == OrderStatus.Готов)
{
var icecream = _iceCreamStorage.GetElement(new IceCreamSearchModel() { Id = model.IceCreamId });
if (icecream == null)
{
_logger.LogWarning("Status update to " + status.ToString() + " operation failed. Document not found.");
return false;
}
if (CheckSupply(icecream, model.Count) == false)
{
_logger.LogWarning("Status update to " + status.ToString() + " operation failed. Shop supply error.");
return false;
}
}
model.Status = status; model.Status = status;
if (model.Status == OrderStatus.Выдан) model.DateImplement = DateTime.Now; if (model.Status == OrderStatus.Выдан) model.DateImplement = DateTime.Now;
if (element.ImplementerId.HasValue) if (element.ImplementerId.HasValue)

View File

@ -18,17 +18,19 @@ namespace IceCreamShopBusinessLogic.BusinessLogic
private readonly IComponentStorage _componentStorage; private readonly IComponentStorage _componentStorage;
private readonly IIceCreamStorage _iceCreamStorage; private readonly IIceCreamStorage _iceCreamStorage;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
private readonly IShopStorage _shopStorage;
private readonly AbstractSaveToExcel _saveToExcel; private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord; private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf; private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(IIceCreamStorage iceCreamStorage, IComponentStorage public ReportLogic(IIceCreamStorage iceCreamStorage, IComponentStorage
componentStorage, IOrderStorage orderStorage, componentStorage, IOrderStorage orderStorage, IShopStorage shopStorage,
AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord,
AbstractSaveToPdf saveToPdf) AbstractSaveToPdf saveToPdf)
{ {
_iceCreamStorage = iceCreamStorage; _iceCreamStorage = iceCreamStorage;
_componentStorage = componentStorage; _componentStorage = componentStorage;
_orderStorage = orderStorage; _orderStorage = orderStorage;
_shopStorage = shopStorage;
_saveToExcel = saveToExcel; _saveToExcel = saveToExcel;
_saveToWord = saveToWord; _saveToWord = saveToWord;
_saveToPdf = saveToPdf; _saveToPdf = saveToPdf;
@ -56,6 +58,67 @@ namespace IceCreamShopBusinessLogic.BusinessLogic
} }
return list; return list;
} }
public List<ReportShopIceCreamViewModel> GetShopsIceCreams()
{
var shops = _shopStorage.GetFullList();
var list = new List<ReportShopIceCreamViewModel>();
foreach (var shop in shops)
{
var record = new ReportShopIceCreamViewModel
{
ShopName = shop.ShopName,
IceCreams = new List<Tuple<string, int>>(),
TotalCount = 0
};
foreach (var iceCream in shop.ShopIceCreams)
{
record.IceCreams.Add(new Tuple<string,
int>(iceCream.Value.Item1.IceCreamName, iceCream.Value.Item2));
record.TotalCount +=
iceCream.Value.Item2;
}
list.Add(record);
}
return list;
}
public List<ReportDateOrdersViewModel> GetDatesOrders()
{
return _orderStorage.GetFullList().GroupBy(x => x.DateCreate.Date).Select(x => new ReportDateOrdersViewModel
{
DateOfOrders = x.Key,
Count = x.Count(),
Sum = x.Sum(y => y.Sum)
}).ToList();
}
public void SaveDatesOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateReportDateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Заказы по датам",
DateOrders = GetDatesOrders()
});
}
public void SaveShopsToWordFile(ReportBindingModel model)
{
var tmp = _shopStorage.GetFullList();
_saveToWord.CreateTableDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список магазинов",
Shops = _shopStorage.GetFullList()
});
}
public void SaveShopsIceCreamsToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateShopReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Загруженность магазинов",
ShopIceCreams = GetShopsIceCreams()
});
}
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model) public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model)
{ {
return _orderStorage.GetFilteredList(new OrderSearchModel return _orderStorage.GetFilteredList(new OrderSearchModel

View File

@ -0,0 +1,179 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.BusinessLogicsContracts;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.StoragesContracts;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopBusinessLogic.BusinessLogic
{
public class ShopLogic : IShopLogic
{
private readonly ILogger _logger;
private readonly IShopStorage _shopStorage;
public ShopLogic(ILogger<ShopLogic> logger, IShopStorage shopStorage)
{
_logger = logger;
_shopStorage = shopStorage;
}
public List<ShopViewModel> ReadList(ShopSearchModel model)
{
_logger.LogInformation("ReadList. ShopName:{Name}. Id:{ Id}", model?.Name, model?.Id);
var list = model == null ? _shopStorage.GetFullList() :
_shopStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool MakeSupply(ShopSearchModel model, IIceCreamModel iceCream, int count)
{
if (model == null)
throw new ArgumentNullException(nameof(model));
if (iceCream == null)
throw new ArgumentNullException(nameof(iceCream));
if (count <= 0)
throw new ArgumentNullException("Количество должно быть положительным числом");
ShopViewModel curModel = _shopStorage.GetElement(model);
if (curModel == null)
throw new ArgumentNullException(nameof(curModel));
var countItems = curModel.ShopIceCreams.Select(x => x.Value.Item2).Sum();
if (curModel.MaxCapacity - countItems >= count)
{
if (curModel.ShopIceCreams.TryGetValue(iceCream.Id, out var sameDocument))
{
curModel.ShopIceCreams[iceCream.Id] = (iceCream, sameDocument.Item2 + count);
_logger.LogInformation("Same iceCream found by supply. Added {0} of {1} in {2} shop", count, iceCream.IceCreamName, curModel.ShopName);
}
else
{
curModel.ShopIceCreams[iceCream.Id] = (iceCream, count);
_logger.LogInformation("New iceCream added by supply. Added {0} of {1} in {2} shop", count, iceCream.IceCreamName, curModel.ShopName);
}
_shopStorage.Update(new()
{
Id = curModel.Id,
ShopName = curModel.ShopName,
Address = curModel.Address,
DateOpen = curModel.DateOpen,
ShopIceCreams = curModel.ShopIceCreams,
MaxCapacity = curModel.MaxCapacity
});
}
else
{
_logger.LogWarning("Required shop is overflowed");
return false;
}
return true;
}
public bool MakeSell(IIceCreamModel iceCream, int count)
{
return _shopStorage.SellIceCreams(iceCream, count);
}
public ShopViewModel ReadElement(ShopSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ShopName:{ShopName}.Id:{ Id}", model.Name, model.Id);
var element = _shopStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ShopBindingModel model)
{
CheckModel(model);
if (_shopStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ShopBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_shopStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ShopBindingModel model, bool withParams =
true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ShopName))
{
throw new ArgumentNullException("Нет названия магазина",
nameof(model.ShopName));
}
if (string.IsNullOrEmpty(model.Address))
{
throw new ArgumentNullException("Нет адресса магазина",
nameof(model.ShopName));
}
if(model.DateOpen == null)
{
throw new ArgumentNullException("Нет даты открытия магазина",
nameof(model.ShopName));
}
_logger.LogInformation("Shop. ShopName:{ShopName}.Address:{Address}. DateOpen:{DateOpen}. Id: { Id}", model.ShopName, model.Address, model.DateOpen, model.Id);
var element = _shopStorage.GetElement(new ShopSearchModel
{
Name = model.ShopName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Магазин с таким названием уже есть");
}
}
}
}

View File

@ -74,6 +74,70 @@ namespace IceCreamShopBusinessLogic.OfficePackage
} }
SaveExcel(info); SaveExcel(info);
} }
public void CreateShopReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint rowIndex = 2;
foreach (var pc in info.ShopIceCreams)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = pc.ShopName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var iceCream in pc.IceCreams)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = iceCream.Item1,
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = iceCream.Item2.ToString(),
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = pc.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
}
SaveExcel(info);
}
protected abstract void CreateExcel(ExcelInfo info); protected abstract void CreateExcel(ExcelInfo info);
protected abstract void InsertCellInWorksheet(ExcelCellParameters protected abstract void InsertCellInWorksheet(ExcelCellParameters
excelParams); excelParams);

View File

@ -53,6 +53,39 @@ order.DateCreate.ToShortDateString(), order.IceCreamName, order.Sum.ToString(),
}); });
SavePdf(info); SavePdf(info);
} }
public void CreateReportDateDoc(PdfInfo info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph
{
Text = info.Title,
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "3cm", "3cm", "7cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Дата", "Количество", "Сумма" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var order in info.DateOrders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { order.DateOfOrders.ToShortDateString(), order.Count.ToString(), order.Sum.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph
{
Text = $"Итого: {info.DateOrders.Sum(x => x.Sum)}\t",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
SavePdf(info);
}
protected abstract void CreatePdf(PdfInfo info); protected abstract void CreatePdf(PdfInfo info);
protected abstract void CreateParagraph(PdfParagraph paragraph); protected abstract void CreateParagraph(PdfParagraph paragraph);
protected abstract void CreateTable(List<string> columns); protected abstract void CreateTable(List<string> columns);

View File

@ -1,4 +1,5 @@
using IceCreamShopBusinessLogic.OfficePackage.HelperEnums; using DocumentFormat.OpenXml.Office2010.ExcelAc;
using IceCreamShopBusinessLogic.OfficePackage.HelperEnums;
using IceCreamShopBusinessLogic.OfficePackage.HelperModels; using IceCreamShopBusinessLogic.OfficePackage.HelperModels;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -40,8 +41,36 @@ WordTextProperties { Bold = true, Size = "24", }) },
} }
SaveWord(info); SaveWord(info);
} }
public void CreateTableDoc(WordInfo info)
{
CreateWord(info);
List<List<string>> list = new List<List<string>>();
foreach (var shop in info.Shops)
{
var ls = new List<string>
{
shop.ShopName,
shop.Address,
shop.DateOpen.ToShortDateString()
};
list.Add(ls);
}
var wordTable = new WordTable
{
Headers = new List<string> {
"Название",
"Адрес",
"Дата открытия"},
Columns = 3,
RowText = list
};
CreateTable(wordTable);
SaveWord(info);
}
protected abstract void CreateWord(WordInfo info); protected abstract void CreateWord(WordInfo info);
protected abstract void CreateParagraph(WordParagraph paragraph); protected abstract void CreateParagraph(WordParagraph paragraph);
protected abstract void CreateTable(WordTable table);
protected abstract void SaveWord(WordInfo info); protected abstract void SaveWord(WordInfo info);
} }

View File

@ -16,6 +16,10 @@ namespace IceCreamShopBusinessLogic.OfficePackage.HelperModels
get; get;
set; set;
} = new(); } = new();
public List<ReportShopIceCreamViewModel> ShopIceCreams
{
get;
set;
} = new();
} }
} }

View File

@ -14,5 +14,6 @@ namespace IceCreamShopBusinessLogic.OfficePackage.HelperModels
public DateTime DateFrom { get; set; } public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; } public DateTime DateTo { get; set; }
public List<ReportOrdersViewModel> Orders { get; set; } = new(); public List<ReportOrdersViewModel> Orders { get; set; } = new();
public List<ReportDateOrdersViewModel> DateOrders { get; set; } = new();
} }
} }

View File

@ -12,5 +12,6 @@ namespace IceCreamShopBusinessLogic.OfficePackage.HelperModels
public string FileName { get; set; } = string.Empty; public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty; public string Title { get; set; } = string.Empty;
public List<IceCreamViewModel> IceCreams { get; set; } = new(); public List<IceCreamViewModel> IceCreams { get; set; } = new();
public List<ShopViewModel> Shops { get; set; } = new();
} }
} }

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopBusinessLogic.OfficePackage.HelperModels
{
public class WordTable
{
public List<string> Headers { get; set; } = new();
public List<List<string>> RowText { get; set; } = new();
public int Columns { get; set; }
}
}

View File

@ -117,5 +117,83 @@ namespace IceCreamShopBusinessLogic.OfficePackage.Implements
_wordDocument.Dispose(); _wordDocument.Dispose();
} }
protected override void CreateTable(WordTable table)
{
if (_docBody == null || table == null)
{
return;
}
Table docTable = new Table();
TableProperties tableProps = new TableProperties(
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
});
docTable.AppendChild<TableProperties>(tableProps);
TableGrid tableGrid = new TableGrid();
for (int i = 0; i < table.Columns; i++)
{
tableGrid.AppendChild(new GridColumn());
}
docTable.AppendChild(tableGrid);
TableRow tableRow = new TableRow();
foreach (var text in table.Headers)
{
tableRow.AppendChild(CreateTableCell(text));
}
docTable.AppendChild(tableRow);
int height = table.RowText.Count;
int width = table.Columns;
for (int i = 0; i < height; i++)
{
tableRow = new TableRow();
for (int j = 0; j < width; j++)
{
var element = table.RowText[i][j];
tableRow.AppendChild(CreateTableCell(element));
}
docTable.AppendChild(tableRow);
}
_docBody.AppendChild(docTable);
}
private TableCell CreateTableCell(string element)
{
var tableParagraph = new Paragraph();
var run = new Run();
run.AppendChild(new Text { Text = element });
tableParagraph.AppendChild(run);
var tableCell = new TableCell();
tableCell.AppendChild(tableParagraph);
return tableCell;
}
} }
} }

View File

@ -0,0 +1,19 @@
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.BindingModels
{
public class ShopBindingModel : IShopModel
{
public int Id { get; set; }
public string ShopName { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public DateTime DateOpen { get; set; }
public int MaxCapacity { get; set; }
public Dictionary<int, (IIceCreamModel, int)> ShopIceCreams { get; set; } = new();
}
}

View File

@ -12,8 +12,13 @@ namespace IceCreamShopContracts.BusinessLogicsContracts
{ {
List<ReportIceCreamComponentViewModel> GetIceCreamComponent(); List<ReportIceCreamComponentViewModel> GetIceCreamComponent();
List<ReportOrdersViewModel> GetOrders(ReportBindingModel model); List<ReportOrdersViewModel> GetOrders(ReportBindingModel model);
List<ReportDateOrdersViewModel> GetDatesOrders();
List<ReportShopIceCreamViewModel> GetShopsIceCreams();
void SaveIceCreamToWordFile(ReportBindingModel model); void SaveIceCreamToWordFile(ReportBindingModel model);
void SaveIceCreamComponentToExcelFile(ReportBindingModel model); void SaveIceCreamComponentToExcelFile(ReportBindingModel model);
void SaveOrdersToPdfFile(ReportBindingModel model); void SaveOrdersToPdfFile(ReportBindingModel model);
void SaveShopsToWordFile(ReportBindingModel model);
void SaveShopsIceCreamsToExcelFile(ReportBindingModel model);
void SaveDatesOrdersToPdfFile(ReportBindingModel model);
} }
} }

View File

@ -0,0 +1,23 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.BusinessLogicsContracts
{
public interface IShopLogic
{
List<ShopViewModel>? ReadList(ShopSearchModel? model);
ShopViewModel? ReadElement(ShopSearchModel model);
bool Create(ShopBindingModel model);
bool Update(ShopBindingModel model);
bool Delete(ShopBindingModel model);
bool MakeSupply(ShopSearchModel model, IIceCreamModel iceCream, int count);
bool MakeSell(IIceCreamModel iceCream, int count);
}
}

View File

@ -0,0 +1,15 @@
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.SearchModels
{
public class ShopSearchModel
{
public int? Id { get; set; }
public string? Name { get; set; }
}
}

View File

@ -0,0 +1,23 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.StoragesContracts
{
public interface IShopStorage
{
List<ShopViewModel> GetFullList();
List<ShopViewModel> GetFilteredList(ShopSearchModel model);
ShopViewModel? GetElement(ShopSearchModel model);
ShopViewModel? Insert(ShopBindingModel model);
ShopViewModel? Update(ShopBindingModel model);
ShopViewModel? Delete(ShopBindingModel model);
public bool SellIceCreams(IIceCreamModel model, int count);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.ViewModels
{
public class ReportDateOrdersViewModel
{
public DateTime DateOfOrders { get; set; }
public int Count { get; set; }
public double Sum { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.ViewModels
{
public class ReportShopIceCreamViewModel
{
public string ShopName { get; set; } = string.Empty;
public int TotalCount { get; set; }
public List<Tuple<string, int>> IceCreams { get; set; } = new();
}
}

View File

@ -0,0 +1,24 @@
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopContracts.ViewModels
{
public class ShopViewModel : IShopModel
{
public int Id { get; set; }
[DisplayName("Название магазина")]
public string ShopName { get; set; }
[DisplayName("Адрес магазина")]
public string Address { get; set; }
[DisplayName("Дата открытия")]
public DateTime DateOpen { get; set; }
[DisplayName("Вместимость")]
public int MaxCapacity { get; set; }
public Dictionary<int, (IIceCreamModel, int)> ShopIceCreams { get; set; } = new();
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopDataModels.Models
{
public interface IShopModel : IId
{
string ShopName { get; }
string Address { get; }
DateTime DateOpen { get; }
Dictionary<int, (IIceCreamModel, int)> ShopIceCreams { get; }
int MaxCapacity { get; }
}
}

View File

@ -16,7 +16,7 @@ optionsBuilder)
{ {
if (optionsBuilder.IsConfigured == false) if (optionsBuilder.IsConfigured == false)
{ {
optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=IceCreamShopDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); optionsBuilder.UseSqlServer(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=IceCreamShopHardDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True");
} }
base.OnConfiguring(optionsBuilder); base.OnConfiguring(optionsBuilder);
} }
@ -24,6 +24,8 @@ optionsBuilder)
public virtual DbSet<IceCream> IceCreams { set; get; } public virtual DbSet<IceCream> IceCreams { set; get; }
public virtual DbSet<IceCreamComponent> IceCreamComponents { set; get; } public virtual DbSet<IceCreamComponent> IceCreamComponents { set; get; }
public virtual DbSet<Order> Orders { set; get; } public virtual DbSet<Order> Orders { set; get; }
public virtual DbSet<Shop> Shops { set; get; }
public virtual DbSet<ShopIceCream> ShopIceCreams { set; get; }
public virtual DbSet<Client> Clients { set; get; } public virtual DbSet<Client> Clients { set; get; }
public virtual DbSet<Implementer> Implementers { set; get; } public virtual DbSet<Implementer> Implementers { set; get; }

View File

@ -76,7 +76,7 @@ namespace IceCreamShopDatabaseImplement.Implements
public OrderViewModel? Delete(OrderBindingModel model) public OrderViewModel? Delete(OrderBindingModel model)
{ {
using var context = new IceCreamShopDataBase(); using var context = new IceCreamShopDataBase();
var element = context.Orders.FirstOrDefault(rec => rec.Id == var element = context.Orders.Include(x => x.IceCream).FirstOrDefault(rec => rec.Id ==
model.Id); model.Id);
if (element != null) if (element != null)
{ {

View File

@ -0,0 +1,153 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.StoragesContracts;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDatabaseImplement.Models;
using IceCreamShopDataModels.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopDatabaseImplement.Implements
{
public class ShopStorage : IShopStorage
{
public ShopViewModel? Delete(ShopBindingModel model)
{
using var context = new IceCreamShopDataBase();
var element = context.Shops.FirstOrDefault(x => x.Id == model.Id);
if (element != null)
{
context.Shops.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
{
return null;
}
using var context = new IceCreamShopDataBase();
return context.Shops
.Include(x => x.IceCreams)
.ThenInclude(x => x.IceCream)
.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
?.GetViewModel;
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.Name))
{
return new();
}
using var context = new IceCreamShopDataBase();
return context.Shops
.Include(x => x.IceCreams)
.ThenInclude(x => x.IceCream)
.Select(x => x.GetViewModel)
.Where(x => x.ShopName.Contains(model.Name ?? string.Empty))
.ToList();
}
public List<ShopViewModel> GetFullList()
{
using var context = new IceCreamShopDataBase();
return context.Shops
.Include(x => x.IceCreams)
.ThenInclude(x => x.IceCream)
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? Insert(ShopBindingModel model)
{
using var context = new IceCreamShopDataBase();
try
{
var newShop = Shop.Create(context, model);
if (newShop == null)
{
return null;
}
if (context.Shops.Any(x => x.ShopName == newShop.ShopName))
{
throw new Exception("Не должно быть два магазина с одним названием");
}
context.Shops.Add(newShop);
context.SaveChanges();
return newShop.GetViewModel;
}
catch
{
throw;
}
}
public ShopViewModel? Update(ShopBindingModel model)
{
using var context = new IceCreamShopDataBase();
var shop = context.Shops.FirstOrDefault(x => x.Id == model.Id);
if (shop == null)
{
return null;
}
try
{
if (context.Shops.Any(x => (x.ShopName == model.ShopName && x.Id != model.Id)))
{
throw new Exception("Не должно быть два магазина с одним названием");
}
shop.Update(model);
shop.UpdateIceCreams(context, model);
context.SaveChanges();
return shop.GetViewModel;
}
catch
{
throw;
}
}
public bool SellIceCreams(IIceCreamModel model, int count)
{
if (model == null)
return false;
using var context = new IceCreamShopDataBase();
using var transaction = context.Database.BeginTransaction();
List<ShopIceCream> lst = new List<ShopIceCream>();
foreach(var el in context.ShopIceCreams.Where(x => x.IceCreamId == model.Id))
{
int dif = count;
if (el.Count < dif)
dif = el.Count;
el.Count -= dif;
count -= dif;
if(el.Count == 0)
{
lst.Add(el);
}
if (count == 0)
break;
}
if (count > 0)
{
transaction.Rollback();
return false;
}
foreach(var el in lst)
{
context.ShopIceCreams.Remove(el);
}
context.SaveChanges();
transaction.Commit();
return true;
}
}
}

View File

@ -12,7 +12,11 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace IceCreamShopDatabaseImplement.Migrations namespace IceCreamShopDatabaseImplement.Migrations
{ {
[DbContext(typeof(IceCreamShopDataBase))] [DbContext(typeof(IceCreamShopDataBase))]
<<<<<<<< HEAD:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240415130513_InitialCreate.Designer.cs
[Migration("20240415130513_InitialCreate")] [Migration("20240415130513_InitialCreate")]
========
[Migration("20240414075932_InitialCreate")]
>>>>>>>> Lab5_Hard:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240414075932_InitialCreate.Designer.cs
partial class InitialCreate partial class InitialCreate
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -186,6 +190,59 @@ namespace IceCreamShopDatabaseImplement.Migrations
b.ToTable("Orders"); b.ToTable("Orders");
}); });
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DateOpen")
.HasColumnType("datetime2");
b.Property<int>("MaxCapacity")
.HasColumnType("int");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.ShopIceCream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("IceCreamId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("IceCreamId");
b.HasIndex("ShopId");
b.ToTable("ShopIceCreams");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.IceCreamComponent", b => modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.IceCreamComponent", b =>
{ {
b.HasOne("IceCreamShopDatabaseImplement.Models.Component", "Component") b.HasOne("IceCreamShopDatabaseImplement.Models.Component", "Component")
@ -230,6 +287,25 @@ namespace IceCreamShopDatabaseImplement.Migrations
b.Navigation("Implementer"); b.Navigation("Implementer");
}); });
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.ShopIceCream", b =>
{
b.HasOne("IceCreamShopDatabaseImplement.Models.IceCream", "IceCream")
.WithMany("ShopIceCreams")
.HasForeignKey("IceCreamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IceCreamShopDatabaseImplement.Models.Shop", "Shop")
.WithMany("IceCreams")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("IceCream");
b.Navigation("Shop");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Client", b => modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Client", b =>
{ {
b.Navigation("Orders"); b.Navigation("Orders");
@ -245,6 +321,13 @@ namespace IceCreamShopDatabaseImplement.Migrations
b.Navigation("Components"); b.Navigation("Components");
b.Navigation("Orders"); b.Navigation("Orders");
b.Navigation("ShopIceCreams");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Shop", b =>
{
b.Navigation("IceCreams");
}); });
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Implementer", b => modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Implementer", b =>

View File

@ -55,11 +55,16 @@ namespace IceCreamShopDatabaseImplement.Migrations
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
<<<<<<<< HEAD:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240415130513_InitialCreate.cs
name: "Implementers", name: "Implementers",
========
name: "Shops",
>>>>>>>> Lab5_Hard:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240414075932_InitialCreate.cs
columns: table => new columns: table => new
{ {
Id = table.Column<int>(type: "int", nullable: false) Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"), .Annotation("SqlServer:Identity", "1, 1"),
<<<<<<<< HEAD:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240415130513_InitialCreate.cs
ImplementerFIO = table.Column<string>(type: "nvarchar(max)", nullable: false), ImplementerFIO = table.Column<string>(type: "nvarchar(max)", nullable: false),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false), Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
Qualification = table.Column<int>(type: "int", nullable: false), Qualification = table.Column<int>(type: "int", nullable: false),
@ -68,6 +73,16 @@ namespace IceCreamShopDatabaseImplement.Migrations
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_Implementers", x => x.Id); table.PrimaryKey("PK_Implementers", x => x.Id);
========
ShopName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Address = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateOpen = table.Column<DateTime>(type: "datetime2", nullable: false),
MaxCapacity = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Shops", x => x.Id);
>>>>>>>> Lab5_Hard:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240414075932_InitialCreate.cs
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
@ -134,6 +149,33 @@ namespace IceCreamShopDatabaseImplement.Migrations
principalColumn: "Id"); principalColumn: "Id");
}); });
migrationBuilder.CreateTable(
name: "ShopIceCreams",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
IceCreamId = table.Column<int>(type: "int", nullable: false),
ShopId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShopIceCreams", x => x.Id);
table.ForeignKey(
name: "FK_ShopIceCreams_IceCreams_IceCreamId",
column: x => x.IceCreamId,
principalTable: "IceCreams",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ShopIceCreams_Shops_ShopId",
column: x => x.ShopId,
principalTable: "Shops",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_IceCreamComponents_ComponentId", name: "IX_IceCreamComponents_ComponentId",
table: "IceCreamComponents", table: "IceCreamComponents",
@ -155,9 +197,20 @@ namespace IceCreamShopDatabaseImplement.Migrations
column: "IceCreamId"); column: "IceCreamId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
<<<<<<<< HEAD:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240415130513_InitialCreate.cs
name: "IX_Orders_ImplementerId", name: "IX_Orders_ImplementerId",
table: "Orders", table: "Orders",
column: "ImplementerId"); column: "ImplementerId");
========
name: "IX_ShopIceCreams_IceCreamId",
table: "ShopIceCreams",
column: "IceCreamId");
migrationBuilder.CreateIndex(
name: "IX_ShopIceCreams_ShopId",
table: "ShopIceCreams",
column: "ShopId");
>>>>>>>> Lab5_Hard:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240414075932_InitialCreate.cs
} }
/// <inheritdoc /> /// <inheritdoc />
@ -169,6 +222,9 @@ namespace IceCreamShopDatabaseImplement.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Orders"); name: "Orders");
migrationBuilder.DropTable(
name: "ShopIceCreams");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Components"); name: "Components");
@ -179,7 +235,11 @@ namespace IceCreamShopDatabaseImplement.Migrations
name: "IceCreams"); name: "IceCreams");
migrationBuilder.DropTable( migrationBuilder.DropTable(
<<<<<<<< HEAD:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240415130513_InitialCreate.cs
name: "Implementers"); name: "Implementers");
========
name: "Shops");
>>>>>>>> Lab5_Hard:IceCreamShop/IceCreamShopDatabaseImplement/Migrations/20240414075932_InitialCreate.cs
} }
} }
} }

View File

@ -183,6 +183,59 @@ namespace IceCreamShopDatabaseImplement.Migrations
b.ToTable("Orders"); b.ToTable("Orders");
}); });
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("DateOpen")
.HasColumnType("datetime2");
b.Property<int>("MaxCapacity")
.HasColumnType("int");
b.Property<string>("ShopName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.ShopIceCream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("IceCreamId")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("IceCreamId");
b.HasIndex("ShopId");
b.ToTable("ShopIceCreams");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.IceCreamComponent", b => modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.IceCreamComponent", b =>
{ {
b.HasOne("IceCreamShopDatabaseImplement.Models.Component", "Component") b.HasOne("IceCreamShopDatabaseImplement.Models.Component", "Component")
@ -227,6 +280,25 @@ namespace IceCreamShopDatabaseImplement.Migrations
b.Navigation("Implementer"); b.Navigation("Implementer");
}); });
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.ShopIceCream", b =>
{
b.HasOne("IceCreamShopDatabaseImplement.Models.IceCream", "IceCream")
.WithMany("ShopIceCreams")
.HasForeignKey("IceCreamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("IceCreamShopDatabaseImplement.Models.Shop", "Shop")
.WithMany("IceCreams")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("IceCream");
b.Navigation("Shop");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Client", b => modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Client", b =>
{ {
b.Navigation("Orders"); b.Navigation("Orders");
@ -242,6 +314,13 @@ namespace IceCreamShopDatabaseImplement.Migrations
b.Navigation("Components"); b.Navigation("Components");
b.Navigation("Orders"); b.Navigation("Orders");
b.Navigation("ShopIceCreams");
});
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Shop", b =>
{
b.Navigation("IceCreams");
}); });
modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Implementer", b => modelBuilder.Entity("IceCreamShopDatabaseImplement.Models.Implementer", b =>

View File

@ -38,6 +38,8 @@ namespace IceCreamShopDatabaseImplement.Models
public virtual List<IceCreamComponent> Components { get; set; } = new(); public virtual List<IceCreamComponent> Components { get; set; } = new();
[ForeignKey("IceCreamId")] [ForeignKey("IceCreamId")]
public virtual List<Order> Orders { get; set; } = new(); public virtual List<Order> Orders { get; set; } = new();
[ForeignKey("IceCreamId")]
public virtual List<ShopIceCream> ShopIceCreams { get; set; } = new();
public static IceCream Create(IceCreamShopDataBase context, public static IceCream Create(IceCreamShopDataBase context,
IceCreamBindingModel model) IceCreamBindingModel model)
{ {
@ -71,7 +73,7 @@ namespace IceCreamShopDatabaseImplement.Models
{ {
var iceCreamComponents = context.IceCreamComponents.Where(rec => var iceCreamComponents = context.IceCreamComponents.Where(rec =>
rec.IceCreamId == model.Id).ToList(); rec.IceCreamId == model.Id).ToList();
if (iceCreamComponents != null && IceCreamComponents.Count > 0) if (iceCreamComponents != null && iceCreamComponents.Count > 0)
{ {
context.IceCreamComponents.RemoveRange(iceCreamComponents.Where(rec context.IceCreamComponents.RemoveRange(iceCreamComponents.Where(rec
=> !model.IceCreamComponents.ContainsKey(rec.ComponentId))); => !model.IceCreamComponents.ContainsKey(rec.ComponentId)));

View File

@ -0,0 +1,120 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopDatabaseImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; private set; }
[Required]
public string ShopName { get; private set; }
[Required]
public string Address { get; private set; }
[Required]
public DateTime DateOpen { get; private set; }
[Required]
public int MaxCapacity { get; private set; }
private Dictionary<int, (IIceCreamModel, int)>? _shopIceCreams =
null;
[NotMapped]
public Dictionary<int, (IIceCreamModel, int)> ShopIceCreams
{
get
{
if (_shopIceCreams == null)
{
_shopIceCreams = IceCreams
.ToDictionary(x => x.IceCreamId, x =>
(x.IceCream as IIceCreamModel, x.Count));
}
return _shopIceCreams;
}
}
[ForeignKey("ShopId")]
public virtual List<ShopIceCream> IceCreams { get; set; } = new();
public static Shop? Create(IceCreamShopDataBase context, ShopBindingModel model)
{
if (model == null)
return null;
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
MaxCapacity = model.MaxCapacity,
IceCreams = model.ShopIceCreams.Select(x => new
ShopIceCream
{
IceCream = context.IceCreams.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
public void Update(ShopBindingModel? model)
{
if (model == null)
{
return;
}
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
MaxCapacity = model.MaxCapacity;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
ShopIceCreams = ShopIceCreams,
MaxCapacity = MaxCapacity
};
public void UpdateIceCreams(IceCreamShopDataBase context,
ShopBindingModel model)
{
if (model.ShopIceCreams == null)
return;
var shopIceCreams = context.ShopIceCreams.Where(rec =>
rec.ShopId == model.Id).ToList();
if (shopIceCreams != null && shopIceCreams.Count > 0)
{
context.ShopIceCreams.RemoveRange(shopIceCreams.Where(rec
=> !model.ShopIceCreams.ContainsKey(rec.IceCreamId)));
context.SaveChanges();
foreach (var updateIceCream in shopIceCreams)
{
updateIceCream.Count =
model.ShopIceCreams[updateIceCream.IceCreamId].Item2;
model.ShopIceCreams.Remove(updateIceCream.IceCreamId);
}
context.SaveChanges();
}
var shop = context.Shops.First(x => x.Id == Id);
foreach (var pc in model.ShopIceCreams)
{
context.ShopIceCreams.Add(new ShopIceCream
{
Shop = shop,
IceCream = context.IceCreams.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
_shopIceCreams = null;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopDatabaseImplement.Models
{
public class ShopIceCream
{
public int Id { get; set; }
[Required]
public int IceCreamId { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int Count { get; set; }
public virtual Shop Shop { get; set; } = new();
public virtual IceCream IceCream { get; set; } = new();
}
}

View File

@ -14,11 +14,13 @@ namespace IceCreamShopFileImplement
private readonly string ComponentFileName = "Component.xml"; private readonly string ComponentFileName = "Component.xml";
private readonly string OrderFileName = "Order.xml"; private readonly string OrderFileName = "Order.xml";
private readonly string IceCreamFileName = "IceCream.xml"; private readonly string IceCreamFileName = "IceCream.xml";
private readonly string ShopFileName = "Shops.xml";
private readonly string ClientFileName = "Client.xml"; private readonly string ClientFileName = "Client.xml";
private readonly string ImplementerFileName = "Implementer.xml"; private readonly string ImplementerFileName = "Implementer.xml";
public List<Component> Components { get; private set; } public List<Component> Components { get; private set; }
public List<Order> Orders { get; private set; } public List<Order> Orders { get; private set; }
public List<IceCream> IceCreams { get; private set; } public List<IceCream> IceCreams { get; private set; }
public List<Shop> Shops { get; private set; }
public List<Client> Clients { get; private set; } public List<Client> Clients { get; private set; }
public List<Implementer> Implementers { get; private set; } public List<Implementer> Implementers { get; private set; }
@ -37,6 +39,8 @@ namespace IceCreamShopFileImplement
"IceCreams", x => x.GetXElement); "IceCreams", x => x.GetXElement);
public void SaveOrders() => SaveData(Orders, OrderFileName, public void SaveOrders() => SaveData(Orders, OrderFileName,
"Orders", x => x.GetXElement); "Orders", x => x.GetXElement);
public void SaveShops() => SaveData(Shops, ShopFileName,
"Shops", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, ClientFileName, public void SaveClients() => SaveData(Clients, ClientFileName,
"Clients", x => x.GetXElement); "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, public void SaveImplementers() => SaveData(Implementers, ImplementerFileName,
@ -49,6 +53,8 @@ namespace IceCreamShopFileImplement
IceCream.Create(x)!)!; IceCream.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Orders = LoadData(OrderFileName, "Order", x =>
Order.Create(x)!)!; Order.Create(x)!)!;
Shops = LoadData(ShopFileName, "Shop", x =>
Shop.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Clients = LoadData(ClientFileName, "Client", x =>
Client.Create(x)!)!; Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementers = LoadData(ImplementerFileName, "Implementer", x =>

View File

@ -2,6 +2,7 @@
using IceCreamShopContracts.SearchModels; using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.StoragesContracts; using IceCreamShopContracts.StoragesContracts;
using IceCreamShopContracts.ViewModels; using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using IceCreamShopFileImplement.Models; using IceCreamShopFileImplement.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -91,5 +92,6 @@ model)
return null; return null;
} }
} }
} }

View File

@ -0,0 +1,140 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.StoragesContracts;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using IceCreamShopFileImplement;
using IceCreamShopFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopFileImplement.Implements
{
public class ShopStorage : IShopStorage
{
private readonly DataFileSingleton _source;
public ShopStorage()
{
_source = DataFileSingleton.GetInstance();
}
public List<ShopViewModel> GetFullList()
{
return _source.Shops
.Select(x => x.GetViewModel)
.ToList();
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel
model)
{
if (string.IsNullOrEmpty(model.Name))
{
return new();
}
return _source.Shops
.Where(x => x.ShopName.Contains(model.Name))
.Select(x => x.GetViewModel)
.ToList(); ;
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
{
return null;
}
return _source.Shops
.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.Name) && x.ShopName ==
model.Name) ||
(model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
}
public ShopViewModel? Insert(ShopBindingModel model)
{
model.Id = _source.Shops.Count > 0 ? _source.Shops.Max(x =>
x.Id) + 1 : 1;
var newShop = Shop.Create(model);
if (newShop == null)
{
return null;
}
_source.Shops.Add(newShop);
_source.SaveShops();
return newShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
var component = _source.Shops.FirstOrDefault(x => x.Id ==
model.Id);
if (component == null)
{
return null;
}
component.Update(model);
_source.SaveShops();
return component.GetViewModel;
}
public ShopViewModel? Delete(ShopBindingModel model)
{
var element = _source.Shops.FirstOrDefault(x => x.Id ==
model.Id);
if (element != null)
{
_source.Shops.Remove(element);
_source.SaveShops();
return element.GetViewModel;
}
return null;
}
public bool CheckAvailability(int iceCreamId, int count)
{
int minus = _source.Shops.Select(x => x.ShopIceCreams.Select(y => (y.Value.Item1.Id == iceCreamId ? y.Value.Item2 : 0)).Sum()).Sum();
count -= minus;
return count <= 0;
}
public bool SellIceCreams(IIceCreamModel model, int count)
{
var iceCream = _source.IceCreams.FirstOrDefault(x => x.Id == model.Id);
if (iceCream == null || !CheckAvailability(iceCream.Id, count))
{
return false;
}
for (int i = 0; i < _source.Shops.Count; i++)
{
var shop = _source.Shops[i];
var icecreams = shop.ShopIceCreams;
foreach (var icecream in icecreams.Where(x => x.Value.Item1.Id == iceCream.Id))
{
var min = Math.Min(icecream.Value.Item2, count);
icecreams[icecream.Value.Item1.Id] = (icecream.Value.Item1, icecream.Value.Item2 - min);
count -= min;
if (count <= 0)
{
break;
}
}
shop.Update(new ShopBindingModel
{
Id = shop.Id,
ShopName = shop.ShopName,
Address = shop.Address,
DateOpen = shop.DateOpen,
MaxCapacity = shop.MaxCapacity,
ShopIceCreams = icecreams
});
}
_source.SaveShops();
return true;
}
}
}

View File

@ -0,0 +1,118 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using IceCreamShopFileImplement;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Xml.Linq;
namespace IceCreamShopFileImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; private set; }
public string ShopName { get; private set; }
public string Address { get; private set; }
public DateTime DateOpen { get; private set; }
public Dictionary<int, int> IceCreams { get; private set; } = new();
private Dictionary<int, (IIceCreamModel, int)>? _shopIceCreams =
null;
public Dictionary<int, (IIceCreamModel, int)> ShopIceCreams
{
get
{
if (_shopIceCreams == null)
{
var source = DataFileSingleton.GetInstance();
_shopIceCreams = IceCreams.ToDictionary(x => x.Key, y =>
((source.IceCreams.FirstOrDefault(z => z.Id == y.Key) as IIceCreamModel)!,
y.Value));
}
return _shopIceCreams;
}
}
public int MaxCapacity { get; private set; }
public static Shop? Create(ShopBindingModel model)
{
if (model == null)
return null;
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
MaxCapacity = model.MaxCapacity,
IceCreams = model.ShopIceCreams.ToDictionary(x => x.Key, x => x.Value.Item2)
};
}
public static Shop? Create(XElement element)
{
if (element == null)
{
return null;
}
return new Shop()
{
Id = Convert.ToInt32(element.Attribute("Id")!.Value),
ShopName = element.Element("ShopName")!.Value,
Address = element.Element("Address")!.Value,
MaxCapacity = Convert.ToInt32(element.Element("MaxCapacity")!.Value),
DateOpen = Convert.ToDateTime(element.Element("DateOpen")!.Value),
IceCreams =
element.Element("ShopIceCreams")!.Elements("ShopIceCream")
.ToDictionary(x =>
Convert.ToInt32(x.Element("Key")?.Value), x =>
Convert.ToInt32(x.Element("Value")?.Value))
};
}
public void Update(ShopBindingModel model)
{
if (model == null)
{
return;
}
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
MaxCapacity = model.MaxCapacity;
if (model.ShopIceCreams.Count > 0)
{
IceCreams = model.ShopIceCreams.ToDictionary(x => x.Key, x => x.Value.Item2);
_shopIceCreams = null;
}
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
MaxCapacity = MaxCapacity,
ShopIceCreams = ShopIceCreams
};
public XElement GetXElement => new("Shop",
new XAttribute("Id", Id),
new XElement("ShopName", ShopName),
new XElement("Address", Address),
new XElement("DateOpen", DateOpen),
new XElement("MaxCapacity", MaxCapacity),
new XElement("ShopIceCreams", IceCreams
.Select(x => new XElement("ShopIceCream",
new XElement("Key", x.Key),
new XElement("Value", x.Value))
).ToArray()));
}
}

View File

@ -13,6 +13,7 @@ namespace IceCreamShopListImplement
public List<Component> Components { get; set; } public List<Component> Components { get; set; }
public List<Order> Orders { get; set; } public List<Order> Orders { get; set; }
public List<IceCream> IceCreams { get; set; } public List<IceCream> IceCreams { get; set; }
public List<Shop> Shops { get; set; }
public List<Client> Clients { get; set; } public List<Client> Clients { get; set; }
public List<Implementer> Implementers { get; set; } public List<Implementer> Implementers { get; set; }
private DataListSingleton() private DataListSingleton()
@ -20,6 +21,7 @@ namespace IceCreamShopListImplement
Components = new List<Component>(); Components = new List<Component>();
Orders = new List<Order>(); Orders = new List<Order>();
IceCreams = new List<IceCream>(); IceCreams = new List<IceCream>();
Shops = new List<Shop>();
Clients = new List<Client>(); Clients = new List<Client>();
Implementers = new List<Implementer>(); Implementers = new List<Implementer>();
} }

View File

@ -0,0 +1,156 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.StoragesContracts;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using IceCreamShopListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IceCreamShopListImplement.Implements
{
public class ShopStorage : IShopStorage
{
private readonly DataListSingleton _source;
public ShopStorage()
{
_source = DataListSingleton.GetInstance();
}
public List<ShopViewModel> GetFullList()
{
var result = new List<ShopViewModel>();
foreach (var shop in _source.Shops)
{
result.Add(shop.GetViewModel);
}
return result;
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel
model)
{
var result = new List<ShopViewModel>();
if (string.IsNullOrEmpty(model.Name))
{
return result;
}
foreach (var shop in _source.Shops)
{
if (shop.ShopName.Contains(model.Name))
{
result.Add(shop.GetViewModel);
}
}
return result;
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
{
return null;
}
foreach (var shop in _source.Shops)
{
if ((!string.IsNullOrEmpty(model.Name) &&
shop.ShopName == model.Name) ||
(model.Id.HasValue && shop.Id == model.Id))
{
return shop.GetViewModel;
}
}
return null;
}
public ShopViewModel? Insert(ShopBindingModel model)
{
model.Id = 1;
foreach (var shop in _source.Shops)
{
if (model.Id <= shop.Id)
{
model.Id = shop.Id + 1;
}
}
var newShop = Shop.Create(model);
if (newShop == null)
{
return null;
}
_source.Shops.Add(newShop);
return newShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
foreach (var shop in _source.Shops)
{
if (shop.Id == model.Id)
{
shop.Update(model);
return shop.GetViewModel;
}
}
return null;
}
public ShopViewModel? Delete(ShopBindingModel model)
{
for (int i = 0; i < _source.Shops.Count; ++i)
{
if (_source.Shops[i].Id == model.Id)
{
var element = _source.Shops[i];
_source.Shops.RemoveAt(i);
return element.GetViewModel;
}
}
return null;
}
public bool CheckAvailability(int iceCreamId, int count)
{
int minus = _source.Shops.Select(x => x.ShopIceCreams.Select(y => (y.Value.Item1.Id == iceCreamId ? y.Value.Item2 : 0)).Sum()).Sum();
count -= minus;
return count <= 0;
}
public bool SellIceCreams(IIceCreamModel model, int count)
{
var iceCream = _source.IceCreams.FirstOrDefault(x => x.Id == model.Id);
if (iceCream == null || !CheckAvailability(iceCream.Id, count))
{
return false;
}
for (int i = 0; i < _source.Shops.Count; i++)
{
var shop = _source.Shops[i];
var icecreams = shop.ShopIceCreams;
foreach (var icecream in icecreams.Where(x => x.Value.Item1.Id == iceCream.Id))
{
var min = Math.Min(icecream.Value.Item2, count);
icecreams[icecream.Value.Item1.Id] = (icecream.Value.Item1, icecream.Value.Item2 - min);
count -= min;
if (count <= 0)
{
break;
}
}
shop.Update(new ShopBindingModel
{
Id = shop.Id,
ShopName = shop.ShopName,
Address = shop.Address,
DateOpen = shop.DateOpen,
MaxCapacity = shop.MaxCapacity,
ShopIceCreams = icecreams
});
}
return true;
}
}
}

View File

@ -56,7 +56,6 @@ namespace IceCreamShopListImplement.Models
Count = model.Count; Count = model.Count;
Sum = model.Sum; Sum = model.Sum;
Status = model.Status; Status = model.Status;
DateCreate = model.DateCreate;
DateImplement = model.DateImplement; DateImplement = model.DateImplement;
ImplementerId = model.ImplementerId; ImplementerId = model.ImplementerId;
} }

View File

@ -0,0 +1,57 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace IceCreamShopListImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; private set; }
public string ShopName { get; private set; }
public string Address { get; private set; }
public DateTime DateOpen { get; private set; }
public int MaxCapacity { get; private set; }
public Dictionary<int, (IIceCreamModel, int)> ShopIceCreams { get; private set; } = new();
public static Shop? Create (ShopBindingModel model)
{
if (model == null)
return null;
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
ShopIceCreams = new()
};
}
public void Update(ShopBindingModel? model)
{
if (model == null)
{
return;
}
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
ShopIceCreams = model.ShopIceCreams;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
ShopIceCreams = ShopIceCreams
};
}
}

View File

@ -0,0 +1,109 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.BusinessLogicsContracts;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopDataModels.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace IceCreamShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ShopController : ControllerBase
{
private readonly ILogger _logger;
private readonly IShopLogic _logic;
public ShopController(IShopLogic logic, ILogger<ShopController>
logger)
{
_logger = logger;
_logic = logic;
}
[HttpGet]
public Tuple<ShopViewModel, List<Tuple<string, int>>>? GetShop(int shopId)
{
try
{
var elem = _logic.ReadElement(new ShopSearchModel { Id = shopId });
if (elem == null)
return null;
return Tuple.Create(elem, elem.ShopIceCreams.Select(x => Tuple.Create(x.Value.Item1.IceCreamName, x.Value.Item2)).ToList());
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения магазина по id={Id}", shopId);
throw;
}
}
[HttpGet]
public List<ShopViewModel> GetShops()
{
try
{
return _logic.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка магазинов");
throw;
}
}
[HttpPost]
public bool CreateShop(ShopBindingModel model)
{
try
{
return _logic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Не удалось создать магазин");
throw;
}
}
[HttpPost]
public bool UpdateShop(ShopBindingModel model)
{
try
{
model.ShopIceCreams = null!;
return _logic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Не удалось обновить магазин");
throw;
}
}
[HttpPost]
public bool DeleteShop(ShopBindingModel model)
{
try
{
return _logic.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления магазина");
throw;
}
}
[HttpPost]
public bool MakeSupply(Tuple<ShopSearchModel, IceCreamViewModel, int> model)
{
try
{
return _logic.MakeSupply(model.Item1, model.Item2, model.Item3);
}
catch (Exception ex)
{
_logger.LogError(ex, "Не удалось сделать поставку в магазин");
throw;
}
}
}
}

View File

@ -8,9 +8,11 @@ builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config"); builder.Logging.AddLog4Net("log4net.config");
// Add services to the container. // Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IShopStorage, ShopStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IIceCreamStorage, IceCreamStorage>(); builder.Services.AddTransient<IIceCreamStorage, IceCreamStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IShopLogic, ShopLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IIceCreamLogic, IceCreamLogic>(); builder.Services.AddTransient<IIceCreamLogic, IceCreamLogic>();
builder.Services.AddControllers(); builder.Services.AddControllers();

View File

@ -0,0 +1,54 @@
using IceCreamShopContracts.ViewModels;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
namespace IceCreamShopsApp
{
public static class ApiClient
{
private static readonly HttpClient _client = new();
private static string password = string.Empty;
public static bool Access { get; private set; } = false;
public static void Connect(IConfiguration configuration)
{
password = configuration["Password"];
_client.BaseAddress = new Uri(configuration["IPAddress"]);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
}
public static T? GetRequest<T>(string requestUrl)
{
var response = _client.GetAsync(requestUrl);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (response.Result.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(result);
}
else
{
throw new Exception(result);
}
}
public static void PostRequest<T>(string requestUrl, T model)
{
var json = JsonConvert.SerializeObject(model);
var data = new StringContent(json, Encoding.UTF8,
"application/json");
var response = _client.PostAsync(requestUrl, data);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (!response.Result.IsSuccessStatusCode)
{
throw new Exception(result);
}
}
public static bool CheckPassword(string _password)
{
return Access = (_password == password);
}
}
}

View File

@ -0,0 +1,199 @@
using IceCreamShopContracts.BindingModels;
using IceCreamShopContracts.SearchModels;
using IceCreamShopContracts.ViewModels;
using IceCreamShopsApp.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace IceCreamShopsApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
if (ApiClient.Access == false)
{
return Redirect("~/Home/Enter");
}
return
View(ApiClient.GetRequest<List<ShopViewModel>>($"api/shop/getshops"));
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string password)
{
if (string.IsNullOrEmpty(password))
{
throw new Exception("Введите пароль");
}
ApiClient.CheckPassword(password);
if (ApiClient.Access == false)
{
throw new Exception("Неправильный пароль");
}
Response.Redirect("Index");
}
public IActionResult Create()
{
if (ApiClient.Access == false)
{
return Redirect("~/Home/Enter");
}
return View();
}
[HttpPost]
public void Create(string name, string address, DateTime dateOpen, int maxCapacity)
{
if (ApiClient.Access == false)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(address)
|| maxCapacity <= 0)
{
throw new Exception("Ошибка в введенных данных");
}
ApiClient.PostRequest("api/shop/createshop", new ShopBindingModel
{
ShopName = name,
Address = address,
MaxCapacity = maxCapacity,
DateOpen = dateOpen
});
Response.Redirect("Index");
}
public IActionResult Delete()
{
if (ApiClient.Access == false)
{
return Redirect("~/Home/Enter");
}
ViewBag.Shops = ApiClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
return View();
}
[HttpPost]
public void Delete(int shop)
{
if (ApiClient.Access == false)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
ApiClient.PostRequest("api/shop/deleteshop", new ShopBindingModel
{
Id = shop
});
Response.Redirect("Index");
}
public IActionResult Update()
{
if (ApiClient.Access == false)
{
return Redirect("~/Home/Enter");
}
ViewBag.Shops = ApiClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
return View();
}
[HttpPost]
public void Update(int shop, string name, string address, DateTime dateOpen, int maxCapacity)
{
if (ApiClient.Access == false)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(address)
|| maxCapacity <= 0)
{
throw new Exception("Ошибка в введенных данных");
}
ApiClient.PostRequest("api/shop/updateshop", new ShopBindingModel
{
Id = shop,
ShopName = name,
Address = address,
DateOpen = dateOpen,
MaxCapacity = maxCapacity,
});
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[HttpGet]
public Tuple<ShopViewModel, string>? GetShop(int shopId)
{
if (ApiClient.Access == false)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
var result = ApiClient.GetRequest<Tuple<ShopViewModel, List<Tuple<string, int>>>>($"api/shop/getshop?shopid={shopId}");
if (result == null)
{
return default;
}
string table = "";
result.Item1.ShopIceCreams.Clear();
for (int i = 0; i < result.Item2.Count; i++)
{
var icecream = result.Item2[i].Item1;
var count = result.Item2[i].Item2;
table += "<tr>";
table += $"<td>{icecream}</td>";
table += $"<td>{count}</td>";
table += "</tr>";
}
return Tuple.Create(result.Item1, table);
}
public IActionResult MakeSupply()
{
if (ApiClient.Access == false)
{
return Redirect("~/Home/Enter");
}
ViewBag.Shops = ApiClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
ViewBag.ListIceCream = ApiClient.GetRequest<List<IceCreamViewModel>>("api/main/GetIceCreamList");
return View();
}
[HttpPost]
public void MakeSupply(int shop, int icecream, int count)
{
if (ApiClient.Access == false)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
ApiClient.PostRequest("api/shop/makesupply", Tuple.Create(
new ShopSearchModel() { Id = shop },
new IceCreamViewModel() { Id = icecream },
count
));
Response.Redirect("Index");
}
}
}

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IceCreamShopContracts\IceCreamShopContracts.csproj" />
<ProjectReference Include="..\IceCreamShopRestApi\IceCreamShopRestApi.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,9 @@
namespace IceCreamShopsApp.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

View File

@ -0,0 +1,30 @@
using IceCreamShopsApp;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
ApiClient.Connect(builder.Configuration);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

View File

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:36478",
"sslPort": 44347
}
},
"profiles": {
"IceCreamShopsApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7077;http://localhost:5262",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,40 @@
@{
ViewData["Title"] = "Create";
}
<div class="text-center">
<h2 class="display-4">Создание магазина</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Название:</div>
<div class="col-8">
<input type="text" name="name" id="name" />
</div>
</div>
<div class="row">
<div class="col-4">Адрес:</div>
<div class="col-8">
<input type="text" name="address" id="address" />
</div>
</div>
<div class="row">
<div class="col-4">Дата открытия:</div>
<div class="col-8">
<input type="date" name="dateopen" id="dateopen" />
</div>
</div>
<div class="row">
<div class="col-4">Вместимость:</div>
<div class="col-8">
<input type="number" name="maxcapacity" id="maxcapacity" />
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4">
<input type="submit" value="Создать" class="btn
btn-primary" />
</div>
</div>
</form>

View File

@ -0,0 +1,18 @@
@{
ViewData["Title"] = "Delete";
}
<div class="text-center">
<h2 class="display-4">Удаление магазина</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Магазин:</div>
<div class="col-8">
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "ShopName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4"></div>
<div class="col-8"><input type="submit" value="Удалить" class="btn btn-danger" /></div>
</div>
</form>

View File

@ -0,0 +1,16 @@
@{
ViewData["Title"] = "Enter";
}
<div class="text-center">
<h2 class="display-4">Вход в приложение</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btnprimary" /></div>
</div>
</form>

View File

@ -0,0 +1,71 @@
@using IceCreamShopContracts.ViewModels
@model List<ShopViewModel>
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Магазины</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a asp-action="Create">Создать магазин</a>
<a asp-action="Update">Обновить магазин</a>
<a asp-action="Delete">Удалить магазин</a>
<a asp-action="MakeSupply">Пополнить магазин</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Название
</th>
<th>
Адрес
</th>
<th>
Дата открытия
</th>
<th>
Вместимость
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem =>
item.Id)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.ShopName)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Address)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.DateOpen)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.MaxCapacity)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,34 @@
@using IceCreamShopContracts.ViewModels;
@using IceCreamShopDataModels.Models;
@{
ViewData["Title"] = "Create";
}
@model Dictionary<int, (IIceCreamModel, int)>
<div class="text-center">
<h2 class="display-4">Добавление мороженого в магазин</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Магазин:</div>
<div class="col-8">
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "ShopName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Мороженное:</div>
<div class="col-8">
<select id="icecream" name="icecream" class="form-control" asp-items="@(new SelectList(@ViewBag.ListIceCream, "Id", "IceCreamName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Количество:</div>
<div class="col-8"><input type="number" id="count" name="count" min="1" class="form-control" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
</div>
</form>

View File

@ -0,0 +1,79 @@
@using IceCreamShopContracts.ViewModels;
@{
ViewData["Title"] = "Update";
}
<div class="text-center">
<h2 class="display-4">Редактирование магазина</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Магазин:</div>
<div class="col-8">
<select id="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "ShopName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Название:</div>
<div class="col-8"><input type="text" name="name" id="name" class="form-control" /></div>
</div>
<div class="row">
<div class="col-4">Адрес:</div>
<div class="col-8"><input type="text" id="address" name="address" class="form-control" /></div>
</div>
<div class="row">
<div class="col-4">Дата открытия:</div>
<div class="col-8"><input type="datetime-local" id="dateopen" name="dateopen" class="form-control" required /></div>
</div>
<div class="row">
<div class="col-4">Вместимость:</div>
<div class="col-8"><input type="number" id="maxcapacity" name="maxcapacity" class="form-control" /></div>
</div>
<table class="table">
<thead>
<tr>
<th>
Мороженое
</th>
<th>
Количество
</th>
</tr>
</thead>
<tbody id="table-elements">
</tbody>
</table>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
</div>
</form>
@section Scripts
{
<script>
function check() {
var shop = $('#shop').val();
if (shop) {
$.ajax({
method: "GET",
url: "/Home/GetShop",
data: { shopId: shop },
success: function (result) {
$('#name').val(result.item1.shopName);
$('#address').val(result.item1.address);
$('#dateopen').val(result.item1.dateOpen);
$('#maxcapacity').val(result.item1.maxCapacity);
$('#table-elements').html(result.item2);
}
});
};
}
check();
$('#shop').on('change', function () {
check();
});
</script>
}

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - IceCreamShopsApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/IceCreamShopsApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">IceCreamShopsApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - IceCreamShopsApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,48 @@
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

View File

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View File

@ -0,0 +1,3 @@
@using IceCreamShopsApp
@using IceCreamShopsApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,11 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"IPAddress": "http://localhost:5189/",
"Password": "bebra"
}

View File

@ -0,0 +1,18 @@
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
html {
position: relative;
min-height: 100%;
}
body {
margin-bottom: 60px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,4 @@
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2011-2021 Twitter, Inc.
Copyright (c) 2011-2021 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,427 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr /* rtl:ignore */;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,424 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr ;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More