diff --git a/BeautySaloon/BeautySaloonBusinessLogic/ServiceLogic.cs b/BeautySaloon/BeautySaloonBusinessLogic/ServiceLogic.cs index cd958b0..c2ce8a8 100644 --- a/BeautySaloon/BeautySaloonBusinessLogic/ServiceLogic.cs +++ b/BeautySaloon/BeautySaloonBusinessLogic/ServiceLogic.cs @@ -58,6 +58,16 @@ namespace BeautySaloonBusinessLogic return list; } + public List? ReadMostPopular() + { + var list = _serviceStorage.ReadMostPopular(); + if (list == null) + { + return null; + } + return list; + } + public bool Update(ServiceBindingModel model) { CheckModel(model); diff --git a/BeautySaloon/BeautySaloonContracts/BusinessLogicsContracts/IServiceLogic.cs b/BeautySaloon/BeautySaloonContracts/BusinessLogicsContracts/IServiceLogic.cs index d51b64b..6b031d0 100644 --- a/BeautySaloon/BeautySaloonContracts/BusinessLogicsContracts/IServiceLogic.cs +++ b/BeautySaloon/BeautySaloonContracts/BusinessLogicsContracts/IServiceLogic.cs @@ -15,5 +15,7 @@ namespace BeautySaloonContracts.BusinessLogicsContracts bool Update(ServiceBindingModel model); bool Delete(ServiceBindingModel model); + + List? ReadMostPopular(); } } diff --git a/BeautySaloon/BeautySaloonContracts/StoragesContracts/IServiceStorage.cs b/BeautySaloon/BeautySaloonContracts/StoragesContracts/IServiceStorage.cs index adb6b8a..05b7c61 100644 --- a/BeautySaloon/BeautySaloonContracts/StoragesContracts/IServiceStorage.cs +++ b/BeautySaloon/BeautySaloonContracts/StoragesContracts/IServiceStorage.cs @@ -7,6 +7,7 @@ namespace BeautySaloonContracts.StoragesContracts public interface IServiceStorage { List GetFullList(); + List ReadMostPopular(); List GetFilteredList(ServiceSearchModel model); ServiceViewModel? GetElement(ServiceSearchModel model); ServiceViewModel? Insert(ServiceBindingModel model); diff --git a/BeautySaloon/BeautySaloonContracts/ViewModels/ReportViewModel.cs b/BeautySaloon/BeautySaloonContracts/ViewModels/ReportViewModel.cs new file mode 100644 index 0000000..96f85f6 --- /dev/null +++ b/BeautySaloon/BeautySaloonContracts/ViewModels/ReportViewModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace BeautySaloonContracts.ViewModels +{ + public class ReportViewModel + { + [DisplayName("Услуга")] + public string Name { get; set; } = string.Empty; + //[DisplayName("Кол-во")] + //public decimal Count { get; set; } + [DisplayName("Сумма")] + public decimal Sum { get; set; } + } +} diff --git a/BeautySaloon/BeautySaloonDatabaseImplement/Implements/OrderStorage.cs b/BeautySaloon/BeautySaloonDatabaseImplement/Implements/OrderStorage.cs index 896adb3..d1b417e 100644 --- a/BeautySaloon/BeautySaloonDatabaseImplement/Implements/OrderStorage.cs +++ b/BeautySaloon/BeautySaloonDatabaseImplement/Implements/OrderStorage.cs @@ -49,21 +49,21 @@ namespace BeautySaloonDatabaseImplement.Implements .Include(x => x.Client) .Where(x => x.ClientId == model.ClientId) .Select(x => x.GetViewModel) - .ToList(); + .ToList().OrderByDescending(x => x.Date).ToList(); if (model.EmployeeId.HasValue) return context.Orders .Include(x => x.Employee) .Include(x => x.Client) .Where(x => x.EmployeeId == model.EmployeeId) .Select(x => x.GetViewModel) - .ToList(); + .ToList().OrderByDescending(x => x.Date).ToList(); if (model.Date.HasValue) return context.Orders .Include(x => x.Employee) .Include(x => x.Client) .Where(x => x.Date == model.Date) .Select(x => x.GetViewModel) - .ToList(); + .ToList().OrderByDescending(x => x.Date).ToList(); return new(); } @@ -74,7 +74,7 @@ namespace BeautySaloonDatabaseImplement.Implements .Include(x => x.Employee) .Include(x => x.Client) .Select(x => x.GetViewModel) - .ToList(); + .ToList().OrderByDescending(x => x.Date).ToList(); } public OrderViewModel? Insert(OrderBindingModel model) diff --git a/BeautySaloon/BeautySaloonDatabaseImplement/Implements/ServiceStorage.cs b/BeautySaloon/BeautySaloonDatabaseImplement/Implements/ServiceStorage.cs index f7fa16f..23794a5 100644 --- a/BeautySaloon/BeautySaloonDatabaseImplement/Implements/ServiceStorage.cs +++ b/BeautySaloon/BeautySaloonDatabaseImplement/Implements/ServiceStorage.cs @@ -2,6 +2,9 @@ using BeautySaloonContracts.SearchModels; using BeautySaloonContracts.StoragesContracts; using BeautySaloonContracts.ViewModels; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using System.Diagnostics; namespace BeautySaloonDatabaseImplement.Implements { @@ -71,6 +74,25 @@ namespace BeautySaloonDatabaseImplement.Implements return newService.GetViewModel; } + public List ReadMostPopular() + { + using var context = new NewdbContext(); + /*var temp = context.Services + .Select(x => x.GetViewModel) + .ToList();*/ + return context.ServiceOrders + .Include(x => x.Service) + .GroupBy(x => x.Service.Name) + .Select(x => new ReportViewModel() + { + Name = x.Key, + Sum = x.Sum(x => x.Service.Price) + }) + .OrderByDescending(x => x.Sum) + + .ToList(); + } + public ServiceViewModel? Update(ServiceBindingModel model) { using var context = new NewdbContext(); diff --git a/BeautySaloon/BeautySaloonDatabaseImplement/NewdbContext.cs b/BeautySaloon/BeautySaloonDatabaseImplement/NewdbContext.cs index 2a7bb91..155b537 100644 --- a/BeautySaloon/BeautySaloonDatabaseImplement/NewdbContext.cs +++ b/BeautySaloon/BeautySaloonDatabaseImplement/NewdbContext.cs @@ -27,7 +27,7 @@ public partial class NewdbContext : DbContext protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263. - => optionsBuilder.UseNpgsql("Host=192.168.0.103;Port=5432;Database=newdb;Username=username123;Password=12345"); + => optionsBuilder.UseNpgsql("Host=192.168.56.102;Port=5432;Database=newdb;Username=username123;Password=12345"); protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/BeautySaloon/BeautySaloonView/FormMain.Designer.cs b/BeautySaloon/BeautySaloonView/FormMain.Designer.cs index af20e02..9936a33 100644 --- a/BeautySaloon/BeautySaloonView/FormMain.Designer.cs +++ b/BeautySaloon/BeautySaloonView/FormMain.Designer.cs @@ -37,6 +37,8 @@ this.клиентыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.buttonUpdate = new System.Windows.Forms.Button(); this.buttonTest = new System.Windows.Forms.Button(); + this.отчетыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.услугиToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -56,7 +58,8 @@ // menuStrip1 // this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.справочникиToolStripMenuItem}); + this.справочникиToolStripMenuItem, + this.отчетыToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(1037, 24); @@ -124,6 +127,21 @@ this.buttonTest.UseVisualStyleBackColor = true; this.buttonTest.Click += new System.EventHandler(this.ButtonTest_Click); // + // отчетыToolStripMenuItem + // + this.отчетыToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.услугиToolStripMenuItem1}); + this.отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem"; + this.отчетыToolStripMenuItem.Size = new System.Drawing.Size(60, 20); + this.отчетыToolStripMenuItem.Text = "Отчеты"; + // + // услугиToolStripMenuItem1 + // + this.услугиToolStripMenuItem1.Name = "услугиToolStripMenuItem1"; + this.услугиToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); + this.услугиToolStripMenuItem1.Text = "Услуги"; + this.услугиToolStripMenuItem1.Click += new System.EventHandler(this.ReportServicesToolStripMenuItem_Click); + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -157,5 +175,7 @@ private Button buttonUpdate; private Button buttonCreateOrder; private Button buttonTest; + private ToolStripMenuItem отчетыToolStripMenuItem; + private ToolStripMenuItem услугиToolStripMenuItem1; } } \ No newline at end of file diff --git a/BeautySaloon/BeautySaloonView/FormMain.cs b/BeautySaloon/BeautySaloonView/FormMain.cs index c8fbf29..eba7d0d 100644 --- a/BeautySaloon/BeautySaloonView/FormMain.cs +++ b/BeautySaloon/BeautySaloonView/FormMain.cs @@ -81,5 +81,14 @@ namespace BeautySaloonView form.ShowDialog(); } } + + private void ReportServicesToolStripMenuItem_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormReportServices)); + if (service is FormReportServices form) + { + form.ShowDialog(); + } + } } } \ No newline at end of file diff --git a/BeautySaloon/BeautySaloonView/FormReportServices.Designer.cs b/BeautySaloon/BeautySaloonView/FormReportServices.Designer.cs new file mode 100644 index 0000000..243b70c --- /dev/null +++ b/BeautySaloon/BeautySaloonView/FormReportServices.Designer.cs @@ -0,0 +1,66 @@ +namespace BeautySaloonView +{ + partial class FormReportServices + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dataGridView = new System.Windows.Forms.DataGridView(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); + this.SuspendLayout(); + // + // dataGridView + // + this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView.GridColor = System.Drawing.Color.White; + this.dataGridView.Location = new System.Drawing.Point(0, 0); + this.dataGridView.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.dataGridView.Name = "dataGridView"; + this.dataGridView.RowHeadersWidth = 51; + this.dataGridView.RowTemplate.Height = 29; + this.dataGridView.Size = new System.Drawing.Size(800, 450); + this.dataGridView.TabIndex = 11; + // + // FormReportServices + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.dataGridView); + this.Name = "FormReportServices"; + this.Text = "Отчет по услугам"; + this.Load += new System.EventHandler(this.FormReportServices_Load); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private DataGridView dataGridView; + } +} \ No newline at end of file diff --git a/BeautySaloon/BeautySaloonView/FormReportServices.cs b/BeautySaloon/BeautySaloonView/FormReportServices.cs new file mode 100644 index 0000000..dd12bc8 --- /dev/null +++ b/BeautySaloon/BeautySaloonView/FormReportServices.cs @@ -0,0 +1,36 @@ +using BeautySaloonContracts.BusinessLogicsContracts; +using BeautySaloonContracts.SearchModels; +using System.Windows.Forms; + +namespace BeautySaloonView +{ + public partial class FormReportServices : Form + { + private readonly IServiceLogic _logic; + public FormReportServices(IServiceLogic logic) + { + InitializeComponent(); + _logic = logic; + } + private void FormReportServices_Load(object sender, EventArgs e) + { + LoadData(); + } + private void LoadData() + { + try + { + var list = _logic.ReadMostPopular(); + if (list != null) + { + dataGridView.DataSource = list; + dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} diff --git a/BeautySaloon/BeautySaloonView/FormReportServices.resx b/BeautySaloon/BeautySaloonView/FormReportServices.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/BeautySaloon/BeautySaloonView/FormReportServices.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BeautySaloon/BeautySaloonView/FormTest.cs b/BeautySaloon/BeautySaloonView/FormTest.cs index 9c5c4f2..305d473 100644 --- a/BeautySaloon/BeautySaloonView/FormTest.cs +++ b/BeautySaloon/BeautySaloonView/FormTest.cs @@ -4,7 +4,6 @@ using BeautySaloonContracts.SearchModels; using BeautySaloonContracts.ViewModels; using BeautySaloonDataModels; using System.Diagnostics; -using System.Drawing; using System.Text; namespace BeautySaloonView diff --git a/BeautySaloon/BeautySaloonView/Program.cs b/BeautySaloon/BeautySaloonView/Program.cs index 4ec300c..14290f1 100644 --- a/BeautySaloon/BeautySaloonView/Program.cs +++ b/BeautySaloon/BeautySaloonView/Program.cs @@ -54,6 +54,7 @@ namespace BeautySaloonView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } \ No newline at end of file