Добавьте файлы проекта.
25
ServiceApp.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.11.35222.181
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceApp", "ServiceApp\ServiceApp.csproj", "{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {A812EF99-15E4-4DD1-A3AD-370E1AB49A94}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
15
ServiceApp/App.axaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="ServiceApp.App"
|
||||||
|
RequestedThemeVariant="Default">
|
||||||
|
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||||
|
|
||||||
|
<Application.Styles>
|
||||||
|
<FluentTheme />
|
||||||
|
</Application.Styles>
|
||||||
|
<Application.Resources>
|
||||||
|
<SolidColorBrush x:Key="PrimaryColor" Color="#ffffff"/>
|
||||||
|
<SolidColorBrush x:Key="SecondaryColor" Color="#ffffe1"/>
|
||||||
|
<SolidColorBrush x:Key="AccentColor" Color="#ff9c1a"/>
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
24
ServiceApp/App.axaml.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace ServiceApp
|
||||||
|
{
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnFrameworkInitializationCompleted()
|
||||||
|
{
|
||||||
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
|
{
|
||||||
|
desktop.MainWindow = new MainWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
ServiceApp/Assets/diz.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
ServiceApp/Assets/download.png
Normal file
After Width: | Height: | Size: 234 KiB |
BIN
ServiceApp/Assets/rulevoe-upravlenie-avtomobilya.jpg
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
ServiceApp/Assets/transmission.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
ServiceApp/Assets/АКПП.jpg
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
ServiceApp/Assets/Вариатор.jpg
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
ServiceApp/Assets/Выхлопная система.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
ServiceApp/Assets/ГУР.png
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
ServiceApp/Assets/Двигатель.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
ServiceApp/Assets/Дополнительные услуги.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
ServiceApp/Assets/КПП.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
ServiceApp/Assets/Кондиционер.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
ServiceApp/Assets/Подвеска.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
ServiceApp/Assets/Сцепление.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
ServiceApp/Assets/Техническое обслуживание.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
ServiceApp/Assets/Топливная система.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
ServiceApp/Assets/Шиномонтаж.jpg
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
ServiceApp/Assets/Электрика.png
Normal file
After Width: | Height: | Size: 18 KiB |
33
ServiceApp/EntityModels/Client.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Client
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Firstname { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Lastname { get; set; } = null!;
|
||||||
|
|
||||||
|
public string? Patronymic { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? Birthday { get; set; }
|
||||||
|
|
||||||
|
public DateTime Registrationdate { get; set; }
|
||||||
|
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
public string Phone { get; set; } = null!;
|
||||||
|
|
||||||
|
public int Gendercode { get; set; }
|
||||||
|
|
||||||
|
public string? Photopath { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Clientservice> Clientservices { get; set; } = new List<Clientservice>();
|
||||||
|
|
||||||
|
public virtual Gender GendercodeNavigation { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual ICollection<Tag> Tags { get; set; } = new List<Tag>();
|
||||||
|
}
|
25
ServiceApp/EntityModels/Clientservice.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Clientservice
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int Clientid { get; set; }
|
||||||
|
|
||||||
|
public int Serviceid { get; set; }
|
||||||
|
|
||||||
|
public DateTime Starttime { get; set; }
|
||||||
|
|
||||||
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
public virtual Client Client { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual ICollection<Documentbyservice> Documentbyservices { get; set; } = new List<Documentbyservice>();
|
||||||
|
|
||||||
|
public virtual ICollection<Productsale> Productsales { get; set; } = new List<Productsale>();
|
||||||
|
|
||||||
|
public virtual Service Service { get; set; } = null!;
|
||||||
|
}
|
15
ServiceApp/EntityModels/Documentbyservice.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Documentbyservice
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int Clientserviceid { get; set; }
|
||||||
|
|
||||||
|
public string Documentpath { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual Clientservice Clientservice { get; set; } = null!;
|
||||||
|
}
|
13
ServiceApp/EntityModels/Gender.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Gender
|
||||||
|
{
|
||||||
|
public int Code { get; set; }
|
||||||
|
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Client> Clients { get; set; } = new List<Client>();
|
||||||
|
}
|
334
ServiceApp/EntityModels/IsajkinContext.cs
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class IsajkinContext : DbContext
|
||||||
|
{
|
||||||
|
public IsajkinContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsajkinContext(DbContextOptions<IsajkinContext> options)
|
||||||
|
: base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual DbSet<Client> Clients { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Clientservice> Clientservices { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Documentbyservice> Documentbyservices { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Gender> Genders { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Manufacturer> Manufacturers { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Product> Products { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Productphoto> Productphotos { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Productsale> Productsales { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Service> Services { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Servicephoto> Servicephotos { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Tag> Tags { get; set; }
|
||||||
|
|
||||||
|
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 https://go.microsoft.com/fwlink/?LinkId=723263.
|
||||||
|
=> optionsBuilder.UseNpgsql("Host=45.67.56.214;Port=5454;Username=isajkin;Password=hqD9f9EZ");
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<Client>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("client_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("client");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Birthday).HasColumnName("birthday");
|
||||||
|
entity.Property(e => e.Email)
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnName("email");
|
||||||
|
entity.Property(e => e.Firstname)
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnName("firstname");
|
||||||
|
entity.Property(e => e.Gendercode).HasColumnName("gendercode");
|
||||||
|
entity.Property(e => e.Lastname)
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnName("lastname");
|
||||||
|
entity.Property(e => e.Patronymic)
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnName("patronymic");
|
||||||
|
entity.Property(e => e.Phone)
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnName("phone");
|
||||||
|
entity.Property(e => e.Photopath)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnName("photopath");
|
||||||
|
entity.Property(e => e.Registrationdate)
|
||||||
|
.HasColumnType("timestamp(6) without time zone")
|
||||||
|
.HasColumnName("registrationdate");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.GendercodeNavigation).WithMany(p => p.Clients)
|
||||||
|
.HasForeignKey(d => d.Gendercode)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_client_gender");
|
||||||
|
|
||||||
|
entity.HasMany(d => d.Tags).WithMany(p => p.Clients)
|
||||||
|
.UsingEntity<Dictionary<string, object>>(
|
||||||
|
"Tagofclient",
|
||||||
|
r => r.HasOne<Tag>().WithMany()
|
||||||
|
.HasForeignKey("Tagid")
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_tagofclient_tag"),
|
||||||
|
l => l.HasOne<Client>().WithMany()
|
||||||
|
.HasForeignKey("Clientid")
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_tagofclient_client"),
|
||||||
|
j =>
|
||||||
|
{
|
||||||
|
j.HasKey("Clientid", "Tagid").HasName("tagofclient_pkey");
|
||||||
|
j.ToTable("tagofclient");
|
||||||
|
j.IndexerProperty<int>("Clientid").HasColumnName("clientid");
|
||||||
|
j.IndexerProperty<int>("Tagid").HasColumnName("tagid");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Clientservice>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("clientservice_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("clientservice");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Clientid).HasColumnName("clientid");
|
||||||
|
entity.Property(e => e.Comment).HasColumnName("comment");
|
||||||
|
entity.Property(e => e.Serviceid).HasColumnName("serviceid");
|
||||||
|
entity.Property(e => e.Starttime)
|
||||||
|
.HasColumnType("timestamp(6) without time zone")
|
||||||
|
.HasColumnName("starttime");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Client).WithMany(p => p.Clientservices)
|
||||||
|
.HasForeignKey(d => d.Clientid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_clientservice_client");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Service).WithMany(p => p.Clientservices)
|
||||||
|
.HasForeignKey(d => d.Serviceid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_clientservice_service");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Documentbyservice>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("documentbyservice_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("documentbyservice");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Clientserviceid).HasColumnName("clientserviceid");
|
||||||
|
entity.Property(e => e.Documentpath)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnName("documentpath");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Clientservice).WithMany(p => p.Documentbyservices)
|
||||||
|
.HasForeignKey(d => d.Clientserviceid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_documentbyservice_clientservice");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Gender>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Code).HasName("gender_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("gender");
|
||||||
|
|
||||||
|
entity.Property(e => e.Code).HasColumnName("code");
|
||||||
|
entity.Property(e => e.Name)
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnName("name");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Manufacturer>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("manufacturer_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("manufacturer");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Name)
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnName("name");
|
||||||
|
entity.Property(e => e.Startdate).HasColumnName("startdate");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Product>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("product_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("product");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Cost)
|
||||||
|
.HasPrecision(19, 4)
|
||||||
|
.HasColumnName("cost");
|
||||||
|
entity.Property(e => e.Description).HasColumnName("description");
|
||||||
|
entity.Property(e => e.Isactive).HasColumnName("isactive");
|
||||||
|
entity.Property(e => e.Mainimagepath)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnName("mainimagepath");
|
||||||
|
entity.Property(e => e.Manufacturerid).HasColumnName("manufacturerid");
|
||||||
|
entity.Property(e => e.Title)
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnName("title");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Manufacturer).WithMany(p => p.Products)
|
||||||
|
.HasForeignKey(d => d.Manufacturerid)
|
||||||
|
.HasConstraintName("fk_product_manufacturer");
|
||||||
|
|
||||||
|
entity.HasMany(d => d.Attachedproducts).WithMany(p => p.Mainproducts)
|
||||||
|
.UsingEntity<Dictionary<string, object>>(
|
||||||
|
"Attachedproduct",
|
||||||
|
r => r.HasOne<Product>().WithMany()
|
||||||
|
.HasForeignKey("Attachedproductid")
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_attachedproduct_product1"),
|
||||||
|
l => l.HasOne<Product>().WithMany()
|
||||||
|
.HasForeignKey("Mainproductid")
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_attachedproduct_product"),
|
||||||
|
j =>
|
||||||
|
{
|
||||||
|
j.HasKey("Mainproductid", "Attachedproductid").HasName("attachedproduct_pkey");
|
||||||
|
j.ToTable("attachedproduct");
|
||||||
|
j.IndexerProperty<int>("Mainproductid").HasColumnName("mainproductid");
|
||||||
|
j.IndexerProperty<int>("Attachedproductid").HasColumnName("attachedproductid");
|
||||||
|
});
|
||||||
|
|
||||||
|
entity.HasMany(d => d.Mainproducts).WithMany(p => p.Attachedproducts)
|
||||||
|
.UsingEntity<Dictionary<string, object>>(
|
||||||
|
"Attachedproduct",
|
||||||
|
r => r.HasOne<Product>().WithMany()
|
||||||
|
.HasForeignKey("Mainproductid")
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_attachedproduct_product"),
|
||||||
|
l => l.HasOne<Product>().WithMany()
|
||||||
|
.HasForeignKey("Attachedproductid")
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_attachedproduct_product1"),
|
||||||
|
j =>
|
||||||
|
{
|
||||||
|
j.HasKey("Mainproductid", "Attachedproductid").HasName("attachedproduct_pkey");
|
||||||
|
j.ToTable("attachedproduct");
|
||||||
|
j.IndexerProperty<int>("Mainproductid").HasColumnName("mainproductid");
|
||||||
|
j.IndexerProperty<int>("Attachedproductid").HasColumnName("attachedproductid");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Productphoto>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("productphoto_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("productphoto");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Photopath)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnName("photopath");
|
||||||
|
entity.Property(e => e.Productid).HasColumnName("productid");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Product).WithMany(p => p.Productphotos)
|
||||||
|
.HasForeignKey(d => d.Productid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_productphoto_product");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Productsale>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("productsale_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("productsale");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Clientserviceid).HasColumnName("clientserviceid");
|
||||||
|
entity.Property(e => e.Productid).HasColumnName("productid");
|
||||||
|
entity.Property(e => e.Quantity).HasColumnName("quantity");
|
||||||
|
entity.Property(e => e.Saledate)
|
||||||
|
.HasColumnType("timestamp(6) without time zone")
|
||||||
|
.HasColumnName("saledate");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Clientservice).WithMany(p => p.Productsales)
|
||||||
|
.HasForeignKey(d => d.Clientserviceid)
|
||||||
|
.HasConstraintName("fk_productsale_clientservice");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Product).WithMany(p => p.Productsales)
|
||||||
|
.HasForeignKey(d => d.Productid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_productsale_product");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Service>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("service_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("service");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Cost)
|
||||||
|
.HasPrecision(19, 4)
|
||||||
|
.HasColumnName("cost");
|
||||||
|
entity.Property(e => e.Description).HasColumnName("description");
|
||||||
|
entity.Property(e => e.Discount).HasColumnName("discount");
|
||||||
|
entity.Property(e => e.Durationinminutes).HasColumnName("durationinminutes");
|
||||||
|
entity.Property(e => e.Mainimagepath)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnName("mainimagepath");
|
||||||
|
entity.Property(e => e.Title)
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnName("title");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Servicephoto>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("servicephoto_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("servicephoto");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Photopath)
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnName("photopath");
|
||||||
|
entity.Property(e => e.Serviceid).HasColumnName("serviceid");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Service).WithMany(p => p.Servicephotos)
|
||||||
|
.HasForeignKey(d => d.Serviceid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("fk_servicephoto_service");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Tag>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Id).HasName("tag_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("tag");
|
||||||
|
|
||||||
|
entity.Property(e => e.Id).HasColumnName("id");
|
||||||
|
entity.Property(e => e.Color)
|
||||||
|
.HasMaxLength(6)
|
||||||
|
.IsFixedLength()
|
||||||
|
.HasColumnName("color");
|
||||||
|
entity.Property(e => e.Title)
|
||||||
|
.HasMaxLength(30)
|
||||||
|
.HasColumnName("title");
|
||||||
|
});
|
||||||
|
|
||||||
|
OnModelCreatingPartial(modelBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||||
|
}
|
15
ServiceApp/EntityModels/Manufacturer.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Manufacturer
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
public DateOnly? Startdate { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
|
||||||
|
}
|
31
ServiceApp/EntityModels/Product.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Product
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
|
||||||
|
public decimal Cost { get; set; }
|
||||||
|
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
public string? Mainimagepath { get; set; }
|
||||||
|
|
||||||
|
public int Isactive { get; set; }
|
||||||
|
|
||||||
|
public int? Manufacturerid { get; set; }
|
||||||
|
|
||||||
|
public virtual Manufacturer? Manufacturer { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Productphoto> Productphotos { get; set; } = new List<Productphoto>();
|
||||||
|
|
||||||
|
public virtual ICollection<Productsale> Productsales { get; set; } = new List<Productsale>();
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Attachedproducts { get; set; } = new List<Product>();
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Mainproducts { get; set; } = new List<Product>();
|
||||||
|
}
|
15
ServiceApp/EntityModels/Productphoto.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Productphoto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int Productid { get; set; }
|
||||||
|
|
||||||
|
public string Photopath { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual Product Product { get; set; } = null!;
|
||||||
|
}
|
21
ServiceApp/EntityModels/Productsale.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Productsale
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public DateTime Saledate { get; set; }
|
||||||
|
|
||||||
|
public int Productid { get; set; }
|
||||||
|
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
|
||||||
|
public int? Clientserviceid { get; set; }
|
||||||
|
|
||||||
|
public virtual Clientservice? Clientservice { get; set; }
|
||||||
|
|
||||||
|
public virtual Product Product { get; set; } = null!;
|
||||||
|
}
|
25
ServiceApp/EntityModels/Service.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Service
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
|
||||||
|
public decimal Cost { get; set; }
|
||||||
|
|
||||||
|
public int Durationinminutes { get; set; }
|
||||||
|
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
public double? Discount { get; set; }
|
||||||
|
|
||||||
|
public string? Mainimagepath { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Clientservice> Clientservices { get; set; } = new List<Clientservice>();
|
||||||
|
|
||||||
|
public virtual ICollection<Servicephoto> Servicephotos { get; set; } = new List<Servicephoto>();
|
||||||
|
}
|
15
ServiceApp/EntityModels/Servicephoto.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Servicephoto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int Serviceid { get; set; }
|
||||||
|
|
||||||
|
public string Photopath { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual Service Service { get; set; } = null!;
|
||||||
|
}
|
15
ServiceApp/EntityModels/Tag.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServiceApp.EnityModels;
|
||||||
|
|
||||||
|
public partial class Tag
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Color { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual ICollection<Client> Clients { get; set; } = new List<Client>();
|
||||||
|
}
|
30
ServiceApp/MainWindow.axaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="ServiceApp.MainWindow"
|
||||||
|
x:CompileBindings="False"
|
||||||
|
Title="ServiceApp">
|
||||||
|
<StackPanel
|
||||||
|
Spacing="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<TextBlock>Введите код для перехода в режим авдминистратора</TextBlock>
|
||||||
|
<TextBox Name="CodeTextBox" Width="150"/>
|
||||||
|
<StackPanel
|
||||||
|
Spacing="10"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button
|
||||||
|
Click="LoginAdminButton_Click"
|
||||||
|
Name="LoginAdminButton"
|
||||||
|
>Войти</Button>
|
||||||
|
<Button
|
||||||
|
Click="LoginClientButton_Click"
|
||||||
|
Name="LoginClientButton"
|
||||||
|
>Режим клиента</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Window>
|
27
ServiceApp/MainWindow.axaml.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace ServiceApp
|
||||||
|
{
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
private string _secretCode = "0000";
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoginClientButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
new ServiceWindow().Show();
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
private void LoginAdminButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (CodeTextBox.Text == _secretCode) {
|
||||||
|
new ServiceAdminWindow().Show();
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
22
ServiceApp/Program.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ServiceApp
|
||||||
|
{
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||||
|
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||||
|
// yet and stuff might break.
|
||||||
|
[STAThread]
|
||||||
|
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||||
|
.StartWithClassicDesktopLifetime(args);
|
||||||
|
|
||||||
|
// Avalonia configuration, don't remove; also used by visual designer.
|
||||||
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
|
=> AppBuilder.Configure<App>()
|
||||||
|
.UsePlatformDetect()
|
||||||
|
.WithInterFont()
|
||||||
|
.LogToTrace();
|
||||||
|
}
|
||||||
|
}
|
39
ServiceApp/ServiceApp.csproj
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<AvaloniaResource Include="Assets\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Assets\download.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia" Version="11.1.0" />
|
||||||
|
<PackageReference Include="Avalonia.Desktop" Version="11.1.0" />
|
||||||
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.0" />
|
||||||
|
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.1.0" />
|
||||||
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="ServiceWindowAdmin.axaml.cs">
|
||||||
|
<DependentUpon>ServiceWindowAdmin.axaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
62
ServiceApp/ServiceWindow.axaml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:CompileBindings="False"
|
||||||
|
x:Class="ServiceApp.ServiceWindow"
|
||||||
|
Title="ServiceWindow">
|
||||||
|
<DockPanel>
|
||||||
|
<Border
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
Name="SearchPanel">
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Spacing="20">
|
||||||
|
<TextBox
|
||||||
|
Name="SearchTextBox"
|
||||||
|
Width="200"
|
||||||
|
TextChanged="SearchTextBox_TextChanged"
|
||||||
|
/>
|
||||||
|
<ComboBox
|
||||||
|
Width="150"
|
||||||
|
Name="SortingComboBox"
|
||||||
|
SelectionChanged="SortingComboBox_SelectionChanged"/>
|
||||||
|
<ComboBox
|
||||||
|
Width="150"
|
||||||
|
SelectionChanged="FilteringComboBox_SelectionChanged"
|
||||||
|
Name="FilteringComboBox"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Border
|
||||||
|
DockPanel.Dock="Bottom"
|
||||||
|
Name="StatisticPanel">
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
>
|
||||||
|
<TextBlock Name="StatisticTextBlock">Статистика</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Border Name="MainPanel">
|
||||||
|
<ListBox Name="ServiceListBox">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="20">
|
||||||
|
<Image Source="{Binding ServiceImage}" Width="100" Height="100"/>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{Binding ServiceName}"/>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="5">
|
||||||
|
<TextBlock Text="{Binding OldCost}" TextDecorations="Strikethrough"/>
|
||||||
|
<TextBlock Text="{Binding SeviceCostPerSeconds}" />
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock Text="{Binding ServiceDiscount}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</Border>
|
||||||
|
</DockPanel>
|
||||||
|
</Window>
|
132
ServiceApp/ServiceWindow.axaml.cs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using System.Linq;
|
||||||
|
using ServiceApp.EnityModels;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using SkiaSharp;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Json;
|
||||||
|
using System;
|
||||||
|
using Npgsql.TypeMapping;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using Avalonia.Platform;
|
||||||
|
|
||||||
|
namespace ServiceApp;
|
||||||
|
|
||||||
|
public partial class ServiceWindow : Window
|
||||||
|
{
|
||||||
|
public List<ServicePresenter> sourceList { get; set; }
|
||||||
|
public ObservableCollection<ServicePresenter> displayList { get; }
|
||||||
|
|
||||||
|
private string _searchWord = string.Empty;
|
||||||
|
|
||||||
|
private string[] _sortingSource = new string[3] { "îòñóò.", "ïî âîçðàñò.", "ïî óáûâ." };
|
||||||
|
private Dictionary<string, (int, int)> _dicountFilter = new Dictionary<string, (int, int)> {
|
||||||
|
{"âñå", (0, 0) },
|
||||||
|
{ "0-5", (0,5)},
|
||||||
|
{ "15-30", (5,15)},
|
||||||
|
{ "30-70", (30,70)},
|
||||||
|
{ "70-100", (70,100)},
|
||||||
|
};
|
||||||
|
|
||||||
|
public ServiceWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
using (var dbContext = new IsajkinContext())
|
||||||
|
{
|
||||||
|
|
||||||
|
sourceList = dbContext.Services.Select(service =>
|
||||||
|
new ServicePresenter
|
||||||
|
{
|
||||||
|
Title = service.Title,
|
||||||
|
Discount = service.Discount,
|
||||||
|
Durationinminutes = service.Durationinminutes,
|
||||||
|
Id = service.Id,
|
||||||
|
Cost = service.Cost,
|
||||||
|
Mainimagepath = service.Mainimagepath,
|
||||||
|
}
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
displayList = new ObservableCollection<ServicePresenter>(sourceList);
|
||||||
|
SortingComboBox.ItemsSource = _sortingSource;
|
||||||
|
ServiceListBox.ItemsSource = displayList;
|
||||||
|
FilteringComboBox.ItemsSource = _dicountFilter.Keys;
|
||||||
|
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayList.Count, sourceList.Count);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisplayService() {
|
||||||
|
|
||||||
|
var displayServiceList = sourceList;
|
||||||
|
if (FilteringComboBox.SelectedIndex > 0) displayServiceList = displayServiceList.Where(service =>
|
||||||
|
FilterByDiscount(service, FilteringComboBox.SelectionBoxItem.ToString())).ToList();
|
||||||
|
if(!String.IsNullOrEmpty(_searchWord)) displayServiceList = displayServiceList.Where(service => SearchByWord(service, _searchWord)).ToList();
|
||||||
|
if(SortingComboBox.SelectedIndex > 0) displayServiceList = SortingComboBox.SelectedIndex == 1?
|
||||||
|
displayServiceList.OrderBy(service => service.Cost).ToList() :
|
||||||
|
displayServiceList.OrderByDescending(service => service.Cost).ToList();
|
||||||
|
displayList.Clear();
|
||||||
|
foreach (var service in displayServiceList) { displayList.Add(service); }
|
||||||
|
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayServiceList.Count, sourceList.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool SearchByWord(ServicePresenter service, string word) {
|
||||||
|
if (service.Title.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
|
||||||
|
if (String.IsNullOrEmpty(service.Description)) return false;
|
||||||
|
if (service.Description.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private bool FilterByDiscount(ServicePresenter servicePresenter, string key) {
|
||||||
|
(int left, int right) = _dicountFilter[key];
|
||||||
|
double discount = servicePresenter.Discount != null? Convert.ToDouble(servicePresenter.Discount) * 100 : 0;
|
||||||
|
return left <= discount && discount < right;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object? sender, Avalonia.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
_searchWord = SearchTextBox.Text.ToString();
|
||||||
|
DisplayService();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void FilteringComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
DisplayService();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SortingComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
DisplayService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ServicePresenter() : Service
|
||||||
|
{
|
||||||
|
public int ServiceID { get => this.Id; }
|
||||||
|
public string ServiceName { get => this.Title; }
|
||||||
|
public string SeviceCostPerSeconds { get =>
|
||||||
|
(this.Discount != 0 ?
|
||||||
|
String.Format("{0:0.00} ðóáëåé çà {1} ìèíóò", this.Cost - this.Cost * Convert.ToDecimal(this.Discount), this.Durationinminutes)
|
||||||
|
:
|
||||||
|
String.Format("{0:0.00} ðóáëåé çà {1} ìèíóò", this.Cost, this.Durationinminutes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public Bitmap ServiceImage { get => GetBitmap(this.Mainimagepath); }
|
||||||
|
public decimal? OldCost { get => (this.Discount != 0 ? this.Cost : null); }
|
||||||
|
public string? ServiceDiscount { get =>
|
||||||
|
(this.Discount != 0 ?
|
||||||
|
String.Format("* ñêèäêà {0}%", Discount * 100)
|
||||||
|
: String.Empty
|
||||||
|
); }
|
||||||
|
|
||||||
|
private Bitmap GetBitmap(string fileName) {
|
||||||
|
try {
|
||||||
|
return new Bitmap($"Assets\\{fileName}");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return new Bitmap("Assets\\download.png");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
ServiceApp/ServiceWindowAdmin.axaml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:CompileBindings="False"
|
||||||
|
x:Class="ServiceApp.ServiceAdminWindow"
|
||||||
|
Title="ServiceAdminWindow">
|
||||||
|
<DockPanel>
|
||||||
|
<Border
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
Name="SearchPanel">
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Spacing="20">
|
||||||
|
<TextBox
|
||||||
|
Name="SearchTextBox"
|
||||||
|
Width="200"
|
||||||
|
TextChanged="SearchTextBox_TextChanged"
|
||||||
|
/>
|
||||||
|
<ComboBox
|
||||||
|
Width="150"
|
||||||
|
Name="SortingComboBox"
|
||||||
|
SelectionChanged="SortingComboBox_SelectionChanged"/>
|
||||||
|
<ComboBox
|
||||||
|
Width="150"
|
||||||
|
SelectionChanged="FilteringComboBox_SelectionChanged"
|
||||||
|
Name="FilteringComboBox"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Border
|
||||||
|
DockPanel.Dock="Bottom"
|
||||||
|
Name="StatisticPanel">
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
>
|
||||||
|
<TextBlock Name="StatisticTextBlock">Статистика</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Border Name="MainPanel">
|
||||||
|
<ListBox Name="ServiceListBox">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="20">
|
||||||
|
<Image Source="{Binding ServiceImage}" Width="100" Height="100"/>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{Binding ServiceName}"/>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="5">
|
||||||
|
<TextBlock Text="{Binding OldCost}" TextDecorations="Strikethrough"/>
|
||||||
|
<TextBlock Text="{Binding SeviceCostPerSeconds}" />
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock Text="{Binding ServiceDiscount}"/>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Button Name="EditButton" Click="EditButton_Click" Tag="{Binding ServiceID}">Редактировать</Button>
|
||||||
|
<Button Name="RemoveButton" Click="RemoveButton_Click" Tag="{Binding ServiceID}">Удалить</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</Border>
|
||||||
|
</DockPanel>
|
||||||
|
</Window>
|
134
ServiceApp/ServiceWindowAdmin.axaml.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using System.Linq;
|
||||||
|
using ServiceApp.EnityModels;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using SkiaSharp;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.Json;
|
||||||
|
using System;
|
||||||
|
using Npgsql.TypeMapping;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using Avalonia.Platform;
|
||||||
|
|
||||||
|
namespace ServiceApp;
|
||||||
|
|
||||||
|
public partial class ServiceAdminWindow : Window
|
||||||
|
{
|
||||||
|
public List<ServicePresenter> sourceList { get; set; }
|
||||||
|
public ObservableCollection<ServicePresenter> displayList { get; }
|
||||||
|
|
||||||
|
private string _searchWord = string.Empty;
|
||||||
|
|
||||||
|
private string[] _sortingSource = new string[3] { "îòñóò.", "ïî âîçðàñò.", "ïî óáûâ." };
|
||||||
|
private Dictionary<string, (int, int)> _dicountFilter = new Dictionary<string, (int, int)> {
|
||||||
|
{"âñå", (0, 0) },
|
||||||
|
{ "0-5", (0,5)},
|
||||||
|
{ "15-30", (5,15)},
|
||||||
|
{ "30-70", (30,70)},
|
||||||
|
{ "70-100", (70,100)},
|
||||||
|
};
|
||||||
|
|
||||||
|
public ServiceAdminWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
using (var dbContext = new IsajkinContext())
|
||||||
|
{
|
||||||
|
|
||||||
|
sourceList = dbContext.Services.Select(service =>
|
||||||
|
new ServicePresenter
|
||||||
|
{
|
||||||
|
Title = service.Title,
|
||||||
|
Discount = service.Discount,
|
||||||
|
Durationinminutes = service.Durationinminutes,
|
||||||
|
Id = service.Id,
|
||||||
|
Cost = service.Cost,
|
||||||
|
Mainimagepath = service.Mainimagepath,
|
||||||
|
}
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
displayList = new ObservableCollection<ServicePresenter>(sourceList);
|
||||||
|
SortingComboBox.ItemsSource = _sortingSource;
|
||||||
|
ServiceListBox.ItemsSource = displayList;
|
||||||
|
FilteringComboBox.ItemsSource = _dicountFilter.Keys;
|
||||||
|
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayList.Count, sourceList.Count);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisplayService() {
|
||||||
|
|
||||||
|
var displayServiceList = sourceList;
|
||||||
|
if (FilteringComboBox.SelectedIndex > 0) displayServiceList = displayServiceList.Where(service =>
|
||||||
|
FilterByDiscount(service, FilteringComboBox.SelectionBoxItem.ToString())).ToList();
|
||||||
|
if(!String.IsNullOrEmpty(_searchWord)) displayServiceList = displayServiceList.Where(service => SearchByWord(service, _searchWord)).ToList();
|
||||||
|
if(SortingComboBox.SelectedIndex > 0) displayServiceList = SortingComboBox.SelectedIndex == 1?
|
||||||
|
displayServiceList.OrderBy(service => service.Cost).ToList() :
|
||||||
|
displayServiceList.OrderByDescending(service => service.Cost).ToList();
|
||||||
|
displayList.Clear();
|
||||||
|
foreach (var service in displayServiceList) { displayList.Add(service); }
|
||||||
|
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayServiceList.Count, sourceList.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool SearchByWord(ServicePresenter service, string word) {
|
||||||
|
if (service.Title.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
|
||||||
|
if (String.IsNullOrEmpty(service.Description)) return false;
|
||||||
|
if (service.Description.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private bool FilterByDiscount(ServicePresenter servicePresenter, string key) {
|
||||||
|
(int left, int right) = _dicountFilter[key];
|
||||||
|
double discount = servicePresenter.Discount != null? Convert.ToDouble(servicePresenter.Discount) * 100 : 0;
|
||||||
|
return left <= discount && discount < right;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchTextBox_TextChanged(object? sender, Avalonia.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
_searchWord = SearchTextBox.Text.ToString();
|
||||||
|
DisplayService();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void FilteringComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
DisplayService();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SortingComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
DisplayService();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EditButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var serviceID = Convert.ToInt32((sender as Button).Tag);
|
||||||
|
using (var dbContext = new IsajkinContext()) {
|
||||||
|
var service = dbContext.Services.First(service => service.Id == serviceID);
|
||||||
|
var serviceLocal = displayList.First(service => service.Id == serviceID);
|
||||||
|
if (service == null) return;
|
||||||
|
if (dbContext.Clientservices.Where(item => item.Serviceid == serviceID).Count() > 0) return;
|
||||||
|
using var transaction = dbContext.Database.BeginTransaction();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (dbContext.Servicephotos.Where(item => item.Serviceid == serviceID).Count() > 0)
|
||||||
|
{
|
||||||
|
dbContext.RemoveRange(dbContext.Servicephotos.Where(item => item.Serviceid == serviceID));
|
||||||
|
}
|
||||||
|
dbContext.Services.Remove(service);
|
||||||
|
displayList.Remove(serviceLocal);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
}
|
||||||
|
}
|
18
ServiceApp/app.manifest
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<!-- This manifest is used on Windows only.
|
||||||
|
Don't remove it as it might cause problems with window transparency and embedded controls.
|
||||||
|
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="ServiceApp.Desktop"/>
|
||||||
|
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- A list of the Windows versions that this application has been tested on
|
||||||
|
and is designed to work with. Uncomment the appropriate elements
|
||||||
|
and Windows will automatically select the most compatible environment. -->
|
||||||
|
|
||||||
|
<!-- Windows 10 -->
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
</assembly>
|