init
This commit is contained in:
commit
1bcaac832a
13
App.axaml
Normal file
13
App.axaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="demo_trade.App"
|
||||||
|
xmlns:local="using:demo_trade"
|
||||||
|
RequestedThemeVariant="Default">
|
||||||
|
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<Application.Styles>
|
||||||
|
<FluentTheme />
|
||||||
|
</Application.Styles>
|
||||||
|
</Application>
|
32
App.axaml.cs
Normal file
32
App.axaml.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using Avalonia.Data.Core;
|
||||||
|
using Avalonia.Data.Core.Plugins;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using demo_trade.Views;
|
||||||
|
|
||||||
|
namespace demo_trade
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
DataContext = new MainWindowViewModel(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
Assets/avalonia-logo.ico
Normal file
BIN
Assets/avalonia-logo.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
13
Data/RemoteData/Entity/Category.cs
Normal file
13
Data/RemoteData/Entity/Category.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Category
|
||||||
|
{
|
||||||
|
public int CategoryId { get; set; }
|
||||||
|
|
||||||
|
public string? CategoryName { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
|
||||||
|
}
|
13
Data/RemoteData/Entity/Manufacturer.cs
Normal file
13
Data/RemoteData/Entity/Manufacturer.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Manufacturer
|
||||||
|
{
|
||||||
|
public int ManufacturerId { get; set; }
|
||||||
|
|
||||||
|
public string? ManufacturerName { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
|
||||||
|
}
|
22
Data/RemoteData/Entity/Order.cs
Normal file
22
Data/RemoteData/Entity/Order.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Order
|
||||||
|
{
|
||||||
|
public int Orderid { get; set; }
|
||||||
|
|
||||||
|
public string Orderstatus { get; set; } = null!;
|
||||||
|
|
||||||
|
public DateOnly Orderdeliverydate { get; set; }
|
||||||
|
|
||||||
|
public int Orderpickuppoint { get; set; }
|
||||||
|
public decimal? OrderSumCost { get; set; }
|
||||||
|
|
||||||
|
public string? ClientName { get; set; }
|
||||||
|
|
||||||
|
public virtual PickupPoint OrderpickuppointNavigation { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual ICollection<Orderproduct> Orderproducts { get; set; } = new List<Orderproduct>();
|
||||||
|
}
|
17
Data/RemoteData/Entity/Orderproduct.cs
Normal file
17
Data/RemoteData/Entity/Orderproduct.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Orderproduct
|
||||||
|
{
|
||||||
|
public int Orderid { get; set; }
|
||||||
|
|
||||||
|
public string Productarticlenumber { get; set; } = null!;
|
||||||
|
|
||||||
|
public int? ProductCount { get; set; }
|
||||||
|
|
||||||
|
public virtual Order Order { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual Product ProductarticlenumberNavigation { get; set; } = null!;
|
||||||
|
}
|
13
Data/RemoteData/Entity/PickupPoint.cs
Normal file
13
Data/RemoteData/Entity/PickupPoint.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class PickupPoint
|
||||||
|
{
|
||||||
|
public int PickupPointId { get; set; }
|
||||||
|
|
||||||
|
public string? PickupPointName { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Order> Orders { get; set; } = new List<Order>();
|
||||||
|
}
|
14
Data/RemoteData/Entity/Porductprovider.cs
Normal file
14
Data/RemoteData/Entity/Porductprovider.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
|
||||||
|
public partial class Porductprovider
|
||||||
|
{
|
||||||
|
public int PorductproviderId { get; set; }
|
||||||
|
|
||||||
|
public string? PorductproviderName { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
|
||||||
|
}
|
43
Data/RemoteData/Entity/Product.cs
Normal file
43
Data/RemoteData/Entity/Product.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Product
|
||||||
|
{
|
||||||
|
public string Productarticlenumber { get; set; } = null!;
|
||||||
|
|
||||||
|
public string? Productname { get; set; }
|
||||||
|
|
||||||
|
public string? Productdescription { get; set; }
|
||||||
|
|
||||||
|
public byte[]? Productphoto { get; set; }
|
||||||
|
|
||||||
|
public decimal? Productcost { get; set; }
|
||||||
|
|
||||||
|
public short? Productdiscountamount { get; set; }
|
||||||
|
|
||||||
|
public int? Productquantityinstock { get; set; }
|
||||||
|
|
||||||
|
public string? Imagename { get; set; }
|
||||||
|
|
||||||
|
public int? UnitId { get; set; }
|
||||||
|
|
||||||
|
public int? Productmaxdiscount { get; set; }
|
||||||
|
|
||||||
|
public int? CategoryId { get; set; }
|
||||||
|
|
||||||
|
public int? ManufacturerId { get; set; }
|
||||||
|
|
||||||
|
public int? PorductproviderId { get; set; }
|
||||||
|
|
||||||
|
public virtual Category? Category { get; set; }
|
||||||
|
|
||||||
|
public virtual Manufacturer? Manufacturer { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Orderproduct> Orderproducts { get; set; } = new List<Orderproduct>();
|
||||||
|
|
||||||
|
public virtual Porductprovider? Porductprovider { get; set; }
|
||||||
|
|
||||||
|
public virtual Productunit? Unit { get; set; }
|
||||||
|
}
|
13
Data/RemoteData/Entity/Productunit.cs
Normal file
13
Data/RemoteData/Entity/Productunit.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Productunit
|
||||||
|
{
|
||||||
|
public int UnitId { get; set; }
|
||||||
|
|
||||||
|
public string UnitName { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
|
||||||
|
}
|
13
Data/RemoteData/Entity/Role.cs
Normal file
13
Data/RemoteData/Entity/Role.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class Role
|
||||||
|
{
|
||||||
|
public int Roleid { get; set; }
|
||||||
|
|
||||||
|
public string Rolename { get; set; } = null!;
|
||||||
|
|
||||||
|
public virtual ICollection<User> Users { get; set; } = new List<User>();
|
||||||
|
}
|
225
Data/RemoteData/Entity/TradeContext.cs
Normal file
225
Data/RemoteData/Entity/TradeContext.cs
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class TradeContext : DbContext
|
||||||
|
{
|
||||||
|
public TradeContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeContext(DbContextOptions<TradeContext> options)
|
||||||
|
: base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual DbSet<Category> Categories { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Manufacturer> Manufacturers { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Order> Orders { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Orderproduct> Orderproducts { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<PickupPoint> PickupPoints { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Porductprovider> Porductproviders { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Product> Products { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Productunit> Productunits { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<Role> Roles { get; set; }
|
||||||
|
|
||||||
|
public virtual DbSet<User> Users { 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=localhost;Username=postgres;Database=trade;Password=Student");
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<Category>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.CategoryId).HasName("category_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("category");
|
||||||
|
|
||||||
|
entity.Property(e => e.CategoryId)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("category_id");
|
||||||
|
entity.Property(e => e.CategoryName).HasColumnName("category_name");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Manufacturer>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.ManufacturerId).HasName("manufacturer_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("manufacturer");
|
||||||
|
|
||||||
|
entity.Property(e => e.ManufacturerId)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("manufacturer_id");
|
||||||
|
entity.Property(e => e.ManufacturerName).HasColumnName("manufacturer_name");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Order>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Orderid).HasName("Order_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("Order");
|
||||||
|
|
||||||
|
entity.Property(e => e.Orderid)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("orderid");
|
||||||
|
entity.Property(e => e.Orderdeliverydate).HasColumnName("orderdeliverydate");
|
||||||
|
entity.Property(e => e.Orderpickuppoint).HasColumnName("orderpickuppoint");
|
||||||
|
entity.Property(e => e.Orderstatus).HasColumnName("orderstatus");
|
||||||
|
entity.Property(e => e.ClientName).HasColumnName("client_name");
|
||||||
|
entity.Property(e => e.OrderSumCost).HasColumnName("order_sum_cost");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.OrderpickuppointNavigation).WithMany(p => p.Orders)
|
||||||
|
.HasForeignKey(d => d.Orderpickuppoint)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("Order_orderpickuppoint_fkey");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Orderproduct>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => new { e.Orderid, e.Productarticlenumber }).HasName("orderproduct_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("orderproduct");
|
||||||
|
|
||||||
|
entity.Property(e => e.Orderid).HasColumnName("orderid");
|
||||||
|
entity.Property(e => e.Productarticlenumber).HasColumnName("productarticlenumber");
|
||||||
|
entity.Property(e => e.ProductCount).HasColumnName("product_count");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Order).WithMany(p => p.Orderproducts)
|
||||||
|
.HasForeignKey(d => d.Orderid)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("orderproduct_orderid_fkey");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.ProductarticlenumberNavigation).WithMany(p => p.Orderproducts)
|
||||||
|
.HasForeignKey(d => d.Productarticlenumber)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("orderproduct_productarticlenumber_fkey");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<PickupPoint>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.PickupPointId).HasName("pickup_point_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("pickup_point");
|
||||||
|
|
||||||
|
entity.Property(e => e.PickupPointId)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("pickup_point_id");
|
||||||
|
entity.Property(e => e.PickupPointName).HasColumnName("pickup_point_name");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Porductprovider>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.PorductproviderId).HasName("porductprovider_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("porductprovider");
|
||||||
|
|
||||||
|
entity.Property(e => e.PorductproviderId)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("porductprovider_id");
|
||||||
|
entity.Property(e => e.PorductproviderName).HasColumnName("porductprovider_name");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Product>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Productarticlenumber).HasName("product_pkey1");
|
||||||
|
|
||||||
|
entity.ToTable("product");
|
||||||
|
|
||||||
|
entity.Property(e => e.Productarticlenumber).HasColumnName("productarticlenumber");
|
||||||
|
entity.Property(e => e.CategoryId).HasColumnName("category_id");
|
||||||
|
entity.Property(e => e.Imagename)
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnName("imagename");
|
||||||
|
entity.Property(e => e.ManufacturerId).HasColumnName("manufacturer_id");
|
||||||
|
entity.Property(e => e.PorductproviderId).HasColumnName("porductprovider_id");
|
||||||
|
entity.Property(e => e.Productcost)
|
||||||
|
.HasPrecision(19, 4)
|
||||||
|
.HasColumnName("productcost");
|
||||||
|
entity.Property(e => e.Productdescription).HasColumnName("productdescription");
|
||||||
|
entity.Property(e => e.Productdiscountamount).HasColumnName("productdiscountamount");
|
||||||
|
entity.Property(e => e.Productmaxdiscount).HasColumnName("productmaxdiscount");
|
||||||
|
entity.Property(e => e.Productname).HasColumnName("productname");
|
||||||
|
entity.Property(e => e.Productphoto).HasColumnName("productphoto");
|
||||||
|
entity.Property(e => e.Productquantityinstock).HasColumnName("productquantityinstock");
|
||||||
|
entity.Property(e => e.UnitId).HasColumnName("unit_id");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Category).WithMany(p => p.Products)
|
||||||
|
.HasForeignKey(d => d.CategoryId)
|
||||||
|
.HasConstraintName("product_category_id_fkey");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Manufacturer).WithMany(p => p.Products)
|
||||||
|
.HasForeignKey(d => d.ManufacturerId)
|
||||||
|
.HasConstraintName("product_manufacturer_id_fkey");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Porductprovider).WithMany(p => p.Products)
|
||||||
|
.HasForeignKey(d => d.PorductproviderId)
|
||||||
|
.HasConstraintName("product_porductprovider_id_fkey");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.Unit).WithMany(p => p.Products)
|
||||||
|
.HasForeignKey(d => d.UnitId)
|
||||||
|
.HasConstraintName("product_unit_id_fkey1");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Productunit>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.UnitId).HasName("productunit_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("productunit");
|
||||||
|
|
||||||
|
entity.Property(e => e.UnitId)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("unit_id");
|
||||||
|
entity.Property(e => e.UnitName).HasColumnName("unit_name");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<Role>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Roleid).HasName("Role_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("Role");
|
||||||
|
|
||||||
|
entity.Property(e => e.Roleid)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("roleid");
|
||||||
|
entity.Property(e => e.Rolename).HasColumnName("rolename");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<User>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(e => e.Userid).HasName("User_pkey");
|
||||||
|
|
||||||
|
entity.ToTable("User");
|
||||||
|
|
||||||
|
entity.Property(e => e.Userid)
|
||||||
|
.UseIdentityAlwaysColumn()
|
||||||
|
.HasColumnName("userid");
|
||||||
|
entity.Property(e => e.Userlogin).HasColumnName("userlogin");
|
||||||
|
entity.Property(e => e.Username).HasColumnName("username");
|
||||||
|
entity.Property(e => e.Userpassword).HasColumnName("userpassword");
|
||||||
|
entity.Property(e => e.Userpatronymic).HasColumnName("userpatronymic");
|
||||||
|
entity.Property(e => e.Userrole).HasColumnName("userrole");
|
||||||
|
entity.Property(e => e.Usersurname).HasColumnName("usersurname");
|
||||||
|
|
||||||
|
entity.HasOne(d => d.UserroleNavigation).WithMany(p => p.Users)
|
||||||
|
.HasForeignKey(d => d.Userrole)
|
||||||
|
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||||
|
.HasConstraintName("User_userrole_fkey");
|
||||||
|
});
|
||||||
|
|
||||||
|
OnModelCreatingPartial(modelBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||||
|
}
|
23
Data/RemoteData/Entity/User.cs
Normal file
23
Data/RemoteData/Entity/User.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.RemoteData.Entity;
|
||||||
|
|
||||||
|
public partial class User
|
||||||
|
{
|
||||||
|
public int Userid { get; set; }
|
||||||
|
|
||||||
|
public string Usersurname { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Username { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Userpatronymic { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Userlogin { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Userpassword { get; set; } = null!;
|
||||||
|
|
||||||
|
public int Userrole { get; set; }
|
||||||
|
|
||||||
|
public virtual Role UserroleNavigation { get; set; } = null!;
|
||||||
|
}
|
14
Data/Repository/ILoginRepository.cs
Normal file
14
Data/Repository/ILoginRepository.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public interface ILoginRepository: IDisposable
|
||||||
|
{
|
||||||
|
User? GetUserByLogin(string login);
|
||||||
|
}
|
||||||
|
}
|
18
Data/Repository/IOrderManagerRepository.cs
Normal file
18
Data/Repository/IOrderManagerRepository.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Order = demo_trade.Data.RemoteData.Entity.Order;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IOrderManagerRepository: IDisposable
|
||||||
|
{
|
||||||
|
List<Order> GetAllOrders();
|
||||||
|
bool EditRangeOrders(List<OrderChanged> orders);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
16
Data/Repository/IOrderRepository.cs
Normal file
16
Data/Repository/IOrderRepository.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IOrderRepository
|
||||||
|
{
|
||||||
|
List<Order> GetAllOrders();
|
||||||
|
int GetNumberForNewOrder();
|
||||||
|
Order CreateOrder(Order order, List<Orderproduct> orderproducts);
|
||||||
|
}
|
||||||
|
}
|
15
Data/Repository/IPickupRepositorycs.cs
Normal file
15
Data/Repository/IPickupRepositorycs.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IPickupRepository
|
||||||
|
{
|
||||||
|
List<PickupPoint> GetAllPickupPoints();
|
||||||
|
}
|
||||||
|
}
|
18
Data/Repository/IProductRepository.cs
Normal file
18
Data/Repository/IProductRepository.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public interface IProductRepository : IDisposable
|
||||||
|
{
|
||||||
|
List<Product> GetProducts();
|
||||||
|
Boolean RemoveProductByArticleNumber(string articleNumber);
|
||||||
|
Product? UpdateProductByArticleNumber(Product product);
|
||||||
|
Product? GetProductByArticleNumber(string articleNumber);
|
||||||
|
void Save();
|
||||||
|
}
|
||||||
|
}
|
27
Data/Repository/SQLLoginRepository.cs
Normal file
27
Data/Repository/SQLLoginRepository.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLLoginRepository : ILoginRepository
|
||||||
|
{
|
||||||
|
private TradeContext _tradeContext;
|
||||||
|
public SQLLoginRepository() {
|
||||||
|
_tradeContext = new TradeContext();
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User? GetUserByLogin(string login)
|
||||||
|
{
|
||||||
|
return _tradeContext.Users.Where(user => user.Userlogin == login).FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
Data/Repository/SQLOrderClientRepository.cs
Normal file
51
Data/Repository/SQLOrderClientRepository.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLOrderClientRepository : IOrderRepository, IDisposable
|
||||||
|
{
|
||||||
|
private TradeContext _tradeContext;
|
||||||
|
public SQLOrderClientRepository() {
|
||||||
|
|
||||||
|
_tradeContext = new TradeContext();
|
||||||
|
}
|
||||||
|
public Order CreateOrder(Order order, List<Orderproduct> orderproducts)
|
||||||
|
{
|
||||||
|
using var transaction = _tradeContext.Database.BeginTransaction();
|
||||||
|
try {
|
||||||
|
var createdOrder = _tradeContext.Add(order);
|
||||||
|
_tradeContext.SaveChanges();
|
||||||
|
foreach (var product in orderproducts) {
|
||||||
|
_tradeContext.Add(new Orderproduct { Orderid = order.Orderid, Productarticlenumber = product.Productarticlenumber, ProductCount = product.ProductCount });
|
||||||
|
}
|
||||||
|
_tradeContext.SaveChanges();
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Order> GetAllOrders()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetNumberForNewOrder()
|
||||||
|
{
|
||||||
|
return _tradeContext.Orders.Max(it => it.Orderid) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
Data/Repository/SQLOrderManagerRepository.cs
Normal file
52
Data/Repository/SQLOrderManagerRepository.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Order = demo_trade.Data.RemoteData.Entity.Order;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLOrderManagerRepository : IOrderManagerRepository
|
||||||
|
{
|
||||||
|
private TradeContext _tradeContext;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SQLOrderManagerRepository() {
|
||||||
|
_tradeContext = new TradeContext();
|
||||||
|
}
|
||||||
|
public bool EditRangeOrders(List<OrderChanged> orders)
|
||||||
|
{
|
||||||
|
using var transaction = _tradeContext.Database.BeginTransaction();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var item in orders)
|
||||||
|
{
|
||||||
|
var order = _tradeContext.Orders.Find(item.OrderId);
|
||||||
|
if (item.OrderStatus == null) continue;
|
||||||
|
if (order.Orderstatus != item.OrderStatus) order.Orderstatus = item.OrderStatus;
|
||||||
|
if (item.OrderDeliveryDate == null) continue;
|
||||||
|
if (order.Orderdeliverydate != item.OrderDeliveryDate) order.Orderdeliverydate = item.OrderDeliveryDate.Value;
|
||||||
|
_tradeContext.SaveChanges();
|
||||||
|
}
|
||||||
|
transaction.Commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Order> GetAllOrders()
|
||||||
|
{
|
||||||
|
return _tradeContext.Orders.Include(it => it.Orderproducts).ThenInclude(it => it.ProductarticlenumberNavigation).Include(it => it.OrderpickuppointNavigation).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
Data/Repository/SQLPickupRepository.cs
Normal file
22
Data/Repository/SQLPickupRepository.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLPickupRepository : IPickupRepository
|
||||||
|
{
|
||||||
|
private TradeContext _tradeContext;
|
||||||
|
public SQLPickupRepository() {
|
||||||
|
|
||||||
|
_tradeContext = new TradeContext();
|
||||||
|
}
|
||||||
|
public List<PickupPoint> GetAllPickupPoints()
|
||||||
|
{
|
||||||
|
return _tradeContext.PickupPoints.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
Data/Repository/SQLProductRepository.cs
Normal file
56
Data/Repository/SQLProductRepository.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Data.Repository
|
||||||
|
{
|
||||||
|
public class SQLProductRepository : IProductRepository
|
||||||
|
{
|
||||||
|
private TradeContext _tradeContext;
|
||||||
|
|
||||||
|
public SQLProductRepository() {
|
||||||
|
_tradeContext = new TradeContext();
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product? GetProductByArticleNumber(string articleNumber)
|
||||||
|
{
|
||||||
|
return _tradeContext.Products.Where(it => articleNumber == it.Productarticlenumber).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Product> GetProducts()
|
||||||
|
{
|
||||||
|
|
||||||
|
return _tradeContext.Products.Include(manfucture => manfucture.Manufacturer).Select(it => it).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveProductByArticleNumber(string articleNumber)
|
||||||
|
{
|
||||||
|
Product? product = GetProductByArticleNumber(articleNumber);
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
_tradeContext.Products.Remove(product);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
_tradeContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product? UpdateProductByArticleNumber(Product product)
|
||||||
|
{
|
||||||
|
_tradeContext.Entry(product).State = EntityState.Modified;
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
Domain/GuestProductUseCase.cs
Normal file
41
Domain/GuestProductUseCase.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using demo_trade.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Domain
|
||||||
|
{
|
||||||
|
public class GuestProductUseCase
|
||||||
|
{
|
||||||
|
private IProductRepository _productRepository;
|
||||||
|
|
||||||
|
public GuestProductUseCase(IProductRepository productRepository) {
|
||||||
|
|
||||||
|
_productRepository = productRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProductPresenter> GetProducts() => _productRepository
|
||||||
|
.GetProducts()
|
||||||
|
.Select(it => new ProductPresenter
|
||||||
|
{
|
||||||
|
ArticleNumber = it.Productarticlenumber,
|
||||||
|
Description = it.Productdescription,
|
||||||
|
Name = it.Productname,
|
||||||
|
DiscountAmount = it.Productdiscountamount,
|
||||||
|
Cost = it.Productcost == null ? 0 : Convert.ToDecimal(it.Productcost),
|
||||||
|
ProductMaxDiscount = it.Productmaxdiscount,
|
||||||
|
QuantityInStock = it.Productquantityinstock,
|
||||||
|
Manufacturer = new Manufacturer { Id = it.Manufacturer.ManufacturerId, Name = it.Manufacturer.ManufacturerName },
|
||||||
|
Image = !String.IsNullOrEmpty(it.Imagename) ?
|
||||||
|
ImageHelper.BASE_URL + "/" + it.Imagename
|
||||||
|
: ImageHelper.BASE_URL + "/" + "default.png"
|
||||||
|
,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
29
Domain/LoginUseCase.cs
Normal file
29
Domain/LoginUseCase.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Authentication;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Domain
|
||||||
|
{
|
||||||
|
public class LoginUseCase
|
||||||
|
{
|
||||||
|
private ILoginRepository _loginRepository;
|
||||||
|
public LoginUseCase(ILoginRepository loginRepository) {
|
||||||
|
_loginRepository = loginRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User AutorizationByLoginAndPassword(UserLogin userLogin)
|
||||||
|
{
|
||||||
|
User? user = _loginRepository.GetUserByLogin(userLogin.Login);
|
||||||
|
if (user == null) throw new AuthenticationException("Пользователь не найден");
|
||||||
|
if (user.Userpassword != userLogin.Password) throw new AuthenticationException("Пароли не совпадают");
|
||||||
|
return user;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
Domain/OrderClientUseCase.cs
Normal file
40
Domain/OrderClientUseCase.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Domain
|
||||||
|
{
|
||||||
|
public class OrderClientUseCase
|
||||||
|
{
|
||||||
|
private IOrderRepository _orderRepository;
|
||||||
|
private IPickupRepository _pickupRepository;
|
||||||
|
public OrderClientUseCase(IOrderRepository orderRepository, IPickupRepository pickupRepository) {
|
||||||
|
_orderRepository = orderRepository;
|
||||||
|
_pickupRepository = pickupRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PickupPoint> GetPickupPoints() => _pickupRepository.GetAllPickupPoints();
|
||||||
|
public int GetNewOrderNumber() => _orderRepository.GetNumberForNewOrder();
|
||||||
|
|
||||||
|
public Models.Order? GenerateNewOrder(PickupPoint orderPickupPoint, List<OrderProductPresenter> products,decimal orderSumCost, string? clientName = null) {
|
||||||
|
int daysOrderCount = CheckProductsQuntity(products) ? 3 : 6;
|
||||||
|
Order order = new Order { Orderdeliverydate = DateOnly.FromDateTime(DateTime.Now.AddDays(daysOrderCount)), Orderpickuppoint = orderPickupPoint.PickupPointId, Orderstatus = "Новый", ClientName= clientName, OrderSumCost=orderSumCost};
|
||||||
|
List<Orderproduct> orderproducts = products.Select(it => new Orderproduct { Productarticlenumber = it.ArticleNumber, ProductCount = it.ProductCount }).ToList();
|
||||||
|
var resultOrder = _orderRepository.CreateOrder(order, orderproducts);
|
||||||
|
if (resultOrder != null) return new demo_trade.Models.Order { Orderid = resultOrder.Orderid, Orderdeliverydate = resultOrder.Orderdeliverydate, PickupPointName = orderPickupPoint.PickupPointName, Orderstatus = resultOrder.Orderstatus, ProductList =products, OrderClient=clientName, OrderSumCost=orderSumCost };
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private bool CheckProductsQuntity(List<OrderProductPresenter> orderProducts) {
|
||||||
|
|
||||||
|
foreach (var product in orderProducts) {
|
||||||
|
if (product.QuantityInStock <= 3) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
Domain/OrderManagerUseCase.cs
Normal file
44
Domain/OrderManagerUseCase.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Domain
|
||||||
|
{
|
||||||
|
public class OrderManagerUseCase
|
||||||
|
{
|
||||||
|
private IOrderManagerRepository _orderRepository;
|
||||||
|
|
||||||
|
public OrderManagerUseCase(IOrderManagerRepository orderRepository) {
|
||||||
|
_orderRepository = orderRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeOrders(List<OrderChanged> orderChangeds) {
|
||||||
|
_orderRepository.EditRangeOrders(orderChangeds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<OrderManager> GetOrders()
|
||||||
|
{
|
||||||
|
return _orderRepository.GetAllOrders().Select(it => new OrderManager {
|
||||||
|
OrderClient = it.ClientName,
|
||||||
|
Orderdeliverydate = it.Orderdeliverydate,
|
||||||
|
Orderid = it.Orderid,
|
||||||
|
Orderstatus = it.Orderstatus,
|
||||||
|
PickupPointName = it.OrderpickuppointNavigation.PickupPointName,
|
||||||
|
ProductList = String.Join("\n", it.Orderproducts.Select(product => String.Format("Article: {0} Count: {1} Stock: {2}",
|
||||||
|
product.Productarticlenumber,
|
||||||
|
product.ProductCount,
|
||||||
|
product.ProductarticlenumberNavigation.Productquantityinstock
|
||||||
|
)).ToList()),
|
||||||
|
OrderSumCost = it.OrderSumCost,
|
||||||
|
ProductStock = it.Orderproducts.Select(it => it.ProductarticlenumberNavigation).ToList()
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
13
Exceptions/AutorizeException.cs
Normal file
13
Exceptions/AutorizeException.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Exceptions
|
||||||
|
{
|
||||||
|
class AutorizeException : Exception
|
||||||
|
{
|
||||||
|
public AutorizeException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
}
|
15
Models/Manufacturer.cs
Normal file
15
Models/Manufacturer.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class Manufacturer
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
25
Models/Order.cs
Normal file
25
Models/Order.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class Order
|
||||||
|
{
|
||||||
|
public int Orderid { get; set; }
|
||||||
|
|
||||||
|
public string Orderstatus { get; set; }
|
||||||
|
|
||||||
|
public string? OrderClient { get; set; } = null;
|
||||||
|
|
||||||
|
public DateOnly Orderdeliverydate { get; set; }
|
||||||
|
|
||||||
|
public string PickupPointName { get; set; }
|
||||||
|
public decimal OrderSumCost { get; set; }
|
||||||
|
|
||||||
|
public List<OrderProductPresenter> ProductList{ get; set; }
|
||||||
|
}
|
||||||
|
}
|
15
Models/OrderChanged.cs
Normal file
15
Models/OrderChanged.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class OrderChanged
|
||||||
|
{
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
public string? OrderStatus { get; set; }
|
||||||
|
public DateOnly? OrderDeliveryDate { get; set; }
|
||||||
|
}
|
||||||
|
}
|
26
Models/OrderManager.cs
Normal file
26
Models/OrderManager.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class OrderManager
|
||||||
|
{
|
||||||
|
public int Orderid { get; set; }
|
||||||
|
|
||||||
|
public string Orderstatus { get; set; }
|
||||||
|
|
||||||
|
public string? OrderClient { get; set; } = null;
|
||||||
|
|
||||||
|
public DateOnly Orderdeliverydate { get; set; }
|
||||||
|
|
||||||
|
public string PickupPointName { get; set; }
|
||||||
|
public decimal? OrderSumCost { get; set; }
|
||||||
|
|
||||||
|
public string ProductList { get; set; }
|
||||||
|
public List<demo_trade.Data.RemoteData.Entity.Product> ProductStock { get; set; }
|
||||||
|
}
|
||||||
|
}
|
25
Models/Product.cs
Normal file
25
Models/Product.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class Product
|
||||||
|
{
|
||||||
|
public string ArticleNumber { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
public decimal Cost { get; set; }
|
||||||
|
|
||||||
|
public short? DiscountAmount { get; set; }
|
||||||
|
|
||||||
|
public int? QuantityInStock { get; set; }
|
||||||
|
|
||||||
|
public int? ProductMaxDiscount { get; set; }
|
||||||
|
|
||||||
|
public Manufacturer Manufacturer { get; set; }
|
||||||
|
}
|
||||||
|
}
|
54
Models/Ticket.cs
Normal file
54
Models/Ticket.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using iText.IO.Font.Constants;
|
||||||
|
using iText.Kernel.Font;
|
||||||
|
using iTextSharp.text;
|
||||||
|
using iTextSharp.text.pdf;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using PdfFont = iText.Kernel.Font.PdfFont;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class Ticket
|
||||||
|
{
|
||||||
|
public int OrderID { get; set; }
|
||||||
|
public string PickupPointName{ get; set; }
|
||||||
|
public decimal OrderSumCost{ get; set; }
|
||||||
|
public string? ClientName { get; set; } = null;
|
||||||
|
public DateOnly OrderDate { get; set; }
|
||||||
|
public DateOnly OrderDelivery { get; set; }
|
||||||
|
|
||||||
|
public List<OrderProductPresenter> Products { get; set; }
|
||||||
|
|
||||||
|
public int OrderCode { get; set; }
|
||||||
|
|
||||||
|
public void GeneratePDF(string path) {
|
||||||
|
using var document = new Document();
|
||||||
|
PdfWriter.GetInstance(document, new FileStream(path, FileMode.OpenOrCreate));
|
||||||
|
document.Open();
|
||||||
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
|
BaseFont baseFont = BaseFont.CreateFont("C:\\Windows\\Fonts\\arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
|
||||||
|
|
||||||
|
Font font = new Font(baseFont, iTextSharp.text.Font.DEFAULTSIZE, iTextSharp.text.Font.NORMAL);
|
||||||
|
Font fontCode = new Font(baseFont, iTextSharp.text.Font.DEFAULTSIZE, iTextSharp.text.Font.BOLD);
|
||||||
|
|
||||||
|
Paragraph paragraph = new Paragraph(String.Format("Order №{0} Create {1} Data delivery {2}\nПункт выдачи: {3}\nСумма заказа: {4}", OrderID, OrderDate, OrderDelivery, PickupPointName, OrderSumCost), font);
|
||||||
|
if (ClientName != null) paragraph.Add(String.Format("\nClient name: {0}", ClientName));
|
||||||
|
document.Add(paragraph);
|
||||||
|
foreach (OrderProductPresenter presenter in Products) {
|
||||||
|
|
||||||
|
document.Add(new Phrase(String.Format("Article: {0}, Name: {2}, Count: {1}\n", presenter.ArticleNumber, presenter.ProductCount, presenter.Name), font));
|
||||||
|
}
|
||||||
|
GenerateCode();
|
||||||
|
document.Add(new Paragraph(String.Format("Code: {0}", OrderCode), fontCode));
|
||||||
|
document.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateCode() {
|
||||||
|
OrderCode = new Random().Next(100, 999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Models/UserLogin.cs
Normal file
15
Models/UserLogin.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Models
|
||||||
|
{
|
||||||
|
public class UserLogin
|
||||||
|
{
|
||||||
|
public string Login { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
21
Program.cs
Normal file
21
Program.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace demo_trade
|
||||||
|
{
|
||||||
|
internal sealed class Program
|
||||||
|
{
|
||||||
|
|
||||||
|
[STAThread]
|
||||||
|
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||||
|
.StartWithClassicDesktopLifetime(args);
|
||||||
|
|
||||||
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
|
=> AppBuilder.Configure<App>()
|
||||||
|
.UseReactiveUI()
|
||||||
|
.UsePlatformDetect()
|
||||||
|
.WithInterFont()
|
||||||
|
.LogToTrace();
|
||||||
|
}
|
||||||
|
}
|
27
UI/Converters/ItemColorConverter.cs
Normal file
27
UI/Converters/ItemColorConverter.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Converters
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ItemEnableConverterByDate : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
|
||||||
|
DateOnly date = (DateOnly)value;
|
||||||
|
return date >= DateOnly.FromDateTime(DateTime.Now);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
UI/Converters/ItemColorOrderConverter.cs
Normal file
28
UI/Converters/ItemColorOrderConverter.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Converters
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ItemColorOrderConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
|
||||||
|
var products = (List<Product>)value;
|
||||||
|
return products.Where(it => it.Productquantityinstock < 3).ToList().Count > 0 ? new SolidColorBrush(Colors.Yellow) : new SolidColorBrush(Colors.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
UI/Converters/ItemComboboxConverter.cs
Normal file
30
UI/Converters/ItemComboboxConverter.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Converters
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ItemComboboxConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
|
||||||
|
string status = (string)value;
|
||||||
|
|
||||||
|
return status == "Новый" ? 0: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
int status = (int)value;
|
||||||
|
|
||||||
|
return status != 0 ? "Завершен" : "Новый";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
UI/Converters/ItemDateConverter.cs
Normal file
30
UI/Converters/ItemDateConverter.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Tmds.DBus.Protocol;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Converters
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ItemDateConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
|
||||||
|
var date = (DateOnly)value;
|
||||||
|
return new DateTimeOffset(new DateTime(date.Year, date.Month, date.Day));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
var date = (DateTimeOffset)value;
|
||||||
|
|
||||||
|
return new DateOnly(date.Year, date.Month, date.Day);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
UI/Converters/ItemEnableConverterByDate.cs
Normal file
26
UI/Converters/ItemEnableConverterByDate.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Converters
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ItemColorConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (short?)value > 15? new SolidColorBrush(Colors.Yellow) : new SolidColorBrush(Colors.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
UI/Presenters/OrderProductPresenter.cs
Normal file
27
UI/Presenters/OrderProductPresenter.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Presenters
|
||||||
|
{
|
||||||
|
public class OrderProductPresenter: ProductPresenter
|
||||||
|
{
|
||||||
|
public int ProductCount { get; set; }
|
||||||
|
|
||||||
|
public OrderProductPresenter(ProductPresenter productPresenter, int count) {
|
||||||
|
this.ArticleNumber = productPresenter.ArticleNumber;
|
||||||
|
this.ProductCount = count;
|
||||||
|
this.ProductMaxDiscount = productPresenter.ProductMaxDiscount;
|
||||||
|
this.QuantityInStock = productPresenter.QuantityInStock;
|
||||||
|
this.Manufacturer = productPresenter.Manufacturer;
|
||||||
|
this.Description = productPresenter.Description;
|
||||||
|
this.Name = productPresenter.Name;
|
||||||
|
this.Cost = productPresenter.Cost;
|
||||||
|
this.DiscountAmount = productPresenter.DiscountAmount;
|
||||||
|
this.Image = productPresenter.Image;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
UI/Presenters/ProductPresenter.cs
Normal file
36
UI/Presenters/ProductPresenter.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Avalonia.Media;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Presenters
|
||||||
|
{
|
||||||
|
public class ProductPresenter
|
||||||
|
{
|
||||||
|
public string ArticleNumber { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
public decimal Cost { get; set; }
|
||||||
|
|
||||||
|
public short? DiscountAmount { get; set; }
|
||||||
|
|
||||||
|
public int? QuantityInStock { get; set; }
|
||||||
|
|
||||||
|
public string Image { get; set; }
|
||||||
|
public int? ProductMaxDiscount { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public decimal? CostWithDiscount { get => Cost - (Cost * DiscountAmount / 100); }
|
||||||
|
|
||||||
|
public Manufacturer Manufacturer { get; set; }
|
||||||
|
|
||||||
|
public SolidColorBrush ColorBackgroundItem { get => DiscountAmount < 15 ?
|
||||||
|
new SolidColorBrush(Color.FromRgb(255, 255, 255))
|
||||||
|
:
|
||||||
|
new SolidColorBrush(Color.FromRgb(255, 245, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
15
UI/Themes/Colors.cs
Normal file
15
UI/Themes/Colors.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Avalonia.Media;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.UI.Themes
|
||||||
|
{
|
||||||
|
public static class Colors
|
||||||
|
{
|
||||||
|
public static Color White = new Color(255, 255, 255, 255);
|
||||||
|
public static Color Green = new Color(255, 255, 245, 0);
|
||||||
|
}
|
||||||
|
}
|
37
Utils/ImageHelper.cs
Normal file
37
Utils/ImageHelper.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using SkiaSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Utils
|
||||||
|
{
|
||||||
|
public static class ImageHelper
|
||||||
|
{
|
||||||
|
public static string BASE_URL = "http://localhost:5025/images";
|
||||||
|
public static async Task<Bitmap?> LoadFromRemoteByName(string imageName)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrWhiteSpace(imageName)) imageName = "default.png";
|
||||||
|
using var httpClient = new HttpClient();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var response = await httpClient.GetAsync(BASE_URL + "/" + imageName);
|
||||||
|
var data = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
var bimap = new Bitmap(new MemoryStream(data));
|
||||||
|
bimap.Save(imageName);
|
||||||
|
return new Bitmap(new MemoryStream(data));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
23
ViewLocator.cs
Normal file
23
ViewLocator.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace demo_trade
|
||||||
|
{
|
||||||
|
public class ViewLocator : ReactiveUI.IViewLocator
|
||||||
|
{
|
||||||
|
public IViewFor? ResolveView<T>(T? viewModel, string? contract = null) => viewModel switch
|
||||||
|
{
|
||||||
|
LoginViewModel context => new LoginControl { DataContext = context },
|
||||||
|
GuestProductViewModel context => new GuestProductControl { DataContext = context },
|
||||||
|
ClientProductViewModel context => new ClientProductControl{ DataContext = context },
|
||||||
|
OrderShowDialogViewModel context => new OrderShowDialog{ DataContext = context},
|
||||||
|
OrderManagerViewModel context => new OrderManagerControl { DataContext = context },
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(viewModel))
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
179
ViewModels/ClientProductViewModel.cs
Normal file
179
ViewModels/ClientProductViewModel.cs
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
using Avalonia.Markup.Xaml.Templates;
|
||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.Domain;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Tmds.DBus.Protocol;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public class ClientProductViewModel : ViewModelBase, IRoutableViewModel
|
||||||
|
{
|
||||||
|
private GuestProductUseCase _guestProductUseCase;
|
||||||
|
public string? UrlPathSegment => Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
private User _user = new();
|
||||||
|
|
||||||
|
private bool _isManager = false;
|
||||||
|
public bool IsManager { get => _isManager; set => this.RaiseAndSetIfChanged(ref _isManager, value); }
|
||||||
|
|
||||||
|
private Dictionary<string, (ProductPresenter, int)> _productOrder = new();
|
||||||
|
public Dictionary<string, (ProductPresenter, int)> ProductOrder
|
||||||
|
{
|
||||||
|
get => _productOrder;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _productOrder, value);
|
||||||
|
}
|
||||||
|
public User AutorizedUser {
|
||||||
|
get => _user;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _user, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProductPresenter> _productOrderList = new();
|
||||||
|
public List<ProductPresenter> ProductOrderList
|
||||||
|
{
|
||||||
|
get => _productOrderList;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _productOrderList, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _thereItemsInOrder = false;
|
||||||
|
public bool ThereItemsInOrder
|
||||||
|
{
|
||||||
|
get => _thereItemsInOrder;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _thereItemsInOrder, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<int, (int, int?)> _filterValues = new Dictionary<int, (int, int?)>() {
|
||||||
|
{0, (0, null)},
|
||||||
|
{1, (0, 10)},
|
||||||
|
{2, (10, 15)},
|
||||||
|
{3, (15, null)}
|
||||||
|
};
|
||||||
|
public ReactiveCommand<ProductPresenter, Unit> AddToOrderCommand { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AttachToOrderCommand { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AttachToOrderManagerCommand { get; }
|
||||||
|
|
||||||
|
|
||||||
|
private int _selectedFilterValue = 0;
|
||||||
|
private int _selectedSortValue = 0;
|
||||||
|
public int SelectedFilterValue
|
||||||
|
{
|
||||||
|
get => _selectedFilterValue;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _selectedFilterValue, value);
|
||||||
|
}
|
||||||
|
public int SelectedSortValue
|
||||||
|
{
|
||||||
|
get => _selectedSortValue;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _selectedSortValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _searchWord = string.Empty;
|
||||||
|
public string SearchWord
|
||||||
|
{
|
||||||
|
|
||||||
|
get => _searchWord;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _searchWord, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _statisticText = string.Empty;
|
||||||
|
public string StatisticText
|
||||||
|
{
|
||||||
|
|
||||||
|
get => _statisticText;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _statisticText, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProductPresenter> _dataSource = new();
|
||||||
|
private List<ProductPresenter> _products = new();
|
||||||
|
public List<ProductPresenter> Products
|
||||||
|
{
|
||||||
|
get => _products;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _products, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScreen HostScreen { get; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ClientProductViewModel(IScreen home, IProductRepository productRepository, User user)
|
||||||
|
{
|
||||||
|
AutorizedUser = user;
|
||||||
|
HostScreen = home;
|
||||||
|
if (AutorizedUser.Userrole == 1 || AutorizedUser.Userrole == 3) IsManager = true;
|
||||||
|
_guestProductUseCase = new GuestProductUseCase(productRepository);
|
||||||
|
_dataSource = _guestProductUseCase.GetProducts();
|
||||||
|
this.WhenAnyValue(search => search.SearchWord).Subscribe(_ => { DisplayList(); });
|
||||||
|
this.WhenAnyValue(selectedFilter => selectedFilter.SelectedFilterValue).Subscribe(_ => { DisplayList(); });
|
||||||
|
this.WhenAnyValue(selectedSort => selectedSort.SelectedSortValue).Subscribe(_ => { DisplayList(); });
|
||||||
|
DisplayList();
|
||||||
|
AddToOrderCommand = ReactiveCommand.Create<ProductPresenter>(product => {
|
||||||
|
if (ProductOrder.ContainsKey(product.ArticleNumber))
|
||||||
|
{
|
||||||
|
var values = ProductOrder[product.ArticleNumber];
|
||||||
|
ProductOrder[product.ArticleNumber] = (product, values.Item2 + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ProductOrder.Add(product.ArticleNumber, (product, 1));
|
||||||
|
}
|
||||||
|
ThereItemsInOrder = ProductOrder.Keys.Count > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
AttachToOrderManagerCommand = ReactiveCommand.Create(
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
var orderManagerUseCase = new OrderManagerUseCase(new SQLOrderManagerRepository());
|
||||||
|
HostScreen.Router.Navigate.Execute(new OrderManagerViewModel(HostScreen, orderManagerUseCase));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ShowDialog = new Interaction<OrderShowDialogViewModel, bool>();
|
||||||
|
AttachToOrderCommand = ReactiveCommand.CreateFromTask(async () =>
|
||||||
|
{
|
||||||
|
var userOrderCase = new OrderClientUseCase(new SQLOrderClientRepository(), new SQLPickupRepository());
|
||||||
|
var order = new OrderShowDialogViewModel(ProductOrder, userOrderCase, user);
|
||||||
|
var result = await ShowDialog.Handle(order);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
public Interaction<OrderShowDialogViewModel, bool> ShowDialog { get; }
|
||||||
|
|
||||||
|
private bool FilterByDiscount(short? discount)
|
||||||
|
{
|
||||||
|
if (discount == null) return false;
|
||||||
|
(int leftBound, int? rightBound) = _filterValues[SelectedFilterValue];
|
||||||
|
if (rightBound == null) return leftBound <= discount;
|
||||||
|
return leftBound <= discount && discount < rightBound;
|
||||||
|
}
|
||||||
|
private void DisplayList()
|
||||||
|
{
|
||||||
|
var temp = _dataSource;
|
||||||
|
if (SelectedFilterValue > 0)
|
||||||
|
{
|
||||||
|
temp = temp.Where(it => FilterByDiscount(it.DiscountAmount)).ToList();
|
||||||
|
}
|
||||||
|
if (!String.IsNullOrEmpty(SearchWord))
|
||||||
|
{
|
||||||
|
temp = temp.Where(it => it.Name.Contains(SearchWord, StringComparison.CurrentCultureIgnoreCase)).ToList();
|
||||||
|
}
|
||||||
|
if (SelectedSortValue == 1)
|
||||||
|
{
|
||||||
|
temp = temp.OrderByDescending(it => it.Cost).ToList();
|
||||||
|
}
|
||||||
|
else if (SelectedSortValue == 2)
|
||||||
|
{
|
||||||
|
temp = temp.OrderBy(it => it.Cost).ToList();
|
||||||
|
}
|
||||||
|
this.Products = temp;
|
||||||
|
StatisticText = String.Format("{0} из {1}", temp.Count, _dataSource.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
142
ViewModels/GuestProductViewModel.cs
Normal file
142
ViewModels/GuestProductViewModel.cs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
using Avalonia.Markup.Xaml.Templates;
|
||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.Domain;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public class GuestProductViewModel : ViewModelBase, IRoutableViewModel
|
||||||
|
{
|
||||||
|
private GuestProductUseCase _guestProductUseCase;
|
||||||
|
|
||||||
|
private Dictionary<string, (ProductPresenter, int)> _productOrder = new();
|
||||||
|
public Dictionary<string, (ProductPresenter, int)> ProductOrder
|
||||||
|
{
|
||||||
|
get => _productOrder;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _productOrder, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _thereItemsInOrder = false;
|
||||||
|
public bool ThereItemsInOrder {
|
||||||
|
get => _thereItemsInOrder;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _thereItemsInOrder, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? UrlPathSegment => Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
private Dictionary<int, (int, int?)> _filterValues = new Dictionary<int, (int, int?)>() {
|
||||||
|
{0, (0, null)},
|
||||||
|
{1, (0, 10)},
|
||||||
|
{2, (10, 15)},
|
||||||
|
{3, (15, null)}
|
||||||
|
};
|
||||||
|
public ReactiveCommand<ProductPresenter, Unit> AddToOrderCommand { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> AttachToOrderCommand { get; }
|
||||||
|
|
||||||
|
|
||||||
|
private int _selectedFilterValue = 0;
|
||||||
|
private int _selectedSortValue = 0;
|
||||||
|
public int SelectedFilterValue {
|
||||||
|
get => _selectedFilterValue;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _selectedFilterValue, value);
|
||||||
|
}
|
||||||
|
public int SelectedSortValue
|
||||||
|
{
|
||||||
|
get => _selectedSortValue;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _selectedSortValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _searchWord = string.Empty;
|
||||||
|
public string SearchWord {
|
||||||
|
|
||||||
|
get => _searchWord;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _searchWord, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _statisticText = string.Empty;
|
||||||
|
public string StatisticText
|
||||||
|
{
|
||||||
|
|
||||||
|
get => _statisticText;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _statisticText, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProductPresenter> _dataSource = new();
|
||||||
|
private List<ProductPresenter> _products = new();
|
||||||
|
public List<ProductPresenter> Products {
|
||||||
|
get => _products;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _products, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScreen HostScreen { get; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GuestProductViewModel(IScreen home, IProductRepository productRepository) {
|
||||||
|
HostScreen = home;
|
||||||
|
_guestProductUseCase = new GuestProductUseCase(productRepository);
|
||||||
|
_dataSource = _guestProductUseCase.GetProducts();
|
||||||
|
this.WhenAnyValue(search => search.SearchWord).Subscribe(_ => { DisplayList(); });
|
||||||
|
this.WhenAnyValue(selectedFilter => selectedFilter.SelectedFilterValue).Subscribe(_ => { DisplayList(); });
|
||||||
|
this.WhenAnyValue(selectedSort => selectedSort.SelectedSortValue).Subscribe(_ => { DisplayList(); });
|
||||||
|
DisplayList();
|
||||||
|
AddToOrderCommand = ReactiveCommand.Create<ProductPresenter>(product => {
|
||||||
|
if (ProductOrder.ContainsKey(product.ArticleNumber))
|
||||||
|
{
|
||||||
|
var values = ProductOrder[product.ArticleNumber];
|
||||||
|
ProductOrder[product.ArticleNumber] = (product, values.Item2 + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ProductOrder.Add(product.ArticleNumber, (product, 1));
|
||||||
|
}
|
||||||
|
ThereItemsInOrder = ProductOrder.Keys.Count > 0;
|
||||||
|
|
||||||
|
});
|
||||||
|
ShowDialog = new Interaction<OrderShowDialogViewModel, bool>();
|
||||||
|
AttachToOrderCommand = ReactiveCommand.CreateFromTask(async() =>
|
||||||
|
{
|
||||||
|
var userOrderCase = new OrderClientUseCase(new SQLOrderClientRepository(), new SQLPickupRepository());
|
||||||
|
var order = new OrderShowDialogViewModel(ProductOrder, userOrderCase);
|
||||||
|
var result = await ShowDialog.Handle(order);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
private bool FilterByDiscount(short? discount) {
|
||||||
|
if (discount == null) return false;
|
||||||
|
(int leftBound, int? rightBound) = _filterValues[SelectedFilterValue];
|
||||||
|
if (rightBound == null) return leftBound <= discount;
|
||||||
|
return leftBound <= discount && discount < rightBound;
|
||||||
|
}
|
||||||
|
private void DisplayList() {
|
||||||
|
var temp = _dataSource;
|
||||||
|
if (SelectedFilterValue > 0) {
|
||||||
|
temp = temp.Where(it => FilterByDiscount(it.DiscountAmount)).ToList();
|
||||||
|
}
|
||||||
|
if (!String.IsNullOrEmpty(SearchWord)) {
|
||||||
|
temp = temp.Where(it => it.Name.Contains(SearchWord, StringComparison.CurrentCultureIgnoreCase)).ToList();
|
||||||
|
}
|
||||||
|
if (SelectedSortValue == 1)
|
||||||
|
{
|
||||||
|
temp = temp.OrderByDescending(it => it.Cost).ToList();
|
||||||
|
}
|
||||||
|
else if (SelectedSortValue == 2) {
|
||||||
|
temp = temp.OrderBy(it => it.Cost).ToList();
|
||||||
|
}
|
||||||
|
this.Products = temp;
|
||||||
|
StatisticText = String.Format("{0} из {1}", temp.Count, _dataSource.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Interaction<OrderShowDialogViewModel, bool> ShowDialog { get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
63
ViewModels/LoginViewModel.cs
Normal file
63
ViewModels/LoginViewModel.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using demo_trade.Domain;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System;
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public class LoginViewModel: ViewModelBase, IRoutableViewModel
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private LoginUseCase _loginUseCase;
|
||||||
|
|
||||||
|
private string _errorMessage = string.Empty;
|
||||||
|
public string ErrorMessage { get => _errorMessage; set => this.RaiseAndSetIfChanged(ref _errorMessage, value); }
|
||||||
|
private UserLogin _userLogin = new();
|
||||||
|
|
||||||
|
public UserLogin UserLogin {
|
||||||
|
get => _userLogin;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _userLogin, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReactiveCommand<Unit, Unit> LoginCommand { get;}
|
||||||
|
public ReactiveCommand<Unit, Unit> GuestCommand { get; }
|
||||||
|
|
||||||
|
public string? UrlPathSegment { get; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
public IScreen HostScreen { get; }
|
||||||
|
|
||||||
|
public LoginViewModel(IScreen screen, ILoginRepository loginRepository) {
|
||||||
|
_loginUseCase = new LoginUseCase(loginRepository);
|
||||||
|
HostScreen = screen;
|
||||||
|
|
||||||
|
LoginCommand = ReactiveCommand.Create(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userLogin = _loginUseCase.AutorizationByLoginAndPassword(_userLogin);
|
||||||
|
SQLProductRepository sqlProductRepository = new SQLProductRepository();
|
||||||
|
HostScreen.Router.Navigate.Execute(new ClientProductViewModel(HostScreen, sqlProductRepository, userLogin));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
ErrorMessage = ex.Message;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
GuestCommand = ReactiveCommand.Create(() => {
|
||||||
|
SQLProductRepository sqlProductRepository = new SQLProductRepository();
|
||||||
|
HostScreen.Router.Navigate.Execute(new GuestProductViewModel(HostScreen, sqlProductRepository));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
ViewModels/MainWindowViewModel.cs
Normal file
19
ViewModels/MainWindowViewModel.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using demo_trade.Data.Repository;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System.Reactive;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public partial class MainWindowViewModel : ReactiveObject, IScreen
|
||||||
|
{
|
||||||
|
public RoutingState Router { get; } = new RoutingState();
|
||||||
|
|
||||||
|
|
||||||
|
public MainWindowViewModel() {
|
||||||
|
SQLLoginRepository loginRepository = new SQLLoginRepository();
|
||||||
|
Router.Navigate.Execute(new LoginViewModel(this, loginRepository));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
ViewModels/OrderManagerViewModel.cs
Normal file
81
ViewModels/OrderManagerViewModel.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
using demo_trade.Domain;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using DynamicData;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public class OrderManagerViewModel : ViewModelBase, IRoutableViewModel
|
||||||
|
{
|
||||||
|
OrderManagerUseCase _orderManagerUseCase;
|
||||||
|
public string? UrlPathSegment { get; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
private ObservableCollection<OrderManager> _orders = new();
|
||||||
|
|
||||||
|
private Dictionary<int, OrderChanged> _changedOrdes = new();
|
||||||
|
|
||||||
|
private List<OrderManager> _dateSource = new();
|
||||||
|
public ObservableCollection<OrderManager> Orders { get => _orders; set => this.RaiseAndSetIfChanged(ref _orders, value); }
|
||||||
|
|
||||||
|
|
||||||
|
private int _selectedSortNumber = 0;
|
||||||
|
public int SelectedSortNumber { get => _selectedSortNumber; set => this.RaiseAndSetIfChanged(ref _selectedSortNumber, value); }
|
||||||
|
|
||||||
|
public IScreen HostScreen { get; }
|
||||||
|
public ReactiveCommand<Unit, Unit> ConfirmChangeCommand { get; }
|
||||||
|
|
||||||
|
public OrderManagerViewModel(IScreen screen, OrderManagerUseCase orderManagerUseCase)
|
||||||
|
{
|
||||||
|
_orderManagerUseCase = orderManagerUseCase;
|
||||||
|
_dateSource = _orderManagerUseCase.GetOrders();
|
||||||
|
this.WhenAnyValue(sort => sort.SelectedSortNumber).Subscribe(_ => DisplayList());
|
||||||
|
ConfirmChangeCommand = ReactiveCommand.Create(() => {
|
||||||
|
if (_changedOrdes.Values.Count == 0) return;
|
||||||
|
_orderManagerUseCase.ChangeOrders(_changedOrdes.Values.ToList());
|
||||||
|
});
|
||||||
|
HostScreen = screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisplayList() {
|
||||||
|
var temp = _dateSource;
|
||||||
|
if (SelectedSortNumber == 1)
|
||||||
|
{
|
||||||
|
temp = temp.OrderByDescending(it => it.OrderSumCost).ToList();
|
||||||
|
}
|
||||||
|
else if (SelectedSortNumber == 2) temp = temp.OrderBy(it => it.OrderSumCost).ToList();
|
||||||
|
_orders.Clear();
|
||||||
|
foreach (var order in temp)
|
||||||
|
{
|
||||||
|
_orders.Add(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OrderDateChanged(int id, DateTimeOffset dateDelivery) {
|
||||||
|
if (dateDelivery.DateTime <= DateTime.Now) return;
|
||||||
|
if (_changedOrdes.ContainsKey(id)) {
|
||||||
|
_changedOrdes[id].OrderDeliveryDate = DateOnly.FromDateTime(dateDelivery.DateTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_changedOrdes.Add(id, new OrderChanged { OrderDeliveryDate = DateOnly.FromDateTime(dateDelivery.DateTime), OrderId= id });
|
||||||
|
}
|
||||||
|
public void OrderStatusChanged(int id, int status)
|
||||||
|
{
|
||||||
|
if (status != 1) return;
|
||||||
|
if (_changedOrdes.ContainsKey(id))
|
||||||
|
{
|
||||||
|
_changedOrdes[id].OrderStatus = "Завершен";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_changedOrdes.Add(id, new OrderChanged { OrderStatus = "Завершен", OrderId = id });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
119
ViewModels/OrderShowDialogViewModel.cs
Normal file
119
ViewModels/OrderShowDialogViewModel.cs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using demo_trade.Data.RemoteData.Entity;
|
||||||
|
using demo_trade.Domain;
|
||||||
|
using demo_trade.Models;
|
||||||
|
using demo_trade.UI.Presenters;
|
||||||
|
using DynamicData;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public class OrderShowDialogViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
|
||||||
|
private OrderClientUseCase _orderClientUseCase;
|
||||||
|
|
||||||
|
private PickupPoint _pickupPointSelected = new();
|
||||||
|
public PickupPoint PickupPointSelected { get => _pickupPointSelected; set => this.RaiseAndSetIfChanged(ref _pickupPointSelected, value); }
|
||||||
|
|
||||||
|
private Models.Order? orderComplete { get; set; } = null;
|
||||||
|
|
||||||
|
private string _userName = String.Empty;
|
||||||
|
public string UserName{ get => _userName; set => this.RaiseAndSetIfChanged(ref _userName, value); }
|
||||||
|
|
||||||
|
private int _numberOrder = 0;
|
||||||
|
public int NumberOrder { get => _numberOrder; set => this.RaiseAndSetIfChanged(ref _numberOrder, value); }
|
||||||
|
|
||||||
|
private int _selectedPointId = 0;
|
||||||
|
public int SelectedPointId { get => _selectedPointId; set => this.RaiseAndSetIfChanged(ref _selectedPointId, value); }
|
||||||
|
|
||||||
|
private List<PickupPoint> _pickupPoints = new();
|
||||||
|
public List<PickupPoint> PickupPoints { get => _pickupPoints; set => this.RaiseAndSetIfChanged(ref _pickupPoints, value); }
|
||||||
|
|
||||||
|
private Decimal _orderSumValue = 0;
|
||||||
|
public Decimal OrderSumValue { get => _orderSumValue; set => this.RaiseAndSetIfChanged(ref _orderSumValue, value); }
|
||||||
|
|
||||||
|
public ReactiveCommand<Unit, Unit> GenerateOrderCommand { get; }
|
||||||
|
|
||||||
|
|
||||||
|
private ObservableCollection<OrderProductPresenter> _productOrderList = new();
|
||||||
|
public ObservableCollection<OrderProductPresenter> ProductOrderList
|
||||||
|
{
|
||||||
|
get => _productOrderList;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _productOrderList, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderShowDialogViewModel( Dictionary<string, (ProductPresenter, int)> orderProducts, OrderClientUseCase orderClientUseCase, User? user = null) {
|
||||||
|
|
||||||
|
_orderClientUseCase = orderClientUseCase;
|
||||||
|
_numberOrder = _orderClientUseCase.GetNewOrderNumber();
|
||||||
|
_pickupPoints = _orderClientUseCase.GetPickupPoints();
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
UserName = String.Format("{0} {1} {2}", user.Usersurname, user.Username, user.Userpatronymic);
|
||||||
|
}
|
||||||
|
GenerateOrderCommand = ReactiveCommand.Create(() => {
|
||||||
|
string? clientName = null;
|
||||||
|
if(!String.IsNullOrEmpty(UserName)) clientName = UserName;
|
||||||
|
var resultOrder = _orderClientUseCase.GenerateNewOrder(PickupPointSelected, ProductOrderList.ToList(),OrderSumValue, clientName);
|
||||||
|
if (resultOrder != null) {
|
||||||
|
NumberOrder = resultOrder.Orderid + 1;
|
||||||
|
orderComplete = resultOrder;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in orderProducts.Values)
|
||||||
|
{
|
||||||
|
ProductOrderList.Add(new OrderProductPresenter(item.Item1, item.Item2));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.WhenAnyValue(it => it.ProductOrderList).Subscribe(it => CalculateOrderSum());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NumericChange(string ArticleProduct, int value) {
|
||||||
|
ProductOrderList.First(it => it.ArticleNumber == ArticleProduct).ProductCount = value;
|
||||||
|
CalculateOrderSum();
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
ProductOrderList.Remove(ProductOrderList.First(it => it.ArticleNumber == ArticleProduct));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveFile(string path) {
|
||||||
|
if (orderComplete == null) return;
|
||||||
|
Ticket ticket = new Ticket()
|
||||||
|
{
|
||||||
|
ClientName = orderComplete.OrderClient,
|
||||||
|
OrderID = orderComplete.Orderid,
|
||||||
|
OrderDate = DateOnly.FromDateTime(DateTime.Now),
|
||||||
|
OrderDelivery = orderComplete.Orderdeliverydate,
|
||||||
|
Products = orderComplete.ProductList,
|
||||||
|
PickupPointName = orderComplete.PickupPointName,
|
||||||
|
OrderSumCost = orderComplete.OrderSumCost
|
||||||
|
}
|
||||||
|
;
|
||||||
|
ticket.GeneratePDF(path);
|
||||||
|
|
||||||
|
}
|
||||||
|
private void CalculateOrderSum() {
|
||||||
|
var orderSum = ProductOrderList.Sum(product => {
|
||||||
|
if (product.CostWithDiscount != null) return product.CostWithDiscount * product.ProductCount;
|
||||||
|
return product.ProductCount * product.Cost;
|
||||||
|
});
|
||||||
|
if (orderSum != null) OrderSumValue = orderSum.Value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
ViewModels/ViewModelBase.cs
Normal file
9
ViewModels/ViewModelBase.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace demo_trade.ViewModels
|
||||||
|
{
|
||||||
|
public class ViewModelBase : ReactiveObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
74
Views/ClientProductControl.axaml
Normal file
74
Views/ClientProductControl.axaml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<UserControl 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"
|
||||||
|
xmlns:vm="using:demo_trade.ViewModels"
|
||||||
|
x:DataType="vm:ClientProductViewModel"
|
||||||
|
xmlns:conv="using:demo_trade.UI.Converters"
|
||||||
|
x:Class="demo_trade.ClientProductControl">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<conv:ItemColorConverter x:Key="itemColorConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid ColumnDefinitions="*" RowDefinitions="50, *, 50" ShowGridLines="True">
|
||||||
|
<StackPanel
|
||||||
|
Margin="5"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Grid.Row="0"
|
||||||
|
Spacing="10">
|
||||||
|
<TextBlock>
|
||||||
|
<TextBlock.Text>
|
||||||
|
<MultiBinding StringFormat="{}{0} {1} {2}">
|
||||||
|
<Binding Path="AutorizedUser.Usersurname"/>
|
||||||
|
<Binding Path="AutorizedUser.Username"/>
|
||||||
|
<Binding Path="AutorizedUser.Userpatronymic"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</TextBlock.Text>
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock Text="{Binding StatisticText}"/>
|
||||||
|
<TextBox Text="{Binding SearchWord}" MinWidth="200"/>
|
||||||
|
<ComboBox MinWidth="100" SelectedIndex="{Binding SelectedFilterValue}">
|
||||||
|
<ComboBoxItem>Все диапазоны</ComboBoxItem>
|
||||||
|
<ComboBoxItem>0-9.99%</ComboBoxItem>
|
||||||
|
<ComboBoxItem>10-14.99%</ComboBoxItem>
|
||||||
|
<ComboBoxItem>15% и болле</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
<ComboBox MinWidth="100" SelectedIndex="{Binding SelectedSortValue}">
|
||||||
|
<ComboBoxItem>отсут.</ComboBoxItem>
|
||||||
|
<ComboBoxItem>по убыв.</ComboBoxItem>
|
||||||
|
<ComboBoxItem>по возраст.</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ListBox ItemsSource="{Binding Products}" Padding="15" Grid.Row="1">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel ContextMenu="" Orientation="Horizontal" Spacing="10" Background="{Binding DiscountAmount, Converter={StaticResource itemColorConverter}}">
|
||||||
|
<StackPanel.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Command="{Binding $parent[ListBox].((vm:ClientProductViewModel)DataContext).AddToOrderCommand}" CommandParameter="{Binding}" Header="Добавить в заказ"/>
|
||||||
|
</ContextMenu>
|
||||||
|
</StackPanel.ContextMenu>
|
||||||
|
<Image/>
|
||||||
|
<StackPanel Orientation="Vertical" >
|
||||||
|
<TextBlock Text="{Binding Name, StringFormat='Название товара: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding Description, StringFormat='Описание товара: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding Manufacturer.Name, StringFormat='Производитель товара: {0}' }"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Border BorderBrush="Black" BorderThickness="2">
|
||||||
|
<TextBlock Text="{Binding DiscountAmount, StringFormat='Скидка: {0}%'}"/>
|
||||||
|
</Border>
|
||||||
|
<TextBlock Text="{Binding Cost, StringFormat='Цена: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding CostWithDiscount, StringFormat='Цена с учетом скидки: {0}'}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
<StackPanel Grid.Row="2">
|
||||||
|
<Button Content="Перейти к заказу" IsVisible="{Binding ThereItemsInOrder}" Command="{Binding AttachToOrderCommand}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
|
||||||
|
<Button Content="Управление заказами" IsVisible="{Binding IsManager}" Command="{Binding AttachToOrderManagerCommand}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
29
Views/ClientProductControl.axaml.cs
Normal file
29
Views/ClientProductControl.axaml.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System.Reactive.Disposables;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade;
|
||||||
|
|
||||||
|
public partial class ClientProductControl : ReactiveUserControl<ClientProductViewModel>
|
||||||
|
{
|
||||||
|
public ClientProductControl()
|
||||||
|
{
|
||||||
|
this.WhenActivated(disposables => disposables(ViewModel!.ShowDialog.RegisterHandler(DoShowOrderDialogAsync)));
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DoShowOrderDialogAsync(InteractionContext<OrderShowDialogViewModel, bool> interaction)
|
||||||
|
{
|
||||||
|
var dialog = new OrderShowDialog();
|
||||||
|
dialog.DataContext = interaction.Input;
|
||||||
|
var result = await dialog.ShowDialog<OrderShowDialogViewModel>(TopLevel.GetTopLevel(this) as Window);
|
||||||
|
interaction.SetOutput(true);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
65
Views/GuestProductControl.axaml
Normal file
65
Views/GuestProductControl.axaml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<UserControl 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"
|
||||||
|
xmlns:vm="using:demo_trade.ViewModels"
|
||||||
|
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||||
|
xmlns:conv="using:demo_trade.UI.Converters"
|
||||||
|
x:DataType="vm:GuestProductViewModel"
|
||||||
|
x:Class="demo_trade.GuestProductControl">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<conv:ItemColorConverter x:Key="itemColorConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid ColumnDefinitions="*" RowDefinitions="50, *, 50" ShowGridLines="True">
|
||||||
|
<StackPanel
|
||||||
|
Margin="5"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Grid.Row="0"
|
||||||
|
Spacing="10">
|
||||||
|
<TextBlock Text="{Binding StatisticText}"/>
|
||||||
|
<TextBox Text="{Binding SearchWord}" MinWidth="200"/>
|
||||||
|
<ComboBox MinWidth="100" SelectedIndex="{Binding SelectedFilterValue}">
|
||||||
|
<ComboBoxItem>Все диапазоны</ComboBoxItem>
|
||||||
|
<ComboBoxItem>0-9.99%</ComboBoxItem>
|
||||||
|
<ComboBoxItem>10-14.99%</ComboBoxItem>
|
||||||
|
<ComboBoxItem>15% и болле</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
<ComboBox MinWidth="100" SelectedIndex="{Binding SelectedSortValue}">
|
||||||
|
<ComboBoxItem>отсут.</ComboBoxItem>
|
||||||
|
<ComboBoxItem>по убыв.</ComboBoxItem>
|
||||||
|
<ComboBoxItem>по возраст.</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ListBox ItemsSource="{Binding Products}" Padding="15" Grid.Row="1">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel ContextMenu="" Orientation="Horizontal" Spacing="10" Background="{Binding DiscountAmount, Converter={StaticResource itemColorConverter}}">
|
||||||
|
<StackPanel.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Command="{Binding $parent[ListBox].((vm:GuestProductViewModel)DataContext).AddToOrderCommand}" CommandParameter="{Binding}" Header="Добавить в заказ"/>
|
||||||
|
</ContextMenu>
|
||||||
|
</StackPanel.ContextMenu>
|
||||||
|
<Image asyncImageLoader:ImageLoader.Source="{Binding Image}" Height="50" Width="50"/>
|
||||||
|
<StackPanel Orientation="Vertical" >
|
||||||
|
<TextBlock Text="{Binding Name, StringFormat='Название товара: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding Description, StringFormat='Описание товара: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding Manufacturer.Name, StringFormat='Производитель товара: {0}' }"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Border BorderBrush="Black" BorderThickness="2">
|
||||||
|
<TextBlock Text="{Binding DiscountAmount, StringFormat='Скидка: {0}%'}"/>
|
||||||
|
</Border>
|
||||||
|
<TextBlock Text="{Binding Cost, StringFormat='Цена: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding CostWithDiscount, StringFormat='Цена с учетом скидки: {0}'}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
<StackPanel Grid.Row="2">
|
||||||
|
<Button Content="Перейти к заказу" IsVisible="{Binding ThereItemsInOrder}" Command="{Binding AttachToOrderCommand}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
28
Views/GuestProductControl.axaml.cs
Normal file
28
Views/GuestProductControl.axaml.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System.Reactive.Disposables;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade;
|
||||||
|
|
||||||
|
public partial class GuestProductControl : ReactiveUserControl<GuestProductViewModel>
|
||||||
|
{
|
||||||
|
public GuestProductControl()
|
||||||
|
{
|
||||||
|
this.WhenActivated(disposables => disposables(ViewModel!.ShowDialog.RegisterHandler(DoShowOrderDialogAsync)));
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DoShowOrderDialogAsync(InteractionContext<OrderShowDialogViewModel, bool> interaction){
|
||||||
|
var dialog = new OrderShowDialog();
|
||||||
|
dialog.DataContext = interaction.Input;
|
||||||
|
var result = await dialog.ShowDialog<OrderShowDialogViewModel>(TopLevel.GetTopLevel(this) as Window);
|
||||||
|
interaction.SetOutput(true);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
22
Views/LoginControl.axaml
Normal file
22
Views/LoginControl.axaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<UserControl 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"
|
||||||
|
xmlns:rxui="http://reactiveui.net"
|
||||||
|
xmlns:vm="using:demo_trade.ViewModels"
|
||||||
|
x:DataType="vm:LoginViewModel"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="demo_trade.LoginControl">
|
||||||
|
<StackPanel Width="200" Spacing="15" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<TextBlock Text="Login"/>
|
||||||
|
<TextBox Text="{Binding UserLogin.Login}"/>
|
||||||
|
<TextBlock Text="Password"/>
|
||||||
|
<TextBox Text="{Binding UserLogin.Password}" PasswordChar="*"/>
|
||||||
|
<TextBlock Text="{Binding ErrorMessage}" Foreground="Red" HorizontalAlignment="Center"/>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="5" HorizontalAlignment="Center">
|
||||||
|
<Button Content="Login" Command="{Binding LoginCommand}"/>
|
||||||
|
<Button Content="Guest" Command="{Binding GuestCommand}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
17
Views/LoginControl.axaml.cs
Normal file
17
Views/LoginControl.axaml.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace demo_trade;
|
||||||
|
|
||||||
|
public partial class LoginControl : ReactiveUserControl<LoginViewModel>
|
||||||
|
{
|
||||||
|
public LoginControl()
|
||||||
|
{
|
||||||
|
this.WhenActivated(disposables => { });
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
21
Views/MainWindow.axaml
Normal file
21
Views/MainWindow.axaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:rxui="http://reactiveui.net"
|
||||||
|
xmlns:app="clr-namespace:demo_trade"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:vm="using:demo_trade.ViewModels"
|
||||||
|
xmlns:local="clr-namespace:demo_trade.UI.Converters;assembly=demo_trade.UI"
|
||||||
|
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="demo_trade.Views.MainWindow"
|
||||||
|
x:DataType="vm:MainWindowViewModel"
|
||||||
|
Icon="/Assets/avalonia-logo.ico"
|
||||||
|
Title="demo_trade">
|
||||||
|
<DockPanel>
|
||||||
|
<rxui:RoutedViewHost Router="{Binding Router}" DockPanel.Dock="Right" Background="AliceBlue">
|
||||||
|
<rxui:RoutedViewHost.ViewLocator>
|
||||||
|
<app:ViewLocator />
|
||||||
|
</rxui:RoutedViewHost.ViewLocator>
|
||||||
|
</rxui:RoutedViewHost>
|
||||||
|
</DockPanel>
|
||||||
|
</Window>
|
23
Views/MainWindow.axaml.cs
Normal file
23
Views/MainWindow.axaml.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Reactive.Disposables;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace demo_trade.Views
|
||||||
|
{
|
||||||
|
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
|
||||||
|
{
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
this.WhenActivated(disposables => { });
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
47
Views/OrderManagerControl.axaml
Normal file
47
Views/OrderManagerControl.axaml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<UserControl 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"
|
||||||
|
xmlns:vm="using:demo_trade.ViewModels"
|
||||||
|
x:DataType="vm:OrderManagerViewModel"
|
||||||
|
xmlns:conv="using:demo_trade.UI.Converters"
|
||||||
|
x:Class="demo_trade.OrderManagerControl">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<conv:ItemDateConverter x:Key="itemDateConverter"/>
|
||||||
|
<conv:ItemColorOrderConverter x:Key="itemColorOrderConverter"/>
|
||||||
|
<conv:ItemComboboxConverter x:Key="itemComboboxConverter"/>
|
||||||
|
<conv:ItemEnableConverterByDate x:Key="itemEnableConverterByDate"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<DockPanel>
|
||||||
|
|
||||||
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" >
|
||||||
|
<ComboBox MinWidth="100" SelectedIndex="{Binding SelectedSortNumber}">
|
||||||
|
<ComboBoxItem>отсут.</ComboBoxItem>
|
||||||
|
<ComboBoxItem>по убыв.</ComboBoxItem>
|
||||||
|
<ComboBoxItem>по возраст.</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Center">
|
||||||
|
<Button Content="Применить" Command="{Binding ConfirmChangeCommand}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<ListBox ItemsSource="{Binding Orders}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<WrapPanel Orientation="Vertical" Background="{Binding ProductStock, Converter={StaticResource itemColorOrderConverter}}">
|
||||||
|
<TextBlock Text="{Binding Orderid, StringFormat='Номер заказа: {0}'}"/>
|
||||||
|
<ComboBox SelectedIndex="{Binding Orderstatus, Converter={StaticResource itemComboboxConverter}}" IsEnabled="{Binding Orderdeliverydate, Converter={StaticResource itemEnableConverterByDate}}" Tag="{Binding Orderid}" SelectionChanged="StatusComboBox_SelectionChanged">
|
||||||
|
<ComboBoxItem>Новый</ComboBoxItem>
|
||||||
|
<ComboBoxItem>Завершен</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
<DatePicker SelectedDate="{Binding Orderdeliverydate, Converter={StaticResource itemDateConverter}}" Tag="{Binding Orderid}" SelectedDateChanged="DeliveryDatePicker_SelectedDateChanged"/>
|
||||||
|
<TextBlock Text="{Binding PickupPointName, StringFormat='Пункт выдачи:{0}'}"/>
|
||||||
|
<TextBlock Text="{Binding OrderSumCost, StringFormat='Сумма заказа: {0}'}" IsVisible="{Binding OrderSumCost, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||||||
|
<TextBlock Text="{Binding OrderClient, StringFormat='Клиент: {0}'}" IsVisible="{Binding OrderClient, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||||||
|
<TextBlock Text="{Binding ProductList}"/>
|
||||||
|
</WrapPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</DockPanel>
|
||||||
|
</UserControl>
|
36
Views/OrderManagerControl.axaml.cs
Normal file
36
Views/OrderManagerControl.axaml.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace demo_trade;
|
||||||
|
|
||||||
|
public partial class OrderManagerControl : ReactiveUserControl<OrderManagerViewModel>
|
||||||
|
{
|
||||||
|
public OrderManagerControl()
|
||||||
|
{
|
||||||
|
this.WhenActivated(disposables => { });
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeliveryDatePicker_SelectedDateChanged(object? sender, Avalonia.Controls.DatePickerSelectedValueChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var datePicker = (DatePicker)sender;
|
||||||
|
int? orderId = datePicker.Tag as int?;
|
||||||
|
if (orderId != null && datePicker.SelectedDate != null && datePicker.IsEnabled) {
|
||||||
|
ViewModel.OrderDateChanged(orderId.Value, datePicker.SelectedDate.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StatusComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var comboBox = (ComboBox)sender;
|
||||||
|
int? orderId = comboBox.Tag as int?;
|
||||||
|
if (orderId != null && comboBox.SelectedIndex > 0 && comboBox.IsEnabled)
|
||||||
|
{
|
||||||
|
ViewModel.OrderStatusChanged(orderId.Value, comboBox.SelectedIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
Views/OrderShowDialog.axaml
Normal file
57
Views/OrderShowDialog.axaml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<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="demo_trade.OrderShowDialog"
|
||||||
|
xmlns:vm="using:demo_trade.ViewModels"
|
||||||
|
x:DataType="vm:OrderShowDialogViewModel"
|
||||||
|
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||||
|
Title="OrderShowDialog">
|
||||||
|
|
||||||
|
<DockPanel>
|
||||||
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Spacing="20" HorizontalAlignment="Center">
|
||||||
|
<TextBlock IsVisible="{Binding UserName, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" Text="{Binding UserName, StringFormat='Пользователь: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding OrderSumValue, StringFormat='Общая сумма: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding NumberOrder, StringFormat='Номер заказа: {0}'}"/>
|
||||||
|
<ComboBox ItemsSource="{Binding PickupPoints}" SelectedItem="{Binding PickupPointSelected}" SelectedIndex="{Binding SelectedPointId}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock>
|
||||||
|
<TextBlock.Text >
|
||||||
|
<MultiBinding StringFormat="№{0}: {1}">
|
||||||
|
<Binding Path="PickupPointId"/>
|
||||||
|
<Binding Path="PickupPointName"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</TextBlock.Text>
|
||||||
|
</TextBlock>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
<TextBlock/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel DockPanel.Dock="Bottom">
|
||||||
|
<Button Content="Сформировать заказ" HorizontalAlignment="Center" Command="{Binding GenerateOrderCommand}" Click="Save_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
<ListBox ItemsSource="{Binding ProductOrderList}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel ContextMenu="" Orientation="Horizontal" Spacing="10">
|
||||||
|
<Image asyncImageLoader:ImageLoader.Source="{Binding Image}" Height="50" Width="50"/>
|
||||||
|
<StackPanel Orientation="Vertical" >
|
||||||
|
<TextBlock Text="{Binding Name, StringFormat='Название товара: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding Description, StringFormat='Описание товара: {0}'}"/>
|
||||||
|
<TextBlock Text="{Binding Manufacturer.Name, StringFormat='Производитель товара: {0}' }"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Border BorderBrush="Black" BorderThickness="2">
|
||||||
|
<TextBlock Text="{Binding DiscountAmount, StringFormat='Скидка: {0}%'}"/>
|
||||||
|
</Border>
|
||||||
|
<TextBlock Text="{Binding Cost, StringFormat='Цена: {0}'}"/>
|
||||||
|
<NumericUpDown Value="{Binding ProductCount}" Tag="{Binding ArticleNumber}" Minimum="0" Maximum="{Binding QuantityInStock}" ValueChanged="NumericUpDown_ValueChanged"/>
|
||||||
|
<TextBlock Text="{Binding CostWithDiscount, StringFormat='Цена с учетом скидки: {0}'}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</DockPanel>
|
||||||
|
</Window>
|
42
Views/OrderShowDialog.axaml.cs
Normal file
42
Views/OrderShowDialog.axaml.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Dialogs.Internal;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.Platform.Storage;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
using demo_trade.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Tmds.DBus.Protocol;
|
||||||
|
|
||||||
|
namespace demo_trade;
|
||||||
|
|
||||||
|
public partial class OrderShowDialog : ReactiveWindow<OrderShowDialogViewModel>
|
||||||
|
{
|
||||||
|
public OrderShowDialog()
|
||||||
|
{
|
||||||
|
this.WhenActivated(disposables => { });
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NumericUpDown_ValueChanged(object? sender, Avalonia.Controls.NumericUpDownValueChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var numeric = (sender as NumericUpDown);
|
||||||
|
if (numeric.Tag == null) return;
|
||||||
|
string? aritcle = numeric.Tag.ToString();
|
||||||
|
if (numeric.Value == null) return;
|
||||||
|
ViewModel.NumericChange(aritcle, (int)numeric.Value );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FilePickerFileType Pdf { get; } = new FilePickerFileType("All pdf") { Patterns = new[] { ".pdf" } };
|
||||||
|
|
||||||
|
private async void Save_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var file = await TopLevel.GetTopLevel(this).StorageProvider.SaveFilePickerAsync(new Avalonia.Platform.Storage.FilePickerSaveOptions
|
||||||
|
{
|
||||||
|
Title = "Ñîõðàíèòü òàëîí",
|
||||||
|
FileTypeChoices = new List<FilePickerFileType> { Pdf }
|
||||||
|
});
|
||||||
|
if (file != null) ViewModel!.SaveFile(file.Path.AbsolutePath);
|
||||||
|
}
|
||||||
|
}
|
18
app.manifest
Normal file
18
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="demo_trade.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>
|
BIN
bin/Debug/net8.0/A543T6.jpg
Normal file
BIN
bin/Debug/net8.0/A543T6.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 241 KiB |
BIN
bin/Debug/net8.0/AsyncImageLoader.Avalonia.dll
Normal file
BIN
bin/Debug/net8.0/AsyncImageLoader.Avalonia.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Base.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Base.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Controls.ColorPicker.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Controls.ColorPicker.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Controls.DataGrid.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Controls.DataGrid.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Controls.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Controls.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.DesignerSupport.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.DesignerSupport.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Desktop.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Desktop.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Diagnostics.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Diagnostics.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Dialogs.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Dialogs.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Fonts.Inter.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Fonts.Inter.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.FreeDesktop.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.FreeDesktop.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Markup.Xaml.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Markup.Xaml.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Markup.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Markup.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Metal.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Metal.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.MicroCom.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.MicroCom.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Native.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Native.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.OpenGL.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.OpenGL.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.ReactiveUI.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.ReactiveUI.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Remote.Protocol.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Remote.Protocol.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Skia.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Skia.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Themes.Fluent.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Themes.Fluent.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Themes.Simple.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Themes.Simple.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Vulkan.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Vulkan.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.Win32.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.Win32.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.X11.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.X11.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Avalonia.dll
Normal file
BIN
bin/Debug/net8.0/Avalonia.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/BouncyCastle.Cryptography.dll
Normal file
BIN
bin/Debug/net8.0/BouncyCastle.Cryptography.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/CommunityToolkit.Mvvm.dll
Normal file
BIN
bin/Debug/net8.0/CommunityToolkit.Mvvm.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/D419T7.png
Normal file
BIN
bin/Debug/net8.0/D419T7.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
BIN
bin/Debug/net8.0/DynamicData.dll
Normal file
BIN
bin/Debug/net8.0/DynamicData.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/HarfBuzzSharp.dll
Normal file
BIN
bin/Debug/net8.0/HarfBuzzSharp.dll
Normal file
Binary file not shown.
BIN
bin/Debug/net8.0/Humanizer.dll
Normal file
BIN
bin/Debug/net8.0/Humanizer.dll
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user