diff --git a/.gitignore b/.gitignore
index 02b32dc..cc7298e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+ConnectionString.txt
+
# User-specific files
*.rsuser
*.suo
@@ -365,3 +367,5 @@ FodyWeavers.xsd
.csproj
/Gallium v1/Data/ConnexionDAO.cs
/Gallium v1/Data/InformatioConnexion.cs
+
+.idea
\ No newline at end of file
diff --git a/Couche IHM/Couche Data/Couche Data.csproj b/Couche IHM/Couche Data/Couche Data.csproj
index 3e3f7b3..a05696a 100644
--- a/Couche IHM/Couche Data/Couche Data.csproj
+++ b/Couche IHM/Couche Data/Couche Data.csproj
@@ -8,6 +8,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Couche IHM/Couche Data/Dao/UserDAO.cs b/Couche IHM/Couche Data/Dao/AccountDAO.cs
similarity index 50%
rename from Couche IHM/Couche Data/Dao/UserDAO.cs
rename to Couche IHM/Couche Data/Dao/AccountDAO.cs
index dad4623..cfbf1cd 100644
--- a/Couche IHM/Couche Data/Dao/UserDAO.cs
+++ b/Couche IHM/Couche Data/Dao/AccountDAO.cs
@@ -5,17 +5,16 @@
namespace Couche_Data.Dao
{
-
- public class UserDAO : IUserDAO
+ public class AccountDAO : IAccountDao
{
- public void CreateCompte(User compte)
+ public void CreateAdhérent(Account adhérent)
{
//Connection
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm = $"INSERT INTO users VALUES (0,'{compte.Prenom}','{compte.Nom}','{compte.Mail}','{compte.HashedPassword}',{compte.IdRole})";
+ string stm = $"INSERT INTO User VALUES (0,'{adhérent.Identifiant}','{adhérent.Prenom}','{adhérent.Nom}','{adhérent.Mail}',{adhérent.RoleId},'{adhérent.Formation}',{adhérent.Argent},{adhérent.IsMember},' ',' ','2030-11-25 00:00:00')";
MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
@@ -24,87 +23,94 @@ public void CreateCompte(User compte)
using (MySqlCommand selectCommand = new MySqlCommand("SELECT LAST_INSERT_ID() AS nouvel_id", dbsDAO.Instance.Sql))
{
int nouvelId = Convert.ToInt32(selectCommand.ExecuteScalar());
- compte.ID = nouvelId;
-
+ adhérent.Id = nouvelId;
}
+
dbsDAO.Instance.CloseDatabase();
}
- public List GetComptes()
+
+ public List GetAdhérents()
{
//Connection
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm = "SELECT * FROM users ORDER BY firstname";
+ string stm = "SELECT * FROM User ORDER BY userId";
MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
//lecture de la requette
MySqlDataReader rdr = cmd.ExecuteReader();
- List users = new List();
+
+ List acomptes = new List();
while (rdr.Read())
{
- users.Add(new User(rdr.GetInt32("user_id"), rdr.GetString("lastname"), rdr.GetString("firstname"), rdr.GetString("email"), rdr.GetString("password"), rdr.GetInt16("grade_id")));
+ acomptes.Add(new Account(rdr.GetInt32("id"), rdr.GetString("userId"), rdr.GetString("lastName"), rdr.GetString("firstName"), rdr.GetString("email"), rdr.GetFloat("deposit"),rdr.GetString("year"),rdr.GetBoolean("isMember"), rdr.GetInt16("role")));
}
-
+ rdr.Close();
dbsDAO.Instance.CloseDatabase();
- return users;
+ return acomptes;
}
+
public List GetRoles()
{
+ //Connection
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm2 = "SELECT * FROM grades";
- MySqlCommand cmd2 = new MySqlCommand(stm2, dbsDAO.Instance.Sql);
- cmd2.Prepare();
+ string stm = "SELECT * FROM Role";
+ MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
+ cmd.Prepare();
//lecture de la requette
- MySqlDataReader rdr2 = cmd2.ExecuteReader();
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
List roles = new List();
- while (rdr2.Read())
+ while (rdr.Read())
{
- roles.Add(new Role(rdr2.GetInt32("grade_id"), rdr2.GetString("name")));
+ roles.Add(new Role(rdr.GetInt32("id"), rdr.GetString("name")));
}
- rdr2.Close();
+
+ rdr.Close();
dbsDAO.Instance.CloseDatabase();
return roles;
}
- public void RemoveCompte(User compte)
+ public void RemoveAdhérent(Account adhérent)
{
//Connection
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm = $"DELETE FROM users WHERE user_id = {compte.ID}";
+ string stm = $"DELETE FROM User WHERE id = {adhérent.Id}";
MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
+ //lecture de la requette
cmd.ExecuteNonQuery();
dbsDAO.Instance.CloseDatabase();
}
-
- public void UpdateCompte(User compte)
+ public void UpdateAdhérent(Account adhérent)
{
//Connection
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm = $"UPDATE users SET firstname = '{compte.Prenom}',lastname = '{compte.Nom}',email = '{compte.Mail}',password = '{compte.HashedPassword}',grade_id = {compte.IdRole} WHERE user_id = {compte.ID}";
+
+ string formattedAmountMoney = adhérent.Argent.ToString(System.Globalization.CultureInfo.InvariantCulture);
+ string stm = $"UPDATE User set lastName = '{adhérent.Nom}', firstName = '{adhérent.Prenom}', deposit = {formattedAmountMoney}, isMember = {adhérent.IsMember}, role = {adhérent.RoleId} , email = '{adhérent.Mail}' ,year = '{adhérent.Formation}',password = '{adhérent.HashedPassword}', userId = '{adhérent.Identifiant}' WHERE id = {adhérent.Id}";
MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
-
+
+ //lecture de la requette
cmd.ExecuteNonQuery();
dbsDAO.Instance.CloseDatabase();
- }
-
+ }
}
-
}
diff --git a/Couche IHM/Couche Data/Dao/AcompteDAO.cs b/Couche IHM/Couche Data/Dao/AcompteDAO.cs
deleted file mode 100644
index 8ecb5ef..0000000
--- a/Couche IHM/Couche Data/Dao/AcompteDAO.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-
-using Couche_Data.Interfaces;
-using Modeles;
-using MySql.Data.MySqlClient;
-
-namespace Couche_Data.Dao
-{
- public class AcompteDAO : IAcompteDao
- {
-
- public void CreateAdhérent(Acompte adhérent)
- {
- //Connection
- dbsDAO.Instance.OpenDataBase();
-
- //Requette SQL
- string stm = $"INSERT INTO acompte VALUES (0,'{adhérent.Nom}','{adhérent.Prenom}',{adhérent.Argent},{adhérent.StillAdherent},'{adhérent.Formation}','{adhérent.Identifiant}')";
- MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
- cmd.Prepare();
-
- //lecture de la requette
- cmd.ExecuteNonQuery();
- using (MySqlCommand selectCommand = new MySqlCommand("SELECT LAST_INSERT_ID() AS nouvel_id", dbsDAO.Instance.Sql))
- {
- int nouvelId = Convert.ToInt32(selectCommand.ExecuteScalar());
- adhérent.Id = nouvelId;
- }
-
- dbsDAO.Instance.CloseDatabase();
- }
-
-
- public List GetAdhérents()
- {
- //Connection
- dbsDAO.Instance.OpenDataBase();
-
- //Requette SQL
- string stm = "SELECT * FROM acompte ORDER BY login";
- MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
- cmd.Prepare();
-
- //lecture de la requette
- MySqlDataReader rdr = cmd.ExecuteReader();
-
- List acomptes = new List();
- while (rdr.Read())
- {
- acomptes.Add(new Acompte(rdr.GetInt32("acompte_id"), rdr.GetString("login"), rdr.GetString("nom"), rdr.GetString("prenom"), rdr.GetFloat("balance"), rdr.GetString("formation"),rdr.GetBoolean("isAdherent")));
- }
-
- rdr.Close();
- dbsDAO.Instance.CloseDatabase();
- return acomptes;
- }
-
- public void RemoveAdhérent(Acompte adhérent)
- {
- //Connection
- dbsDAO.Instance.OpenDataBase();
-
- //Requette SQL
- string stm = $"DELETE FROM acompte WHERE acompte_id = {adhérent.Id}";
- MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
- cmd.Prepare();
-
- //lecture de la requette
- cmd.ExecuteNonQuery();
-
- dbsDAO.Instance.CloseDatabase();
- }
-
- public void UpdateAdhérent(Acompte adhérent)
- {
- //Connection
- dbsDAO.Instance.OpenDataBase();
-
- //Requette SQL
- string formattedAmountMoney = adhérent.Argent.ToString(System.Globalization.CultureInfo.InvariantCulture);
- string stm = $"UPDATE acompte set nom = '{adhérent.Nom}', prenom = '{adhérent.Prenom}', balance = {formattedAmountMoney}, isAdherent = {adhérent.StillAdherent}, formation = '{adhérent.Formation}', login = '{adhérent.Identifiant}' WHERE acompte_id = {adhérent.Id}";
- MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
- cmd.Prepare();
-
- //lecture de la requette
- cmd.ExecuteNonQuery();
-
- dbsDAO.Instance.CloseDatabase();
-
- }
- }
-}
diff --git a/Couche IHM/Couche Data/Dao/CachedLogReader.cs b/Couche IHM/Couche Data/Dao/CachedLogReader.cs
new file mode 100644
index 0000000..734234a
--- /dev/null
+++ b/Couche IHM/Couche Data/Dao/CachedLogReader.cs
@@ -0,0 +1,68 @@
+using Couche_Data.Interfaces;
+using Modeles;
+using System.Threading.Tasks.Dataflow;
+
+namespace Couche_Data.Dao
+{
+ public class CachedLogReader : IPaginatedLogReader
+ {
+ private List allLogs;
+ private BufferBlock buffer;
+ private int pageSize;
+ private int pageIndex;
+ private bool exhausted;
+ private object loadLock;
+
+ public CachedLogReader(int pageSize, List allLogs)
+ {
+ this.allLogs = allLogs;
+ buffer = new BufferBlock();
+ this.pageSize = pageSize;
+ pageIndex = 0;
+ exhausted = false;
+ loadLock = new object();
+ }
+
+ public int PageSize => pageSize;
+
+ public IAsyncEnumerable GetAsyncStream(CancellationToken ct = default) => buffer.ReceiveAllAsync(ct);
+
+ public void LoadNextPage()
+ {
+ lock (loadLock)
+ {
+ if (!exhausted)
+ {
+ int pageStart = pageIndex * pageSize;
+ int pageEnd = pageStart + pageSize;
+
+ if (pageEnd > allLogs.Count)
+ {
+ pageEnd = allLogs.Count;
+ exhausted = true;
+ }
+ else
+ {
+ pageIndex++;
+ }
+
+ for (int i = pageStart; i < pageEnd; i++)
+ {
+ buffer.Post(allLogs[i]);
+ }
+ }
+ }
+ }
+
+ public void Reset()
+ {
+ // désactiver l'ancien tampon et en créer un nouveau
+ buffer.Complete();
+ buffer = new BufferBlock();
+
+ // remettre le curseur au début
+ pageIndex = 0;
+ exhausted = false;
+ }
+ }
+}
diff --git a/Couche IHM/Couche Data/Dao/LogDAO.cs b/Couche IHM/Couche Data/Dao/LogDAO.cs
index 05df1bd..4983bf6 100644
--- a/Couche IHM/Couche Data/Dao/LogDAO.cs
+++ b/Couche IHM/Couche Data/Dao/LogDAO.cs
@@ -1,45 +1,48 @@
-using Modeles;
+using Couche_Data.Interfaces;
+using Modeles;
using MySql.Data.MySqlClient;
namespace Couche_Data.Dao
{
- public class LogDAO
+ public class LogDAO : ILogDAO
{
public void CreateLog(Log log)
{
- lock (dbsDAO.Instance.DatabaseLock)
- {
- //Connection
- dbsDAO.Instance.OpenDataBase();
+ string connString = dbsDAO.ConnectionString;
+ MySqlConnection sql = new MySqlConnection(connString);
- //Requette SQL
- string formattedDate = log.Date.ToString("yyyy-MM-dd HH:mm:ss");
- string stm = $"INSERT INTO logs VALUES(0,'{log.Message}','{formattedDate}',{log.Theme},'{log.Auteur}')";
- MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
- cmd.Prepare();
+ //Connection
+ sql.Open();
- //lecture de la requette
- cmd.ExecuteNonQuery();
+ //Requette SQL
+ string formattedDate = log.Date.ToString("yyyy-MM-dd HH:mm:ss");
+ string stm = $"INSERT INTO logs VALUES(0,@message,'{formattedDate}',{log.Theme},'{log.Auteur}')";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Parameters.AddWithValue("@message", log.Message);
+ cmd.Prepare();
- dbsDAO.Instance.CloseDatabase();
- }
+ //lecture de la requette
+ cmd.ExecuteNonQuery();
+
+ sql.Close();
+
}
- public List GetLogs(int mois,int annee)
+ public List GetLogs(int mois, int annee)
{
//Connection
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_gallium", "none");
+ string connString = dbsDAO.ConnectionString;
MySqlConnection sql = new MySqlConnection(connString);
sql.Open();
//Requette SQL
- string stm = $"SELECT * FROM Logs WHERE YEAR(date_at) = {annee} AND MONTH(date_at) = {mois} ORDER BY date_at DESC";
+ string stm = $"SELECT * FROM logs WHERE YEAR(date_at) = {annee} AND MONTH(date_at) = {mois} ORDER BY date_at DESC";
MySqlCommand cmd = new MySqlCommand(stm, sql);
cmd.Prepare();
//lecture de la requette
- MySqlDataReader rdr = cmd.ExecuteReader();
+ MySqlDataReader rdr = cmd.ExecuteReader();
List logs = new List();
while (rdr.Read())
@@ -51,9 +54,9 @@ public List GetLogs(int mois,int annee)
return logs;
}
-
-
-
-
+ public IPaginatedLogReader GetLogsReader(int mois, int annee)
+ {
+ return new CachedLogReader(20, this.GetLogs(mois, annee));
+ }
}
}
diff --git a/Couche IHM/Couche Data/Dao/OrderDAO.cs b/Couche IHM/Couche Data/Dao/OrderDAO.cs
new file mode 100644
index 0000000..dcf975a
--- /dev/null
+++ b/Couche IHM/Couche Data/Dao/OrderDAO.cs
@@ -0,0 +1,78 @@
+using Couche_Data.Interfaces;
+using Modeles;
+using MySql.Data.MySqlClient;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Couche_Data.Dao
+{
+ public class OrderDAO : IOrderDao
+ {
+ public void ProcessOrder(Order order)
+ {
+ //Connection
+ dbsDAO.Instance.OpenDataBase();
+
+ float prix = 0;
+ //Requette SQL
+ for (int i=0; i GetProducts()
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm = "SELECT * FROM products ORDER BY name";
+ string stm = "SELECT * FROM Product ORDER BY name";
MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
@@ -50,8 +50,8 @@ public List GetProducts()
while (rdr.Read())
{
- int categoryId = rdr.IsDBNull(rdr.GetOrdinal("category_id")) ? -1 : rdr.GetInt32("category_id");
- products.Add(new Product(rdr.GetInt32("product_id"), rdr.GetString("name"), rdr.GetInt32("stock"), rdr.GetFloat("price_na"), rdr.GetFloat("price_a"), categoryId));
+ int categoryId = rdr.IsDBNull(rdr.GetOrdinal("category")) ? -1 : rdr.GetInt32("category");
+ products.Add(new Product(rdr.GetInt32("id"), rdr.GetString("name"), rdr.GetInt32("stock"), rdr.GetFloat("nonMemberPrice"), rdr.GetFloat("memberPrice"), categoryId));
}
rdr.Close();
dbsDAO.Instance.CloseDatabase();
@@ -64,7 +64,7 @@ public void RemoveProduct(Product product)
dbsDAO.Instance.OpenDataBase();
//Requette SQL
- string stm = $"DELETE FROM products WHERE product_id = {product.ID}";
+ string stm = $"DELETE FROM Product WHERE id = {product.ID}";
MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
@@ -77,22 +77,21 @@ public void RemoveProduct(Product product)
public void UpdateProduct(Product product)
{
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_etismash", "none");
- MySqlConnection sql = new MySqlConnection(connString);
- sql.Open();
+ //Connection
+ dbsDAO.Instance.OpenDataBase();
//Requette SQL
string prixA = product.PrixAdherent.ToString(System.Globalization.CultureInfo.InvariantCulture);
string prixNA = product.PrixNonAdherent.ToString(System.Globalization.CultureInfo.InvariantCulture);
- string stm = $"UPDATE products SET name = '{product.NomProduit}', stock = {product.Quantite}, price_a = {prixA}, price_na = {prixNA}, category_id = {product.Categorie} WHERE product_id = {product.ID}";
- MySqlCommand cmd = new MySqlCommand(stm, sql);
+ string stm = $"UPDATE Product SET name = '{product.NomProduit}', stock = {product.Quantite}, memberPrice = {prixA}, nonMemberPrice = {prixNA}, category = {product.Categorie} WHERE id = {product.ID}";
+ MySqlCommand cmd = new MySqlCommand(stm, dbsDAO.Instance.Sql);
cmd.Prepare();
//lecture de la requette
cmd.ExecuteNonQuery();
- sql.Close();
-
+ dbsDAO.Instance.CloseDatabase();
+
}
}
diff --git a/Couche IHM/Couche Data/Dao/StatAcompteDAO.cs b/Couche IHM/Couche Data/Dao/StatAcompteDAO.cs
index 73749fa..61e2a40 100644
--- a/Couche IHM/Couche Data/Dao/StatAcompteDAO.cs
+++ b/Couche IHM/Couche Data/Dao/StatAcompteDAO.cs
@@ -1,57 +1,175 @@
-using Modeles;
+using Couche_Data.Interfaces;
+using Modeles;
using MySql.Data.MySqlClient;
-
+using System.Diagnostics;
namespace Couche_Data.Dao
{
- public class StatAcompteDAO
+ public class StatAccountDAO : IStatAccountDAO
{
- public List GetStat()
+ public List GetStatByWeek(int semaine, int year)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE WEEK(date) = {semaine} AND " +
+ $"YEAR(date) = {year} group by acompte_id order by argent desc";
+
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatByMonth(int month, int year)
{
//Connection
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_etismash", "none");
- MySqlConnection sql = new MySqlConnection(connString);
- sql.Open();
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
- //Requette SQL
- string stm = "SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE YEARWEEK(date) = YEARWEEK(CURRENT_DATE) group by acompte_id order by argent desc";
- MySqlCommand cmd = new MySqlCommand(stm, sql);
- cmd.Prepare();
+ //Requette SQL
+ string stm = $"SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE month(date) = {month} AND " +
+ $"YEAR(date) = {year} group by acompte_id order by argent desc";
- //lecture de la requette
- MySqlDataReader rdr = cmd.ExecuteReader();
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
- List statAcompteList = new List();
- while (rdr.Read())
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
{
- statAcompteList.Add(new StatAcompte(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt16("acompte_id")));
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
}
+ }
+
+ public List GetStatByYear(int year)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
- rdr.Close();
- sql.Close();
- return statAcompteList;
+ //Requette SQL
+ string stm = $"SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE " +
+ $"YEAR(date) = {year} group by acompte_id order by argent desc";
+
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
}
+ public void CreateStat(StatAccount stat)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string formattedDate = stat.Date.ToString("yyyy-MM-dd");
+ string formattedAmountMoney = stat.Money.ToString(System.Globalization.CultureInfo.InvariantCulture);
+ string stm = $"INSERT INTO best_acomptes VALUES(0,{formattedAmountMoney},'{formattedDate}',{stat.Account_Id})";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+ //lecture de la requette
+ cmd.ExecuteNonQuery();
- public void CreateStat(StatAcompte stat)
+ sql.Close();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant l'ajout d'une stat acompte : {ex.Message}");
+ }
+ }
+
+ public List GetStatBOfAcompteByMonth(int year, int acompte_id)
{
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_etismash", "none");
- MySqlConnection sql = new MySqlConnection(connString);
- sql.Open();
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
- //Requette SQL
- string formattedDate = stat.Date.ToString("yyyy-MM-dd");
- string formattedAmountMoney = stat.Money.ToString(System.Globalization.CultureInfo.InvariantCulture);
- string stm = $"INSERT INTO best_acomptes VALUES(0,{formattedAmountMoney},'{formattedDate}',{stat.Acompte_Id})";
- MySqlCommand cmd = new MySqlCommand(stm, sql);
- cmd.Prepare();
+ //Requette SQL
- //lecture de la requette
- cmd.ExecuteNonQuery();
+ string stm = $"SELECT NVL(acompte_id,{acompte_id}) as acompte_id,lm.mois as date,NVL(SUM(bs.amount), 0) AS argent FROM ( SELECT 1 AS mois UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) lm LEFT JOIN best_acomptes bs ON MONTH(bs.date) = lm.mois AND YEAR(bs.date) = {year} AND bs.acompte_id = {acompte_id} GROUP BY lm.mois ORDER BY lm.mois;";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
- sql.Close();
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, new DateTime(year, rdr.GetInt16("date"), 1), rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
}
}
}
diff --git a/Couche IHM/Couche Data/Dao/StatProduitDAO.cs b/Couche IHM/Couche Data/Dao/StatProduitDAO.cs
index dd329d0..d6a4aa8 100644
--- a/Couche IHM/Couche Data/Dao/StatProduitDAO.cs
+++ b/Couche IHM/Couche Data/Dao/StatProduitDAO.cs
@@ -1,57 +1,163 @@
-using Modeles;
+using Couche_Data.Interfaces;
+using Modeles;
using MySql.Data.MySqlClient;
-
+using System.Diagnostics;
namespace Couche_Data.Dao
{
- public class StatProduitDAO
+ public class StatProduitDAO : IStatProduitDAO
{
+ public List GetStatByYear(int year)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE YEAR(date_sale) = {year} group by product_id order by nb desc";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
+ }
- public List GetStat()
+ public List GetStatByWeek(int semaine, int year)
{
- //Connection
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_etismash", "none");
- MySqlConnection sql = new MySqlConnection(connString);
- sql.Open();
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE week(date_sale) = {semaine} AND YEAR(date_sale) = {year} group by product_id order by nb desc";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
- //Requette SQL
- string stm = "SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE YEARWEEK(date_sale) = YEARWEEK(CURRENT_DATE) group by product_id order by nb desc";
- MySqlCommand cmd = new MySqlCommand(stm, sql);
- cmd.Prepare();
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
- //lecture de la requette
- MySqlDataReader rdr = cmd.ExecuteReader();
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
- List statProduitList = new List();
- while (rdr.Read())
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
{
- statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
}
+ }
+
+ public void CreateStat(StatProduit stat)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
- rdr.Close();
- sql.Close();
- return statProduitList;
+ //Requette SQL
+ string formattedDate = stat.Date.ToString("yyyy-MM-dd");
+ string stm = $"INSERT INTO best_sales VALUES(0,'{formattedDate}',{stat.Number_sales},{stat.Product_id})";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ cmd.ExecuteNonQuery();
+
+ sql.Close();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant l'ajout d'une stat produit : {ex.Message}");
+ }
}
+ public List GetStatByMonth(int month, int year)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
+ //Requette SQL
+ string stm = $"SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE month(date_sale) = {month} AND YEAR(date_sale) = {year} group by product_id order by nb desc";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
- public void CreateStat(StatProduit stat)
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatBOfProductByMonth(int year,int product_id)
{
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_etismash", "none");
- MySqlConnection sql = new MySqlConnection(connString);
- sql.Open();
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionString);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT NVL(product_id,{product_id}) as product_id,lm.mois as date,NVL(SUM(bs.number_sales), 0) AS nb FROM ( SELECT 1 AS mois UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) lm LEFT JOIN best_sales bs ON MONTH(bs.date_sale) = lm.mois AND YEAR(bs.date_sale) = {year} AND bs.product_id = {product_id} GROUP BY lm.mois ORDER BY lm.mois;";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
- //Requette SQL
- string formattedDate = stat.Date.ToString("yyyy-MM-dd");
- string stm = $"INSERT INTO best_sales VALUES(0,'{formattedDate}',{stat.Number_sales},{stat.Product_id})";
- MySqlCommand cmd = new MySqlCommand(stm, sql);
- cmd.Prepare();
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
- //lecture de la requette
- cmd.ExecuteNonQuery();
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, rdr.GetDateTime("date"), rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
- sql.Close();
-
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
}
}
}
diff --git a/Couche IHM/Couche Data/Dao/dbsDAO.cs b/Couche IHM/Couche Data/Dao/dbsDAO.cs
index 4664d20..c178921 100644
--- a/Couche IHM/Couche Data/Dao/dbsDAO.cs
+++ b/Couche IHM/Couche Data/Dao/dbsDAO.cs
@@ -1,4 +1,5 @@
using MySql.Data.MySqlClient;
+using System.Reflection;
namespace Couche_Data.Dao
{
@@ -33,23 +34,7 @@ public static dbsDAO Instance
}
}
- ///
- /// Permet de faire des requêtes
- ///
- public MySqlCommand CMD
- {
- get => cmd;
- set => cmd = value;
- }
-
- ///
- /// permet de lire les données
- ///
- public MySqlDataReader Reader
- {
- get => reader;
- set => reader = value;
- }
+
///
/// Vérifie si la connexion à la bdd existe
@@ -75,13 +60,46 @@ public object DatabaseLock
get { return databaseLock; }
}
+ private static string? connectionString;
+
+ public static string ConnectionString
+ {
+ get
+ {
+ var assembly = Assembly.GetExecutingAssembly();
+ string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith("ConnectionString.txt"));
+ using Stream stream = assembly.GetManifestResourceStream(resourceName)!;
+ using StreamReader reader = new StreamReader(stream);
+ connectionString = reader.ReadToEnd();
+
+ return connectionString;
+ }
+ }
+ public static string ConnectionStringV
+ {
+ get
+ {
+
+ var assembly = Assembly.GetExecutingAssembly();
+ string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith("ConnectionString.txt"));
+ using Stream stream = assembly.GetManifestResourceStream(resourceName)!;
+ using StreamReader reader = new StreamReader(stream);
+ connectionString = reader.ReadToEnd();
+ connectionString = connectionString.Replace("database=c2_gallium", "database=c2_etismash"); // TODO enlever cette ligne quand stat avec api
+
+ return connectionString;
+ }
+ }
+
+
+
+
///
/// Se connecte à la base de donnée
///
private void ConnexionToBdd()
{
- string connString = String.Format("server={0};port={1};user id={2};password={3};database={4};SslMode={5}", "51.178.36.43", "3306", "c2_gallium", "DfD2no5UJc_nB", "c2_etismash", "none");
- this.sql = new MySqlConnection(connString);
+ sql = new MySqlConnection(ConnectionString);
}
///
diff --git a/Couche IHM/Couche Data/Interfaces/IAcompteDao.cs b/Couche IHM/Couche Data/Interfaces/IAcompteDao.cs
index af60874..14f10e8 100644
--- a/Couche IHM/Couche Data/Interfaces/IAcompteDao.cs
+++ b/Couche IHM/Couche Data/Interfaces/IAcompteDao.cs
@@ -4,29 +4,33 @@
namespace Couche_Data.Interfaces
{
- public interface IAcompteDao
+ public interface IAccountDao
{
///
/// Permet de récupérer tous les adhérents
///
- public List GetAdhérents();
+ public List GetAdhérents();
+ ///
+ /// Permet de récupérer tous les roles
+ ///
+ public List GetRoles();
///
/// Permet de supprimer un adhérent
///
- public void RemoveAdhérent(Acompte adhérent);
+ public void RemoveAdhérent(Account adhérent);
///
/// Permet de créer un nouvel adhérent
///
- public void CreateAdhérent(Acompte adhérent);
+ public void CreateAdhérent(Account adhérent);
///
/// Permet de modifier un adhérent
///
- public void UpdateAdhérent(Acompte adhérent);
+ public void UpdateAdhérent(Account adhérent);
}
}
diff --git a/Couche IHM/Couche Data/Interfaces/ILogDAO.cs b/Couche IHM/Couche Data/Interfaces/ILogDAO.cs
new file mode 100644
index 0000000..49abdc9
--- /dev/null
+++ b/Couche IHM/Couche Data/Interfaces/ILogDAO.cs
@@ -0,0 +1,11 @@
+using Modeles;
+
+namespace Couche_Data.Interfaces
+{
+ public interface ILogDAO
+ {
+ void CreateLog(Log log);
+ List GetLogs(int mois, int annee);
+ IPaginatedLogReader GetLogsReader(int mois, int annee);
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/Couche Data/Interfaces/IOrderDao.cs b/Couche IHM/Couche Data/Interfaces/IOrderDao.cs
new file mode 100644
index 0000000..d24dd5d
--- /dev/null
+++ b/Couche IHM/Couche Data/Interfaces/IOrderDao.cs
@@ -0,0 +1,14 @@
+using Modeles;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Couche_Data.Interfaces
+{
+ public interface IOrderDao
+ {
+ void ProcessOrder(Order order);
+ }
+}
diff --git a/Couche IHM/Couche Data/Interfaces/IPaginatedReader.cs b/Couche IHM/Couche Data/Interfaces/IPaginatedReader.cs
new file mode 100644
index 0000000..255d3fd
--- /dev/null
+++ b/Couche IHM/Couche Data/Interfaces/IPaginatedReader.cs
@@ -0,0 +1,36 @@
+using Modeles;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Couche_Data.Interfaces
+{
+ ///
+ /// Permet de récupérer les logs page par page.
+ ///
+ public interface IPaginatedLogReader
+ {
+ ///
+ /// Le nombre d'éléments par page.
+ ///
+ int PageSize { get; }
+
+ ///
+ /// Charge la page suivante s'il reste des logs à charger
+ ///
+ void LoadNextPage();
+
+ ///
+ /// Récupère les logs de manière asynchrone au fur et à mesure qu'ils sont chargés.
+ ///
+ /// Un flux de logs.
+ IAsyncEnumerable GetAsyncStream(CancellationToken ct = default);
+
+ ///
+ /// Réinitialise le lecteur au début.
+ ///
+ void Reset();
+ }
+}
diff --git a/Couche IHM/Couche Data/Interfaces/IStatAcompteDAO.cs b/Couche IHM/Couche Data/Interfaces/IStatAcompteDAO.cs
new file mode 100644
index 0000000..a9eea3e
--- /dev/null
+++ b/Couche IHM/Couche Data/Interfaces/IStatAcompteDAO.cs
@@ -0,0 +1,13 @@
+using Modeles;
+
+namespace Couche_Data.Interfaces
+{
+ public interface IStatAccountDAO
+ {
+ void CreateStat(StatAccount stat);
+ List GetStatByWeek(int semaine,int year);
+ List GetStatByMonth(int month, int year);
+ List GetStatByYear(int year);
+ List GetStatBOfAcompteByMonth(int year, int acompte_id);
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/Couche Data/Interfaces/IStatProduitDAO.cs b/Couche IHM/Couche Data/Interfaces/IStatProduitDAO.cs
new file mode 100644
index 0000000..68ba752
--- /dev/null
+++ b/Couche IHM/Couche Data/Interfaces/IStatProduitDAO.cs
@@ -0,0 +1,13 @@
+using Modeles;
+
+namespace Couche_Data.Interfaces
+{
+ public interface IStatProduitDAO
+ {
+ void CreateStat(StatProduit stat);
+ List GetStatByWeek(int semaine,int year);
+ List GetStatByMonth(int month, int year);
+ List GetStatByYear(int year);
+ List GetStatBOfProductByMonth(int year, int product_id);
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/Couche Data/Interfaces/IUserDAO.cs b/Couche IHM/Couche Data/Interfaces/IUserDAO.cs
deleted file mode 100644
index 801436b..0000000
--- a/Couche IHM/Couche Data/Interfaces/IUserDAO.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-
-using Modeles;
-
-namespace Couche_Data.Interfaces
-{
-
- public interface IUserDAO
- {
- ///
- /// Créer un compte
- ///
- public void CreateCompte(User compte);
-
- ///
- /// Enlève un compte
- ///
- public void RemoveCompte(User compte);
-
- ///
- /// Met à jour un compte
- ///
- public void UpdateCompte(User compte);
-
-
- ///
- /// Récupère tous les comptes
- ///
- public List GetComptes();
-
- ///
- /// Récupère tous les comptes
- ///
- public List GetRoles();
-
- }
-}
diff --git a/Couche IHM/Couche IHM/Assets/Styles/style.xaml b/Couche IHM/Couche IHM/Assets/Styles/style.xaml
index 46625e8..199443c 100644
--- a/Couche IHM/Couche IHM/Assets/Styles/style.xaml
+++ b/Couche IHM/Couche IHM/Assets/Styles/style.xaml
@@ -1,4 +1,5 @@
pack://application:,,,/Fonts/#There Brat
@@ -24,6 +25,13 @@
+
+
+
+
@@ -450,7 +451,7 @@
Width="150"
Margin="20,20,20,10"
materialDesign:HintAssist.Hint="Prénom"
- Text="{Binding AdherentViewModel.CurrentAcompte.PrenomIHM}"
+ Text="{Binding AccountsViewModel.CurrentAccount.PrenomIHM}"
FontSize="16"
Style="{StaticResource MaterialDesignFilledTextBox}"
MaxLength="100"/>
@@ -466,11 +467,8 @@
MaxLength="8">
-
-
-
@@ -484,7 +482,7 @@
Style="{StaticResource MaterialDesignFilledTextBox}">
@@ -499,7 +497,7 @@
Opacity="0.7"
Margin="20,20,20,10"
materialDesign:HintAssist.Hint="Formation (optional)"
- Text="{Binding AdherentViewModel.CurrentAcompte.FormationIHM}"
+ Text="{Binding AccountsViewModel.CurrentAccount.FormationIHM}"
FontSize="16"
Style="{StaticResource MaterialDesignFilledTextBox}"/>
@@ -518,7 +516,7 @@
HorizontalAlignment="Center"
materialDesign:CheckBoxAssist.CheckBoxSize="25"
Grid.Row="10"
- IsChecked="{Binding AdherentViewModel.CurrentAcompte.IsAdherentIHM}"
+ IsChecked="{Binding AccountsViewModel.CurrentAccount.IsAdherentIHM}"
Background="Green"
/>
@@ -527,7 +525,7 @@
Grid.Row="11"
FontSize="16"
Margin="20,0,20,10"
- Command="{Binding AdherentViewModel.CurrentAcompte.ResetAdh}"
+ Command="{Binding AccountsViewModel.CurrentAccount.ResetAdh}"
Content="Annuler"
BorderThickness="0"
Background="Gray"
@@ -540,15 +538,15 @@
Grid.Row="11"
Content="Modifier"
BorderThickness="0"
- Command="{Binding AdherentViewModel.CurrentAcompte.ModifyAdherent}"
+ Command="{Binding AccountsViewModel.CurrentAccount.ModifyAdherent}"
Background="{StaticResource galliumColor}">
@@ -134,15 +137,15 @@
-
+
-
+
-
+
@@ -160,7 +163,8 @@
Foreground="LightGreen"
Background="LightGray"
BorderBrush="Transparent"
- Maximum="100"
+ Maximum="{Binding DataContext.StatViewModel.PodiumAccount[0].Argent,
+ RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}"
Height="12"
Value="{Binding Argent}" />
@@ -174,7 +178,7 @@
Grid.Row="2"
Grid.Column="4"
Grid.ColumnSpan="2"
- FontSize="20"
+ FontSize="23"
HorizontalAlignment="Center"
FontWeight="DemiBold"
Text="Meilleures ventes"/>
@@ -204,6 +208,7 @@
Margin="0,20,0,0"
Text="{Binding Path=PurchaseCount, StringFormat=' {0}'}"
Grid.Column="0"
+ FontSize="15"
/>
@@ -211,17 +216,20 @@
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Right"
+ Command="{Binding DataContext.StatViewModel.FindProduct,
+ RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}"
+ CommandParameter="{Binding ProductViewModel}"
Content="{Binding ProductViewModel.NomProduitIHM}">
@@ -265,7 +273,8 @@
Foreground="#FFB366"
Background="LightGray"
BorderBrush="Transparent"
- Maximum="100"
+ Maximum="{Binding DataContext.StatViewModel.PodiumProduits[0].PurchaseCount,
+ RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}"
Height="12"
Value="{Binding PurchaseCount}" />
diff --git a/Couche IHM/Couche IHM/Frames/FrameCaisse.xaml b/Couche IHM/Couche IHM/Frames/FrameCaisse.xaml
index 29cfa6f..29b40e6 100644
--- a/Couche IHM/Couche IHM/Frames/FrameCaisse.xaml
+++ b/Couche IHM/Couche IHM/Frames/FrameCaisse.xaml
@@ -10,9 +10,9 @@
Title="FrameCaisse"
Background="White">
-
+
-
+
@@ -20,19 +20,19 @@
-
+
-
+
-
+
@@ -42,7 +42,7 @@
FontWeight="Medium"
FontFamily="Roboto"
Content="Panier"
- FontSize="15"
+ FontSize="18"
Foreground="#FF403D39"/>
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
-
-
+
+
+
@@ -113,43 +113,40 @@
-
-
+
+
-
+
-
-
+
+ FontSize="15" />
-
@@ -201,24 +196,21 @@
+ Paiement impossible en dessous de 1€
-
-
-
+
-
-
+
+
@@ -226,18 +218,17 @@
HorizontalAlignment="Center"
FontWeight="Bold"
FontSize="28"
- Text="Paiement par Acompte"
+ Text="Paiement par Account"
Margin="20 0 20 30"/>
-
+
@@ -390,5 +381,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Couche IHM/Couche IHM/Frames/FrameComptes.xaml b/Couche IHM/Couche IHM/Frames/FrameComptes.xaml
index fa5106f..9b6d3c8 100644
--- a/Couche IHM/Couche IHM/Frames/FrameComptes.xaml
+++ b/Couche IHM/Couche IHM/Frames/FrameComptes.xaml
@@ -11,22 +11,15 @@
Title="FrameComptes"
Background="White">
-
-
+
-
-
-
-
-
-
-
-
+
+
@@ -60,7 +53,7 @@
FontWeight="Medium"
FontFamily="Roboto"
FontSize="18"
- Text="Identifiant" />
+ Text="Mail" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -206,6 +162,7 @@
+
@@ -219,41 +176,23 @@
FontSize="30"
FontWeight="Black"/>
-
-
-
+
@@ -261,10 +200,10 @@
@@ -273,8 +212,8 @@
@@ -283,9 +222,9 @@
@@ -294,84 +233,45 @@
-
-
-
diff --git a/Couche IHM/Couche IHM/Frames/FrameEvolStat.xaml b/Couche IHM/Couche IHM/Frames/FrameEvolStat.xaml
new file mode 100644
index 0000000..d9f2d36
--- /dev/null
+++ b/Couche IHM/Couche IHM/Frames/FrameEvolStat.xaml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Couche IHM/Couche IHM/Frames/FrameEvolStat.xaml.cs b/Couche IHM/Couche IHM/Frames/FrameEvolStat.xaml.cs
new file mode 100644
index 0000000..033d254
--- /dev/null
+++ b/Couche IHM/Couche IHM/Frames/FrameEvolStat.xaml.cs
@@ -0,0 +1,32 @@
+using Couche_IHM.VueModeles;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Couche_IHM.Frames
+{
+ ///
+ /// Logique d'interaction pour FrameEvolStat.xaml
+ ///
+ public partial class FrameEvolStat : Page
+ {
+ public FrameEvolStat()
+ {
+ InitializeComponent();
+ DataContext = MainWindowViewModel.Instance;
+
+ }
+
+ }
+}
diff --git a/Couche IHM/Couche IHM/Frames/FrameLog.xaml b/Couche IHM/Couche IHM/Frames/FrameLog.xaml
index 103a616..6a1f96e 100644
--- a/Couche IHM/Couche IHM/Frames/FrameLog.xaml
+++ b/Couche IHM/Couche IHM/Frames/FrameLog.xaml
@@ -11,66 +11,71 @@
Title="FrameLogs">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -125,7 +130,7 @@
Background="#FDF5E6"
VerticalAlignment="Center"
HorizontalAlignment="Right"
- ExpandDirection="Left" >
+ ExpandDirection="Left" Grid.Row="1" >
+ Content="Account"/>
)sender!;
+
+ if (collection.Count == 0)
+ {
+ this.scrollViewer.ScrollToTop();
+ }
+ }
+
+ private void ScrollChanged(object sender, ScrollChangedEventArgs e)
+ {
+ if (e.ExtentHeight < e.ViewportHeight + e.VerticalOffset + 800)
+ {
+ MainWindowViewModel.Instance.LogsViewModel.LoadNextPage();
+ }
+ }
}
}
diff --git a/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml b/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml
index bd8899e..08344fa 100644
--- a/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml
+++ b/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml
@@ -3,13 +3,92 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:vm="clr-namespace:Couche_IHM.VueModeles"
xmlns:local="clr-namespace:Couche_IHM.Frames"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
- Title="FrameStatistique"
- Background="White">
+ Title="FrameChooseStat">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml.cs b/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml.cs
index c496070..573a99b 100644
--- a/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml.cs
+++ b/Couche IHM/Couche IHM/Frames/FrameStatistique.xaml.cs
@@ -1,19 +1,30 @@
-
+using Couche_IHM.VueModeles;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
namespace Couche_IHM.Frames
{
///
- /// Logique d'interaction pour FrameStatistique.xaml
+ /// Logique d'interaction pour FrameChooseStat.xaml
///
public partial class FrameStatistique : Page
{
- ///
- /// Constructeur naturelle
- ///
public FrameStatistique()
{
InitializeComponent();
+ DataContext = MainWindowViewModel.Instance;
}
}
}
diff --git a/Couche IHM/Couche IHM/Frames/FrameStock.xaml b/Couche IHM/Couche IHM/Frames/FrameStock.xaml
index 9baf50a..4885c04 100644
--- a/Couche IHM/Couche IHM/Frames/FrameStock.xaml
+++ b/Couche IHM/Couche IHM/Frames/FrameStock.xaml
@@ -14,7 +14,7 @@
Background="White"
ShowsNavigationUI="False">
-
+
diff --git a/Couche IHM/Couche IHM/Frames/FrameTopStat.xaml b/Couche IHM/Couche IHM/Frames/FrameTopStat.xaml
new file mode 100644
index 0000000..461fbfe
--- /dev/null
+++ b/Couche IHM/Couche IHM/Frames/FrameTopStat.xaml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Couche IHM/Couche IHM/Frames/FrameTopStat.xaml.cs b/Couche IHM/Couche IHM/Frames/FrameTopStat.xaml.cs
new file mode 100644
index 0000000..68cd448
--- /dev/null
+++ b/Couche IHM/Couche IHM/Frames/FrameTopStat.xaml.cs
@@ -0,0 +1,21 @@
+
+using Couche_IHM.VueModeles;
+using System.Windows.Controls;
+
+namespace Couche_IHM.Frames
+{
+ ///
+ /// Logique d'interaction pour FrameTopStat.xaml
+ ///
+ public partial class FrameTopStat : Page
+ {
+ ///
+ /// Constructeur naturelle
+ ///
+ public FrameTopStat()
+ {
+ InitializeComponent();
+ DataContext = MainWindowViewModel.Instance;
+ }
+ }
+}
diff --git a/Couche IHM/Couche IHM/MainWindow.xaml b/Couche IHM/Couche IHM/MainWindow.xaml
index d40208d..d6851ed 100644
--- a/Couche IHM/Couche IHM/MainWindow.xaml
+++ b/Couche IHM/Couche IHM/MainWindow.xaml
@@ -22,7 +22,7 @@
-
+
@@ -57,6 +57,7 @@
-
-
-
+
@@ -171,41 +170,36 @@
-
-
-
-
-
-
-
+
+ Grid.Column="0"
+ Source="/Images/logoEtiq.png"
+ Width="40"
+ Height="auto"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Left" />
+ Margin="10,0,0,0"
+ Grid.Column="1"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Center">
+ Text="{Binding CompteConnected.NomCompletIHM}"
+ FontSize="15"
+ FontWeight="Bold"/>
+ Text="{Binding CompteConnected.Role}"
+ FontSize="13"
+ FontWeight="DemiBold" />
-
+
+
-
-
diff --git a/Couche IHM/Couche IHM/MainWindow.xaml.cs b/Couche IHM/Couche IHM/MainWindow.xaml.cs
index a128148..0ccfd87 100644
--- a/Couche IHM/Couche IHM/MainWindow.xaml.cs
+++ b/Couche IHM/Couche IHM/MainWindow.xaml.cs
@@ -3,9 +3,18 @@
using Couche_IHM.VueModeles;
using Couche_Métier;
using Couche_Métier.Manager;
+using Discord;
+using Discord.Commands;
+using Discord.WebSocket;
using Modeles;
using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Documents;
+using System.Windows.Media;
namespace Couche_IHM
{
@@ -14,23 +23,49 @@ namespace Couche_IHM
///
public partial class MainWindow : Window
{
+ private static DiscordSocketClient _client;
+ private static List products;
+
///
/// Constructeur de la mainwindow
///
- public MainWindow(User user,LogManager logManager,UserManager userManager)
+ public MainWindow(Account user)
{
InitializeComponent();
- MainWindowViewModel.Instance.CompteConnected = new UserViewModel(user,userManager);
+ var mwvm = MainWindowViewModel.GetInstanceFor(this);
+ AccountManager accountManager = MainWindowViewModel.Instance.AccountManager;
+ mwvm.CompteConnected = new AccountViewModel(user, accountManager);
DataContext = MainWindowViewModel.Instance;
+
+ products = mwvm.ProductViewModel.Products.ToList();
+
+ if (DevelopmentInfo.isDevelopment)
+ {
+ Menu.Background = new SolidColorBrush(Colors.DarkRed);
+ buttonAccount.Background = new SolidColorBrush(Colors.DarkRed);
+ buttonAccueil.Background = new SolidColorBrush(Colors.DarkRed);
+ buttonCaisse.Background = new SolidColorBrush(Colors.DarkRed);
+ buttonComptes.Background = new SolidColorBrush(Colors.DarkRed);
+ buttonStock.Background = new SolidColorBrush(Colors.DarkRed);
+ }
+ DiscordBot discordBot = new DiscordBot(mwvm);
}
+
+
+
///
/// Permet de se déconnecter
///
///
///
private void Disconnect(object sender, RoutedEventArgs e)
+ {
+ this.AskToDisconnect();
+ }
+
+ public void AskToDisconnect()
{
ConnexionIHM connexionIHM = new ConnexionIHM();
connexionIHM.Show();
diff --git a/Couche IHM/Couche IHM/MessageBoxErrorHandler.cs b/Couche IHM/Couche IHM/MessageBoxErrorHandler.cs
new file mode 100644
index 0000000..0980ffd
--- /dev/null
+++ b/Couche IHM/Couche IHM/MessageBoxErrorHandler.cs
@@ -0,0 +1,53 @@
+using Couche_IHM.VueModeles;
+using GalliumPlusApi.Exceptions;
+using System;
+using System.Windows;
+
+namespace Couche_IHM
+{
+ public static class MessageBoxErrorHandler
+ {
+ public static Action AttachToAction(Action action)
+ {
+ return input => DoesntThrow(() => action(input));
+ }
+
+ public static bool DoesntThrow(Action action)
+ {
+ try
+ {
+ action();
+ return true;
+ }
+ catch (AggregateException aggregateErrors)
+ {
+ if (aggregateErrors.InnerException != null)
+ {
+ HandleError(aggregateErrors.InnerException);
+ return false;
+ }
+ return true;
+ }
+ catch (Exception error)
+ {
+ HandleError(error);
+ return false;
+ }
+ }
+
+ private static void HandleError(Exception error)
+ {
+ switch (error)
+ {
+ case UnauthenticatedException:
+ MessageBox.Show("Veuillez vous reconnecter.", "Session expirée", MessageBoxButton.OK, MessageBoxImage.Error);
+ MainWindowViewModel.Instance.MainWindow.AskToDisconnect();
+ break;
+
+ default:
+ MessageBox.Show(error.Message, "Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
+ break;
+ }
+ }
+ }
+}
diff --git a/Couche IHM/Couche IHM/VueModeles/AcompteViewModel.cs b/Couche IHM/Couche IHM/VueModeles/AccountViewModel.cs
similarity index 55%
rename from Couche IHM/Couche IHM/VueModeles/AcompteViewModel.cs
rename to Couche IHM/Couche IHM/VueModeles/AccountViewModel.cs
index 3fc73ad..78a9d89 100644
--- a/Couche IHM/Couche IHM/VueModeles/AcompteViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/AccountViewModel.cs
@@ -3,17 +3,18 @@
using Couche_Métier.Utilitaire;
using Modeles;
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Couche_IHM.VueModeles
{
- public class AcompteViewModel : INotifyPropertyChanged
+ public class AccountViewModel : INotifyPropertyChanged
{
#region attributes
- private Acompte acompte;
- private AcompteManager acompteManager;
+ private Account acompte;
+ private AccountManager accountManager;
private string argentIHM;
private string identifiantIHM;
private bool isAdherentIHM;
@@ -21,11 +22,17 @@ public class AcompteViewModel : INotifyPropertyChanged
private string prenomIHM;
private string formationIHM;
private string action;
+ private string email;
+ private Role role;
+ private string mdpIHM1;
+ private string mdpIHM2;
private bool showConfirmationDelete;
+
#endregion
#region events
+ public RelayCommand ShowUpdate { get; set; }
public RelayCommand ModifyAdherent { get; set; }
public RelayCommand ResetAdh { get; set; }
public RelayCommand CreateAdh { get; set; }
@@ -52,7 +59,7 @@ public string NomCompletIHM
get
{
string result = $"{acompte.Nom.ToUpper()} {acompte.Prenom}";
- if (result == " ")
+ if (result.Trim() == "")
{
result = "----------------------------------";
}
@@ -78,7 +85,7 @@ public string ArgentIHM
set
{
argentIHM = value;
- MainWindowViewModel.Instance.AdherentViewModel.ShowModifButtons = true;
+ MainWindowViewModel.Instance.AccountsViewModel.ShowModifButtons = true;
}
}
@@ -91,7 +98,7 @@ public string IdentifiantIHM
set
{
identifiantIHM = value;
- MainWindowViewModel.Instance.AdherentViewModel.ShowModifButtons = true;
+ MainWindowViewModel.Instance.AccountsViewModel.ShowModifButtons = true;
}
}
///
@@ -117,14 +124,11 @@ public string IdentifiantIHM
///
/// Action à réaliser sur l'acompte
///
- public string Action
- {
- get
- {
- return this.action;
- }
- }
+ public string Action { get => this.action; }
+ ///
+ /// Afficher la popup pour supprimer un compte ?
+ ///
public bool ShowConfirmationDelete
{
get => showConfirmationDelete;
@@ -134,33 +138,67 @@ public bool ShowConfirmationDelete
NotifyPropertyChanged();
}
}
+
+ ///
+ /// Mail du compte
+ ///
+ public string Email { get => email; set => email = value; }
+
+ ///
+ /// Mdp1 du compte
+ ///
+ public string MdpIHM1 { get => mdpIHM1; set => mdpIHM1 = value; }
+ ///
+ /// Mdp2 du compte
+ ///
+ public string MdpIHM2 { get => mdpIHM2; set => mdpIHM2 = value; }
+ ///
+ /// Role du compte
+ ///
+ public Role Role { get => role; set => role = value; }
#endregion
#region constructor
///
/// Constructeur du acompteViewModel
///
- public AcompteViewModel(Acompte acompte,AcompteManager acompteManager,string action = "UPDATE")
+ public AccountViewModel(Account acompte, AccountManager accountManager, string action = "UPDATE")
{
this.acompte = acompte;
- this.acompteManager = acompteManager;
+ this.accountManager = accountManager;
this.action = action;
// Initialisation propriétés
this.argentIHM = ConverterFormatArgent.ConvertToString(acompte.Argent);
this.identifiantIHM = acompte.Identifiant;
this.formationIHM = acompte.Formation;
- this.isAdherentIHM = acompte.StillAdherent;
+ this.isAdherentIHM = acompte.IsMember;
this.nomIHM = acompte.Nom;
this.prenomIHM = acompte.Prenom;
+ this.role = accountManager.GetRoles().Find(x => x.Id == acompte.RoleId);
+ this.email = acompte.Mail;
+ this.mdpIHM1 = acompte.HashedPassword;
+ this.mdpIHM2 = acompte.HashedPassword;
// Initialisation des events
- this.ModifyAdherent = new RelayCommand(x => this.UpdateAcompte());
- this.ResetAdh = new RelayCommand(x => this.ResetAcompte());
- this.CreateAdh = new RelayCommand(x => this.CreateAcompte());
+ this.ShowUpdate = new RelayCommand(x =>
+ {
+ MainWindowViewModel.Instance.AccountsViewModel.CurrentAccount = this;
+ MainWindowViewModel.Instance.AccountsViewModel.OpenUserDetails();
+ });
+ this.ModifyAdherent = new RelayCommand(x => this.UpdateAccount());
+
+
+ this.ResetAdh = new RelayCommand(x =>
+ {
+ this.ResetAccount();
+ this.HideAccountDetails();
+ });
+
+ this.CreateAdh = new RelayCommand(x => this.CreateAccount());
this.PreviewAdh = new RelayCommand(x => ShowConfirmationDelete = true);
this.CancelDeleteAdh = new RelayCommand(x => ShowConfirmationDelete = false);
- this.DeleteAdh = new RelayCommand(x => this.DeleteAcompte());
+ this.DeleteAdh = new RelayCommand(x => this.DeleteAccount());
}
#endregion
@@ -169,62 +207,66 @@ public AcompteViewModel(Acompte acompte,AcompteManager acompteManager,string act
///
/// Permet de supprimer un acompte
///
- private void DeleteAcompte()
+ private void DeleteAccount()
{
// Modifier la data
- this.acompteManager.RemoveAdhérent(this.acompte);
-
- // Log l'action
- Log log = new Log(DateTime.Now, 2, $"Suppresion de l acompte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
+ if (MessageBoxErrorHandler.DoesntThrow(() => this.accountManager.RemoveAdhérent(this.acompte)))
+ {
+ // Log l'action
+ Log log = new Log(DateTime.Now, 2, $"Suppresion du compte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
+ MainWindowViewModel.Instance.LogManager.CreateLog(log);
- // Notifier la vue
- MainWindowViewModel.Instance.AdherentViewModel.RemoveAcompte(this);
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
- MainWindowViewModel.Instance.AdherentViewModel.DialogModifAdherent = false;
- MainWindowViewModel.Instance.AdherentViewModel.ShowModifButtons = false;
+ // Notifier la vue
+ MainWindowViewModel.Instance.AccountsViewModel.RemoveAccount(this);
+ MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ MainWindowViewModel.Instance.AccountsViewModel.DialogModifAccount = false;
+ MainWindowViewModel.Instance.AccountsViewModel.ShowModifButtons = false;
+ }
ShowConfirmationDelete = false;
-
}
///
/// Permet de créer un acompte
///
- private void CreateAcompte()
+ private void CreateAccount()
{
-
// Changer la data
this.acompte.Nom = this.nomIHM;
this.acompte.Prenom = this.prenomIHM;
this.acompte.Argent = ConverterFormatArgent.ConvertToDouble(this.ArgentIHM);
this.acompte.Formation = this.formationIHM;
this.acompte.Identifiant = this.identifiantIHM;
- this.acompte.StillAdherent = this.isAdherentIHM;
+ this.acompte.IsMember = this.isAdherentIHM;
+ this.acompte.Mail = "UKN";
this.action = "UPDATE";
- acompteManager.CreateAdhérent(this.acompte);
+
+ if (MessageBoxErrorHandler.DoesntThrow(() => accountManager.CreateAdhérent(this.acompte)))
+ {
+ // Log l'action
+ Log log = new Log(DateTime.Now, 2, $"Création de l acompte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
+ MainWindowViewModel.Instance.LogManager.CreateLog(log);
- // Log l'action
- Log log = new Log(DateTime.Now, 2, $"Création de l acompte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
+ // Notifier la vue
+ MainWindowViewModel.Instance.AccountsViewModel.AddAccount(this);
- // Notifier la vue
- MainWindowViewModel.Instance.AdherentViewModel.AddAcompte(this);
- NotifyPropertyChanged(nameof(this.Action));
- NotifyPropertyChanged(nameof(IdentifiantIHM));
- NotifyPropertyChanged(nameof(ArgentIHM));
- NotifyPropertyChanged(nameof(NomCompletIHM));
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
- MainWindowViewModel.Instance.AdherentViewModel.DialogModifAdherent = false;
- MainWindowViewModel.Instance.AdherentViewModel.ShowModifButtons = false;
+ NotifyPropertyChanged(nameof(this.Action));
+ NotifyPropertyChanged(nameof(IdentifiantIHM));
+ NotifyPropertyChanged(nameof(ArgentIHM));
+ NotifyPropertyChanged(nameof(NomCompletIHM));
+ NotifyPropertyChanged(nameof(Email));
+ NotifyPropertyChanged(nameof(Role));
+ NotifyPropertyChanged(nameof(IsAdherentIHM));
+ MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ }
+ MainWindowViewModel.Instance.AccountsViewModel.DialogModifAccount = false;
+ MainWindowViewModel.Instance.AccountsViewModel.ShowModifButtons = false;
}
-
///
/// Permet de mettre à jour visuellement les modifications de l'adhérent
///
- public void UpdateAcompte(bool doLog = true)
+ public void UpdateAccount(bool doLog = true, bool persistChanges = true)
{
-
// Log l'action
float argent = ConverterFormatArgent.ConvertToDouble(this.ArgentIHM);
if (doLog && acompte.Argent != argent)
@@ -244,7 +286,6 @@ public void UpdateAcompte(bool doLog = true)
MainWindowViewModel.Instance.LogManager.CreateLog(log);
MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
}
-
// Changer la data
this.acompte.Nom = this.nomIHM;
@@ -252,44 +293,62 @@ public void UpdateAcompte(bool doLog = true)
this.acompte.Argent = ConverterFormatArgent.ConvertToDouble(this.ArgentIHM);
this.acompte.Formation = this.formationIHM;
this.acompte.Identifiant = this.identifiantIHM;
- this.acompte.StillAdherent = this.isAdherentIHM;
- acompteManager.UpdateAdhérent(this.acompte);
+ this.acompte.IsMember = this.isAdherentIHM;
+ this.acompte.Mail = this.email;
+ this.acompte.RoleId = this.role.Id;
- // Notifier la vue
- NotifyPropertyChanged(nameof(IdentifiantIHM));
- NotifyPropertyChanged(nameof(ArgentIHM));
- NotifyPropertyChanged(nameof(NomCompletIHM));
- MainWindowViewModel.Instance.AdherentViewModel.DialogModifAdherent = false;
- MainWindowViewModel.Instance.AdherentViewModel.ShowModifButtons = false;
+ if (persistChanges && MessageBoxErrorHandler.DoesntThrow(() => accountManager.UpdateAdhérent(this.acompte)))
+ {
+ // Notifier la vue
+ NotifyPropertyChanged(nameof(IdentifiantIHM));
+ NotifyPropertyChanged(nameof(ArgentIHM));
+ NotifyPropertyChanged(nameof(NomCompletIHM));
+ NotifyPropertyChanged(nameof(Email));
+ NotifyPropertyChanged(nameof(Role));
+ NotifyPropertyChanged(nameof(IsAdherentIHM));
+ }
+ MainWindowViewModel.Instance.AccountsViewModel.InitAccountsAdmins();
+ MainWindowViewModel.Instance.AccountsViewModel.DialogModifAccount = false;
+ MainWindowViewModel.Instance.AccountsViewModel.DialogModifAdmin = false;
+ MainWindowViewModel.Instance.AccountsViewModel.ShowModifButtons = false;
}
-
///
/// Permet de reset les propriétés de l'acompte
///
- public void ResetAcompte()
+ public void ResetAccount()
{
-
// Initialisation propriétés
this.argentIHM = ConverterFormatArgent.ConvertToString(acompte.Argent);
this.identifiantIHM = acompte.Identifiant;
this.formationIHM = acompte.Formation;
this.nomIHM = acompte.Nom;
this.prenomIHM = acompte.Prenom;
- this.isAdherentIHM = acompte.StillAdherent;
+ this.isAdherentIHM = acompte.IsMember;
+ this.email = acompte.Mail;
+ this.role = accountManager.GetRoles().Find(x => x.Id == acompte.RoleId);
// Notifier la vue
NotifyPropertyChanged(nameof(IdentifiantIHM));
NotifyPropertyChanged(nameof(ArgentIHM));
NotifyPropertyChanged(nameof(NomCompletIHM));
NotifyPropertyChanged(nameof(NomIHM));
+ NotifyPropertyChanged(nameof(Email));
+ NotifyPropertyChanged(nameof(Role));
NotifyPropertyChanged(nameof(PrenomIHM));
NotifyPropertyChanged(nameof(FormationIHM));
NotifyPropertyChanged(nameof(IsAdherentIHM));
+ MainWindowViewModel.Instance.AccountsViewModel.ShowModifButtons = false;
+ }
- MainWindowViewModel.Instance.AdherentViewModel.DialogModifAdherent = false;
- MainWindowViewModel.Instance.AdherentViewModel.ShowModifButtons = false;
+ ///
+ /// Permet de fermer les popup de modification de comptes
+ ///
+ public void HideAccountDetails()
+ {
+ MainWindowViewModel.Instance.AccountsViewModel.DialogModifAccount = false;
+ MainWindowViewModel.Instance.AccountsViewModel.DialogModifAdmin = false;
}
public override string? ToString()
@@ -297,6 +356,12 @@ public void ResetAcompte()
return $"{acompte.Identifiant} {acompte.Nom} {acompte.Prenom}";
}
+ public override bool Equals(object? obj)
+ {
+ return obj is AccountViewModel model &&
+ EqualityComparer.Default.Equals(acompte, model.acompte);
+ }
+
#endregion
}
diff --git a/Couche IHM/Couche IHM/VueModeles/AccountsViewModel.cs b/Couche IHM/Couche IHM/VueModeles/AccountsViewModel.cs
new file mode 100644
index 0000000..c53c924
--- /dev/null
+++ b/Couche IHM/Couche IHM/VueModeles/AccountsViewModel.cs
@@ -0,0 +1,314 @@
+
+using Couche_Métier.Manager;
+using DocumentFormat.OpenXml.Office2016.Presentation.Command;
+using Modeles;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace Couche_IHM.VueModeles
+{
+ public class AccountsViewModel : INotifyPropertyChanged
+ {
+ #region attributes
+ private ObservableCollection accounts;
+ private ObservableCollection accountsAdmins;
+ private List roles;
+ private AccountViewModel currentAccount;
+ private AccountManager accountManager;
+ private string searchFilter = "";
+ private bool showAccount = false;
+ private bool showModifButtons = false;
+ private bool showDeleteAccount = false;
+ private bool dialogModifAccount = false;
+
+ private bool dialogModifAdmin = false;
+ #endregion
+
+ #region notify
+ public event PropertyChangedEventHandler? PropertyChanged;
+ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ #endregion
+
+ #region events
+ public RelayCommand OpenModifAdh { get; set; }
+ public RelayCommand OpenModifAdmin { get; set; }
+
+ #endregion
+
+ #region properties
+ ///
+ /// Liste des roles disponibles
+ ///
+ public List Roles { get => roles; }
+
+ ///
+ /// Liste des accounts
+ ///
+ public ObservableCollection Accounts
+ {
+ get
+ {
+ ObservableCollection adhs;
+ if (searchFilter == "")
+ {
+ adhs = this.accounts;
+ }
+ else
+ {
+ adhs = new ObservableCollection(accounts.ToList().FindAll(adh =>
+ adh.NomCompletIHM.ToUpper().Contains(searchFilter.ToUpper()) ||
+ adh.IdentifiantIHM.ToUpper().Contains(searchFilter.ToUpper()))) ;
+ }
+
+ return adhs;
+ }
+ }
+
+ ///
+ /// Liste des accounts
+ ///
+ public ObservableCollection AccountsAdmins
+ {
+ get
+ {
+ return accountsAdmins;
+ }
+ }
+
+ ///
+ /// Filtre de barre de recherche
+ ///
+ public string SearchFilter
+ {
+ get => searchFilter;
+ set
+ {
+ searchFilter = value;
+ NotifyPropertyChanged(nameof(Accounts));
+ }
+ }
+
+ ///
+ /// Est ce qu'on affiche la fenetre de l account
+ ///
+ public bool ShowAccount
+ {
+ get => showAccount;
+ set
+ {
+ showAccount = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+ ///
+ /// Permet d'afficher les boutons de modification de l'account
+ ///
+ public bool ShowModifButtons
+ {
+ get => showModifButtons;
+ set
+ {
+ showModifButtons = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+ ///
+ /// Représente l'account selectionné
+ ///
+ public AccountViewModel CurrentAccount
+ {
+ get => currentAccount;
+ set
+ {
+ if (currentAccount != null)
+ {
+ this.currentAccount.ResetAccount();
+ }
+
+ currentAccount = value;
+ if (value != null)
+ {
+ ShowAccount = true;
+
+ }
+ else
+ {
+ this.ShowAccount = false;
+
+ }
+
+ NotifyPropertyChanged();
+
+ }
+ }
+ ///
+ /// Ouvrir la fenetre pour modifier l'account
+ ///
+ public bool DialogModifAccount
+ {
+ get => dialogModifAccount;
+ set
+ {
+ dialogModifAccount = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+ ///
+ /// Permet d'afficher le bouton de suppresion
+ ///
+ public bool ShowDeleteAccount
+ {
+ get => showDeleteAccount;
+ set
+ {
+ if (MainWindowViewModel.Instance.CompteConnected.Role.Name != "Conseil d'administration")
+ {
+ showDeleteAccount = value;
+ NotifyPropertyChanged();
+ }
+
+ }
+
+ }
+
+ ///
+ /// Permet d'afficher la popup de modification de compte admin
+ ///
+ public bool DialogModifAdmin
+ {
+ get => dialogModifAdmin;
+ set
+ {
+ dialogModifAdmin = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+
+ #endregion
+
+ #region constructor
+ ///
+ /// Constructeur de la classe account view model
+ ///
+ public AccountsViewModel(AccountManager accountManager)
+ {
+ // Initialisation des datas
+ this.accountManager = accountManager;
+ this.accounts = new ObservableCollection();
+ this.accountsAdmins = new ObservableCollection();
+ this.roles = accountManager.GetRoles();
+ InitAccountsAcomptes();
+ InitAccountsAdmins();
+
+ // Initialisation des events
+ this.OpenModifAdh = new RelayCommand(x => this.OpenAccountDetails((string)x));
+ this.OpenModifAdmin = new RelayCommand(x => this.OpenUserDetails());
+
+
+ }
+ #endregion
+
+ #region methods
+ private class AccountComparer : IComparer
+ {
+ public int Compare(Account? x, Account? y)
+ {
+ return StringComparer.Ordinal.Compare(x?.Identifiant, y?.Identifiant);
+ }
+ }
+
+ ///
+ /// Permet de récupérer la liste des accounts
+ ///
+ private void InitAccountsAcomptes()
+ {
+ List adherents = this.accountManager.GetAdhérents();
+ adherents.Sort(new AccountComparer());
+ foreach (Account adh in adherents)
+ {
+ this.accounts.Add(new AccountViewModel(adh,this.accountManager));
+ }
+ }
+
+ ///
+ /// Permet de récupérer la liste des accounts
+ ///
+ public void InitAccountsAdmins()
+ {
+ this.accountsAdmins.Clear();
+ List admins = this.accountManager.GetAdmins();
+ admins.Sort(new AccountComparer());
+ foreach (Account adh in admins)
+ {
+ this.accountsAdmins.Add(new AccountViewModel(adh, this.accountManager));
+ }
+ NotifyPropertyChanged(nameof(this.accountsAdmins));
+ }
+
+ ///
+ /// Permet d'ouvrir les détails du compte
+ ///
+ public void OpenUserDetails()
+ {
+ if (currentAccount == null)
+ {
+ CurrentAccount = new AccountViewModel(new Account(), this.accountManager,"NEW");
+ }
+
+ DialogModifAdmin = true;
+ }
+
+ ///
+ /// Permet d'ouvrir le détail de l'account
+ ///
+ private void OpenAccountDetails(string action)
+ {
+
+ if (action == "NEW" || currentAccount == null || currentAccount.Action == "NEW")
+ {
+ ShowDeleteAccount = false;
+ CurrentAccount = new AccountViewModel(new Account(),this.accountManager,"NEW");
+ }
+ else
+ {
+ ShowDeleteAccount = true;
+ }
+
+ DialogModifAccount = true;
+ }
+
+ ///
+ /// Permet de rajouter un account dans la liste
+ ///
+ public void AddAccount(AccountViewModel account)
+ {
+ this.accounts.Add(account);
+ NotifyPropertyChanged(nameof(Accounts));
+
+ }
+
+ ///
+ /// Permet de supprimer un account dans la liste
+ ///
+ public void RemoveAccount(AccountViewModel account)
+ {
+ this.accounts.Remove(account);
+ NotifyPropertyChanged(nameof(Accounts));
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/Couche IHM/Couche IHM/VueModeles/AcompteAndCheckboxConverter.cs b/Couche IHM/Couche IHM/VueModeles/AcompteAndCheckboxConverter.cs
index 5df3c98..bbf44e0 100644
--- a/Couche IHM/Couche IHM/VueModeles/AcompteAndCheckboxConverter.cs
+++ b/Couche IHM/Couche IHM/VueModeles/AcompteAndCheckboxConverter.cs
@@ -5,13 +5,13 @@
namespace Couche_IHM.VueModeles
{
- public class AcompteAndCheckboxConverter : IMultiValueConverter
+ public class AccountAndCheckboxConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
- if (values.Length == 2 && values[0] is AcompteViewModel acompte && values[1] is bool isChecked)
+ if (values.Length == 2 && values[0] is AccountViewModel acompte && values[1] is bool isChecked)
{
- return new Tuple(acompte, isChecked);
+ return new Tuple(acompte, isChecked);
}
return Binding.DoNothing;
}
diff --git a/Couche IHM/Couche IHM/VueModeles/AcomptesViewModel.cs b/Couche IHM/Couche IHM/VueModeles/AcomptesViewModel.cs
deleted file mode 100644
index d95ef7b..0000000
--- a/Couche IHM/Couche IHM/VueModeles/AcomptesViewModel.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-
-using Couche_Métier.Manager;
-using Modeles;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Linq;
-using System.Runtime.CompilerServices;
-
-namespace Couche_IHM.VueModeles
-{
- public class AcomptesViewModel : INotifyPropertyChanged
- {
- #region attributes
- private ObservableCollection acomptes;
- private AcompteViewModel currentAcompte;
- private AcompteManager acompteManager;
- private string searchFilter = "";
- private bool showAcompte = false;
- private bool showModifButtons = false;
- private bool showDeleteAcompte = false;
- private bool dialogModifAcompte = false;
- #endregion
-
- #region notify
- public event PropertyChangedEventHandler? PropertyChanged;
- private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- #endregion
-
- #region events
- public RelayCommand OpenModifAdh { get; set; }
- #endregion
-
- #region properties
-
-
- ///
- /// Liste des acomptes
- ///
- public ObservableCollection Acomptes
- {
- get
- {
- ObservableCollection adhs;
- if (searchFilter == "")
- {
- adhs = this.acomptes;
- }
- else
- {
- adhs = new ObservableCollection(acomptes.ToList().FindAll(adh =>
- adh.NomCompletIHM.ToUpper().Contains(searchFilter.ToUpper()) ||
- adh.IdentifiantIHM.ToUpper().Contains(searchFilter.ToUpper()))) ;
- }
-
- return adhs;
- }
- set => acomptes = value;
- }
-
- ///
- /// Filtre de barre de recherche
- ///
- public string SearchFilter
- {
- get => searchFilter;
- set
- {
- searchFilter = value;
- NotifyPropertyChanged(nameof(Acomptes));
- }
- }
-
- ///
- /// Est ce qu'on affiche la fenetre de l acompte
- ///
- public bool ShowAcompte
- {
- get => showAcompte;
- set
- {
- showAcompte = value;
- NotifyPropertyChanged();
- }
- }
-
- ///
- /// Permet d'afficher les boutons de modification de l'acompte
- ///
- public bool ShowModifButtons
- {
- get => showModifButtons;
- set
- {
- showModifButtons = value;
- NotifyPropertyChanged();
- }
- }
-
- ///
- /// Représente l'acompte selectionné
- ///
- public AcompteViewModel CurrentAcompte
- {
- get => currentAcompte;
- set
- {
- if (currentAcompte != null)
- {
- this.currentAcompte.ResetAcompte();
- }
-
- currentAcompte = value;
- if (value != null)
- {
- ShowAcompte = true;
-
- }
- else
- {
- this.ShowAcompte = false;
-
- }
-
- NotifyPropertyChanged(nameof(CurrentAcompte));
- }
- }
- ///
- /// Ouvrir la fenetre pour modifier l'acompte
- ///
- public bool DialogModifAdherent
- {
- get => dialogModifAcompte;
- set
- {
- dialogModifAcompte = value;
- NotifyPropertyChanged(nameof(DialogModifAdherent));
- }
- }
-
- ///
- /// Permet d'afficher le bouton de suppresion
- ///
- public bool ShowDeleteAcompte
- {
- get => showDeleteAcompte;
- set
- {
- if (MainWindowViewModel.Instance.CompteConnected.RoleIHM.Name != "Conseil d'administration")
- {
- showDeleteAcompte = value;
- NotifyPropertyChanged();
- }
-
- }
-
- }
-
-
- #endregion
-
- #region constructor
- ///
- /// Constructeur de la classe acompte view model
- ///
- public AcomptesViewModel(AcompteManager acompteManager)
- {
- // Initialisation des datas
- this.acompteManager = acompteManager;
- this.acomptes = new ObservableCollection();
- InitAcomptes();
-
- // Initialisation des events
- this.OpenModifAdh = new RelayCommand(x => this.OpenAcompteDetails((string)x));
-
-
- }
- #endregion
-
- #region methods
- ///
- /// Permet de récupérer la liste des acomptes
- ///
- private void InitAcomptes()
- {
- List adherents = this.acompteManager.GetAdhérents();
- foreach (Acompte adh in adherents)
- {
- this.acomptes.Add(new AcompteViewModel(adh,this.acompteManager));
- }
- }
-
- ///
- /// Permet d'ouvrir le détail de l'acompte
- ///
- private void OpenAcompteDetails(string action)
- {
-
- if (action == "NEW" || currentAcompte == null || currentAcompte.Action == "NEW")
- {
- ShowDeleteAcompte = false;
- CurrentAcompte = new AcompteViewModel(new Acompte(),this.acompteManager,"NEW");
- }
- else
- {
- ShowDeleteAcompte = true;
- }
-
- DialogModifAdherent = true;
- }
-
- ///
- /// Permet de rajouter un acompte dans la liste
- ///
- public void AddAcompte(AcompteViewModel acompte)
- {
- this.acomptes.Add(acompte);
- NotifyPropertyChanged(nameof(Acomptes));
-
- }
-
- ///
- /// Permet de supprimer un acompte dans la liste
- ///
- public void RemoveAcompte(AcompteViewModel acompte)
- {
- this.acomptes.Remove(acompte);
- NotifyPropertyChanged(nameof(Acomptes));
- }
-
- #endregion
-
-
- }
-}
diff --git a/Couche IHM/Couche IHM/VueModeles/CaisseViewModel.cs b/Couche IHM/Couche IHM/VueModeles/CaisseViewModel.cs
index 407253a..02d98af 100644
--- a/Couche IHM/Couche IHM/VueModeles/CaisseViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/CaisseViewModel.cs
@@ -9,44 +9,49 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
+using Xceed.Wpf.Toolkit;
namespace Couche_IHM.VueModeles
{
public class CaisseViewModel : INotifyPropertyChanged
{
#region attributes
- private ObservableDictionary productOrder = new ObservableDictionary();
+ private ObservableDictionary productOrder = new ObservableDictionary();
private string currentPaiement;
- private bool showPayAcompte = false;
+ private bool showPayAccount = false;
private bool showPayPaypal = false;
private bool showPayLiquide = false;
private bool showPayBanque = false;
private bool isAdherent = true;
private string prixIhm;
- private AcompteViewModel adherentPayer = null;
+ private AccountViewModel adherentPayer = null;
private StatProduitManager statProduitManager;
- private StatAcompteManager statAcompteManager;
+ private StatAccountManager statAccountManager;
+ private OrderManager orderManager;
+ private bool retourAccountArgent = false;
+ private string textArgentAdherentRetour;
#endregion
#region constructor
///
/// Constructeur de caisse vue modele
///
- public CaisseViewModel(StatAcompteManager statAcompte,StatProduitManager statProduit)
+ public CaisseViewModel(StatAccountManager statAccount, StatProduitManager statProduit, OrderManager orderManager)
{
// Initialisation objets métier
this.statProduitManager = statProduit;
- this.statAcompteManager = statAcompte;
+ this.statAccountManager = statAccount;
+ this.orderManager = orderManager;
// Initialisation events
this.AddProd = new RelayCommand(prodIHM => AddProduct(prodIHM));
this.RemoveProd = new RelayCommand(prodIHM => RemoveProduct(prodIHM));
this.ShowPay = new RelayCommand(x => PreviewPayArticles());
- this.CancelPay = new RelayCommand(x =>
+ this.CancelPay = new RelayCommand(x =>
{
this.ShowPayPaypal = false;
this.ShowPayBanque = false;
- this.ShowPayAcompte = false;
+ this.ShowPayAccount = false;
this.ShowPayLiquide = false;
}
);
@@ -55,9 +60,9 @@ public CaisseViewModel(StatAcompteManager statAcompte,StatProduitManager statPro
{
this.ProductOrder.Clear();
this.NotifyPropertyChanged(nameof(this.PriceAdherIHM));
-
+ this.NotifyPropertyChanged(nameof(CreditCardPaymentVisibility));
this.NotifyPropertyChanged(nameof(this.PriceNonAdherIHM));
- });
+ });
this.CurrentPaiement = Paiements[0];
}
#endregion
@@ -76,11 +81,26 @@ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
public RelayCommand AddProd { get; set; }
public RelayCommand RemoveProd { get; set; }
public RelayCommand CancelPay { get; set; }
- public RelayCommand Pay { get; set; }
+ public RelayCommand Pay { get; set; }
public RelayCommand ShowPay { get; set; }
#endregion
#region properties
+ ///
+ /// Permet d'afficher une popup avec l'argent qu'il reste à l'adhérent
+ ///
+ public bool RetourAccountArgent
+ {
+ get
+ {
+ return this.retourAccountArgent;
+ }
+ set
+ {
+ this.retourAccountArgent = value;
+ NotifyPropertyChanged();
+ }
+ }
///
/// Liste des moyens de paiements
@@ -104,7 +124,7 @@ public float PriceAdher
float prixTotal = 0.00f;
foreach (ProductViewModel product in productOrder.Keys)
{
- prixTotal += (float)ConverterFormatArgent.ConvertToDouble(product.PrixAdherentIHM) * productOrder[product];
+ prixTotal += (float)ConverterFormatArgent.ConvertToDouble(product.PrixAdherentIHM) * productOrder[product];
}
return prixTotal;
}
@@ -143,53 +163,63 @@ public float PriceNanAdher
}
return prixTotal;
}
-
}
///
/// Représente les produits du panier
///
public ObservableDictionary ProductOrder
- {
- get => productOrder;
- set => productOrder = value;
+ {
+ get => productOrder;
+ set => productOrder = value;
}
///
/// Représente le moyen de paiement sélectionné
///
- public string CurrentPaiement
- {
+ public string CurrentPaiement
+ {
get => currentPaiement;
- set
- {
+ set
+ {
currentPaiement = value;
NotifyPropertyChanged();
+ NotifyPropertyChanged(nameof(CreditCardPaymentVisibility));
}
}
+ public bool CreditCardPayment
+ {
+ get => (this.isAdherent ? this.PriceAdher : this.PriceNanAdher) >= 1;
+ }
+
+ public Visibility CreditCardPaymentVisibility
+ {
+ get => (this.CreditCardPayment || this.CurrentPaiement != "Carte" ? Visibility.Hidden : Visibility.Visible);
+ }
+
///
/// Représente l'adhérent qui va payer
///
- public AcompteViewModel AdherentPayer
+ public AccountViewModel AdherentPayer
{
get => adherentPayer;
- set
+ set
{
adherentPayer = value;
NotifyPropertyChanged();
- }
+ }
}
///
/// Permet d'afficher la sélection d'acompte
///
- public bool ShowPayAcompte
- {
- get => showPayAcompte;
+ public bool ShowPayAccount
+ {
+ get => showPayAccount;
set
{
- showPayAcompte = value;
+ showPayAccount = value;
NotifyPropertyChanged();
}
}
@@ -203,14 +233,15 @@ public bool IsAdherent
{
isAdherent = value;
NotifyPropertyChanged();
+ NotifyPropertyChanged(nameof(CreditCardPaymentVisibility));
}
}
- public bool ShowPayPaypal
- {
+ public bool ShowPayPaypal
+ {
get => showPayPaypal;
- set
- {
+ set
+ {
showPayPaypal = value;
NotifyPropertyChanged();
}
@@ -219,8 +250,8 @@ public bool ShowPayPaypal
public bool ShowPayBanque
{
get => showPayBanque;
- set
- {
+ set
+ {
showPayBanque = value;
NotifyPropertyChanged();
}
@@ -229,129 +260,167 @@ public bool ShowPayBanque
public string PrixIHM
{
get { return prixIhm; }
- set
- {
+ set
+ {
prixIhm = value;
NotifyPropertyChanged();
}
}
- public bool ShowPayLiquide
- {
+ public bool ShowPayLiquide
+ {
get => showPayLiquide;
- set
- {
+ set
+ {
showPayLiquide = value;
NotifyPropertyChanged();
}
}
+ public string TextArgentAdherentRetour
+ {
+ get => textArgentAdherentRetour;
+ set
+ {
+ textArgentAdherentRetour = value;
+ NotifyPropertyChanged();
+ }
+ }
+
#endregion
#region methods
+ private record class InfosPaiementAccount(AccountViewModel acompte, float argent, float prix);
+
+ private static string FindPaymentCodeFor(string paymentName)
+ {
+ return paymentName switch
+ {
+ "Acompte" => "Deposit",
+ "Paypal" => "Paypal",
+ "Carte" => "CreditCard",
+ "Liquide" => "Cash",
+ _ => throw new ArgumentException($"Méthode de paiement inconnue : « {paymentName} »")
+ };
+ }
+
///
/// Permet de payer les articles
///
- private async void PayArticles(object tuple = null)
+ private void PayArticles(object tuple = null)
+ {
+ if (MessageBoxErrorHandler.DoesntThrow(() => this.PayArticlesUnchecked(tuple)))
+ {
+ // Notifier la vue
+ this.ShowPayAccount = false;
+ this.ShowPayPaypal = false;
+ this.ShowPayLiquide = false;
+ this.ShowPayBanque = false;
+ }
+ }
+
+ private void PayArticlesUnchecked(object tuple = null)
{
string messageLog = $"Achat par {currentPaiement} ";
+ InfosPaiementAccount? paiementAccount = null;
// Paiement par acompte
- try
+ if (tuple is (AccountViewModel acompte, bool isAdherentCheckboxChecked))
{
- if (tuple is Tuple values)
+ float prix;
+ if (isAdherentCheckboxChecked)
{
- AcompteViewModel acompte = values.Item1;
- bool isAdherentCheckboxChecked = values.Item2;
-
- float argent = ConverterFormatArgent.ConvertToDouble(acompte.ArgentIHM);
- float prix;
- if (isAdherentCheckboxChecked)
- {
- prix = this.PriceAdher;
- }
- else
- {
- prix = this.PriceNanAdher;
- }
-
- if (argent - prix < 0)
- {
- throw new Exception("Pas assez d'argent sur l'acompte");
- }
-
- _ = Task.Run(() =>
- {
- StatAcompte stat = new StatAcompte(0, DateTime.Now, prix, acompte.Id);
- MainWindowViewModel.Instance.StatViewModel.AddStatAcompte(stat);
- statAcompteManager.CreateStat(stat);
- });
-
- string prixFormatted = ConverterFormatArgent.ConvertToString(prix);
- acompte.ArgentIHM = ConverterFormatArgent.ConvertToString(argent - prix);
- messageLog += $"{acompte.IdentifiantIHM} ";
- messageLog += $"({prixFormatted}) : ";
- acompte.UpdateAcompte(false);
-
+ prix = this.PriceAdher;
+ messageLog += $"({acompte.IdentifiantIHM} : {this.PriceAdherIHM}) : ";
}
else
{
- if (isAdherent)
- {
- messageLog += $"({this.PriceAdherIHM}) : ";
- }
- else
- {
- messageLog += $"{this.PriceNonAdherIHM} : ";
- }
+ prix = this.PriceNanAdher;
+ messageLog += $"{acompte.IdentifiantIHM} : {this.PriceNonAdherIHM} : ";
}
-
- foreach (ProductViewModel product in productOrder.Keys)
+ paiementAccount = new InfosPaiementAccount(
+ acompte,
+ argent: ConverterFormatArgent.ConvertToDouble(acompte.ArgentIHM),
+ prix
+ );
+
+
+ if (paiementAccount.argent - prix < 0)
{
- messageLog += product.NomProduitIHM + ", ";
+ throw new Exception("Pas assez d'argent sur l'acompte");
}
- // Gérer les stats
- ObservableDictionary productOrder2 = new ObservableDictionary(productOrder);
- _ = Task.Run(() =>
- {
- foreach (ProductViewModel product in productOrder2.Keys)
- {
- StatProduit stat = new StatProduit(0, DateTime.Now, productOrder2[product], product.Id);
- MainWindowViewModel.Instance.StatViewModel.AddStatProduit(stat);
- statProduitManager.CreateStat(stat);
+ orderManager.NewOrder("Deposit", acompte.IdentifiantIHM);
+ }
+ else
+ {
+ if (isAdherent)
+ {
+ orderManager.NewOrder(
+ FindPaymentCodeFor(currentPaiement),
+ Order.ANONYMOUS_MEMBER // le client est un adhérent, juste on sait pas qui
+ );
+ messageLog += $"({this.PriceAdherIHM}) : ";
+ }
+ else
+ {
+ orderManager.NewOrder(FindPaymentCodeFor(currentPaiement));
+ messageLog += $"{this.PriceNonAdherIHM} : ";
+ }
+ }
- product.QuantiteIHM -= productOrder2[product];
- product.UpdateProduct(false);
- }
- });
+ foreach (var kvp in productOrder)
+ {
+ orderManager.CurrentOrder.AddProduct(kvp.Key.Id, kvp.Value);
+ messageLog += kvp.Key.NomProduitIHM + ", ";
+ }
- // Log l'action
- Log log = new Log(DateTime.Now, 5, messageLog, MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- _ = Task.Run(() => MainWindowViewModel.Instance.LogManager.CreateLog(log));
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ // Envoyer le paiement à l'API
+ orderManager.ProcessOrder();
- this.ProductOrder.Clear();
- NotifyPropertyChanged(nameof(PriceAdherIHM));
- NotifyPropertyChanged(nameof(PriceNonAdherIHM));
- }
- catch (Exception ex)
+ // Terminer le paiment par acompte
+ if (paiementAccount is InfosPaiementAccount infos)
{
- MessageBox.Show(ex.Message);
+ _ = Task.Run(() =>
+ {
+ StatAccount stat = new StatAccount(0, DateTime.Now, infos.prix, infos.acompte.Id);
+ MainWindowViewModel.Instance.StatViewModel.AddStatAccount(stat);
+ statAccountManager.CreateStat(stat);
+ });
+ string prixFormatted = ConverterFormatArgent.ConvertToString(infos.prix);
+ infos.acompte.ArgentIHM = ConverterFormatArgent.ConvertToString(infos.argent - infos.prix);
+ infos.acompte.UpdateAccount(false, false);
+ this.TextArgentAdherentRetour = $"Il vous reste {infos.acompte.ArgentIHM}";
+ this.RetourAccountArgent = true;
}
+ // Gérer les stats
+ ObservableDictionary productOrder2 = new ObservableDictionary(productOrder);
+ _ = Task.Run(() =>
+ {
+ foreach (ProductViewModel product in productOrder2.Keys)
+ {
+ product.QuantiteIHM -= productOrder2[product];
+ product.UpdateLocalProduct();
+ StatProduit stat = new StatProduit(0, DateTime.Now, productOrder2[product], product.Id);
+ MainWindowViewModel.Instance.StatViewModel.AddStatProduit(stat);
+ statProduitManager.CreateStat(stat);
+ }
+ });
- // Notifier la vue
- this.ShowPayAcompte = false;
- this.ShowPayPaypal = false;
- this.ShowPayLiquide = false;
- this.ShowPayBanque = false;
-
+ // Log l'action
+ Log log = new Log(DateTime.Now, 5, messageLog, MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
+ _ = Task.Run(() => MainWindowViewModel.Instance.LogManager.CreateLog(log));
+ MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ this.ProductOrder.Clear();
+ NotifyPropertyChanged(nameof(PriceAdherIHM));
+ NotifyPropertyChanged(nameof(CreditCardPaymentVisibility));
+ NotifyPropertyChanged(nameof(PriceNonAdherIHM));
}
///
@@ -364,23 +433,26 @@ private void PreviewPayArticles()
switch (currentPaiement)
{
case "Acompte":
- this.ShowPayAcompte = true;
+ this.ShowPayAccount = true;
break;
case "Paypal":
PrixIHM = "Montant : " + (this.isAdherent ? this.PriceAdherIHM : this.PriceNonAdherIHM);
this.ShowPayPaypal = true;
break;
case "Carte":
- PrixIHM = "Montant : " + (this.isAdherent ? this.PriceAdherIHM : this.PriceNonAdherIHM);
- this.ShowPayBanque = true;
+ if (CreditCardPayment)
+ {
+ PrixIHM = "Montant : " + (this.isAdherent ? this.PriceAdherIHM : this.PriceNonAdherIHM);
+ this.ShowPayBanque = true;
+ }
break;
case "Liquide":
PrixIHM = "Montant : " + (this.isAdherent ? this.PriceAdherIHM : this.PriceNonAdherIHM);
- this.ShowPayLiquide=true;
+ this.ShowPayLiquide = true;
break;
}
}
-
+
}
///
@@ -396,9 +468,9 @@ public void AddProduct(object product)
if (produitIHM.QuantiteIHM - productOrder[produitIHM] > 0)
{
this.productOrder[produitIHM]++;
-
+
}
-
+
}
else
{
@@ -406,6 +478,7 @@ public void AddProduct(object product)
}
NotifyPropertyChanged(nameof(PriceAdherIHM));
+ NotifyPropertyChanged(nameof(CreditCardPaymentVisibility));
NotifyPropertyChanged(nameof(PriceNonAdherIHM));
}
@@ -426,6 +499,7 @@ private void RemoveProduct(object product)
NotifyPropertyChanged(nameof(PriceAdherIHM));
NotifyPropertyChanged(nameof(PriceNonAdherIHM));
+ NotifyPropertyChanged(nameof(CreditCardPaymentVisibility));
}
diff --git a/Couche IHM/Couche IHM/VueModeles/CategoryViewModel.cs b/Couche IHM/Couche IHM/VueModeles/CategoryViewModel.cs
index 97577c6..7a3a3be 100644
--- a/Couche IHM/Couche IHM/VueModeles/CategoryViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/CategoryViewModel.cs
@@ -97,8 +97,8 @@ public CategoryViewModel(CategoryManager categoryManager,Category category)
public void ActivateCategory()
{
// Mise à jour data
- category.Visible = !this.invisible;
- this.categoryManager.UpdateCategory(category);
+ category.Visible = true;
+ // TOUJOURS VISIBLE AHAHAHHAHA this.categoryManager.UpdateCategory(category);
}
///
@@ -108,7 +108,7 @@ public void UpdateCategory()
{
// Mise à jour data
category.NomCategory = this.nomCat;
- this.categoryManager.UpdateCategory(category);
+ MessageBoxErrorHandler.DoesntThrow(()=> this.categoryManager.UpdateCategory(category));
}
@@ -130,14 +130,16 @@ public void ResetCategory()
public void DeleteCategory()
{
// Mise à jour data
- this.categoryManager.DeleteCategory(category);
- foreach (ProductViewModel prod in MainWindowViewModel.Instance.ProductViewModel.Products.ToList().FindAll(x => x.CategoryIHM == this))
+ if (MessageBoxErrorHandler.DoesntThrow(() => this.categoryManager.DeleteCategory(category)))
{
- prod.DeleteCatNotify();
+ foreach (ProductViewModel prod in MainWindowViewModel.Instance.ProductViewModel.Products.ToList().FindAll(x => x.CategoryIHM == this))
+ {
+ prod.DeleteCatNotify();
+ }
+
+ // Notifier la vue
+ MainWindowViewModel.Instance.ProductViewModel.Categories.Remove(this);
}
-
- // Notifier la vue
- MainWindowViewModel.Instance.ProductViewModel.Categories.Remove(this);
}
diff --git a/Couche IHM/Couche IHM/VueModeles/Frame.cs b/Couche IHM/Couche IHM/VueModeles/Frame.cs
index 4980314..ca9095e 100644
--- a/Couche IHM/Couche IHM/VueModeles/Frame.cs
+++ b/Couche IHM/Couche IHM/VueModeles/Frame.cs
@@ -5,11 +5,13 @@ namespace Couche_IHM.VueModeles
public enum Frame
{
FRAMEACCUEIL,
- FRAMEACOMPTE,
+ FRAMEACCOUNT,
FRAMECAISSE,
FRAMESTOCK,
FRAMECOMPTES,
FRAMELOG,
- FRAMESTATISTIQUE
+ FRAMESTATISTIQUE,
+ FRAMETOPSTAT,
+ FRAMEEVOLSTAT
}
}
diff --git a/Couche IHM/Couche IHM/VueModeles/LogsViewModel.cs b/Couche IHM/Couche IHM/VueModeles/LogsViewModel.cs
index bc17f75..6cab18d 100644
--- a/Couche IHM/Couche IHM/VueModeles/LogsViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/LogsViewModel.cs
@@ -1,4 +1,5 @@
-using Couche_Métier;
+using Couche_Data.Interfaces;
+using Couche_Métier;
using Couche_Métier.Manager;
using Modeles;
using System;
@@ -8,7 +9,9 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
namespace Couche_IHM.VueModeles
{
@@ -17,7 +20,7 @@ public class LogsViewModel : INotifyPropertyChanged
#region attributes
private ObservableCollection logs = new ObservableCollection();
- private UserManager userManager;
+ private AccountManager userManager;
private LogManager logManager;
private string currentAuteur;
private int currentAnnee;
@@ -42,8 +45,12 @@ public class LogsViewModel : INotifyPropertyChanged
private bool selectVente;
private bool selectConnexion;
private bool selectProduct;
- private bool selectAcompte;
+ private bool selectAccount;
private bool selectCompte;
+ private CancellationTokenSource reloadCTS;
+ private DateTime nextPageLoadTime;
+ private TimeSpan pageLoadCooldown;
+ private IPaginatedLogReader? logsReader;
#endregion
#region constructor
@@ -51,7 +58,7 @@ public class LogsViewModel : INotifyPropertyChanged
///
/// Constructeur du logs vue modele
///
- public LogsViewModel(UserManager userManager,LogManager logManager)
+ public LogsViewModel(AccountManager userManager,LogManager logManager)
{
// Initialisation des datas
this.themeLog = new List();
@@ -64,11 +71,12 @@ public LogsViewModel(UserManager userManager,LogManager logManager)
currentMois = currentDate.ToString("MMMM");
currentAnnee = année;
this.SelectVente = true;
- this.SelectAcompte = false;
+ this.SelectAccount = false;
this.SelectConnexion = false;
this.SelectProduct = false;
this.SelectCompte = false;
- InitLogs();
+ this.reloadCTS = new CancellationTokenSource();
+ this.pageLoadCooldown = TimeSpan.FromMilliseconds(100);
}
#endregion
@@ -82,7 +90,7 @@ public string CurrentAuteur
set
{
currentAuteur = value;
- NotifyPropertyChanged(nameof(Logs));
+ this.ReloadFiltersInBackground();
}
}
///
@@ -93,8 +101,8 @@ public List Auteurs
get
{
List auteurs = new List() { "Tout le monde" };
- List users = this.userManager.GetComptes();
- foreach (User u in users)
+ List users = this.userManager.GetAdmins();
+ foreach (Account u in users)
{
auteurs.Add($"{u.Prenom} {u.Nom}");
}
@@ -105,27 +113,19 @@ public List Auteurs
///
/// Liste des logs
///
- public ObservableCollection Logs
+ public ObservableCollection Logs
{
- get
- {
- List logsFiltres = logs.ToList().FindAll(x => themeLog.Contains(x.IdTheme));
- if (currentAuteur != "Tout le monde")
- {
- logsFiltres = logsFiltres.FindAll(x => x.Auteur == currentAuteur);
- }
- return new ObservableCollection(logsFiltres);
- }
- set => logs = value;
+ get => this.logs;
+ set => logs = value;
}
///
/// Filtre afficher les ventes
///
- public bool SelectVente
- {
+ public bool SelectVente
+ {
get => selectVente;
- set
+ set
{
if (value)
{
@@ -136,7 +136,7 @@ public bool SelectVente
this.themeLog.Remove(5);
}
selectVente = value;
- NotifyPropertyChanged(nameof(Logs));
+ this.ReloadFiltersInBackground();
}
}
@@ -146,7 +146,7 @@ public bool SelectVente
public bool SelectConnexion
{
get => selectConnexion;
- set
+ set
{
if (value)
{
@@ -157,16 +157,16 @@ public bool SelectConnexion
this.themeLog.Remove(1);
}
selectConnexion = value;
- NotifyPropertyChanged(nameof(Logs));
- }
+ this.ReloadFiltersInBackground();
+ }
}
///
/// Filtre afficher les produits
///
- public bool SelectProduct
- {
+ public bool SelectProduct
+ {
get => selectProduct;
- set
+ set
{
if (value)
{
@@ -177,16 +177,16 @@ public bool SelectProduct
this.themeLog.Remove(3);
}
selectProduct = value;
- NotifyPropertyChanged(nameof(Logs));
+ this.ReloadFiltersInBackground();
}
}
///
/// Filtre afficher les acomptes
///
- public bool SelectAcompte
+ public bool SelectAccount
{
- get => selectAcompte;
+ get => selectAccount;
set
{
if (value)
@@ -197,18 +197,18 @@ public bool SelectAcompte
{
this.themeLog.Remove(2);
}
- selectAcompte = value;
- NotifyPropertyChanged(nameof(Logs));
+ selectAccount = value;
+ this.ReloadFiltersInBackground();
}
}
///
/// Filtre afficher les comptes
///
- public bool SelectCompte
- {
+ public bool SelectCompte
+ {
get => selectCompte;
- set
+ set
{
if (value)
{
@@ -219,7 +219,7 @@ public bool SelectCompte
this.themeLog.Remove(6);
}
selectCompte = value;
- NotifyPropertyChanged(nameof(Logs));
+ this.ReloadFiltersInBackground();
}
}
///
@@ -235,30 +235,28 @@ public bool SelectCompte
///
/// Mois sélectionné
///
- public string CurrentMois
- {
+ public string CurrentMois
+ {
get => currentMois;
set
{
currentMois = value;
- this.logs.Clear();
- InitLogs(this.mois.IndexOf(currentMois) + 1, this.currentAnnee);
- NotifyPropertyChanged(nameof(Logs));
+ //InitLogs(this.mois.IndexOf(currentMois) + 1, this.currentAnnee);
+ this.ReloadInBackground();
}
}
///
/// Annee selectionné
///
- public int CurrentAnnee
- {
+ public int CurrentAnnee
+ {
get => currentAnnee;
set
{
currentAnnee = value;
- this.logs.Clear();
- InitLogs(this.mois.IndexOf(currentMois) + 1, this.currentAnnee);
- NotifyPropertyChanged(nameof(Logs));
+ //InitLogs(this.mois.IndexOf(currentMois) + 1, this.currentAnnee);
+ this.ReloadInBackground();
}
}
#endregion
@@ -275,9 +273,9 @@ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
///
/// Permet d'initialiser la liste des logs
///
- public void InitLogs(int mois=0,int annee=0)
+ public void InitLogs(int mois = 0, int annee = 0)
{
- List logs = this.logManager.GetLogs(mois,annee);
+ List logs = this.logManager.GetLogs(mois, annee);
foreach (Log log in logs)
{
this.logs.Add(new LogViewModel(log));
@@ -292,11 +290,123 @@ public void InitLogs(int mois=0,int annee=0)
public void AddLog(LogViewModel log)
{
- if (mois.IndexOf(currentMois)+1 == Convert.ToInt16(log.DateTime.ToString("MM")) && currentAnnee == Convert.ToInt16(log.DateTime.ToString("yyyy")))
+ if (mois.IndexOf(currentMois) + 1 == Convert.ToInt16(log.DateTime.ToString("MM")) && currentAnnee == Convert.ToInt16(log.DateTime.ToString("yyyy")))
{
this.logs.Insert(0, log);
}
-
+
+ }
+
+ ///
+ /// Indique si une entrée doit être affiché ou non.
+ ///
+ /// L'entrée à tester.
+ /// si l'entrée peut être affichée.
+ private bool Filtrer(Log log)
+ {
+ if (!themeLog.Contains(log.Theme))
+ {
+ return false;
+ }
+ if (currentAuteur != "Tout le monde" && log.Auteur != currentAuteur)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ ///
+ /// Lance le chargement des logs en arrière-plan.
+ ///
+ public void ReloadInBackground()
+ {
+ this.StopLoading();
+ this.reloadCTS = new();
+ this.logsReader = this.logManager.GetLogsReader(this.mois.IndexOf(currentMois) + 1, this.currentAnnee);
+ Task.Run(() => this.ReloadAsync(this.reloadCTS.Token));
+ }
+
+ ///
+ /// Recharge les logs en changeant uniquement les filtres.
+ ///
+ public void ReloadFiltersInBackground()
+ {
+ // rien gardé en mémoire, on recharge tout
+ if (this.logsReader == null)
+ {
+ this.ReloadInBackground();
+ return;
+ }
+
+ this.StopLoading();
+ this.reloadCTS = new();
+ this.logsReader.Reset();
+ Task.Run(() => this.ReloadAsync(this.reloadCTS.Token));
+
+ }
+
+ ///
+ /// Arrête le chargement des logs.
+ ///
+ public void StopLoading()
+ {
+ this.reloadCTS?.Cancel();
+ }
+
+ ///
+ /// Charge les logs suivants.
+ ///
+ public void LoadNextPage()
+ {
+ if (DateTime.Now > this.nextPageLoadTime)
+ {
+ this.logsReader?.LoadNextPage();
+ this.nextPageLoadTime = DateTime.Now + this.pageLoadCooldown;
+ }
+ }
+
+ ///
+ /// Charge les logs.
+ ///
+ /// Un jeton d'annulation pour arrêter le chargement en cours.
+ private async Task ReloadAsync(CancellationToken ct = default)
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ this.logs.Clear();
+ });
+
+ if (this.logsReader == null) return;
+
+ int read = 0;
+ int added = 0;
+ await foreach (Log log in this.logsReader!.GetAsyncStream(ct))
+ {
+ read++;
+ if (this.Filtrer(log))
+ {
+ added++;
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ this.logs.Add(new LogViewModel(log));
+ });
+ }
+
+ // on a traité une page entière
+ if (read == this.logsReader.PageSize)
+ {
+ // si des éléments se sont fait filtrer, on charge la suivante
+ if (added < this.logsReader.PageSize)
+ {
+ read = 0;
+ this.logsReader!.LoadNextPage();
+ }
+ else
+ {
+ added = 0;
+ }
+ }
+ }
}
#endregion
diff --git a/Couche IHM/Couche IHM/VueModeles/MainWindowViewModel.cs b/Couche IHM/Couche IHM/VueModeles/MainWindowViewModel.cs
index 9cf2387..1a67597 100644
--- a/Couche IHM/Couche IHM/VueModeles/MainWindowViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/MainWindowViewModel.cs
@@ -18,36 +18,34 @@ public class MainWindowViewModel : INotifyPropertyChanged
{
#region singleton
private static MainWindowViewModel instance = null;
- public static MainWindowViewModel Instance
+
+ public static MainWindowViewModel Instance => instance ?? throw new NullReferenceException("Le MainWindowViewModel doit d'abord être instancié par la fenêtre.");
+
+ public static MainWindowViewModel GetInstanceFor(MainWindow mainWindow)
{
- get
+ if (instance == null)
{
- if (instance == null)
- {
- instance = new MainWindowViewModel();
- }
- return instance;
+ instance = new MainWindowViewModel(mainWindow);
}
+ return instance;
}
#endregion
#region viewmodels
- public AcomptesViewModel AdherentViewModel { get => adherentViewModel; set => adherentViewModel = value; }
+ public AccountsViewModel AccountsViewModel { get => accountsViewModel; set => accountsViewModel = value; }
public ProductsViewModel ProductViewModel { get => productViewModel; set => productViewModel = value; }
public PartenariatViewModel PartenariatViewModel { get => partenariatViewModel; set => partenariatViewModel = value; }
public CaisseViewModel CaisseViewModel { get => caisseViewModel; set => caisseViewModel = value; }
public LogsViewModel LogsViewModel { get => logsViewModel; set => logsViewModel = value; }
-
- public UsersViewModel UserViewModel { get => userViewModel; set => userViewModel = value; }
public StatistiqueViewModel StatViewModel { get => statViewModel; set => statViewModel = value; }
- private AcomptesViewModel adherentViewModel;
+ private AccountsViewModel accountsViewModel;
private ProductsViewModel productViewModel;
private PartenariatViewModel partenariatViewModel;
private CaisseViewModel caisseViewModel;
private LogsViewModel logsViewModel;
- private UsersViewModel userViewModel;
private StatistiqueViewModel statViewModel;
+ private MainWindow mainWindow;
#endregion
#region notify
@@ -60,14 +58,14 @@ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
#endregion
#region attributes
- private UserViewModel compteConnected;
+ private AccountViewModel compteConnected;
private Frame frame = Frame.FRAMEACCUEIL;
private LogManager logManager;
- private UserManager userManager;
- private AcompteManager acompteManager;
+ private AccountManager accountManager;
private ProductManager productManager;
- private StatAcompteManager statAcompteManager;
+ private StatAccountManager statAccountManager;
private StatProduitManager statProduitManager;
+ private OrderManager orderManager;
#endregion
#region events
@@ -82,7 +80,7 @@ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
///
/// Compte connecté à gallium
///
- public UserViewModel CompteConnected
+ public AccountViewModel CompteConnected
{
get => compteConnected;
set => compteConnected = value;
@@ -97,14 +95,7 @@ public LogManager LogManager
set => logManager = value;
}
- ///
- /// Permet de gérer les comptes
- ///
- public UserManager UserManager
- {
- get => userManager;
- set => userManager = value;
- }
+ public AccountManager AccountManager { get => accountManager; set => accountManager = value; }
///
@@ -133,7 +124,9 @@ public Uri Uri
}
}
-
+
+ public MainWindow MainWindow => mainWindow;
+
#endregion
@@ -141,26 +134,71 @@ public Uri Uri
///
/// Constructeur du mainwindow vue modele
///
- private MainWindowViewModel()
+ private MainWindowViewModel(MainWindow mainWindow)
{
- this.logManager = new LogManager();
- this.userManager = new UserManager();
this.productManager = new ProductManager();
- this.acompteManager = new AcompteManager();
- this.statAcompteManager = new StatAcompteManager();
+ this.accountManager = new AccountManager();
+ this.logManager = new LogManager(this.accountManager);
+ this.statAccountManager = new StatAccountManager();
this.statProduitManager = new StatProduitManager();
- this.adherentViewModel = new AcomptesViewModel(acompteManager);
+ this.orderManager = new OrderManager();
+ this.accountsViewModel = new AccountsViewModel(accountManager);
this.productViewModel = new ProductsViewModel(productManager);
- this.caisseViewModel = new CaisseViewModel(this.statAcompteManager,this.statProduitManager);
- this.statViewModel = new StatistiqueViewModel(productManager, acompteManager,statAcompteManager,statProduitManager);
- this.logsViewModel = new LogsViewModel(userManager, logManager);
- this.userViewModel = new UsersViewModel(this.userManager);
+ this.caisseViewModel = new CaisseViewModel(this.statAccountManager, this.statProduitManager, this.orderManager);
+ this.statViewModel = new StatistiqueViewModel(productManager, accountManager, statAccountManager, statProduitManager);
+ this.logsViewModel = new LogsViewModel(accountManager, logManager);
this.partenariatViewModel = new PartenariatViewModel();
-
+ this.mainWindow = mainWindow;
+
// Initialisation des events
- this.ChangeFrame = new RelayCommand(fram => this.Frame = (Frame)fram);
-
+ this.ChangeFrame = new RelayCommand(fram => ChangeFrameInit((Frame)fram));
}
+ ///
+ /// Permet de changer de frame et d'initialiser des données voulues
+ ///
+ /// Nouvelle frame à afficher
+ private void ChangeFrameInit(Frame frame)
+ {
+ // gestion de la sortie de l'ancienne frame
+ this.LeaveFrame(this.Frame);
+ // gestion de l'entrée sur une nouvelle frame
+ this.EnterFrame(frame);
+ // changement
+ this.Frame = frame;
+ }
+
+ ///
+ /// Appelée quand la frame change pour gérer la sortie de la frame.
+ ///
+ /// La frame actuelle qui va être remplacée.
+ private void LeaveFrame(Frame frame)
+ {
+ switch (frame)
+ {
+ case Frame.FRAMELOG:
+ this.logsViewModel.StopLoading();
+ break;
+ }
+ }
+
+ ///
+ /// Appelée quand la frame change pour gérer l'entrée de la nouvelle frame.
+ ///
+ /// La nouvelle frame qui va remplacer la frame actuelle.
+ private void EnterFrame(Frame frame)
+ {
+ switch (frame)
+ {
+ case Frame.FRAMECAISSE:
+ this.productViewModel.SearchFilter = "";
+ this.accountsViewModel.SearchFilter = "";
+ break;
+
+ case Frame.FRAMELOG:
+ this.logsViewModel.ReloadInBackground();
+ break;
+ }
+ }
}
}
diff --git a/Couche IHM/Couche IHM/VueModeles/ProductViewModel.cs b/Couche IHM/Couche IHM/VueModeles/ProductViewModel.cs
index 64c0ee7..22ce515 100644
--- a/Couche IHM/Couche IHM/VueModeles/ProductViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/ProductViewModel.cs
@@ -60,6 +60,10 @@ public int Id
get => product.ID;
}
+ public double test
+ {
+ get => Math.Round(product.PrixAdherent,2);
+ }
public double Opacity
{
get
@@ -244,6 +248,45 @@ public void DeleteCatNotify()
NotifyPropertyChanged(nameof(this.CategoryIHM));
}
+ ///
+ /// Permet de mettre à jour l'image si elle a été changée
+ ///
+ private void ChangeImageIfNeeded()
+ {
+ // Changer l'image
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (image.UriSource.ToString() != image2)
+ {
+ this.image2 = image.UriSource.ToString();
+ byte[] bitsImage = ImageManager.ConvertImageToBlob(image.UriSource.ToString());
+ ImageManager.CreateImageFromBlob(this.nomProduitIHM, bitsImage);
+ }
+ });
+
+ }
+
+ ///
+ /// Permet de mettre à jour le produit en local
+ ///
+ public void UpdateLocalProduct()
+ {
+ // Changer la data
+ this.product.Quantite = this.quantiteIHM;
+ this.product.NomProduit = this.nomProduitIHM;
+ this.product.Categorie = this.categoryManager.ListAllCategory().Find(x => x.NomCategory == categoryIHM.NomCat).IdCat;
+ this.product.PrixAdherent = ConverterFormatArgent.ConvertToDouble(this.prixAdherentIHM);
+ this.product.PrixNonAdherent = ConverterFormatArgent.ConvertToDouble(this.prixNonAdherentIHM);
+ ChangeImageIfNeeded();
+
+ // Notifier la vue
+ NotifyPropertyChanged(nameof(NomProduitIHM));
+ NotifyPropertyChanged(nameof(PrixAdherentIHM));
+ NotifyPropertyChanged(nameof(QuantiteIHM));
+ NotifyPropertyChanged(nameof(CategoryIHM));
+ NotifyPropertyChanged(nameof(isDisponible));
+
+ }
///
/// Permet de mettre à jour visuellement les modifications de l'adhérent
///
@@ -251,6 +294,8 @@ public void UpdateProduct(bool doLog = true)
{
if (this.categoryIHM != null)
{
+ UpdateLocalProduct();
+ MessageBoxErrorHandler.DoesntThrow(() => this.productManager.UpdateProduct(this.product));
// Log l'opération
if (doLog && product.Quantite != this.quantiteIHM)
@@ -269,34 +314,7 @@ public void UpdateProduct(bool doLog = true)
MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log2));
}
-
- if (doLog)
- {
-
- // Changer l'image
- if (image.UriSource.ToString() != image2)
- {
- this.image2 = image.UriSource.ToString();
- byte[] bitsImage = ImageManager.ConvertImageToBlob(image.UriSource.ToString());
- ImageManager.CreateImageFromBlob(this.nomProduitIHM, bitsImage);
- }
-
- }
-
- // Changer la data
- this.product.Quantite = this.quantiteIHM;
- this.product.NomProduit = this.nomProduitIHM;
- this.product.Categorie = this.categoryManager.ListAllCategory().Find(x => x.NomCategory == categoryIHM.NomCat).IdCat;
- this.product.PrixAdherent = ConverterFormatArgent.ConvertToDouble(this.prixAdherentIHM);
- this.product.PrixNonAdherent = ConverterFormatArgent.ConvertToDouble(this.prixNonAdherentIHM);
- this.productManager.UpdateProduct(this.product);
-
- // Notifier la vue
- NotifyPropertyChanged(nameof(NomProduitIHM));
- NotifyPropertyChanged(nameof(PrixAdherentIHM));
- NotifyPropertyChanged(nameof(QuantiteIHM));
- NotifyPropertyChanged(nameof(CategoryIHM));
- NotifyPropertyChanged(nameof(isDisponible));
+
MainWindowViewModel.Instance.ProductViewModel.ShowProductDetail = false;
MainWindowViewModel.Instance.ProductViewModel.ShowModifButtons = false;
}
@@ -313,15 +331,17 @@ public void UpdateProduct(bool doLog = true)
public void DeleteProduct()
{
// Changer la data
- this.productManager.RemoveProduct(this.product);
+ if (MessageBoxErrorHandler.DoesntThrow(() => this.productManager.RemoveProduct(this.product)))
+ {
- // Log l'action
- Log log = new Log(DateTime.Now, 3, $"Suppression du produit : {this.NomProduitIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
+ // Log l'action
+ Log log = new Log(DateTime.Now, 3, $"Suppression du produit : {this.NomProduitIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
+ MainWindowViewModel.Instance.LogManager.CreateLog(log);
- // Notifier la vue
- MainWindowViewModel.Instance.ProductViewModel.RemoveProduct(this);
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ // Notifier la vue
+ MainWindowViewModel.Instance.ProductViewModel.RemoveProduct(this);
+ MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ }
MainWindowViewModel.Instance.ProductViewModel.ShowProductDetail = false;
MainWindowViewModel.Instance.ProductViewModel.ShowModifButtons = false;
this.ShowConfirmationDelete = false;
@@ -344,21 +364,24 @@ public void CreateProduct()
this.product.Categorie = this.categoryManager.ListAllCategory().Find(x => x.NomCategory == categoryIHM.NomCat).IdCat;
this.product.PrixAdherent = ConverterFormatArgent.ConvertToDouble(this.prixAdherentIHM);
this.product.PrixNonAdherent = ConverterFormatArgent.ConvertToDouble(this.prixNonAdherentIHM);
- this.productManager.CreateProduct(this.product);
- this.action = "UPDATE";
- // Log l'action
- Log log = new Log(DateTime.Now, 3, $"Ajout du produit : {product.NomProduit}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
+ if (MessageBoxErrorHandler.DoesntThrow(() => this.productManager.CreateProduct(this.product)))
+ {
+ this.action = "UPDATE";
+ // Log l'action
+ Log log = new Log(DateTime.Now, 3, $"Ajout du produit : {product.NomProduit}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
+ MainWindowViewModel.Instance.LogManager.CreateLog(log);
- // Notifier la vue
- MainWindowViewModel.Instance.ProductViewModel.AddProduct(this);
- NotifyPropertyChanged(nameof(NomProduitIHM));
- NotifyPropertyChanged(nameof(QuantiteIHM));
- NotifyPropertyChanged(nameof(CategoryIHM));
- NotifyPropertyChanged(nameof(isDisponible));
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+
+ // Notifier la vue
+ MainWindowViewModel.Instance.ProductViewModel.AddProduct(this);
+ NotifyPropertyChanged(nameof(NomProduitIHM));
+ NotifyPropertyChanged(nameof(QuantiteIHM));
+ NotifyPropertyChanged(nameof(CategoryIHM));
+ NotifyPropertyChanged(nameof(isDisponible));
+ MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
+ }
MainWindowViewModel.Instance.ProductViewModel.ShowProductDetail = false;
MainWindowViewModel.Instance.ProductViewModel.ShowModifButtons = false;
}
@@ -404,7 +427,12 @@ public override bool Equals(object? obj)
nomProduitIHM == model.nomProduitIHM;
}
-
+ public override string? ToString()
+ {
+ return NomProduitIHM;
+ }
+
+
#endregion
}
diff --git a/Couche IHM/Couche IHM/VueModeles/ProductsViewModel.cs b/Couche IHM/Couche IHM/VueModeles/ProductsViewModel.cs
index 0d9baf2..b60decf 100644
--- a/Couche IHM/Couche IHM/VueModeles/ProductsViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/ProductsViewModel.cs
@@ -108,9 +108,9 @@ public ObservableCollection Products
return produitsIHM;
}
- set
- {
- products = value;
+ set
+ {
+ products = value;
}
}
@@ -133,23 +133,23 @@ public bool ShowModifButtons
public string SearchFilter
{
get => searchFilter;
- set
+ set
{
searchFilter = value;
NotifyPropertyChanged(nameof(Products));
-
- }
+
+ }
}
///
/// Permet de montrer la popup du produit
///
- public bool ShowProductDetail
- {
+ public bool ShowProductDetail
+ {
get => showProductDetail;
- set
- {
- showProductDetail = value;
+ set
+ {
+ showProductDetail = value;
NotifyPropertyChanged(nameof(ShowProductDetail));
}
}
@@ -157,12 +157,12 @@ public bool ShowProductDetail
///
/// Permet d'afficher la popup des catégories
///
- public bool ShowCategories
- {
+ public bool ShowCategories
+ {
get => showCategories;
set
- {
- showCategories = value;
+ {
+ showCategories = value;
NotifyPropertyChanged();
}
}
@@ -170,12 +170,12 @@ public bool ShowCategories
///
/// Permet d'afficher l'icone pour supprimer un produit
///
- public bool ShowDeleteProduct
- {
+ public bool ShowDeleteProduct
+ {
get => showDeleteProduct;
- set
+ set
{
- if (MainWindowViewModel.Instance.CompteConnected.RoleIHM.Name != "Conseil d'administration")
+ if (MainWindowViewModel.Instance.CompteConnected.Role.Name != "Conseil d'administration")
{
showDeleteProduct = value;
NotifyPropertyChanged();
@@ -229,12 +229,21 @@ public ProductsViewModel(ProductManager productManager)
#endregion
#region methods
+ private class ProductComparer : IComparer
+ {
+ public int Compare(Product? x, Product? y)
+ {
+ return StringComparer.CurrentCultureIgnoreCase.Compare(x?.NomProduit, y?.NomProduit);
+ }
+ }
+
///
/// Permet de récupérer la liste des adhérents
///
private void InitProducts()
{
List produitsMetier = this.productManager.GetProducts();
+ produitsMetier.Sort(new ProductComparer());
List categories = this.categories.ToList();
foreach (Product prd in produitsMetier)
{
@@ -243,8 +252,8 @@ private void InitProducts()
{
catProduit = categories.Find(x => x.Id == prd.Categorie);
}
-
- this.products.Add(new ProductViewModel(prd,this.productManager,this.categoryManager,catProduit));
+
+ this.products.Add(new ProductViewModel(prd, this.productManager, this.categoryManager, catProduit));
}
}
@@ -257,7 +266,7 @@ private void InitCategories()
List categories = this.categoryManager.ListAllCategory();
foreach (Category cat in categories)
{
- this.categories.Add(new CategoryViewModel(this.categoryManager,cat));
+ this.categories.Add(new CategoryViewModel(this.categoryManager, cat));
}
}
@@ -271,13 +280,13 @@ private void OpenProductDetails(string action)
if (action == "NEW" || currentProduct == null || currentProduct.Action == "NEW")
{
ShowDeleteProduct = false;
- CurrentProduct = new ProductViewModel(new Product(),this.productManager,this.categoryManager ,null,"NEW");
+ CurrentProduct = new ProductViewModel(new Product(), this.productManager, this.categoryManager, null, "NEW");
}
else
{
ShowDeleteProduct = true;
}
-
+
ShowProductDetail = true;
}
@@ -287,11 +296,13 @@ private void OpenProductDetails(string action)
public void CreateCategory()
{
// Mise à jour data
- CategoryViewModel cat = new CategoryViewModel(this.categoryManager,new Category(0,"New",true));
- this.categoryManager.CreateCategory(cat.Category);
+ CategoryViewModel cat = new CategoryViewModel(this.categoryManager, new Category(0, "New", true));
+ if (MessageBoxErrorHandler.DoesntThrow(() => this.categoryManager.CreateCategory(cat.Category)))
+ {
- // Notifier la vue
- Categories.Add(cat);
+ // Notifier la vue
+ Categories.Add(cat);
+ }
}
diff --git a/Couche IHM/Couche IHM/VueModeles/StatAcompteViewModel.cs b/Couche IHM/Couche IHM/VueModeles/StatAcompteViewModel.cs
index ba88026..c512c54 100644
--- a/Couche IHM/Couche IHM/VueModeles/StatAcompteViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/StatAcompteViewModel.cs
@@ -1,21 +1,24 @@
using Couche_Métier.Utilitaire;
using Modeles;
+using System.Globalization;
namespace Couche_IHM.VueModeles
{
- public class StatAcompteViewModel
+ public class StatAccountViewModel
{
#region attributes
- private AcompteViewModel adherentViewModel;
+ private AccountViewModel adherentViewModel;
private float argent;
+ private StatAccount stat;
#endregion
#region constructor
///
/// Constructeur du stat acompte vue modele
///
- public StatAcompteViewModel(StatAcompte stat,AcompteViewModel adherentViewModel)
+ public StatAccountViewModel(StatAccount stat,AccountViewModel adherentViewModel)
{
+ this.stat = stat;
this.adherentViewModel = adherentViewModel;
this.argent = stat.Money;
}
@@ -23,9 +26,9 @@ public StatAcompteViewModel(StatAcompte stat,AcompteViewModel adherentViewModel)
#region properties
///
- /// Acompte de la stat
+ /// Account de la stat
///
- public AcompteViewModel AdherentViewModel { get => adherentViewModel; set => adherentViewModel = value; }
+ public AccountViewModel AccountsViewModel { get => adherentViewModel; set => adherentViewModel = value; }
///
/// Argent dépensé formatté
///
@@ -37,6 +40,12 @@ public string FormattedArgent
}
}
+
+ public string Date
+ {
+ get => stat.Date.ToString("MMMM", new CultureInfo("fr-FR"));
+ }
+
///
/// Argent dépensé par l'acompte
///
diff --git a/Couche IHM/Couche IHM/VueModeles/StatProduitViewModel.cs b/Couche IHM/Couche IHM/VueModeles/StatProduitViewModel.cs
index 8529492..e217e0d 100644
--- a/Couche IHM/Couche IHM/VueModeles/StatProduitViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/StatProduitViewModel.cs
@@ -1,4 +1,6 @@
using Modeles;
+using System;
+using System.Globalization;
namespace Couche_IHM.VueModeles
{
@@ -7,6 +9,7 @@ public class StatProduitViewModel
#region attributes
private ProductViewModel productViewModel;
private int purchaseCount;
+ private StatProduit stat;
#endregion
#region constructor
@@ -15,12 +18,17 @@ public class StatProduitViewModel
///
public StatProduitViewModel(StatProduit stat,ProductViewModel product)
{
+ this.stat = stat;
this.purchaseCount = stat.Number_sales;
this.productViewModel = product;
}
#endregion
#region properties
+ public string Date
+ {
+ get => stat.Date.ToString("MMMM", new CultureInfo("fr-FR"));
+ }
///
/// Produit acheté
///
diff --git a/Couche IHM/Couche IHM/VueModeles/StatistiqueViewModel.cs b/Couche IHM/Couche IHM/VueModeles/StatistiqueViewModel.cs
index 9d6bfa9..f086353 100644
--- a/Couche IHM/Couche IHM/VueModeles/StatistiqueViewModel.cs
+++ b/Couche IHM/Couche IHM/VueModeles/StatistiqueViewModel.cs
@@ -1,12 +1,17 @@
using Couche_Métier.Manager;
+using DocumentFormat.OpenXml.Drawing.Charts;
using MaterialDesignThemes.Wpf;
using Modeles;
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using System.Windows;
namespace Couche_IHM.VueModeles
{
@@ -15,12 +20,22 @@ public class StatistiqueViewModel : INotifyPropertyChanged
#region attributes
private StatProduitManager statProduitManager;
- private AcompteManager acompteManager;
+ private AccountManager accountManager;
private List statsProduit = new List();
- private StatAcompteManager statAcompteManager;
+ private StatAccountManager statAccountManager;
private ProductManager productManager;
- private List statsAcompte = new List();
+ private List statsAccount = new List();
+ private List typeEvolutions;
+ private ProductViewModel currentEvolProduct;
+ private AccountViewModel currentEvolAcompte;
+ private string typeEvolutionChoisi;
+ private string typeRechercheStat;
+
+ private DateTime date = DateTime.Now;
+ private int anneeSelected;
+
+
#endregion
#region inotify
@@ -33,6 +48,153 @@ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
#region properties
+ public List AnneeList
+ {
+ get
+ {
+ return new List() { DateTime.Now.Year, DateTime.Now.Year-1, DateTime.Now.Year - 2 };
+ }
+ }
+
+ public List TypeRechercheList
+ {
+ get
+ {
+ return new List() { "Par semaine", "Par mois", "Par année" };
+ }
+ }
+ ///
+ /// Représente la date de recherche
+ ///
+ public string DateIHM
+ {
+ get
+ {
+ string dateFormatted = "";
+ switch (typeRechercheStat)
+ {
+ case "Par semaine":
+ dateFormatted = $"Du {date.Day} au {date.AddDays(6).Day} {date:MMMM} {date:yyyy}";
+ break;
+ case "Par mois":
+ dateFormatted = $"{date:MMMM} {date:yyyy}";
+ break;
+ case "Par année":
+ dateFormatted = $"{date:yyyy}";
+ break;
+ }
+ return dateFormatted;
+ }
+ }
+
+ ///
+ /// Représente le top des acompts de la semaine choisie
+ ///
+ public List BestAcomptes
+ {
+ get
+ {
+
+
+ List statAcomptes = new List();
+ switch (typeRechercheStat)
+ {
+ case "Par semaine":
+ CultureInfo ci = CultureInfo.CurrentCulture;
+ CalendarWeekRule rule = ci.DateTimeFormat.CalendarWeekRule;
+ DayOfWeek firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
+ int week = ci.Calendar.GetWeekOfYear(date, rule, firstDayOfWeek) - 1;
+ statAcomptes = this.statAccountManager.GetStatsByWeek(week, date.Year).OrderByDescending(x => x.Money).Take(10).ToList();
+ break;
+ case "Par mois":
+ statAcomptes = this.statAccountManager.GetStatsByMonth(date.Month, date.Year).OrderByDescending(x => x.Money).Take(10).ToList();
+ break;
+ case "Par année":
+ statAcomptes = this.statAccountManager.GetStatsByYear(date.Year).OrderByDescending(x => x.Money).Take(10).ToList();
+ break;
+ }
+
+ List statAcomptesVM = new List();
+ foreach (StatAccount stat in statAcomptes)
+ {
+ if (accountManager.GetAdhérents().Find(x => x.Id == stat.Account_Id) is Account acompte)
+ {
+ statAcomptesVM.Add(new StatAccountViewModel(stat, new AccountViewModel(acompte, this.accountManager)));
+ }
+ }
+
+ return statAcomptesVM;
+ }
+ }
+ ///
+ /// Représente le top des produits de la semaine choisie
+ ///
+ public List BestProducts
+ {
+ get
+ {
+ List statProduit = new List();
+ switch (typeRechercheStat)
+ {
+ case "Par semaine":
+ CultureInfo ci = CultureInfo.CurrentCulture;
+ CalendarWeekRule rule = ci.DateTimeFormat.CalendarWeekRule;
+ DayOfWeek firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
+ int week = ci.Calendar.GetWeekOfYear(date, rule, firstDayOfWeek) - 1;
+ statProduit = this.statProduitManager.GetStatsByWeek(week, date.Year).OrderByDescending(x => x.Number_sales).Take(10).ToList();
+ break;
+ case "Par mois":
+ statProduit = this.statProduitManager.GetStatsByMonth(date.Month, date.Year).OrderByDescending(x => x.Number_sales).Take(10).ToList();
+ break;
+ case "Par année":
+ statProduit = this.statProduitManager.GetStatsByYear(date.Year).OrderByDescending(x => x.Number_sales).Take(10).ToList();
+ break;
+ }
+
+
+ List statProductVM = new List();
+ foreach (StatProduit stat in statProduit)
+ {
+ if (productManager.GetProducts().Find(x => x.ID == stat.Product_id) is Product productLogic)
+ {
+ statProductVM.Add(new StatProduitViewModel(stat, new ProductViewModel(productLogic, null, null, null)));
+ }
+ }
+
+ return statProductVM;
+ }
+ }
+
+
+ private ObservableCollection evolProducts;
+
+
+ ///
+ /// Représente le top des produits de la semaine choisie
+ ///
+ public ObservableCollection EvolProducts
+ {
+ set => evolProducts = value;
+ get
+ {
+ return evolProducts;
+ }
+ }
+
+ private ObservableCollection evolAcomptes;
+
+
+ ///
+ /// Représente le top des produits de la semaine choisie
+ ///
+ public ObservableCollection EvolAcomptes
+ {
+ set => evolAcomptes = value;
+ get
+ {
+ return evolAcomptes;
+ }
+ }
///
/// Podium des trois meilleurs produits
///
@@ -47,35 +209,225 @@ public List PodiumProduits
///
/// Podium des trois meilleurs acomptes
///
- public List PodiumAcompte
+ public List PodiumAccount
{
get
{
- return statsAcompte.OrderByDescending(x => x.Argent).Take(4).ToList();
+ return statsAccount.OrderByDescending(x => x.Argent).Take(4).ToList();
}
}
#endregion
+ #region events
+ public RelayCommand FindAccount { get; set;}
+ public RelayCommand FindProduct { get; set;}
+ public RelayCommand Next { get; set; }
+ public RelayCommand Previous { get; set; }
+ public string TypeRechercheStat
+ {
+ get => typeRechercheStat;
+ set
+ {
+ typeRechercheStat = value;
+ NotifyPropertyChanged(nameof(this.DateIHM));
+ NotifyPropertyChanged(nameof(this.BestProducts));
+ NotifyPropertyChanged(nameof(this.BestAcomptes));
+ }
+ }
+
+
+ public string TitreEvolution
+ {
+ get
+ {
+ string titre = "";
+ if (typeEvolutionChoisi == "Produit")
+ {
+ if (currentEvolProduct != null)
+ {
+ titre = $"Vente de {currentEvolProduct.NomProduitIHM} par mois";
+ }
+ }
+ else
+ {
+ if (currentEvolAcompte != null)
+ {
+ titre = $"Dépenses de {currentEvolAcompte.NomCompletIHM} par mois";
+ }
+ }
+
+ return titre;
+ }
+ }
+ ///
+ /// Représente les types d'évolutions disponibles
+ ///
+ public List TypeEvolutions
+ {
+ get => typeEvolutions;
+ set => typeEvolutions = value;
+ }
+ ///
+ /// Représente le type d'évolution choisi
+ ///
+ public string TypeEvolutionChoisi
+ {
+ get => typeEvolutionChoisi;
+ set
+ {
+ typeEvolutionChoisi = value;
+ NotifyPropertyChanged();
+ NotifyPropertyChanged(nameof(this.TitreEvolution));
+ }
+ }
+
+ ///
+ /// Représente le produit dont on souhaite connaitre l'évolution
+ ///
+ public ProductViewModel CurrentEvolProduct
+ {
+ get => currentEvolProduct;
+ set {
+ currentEvolProduct = value;
+ InitStatOfProduct(currentEvolProduct.Id);
+ NotifyPropertyChanged(nameof(this.TitreEvolution));
+ }
+ }
+
+ public int AnneeSelected
+ {
+ get => anneeSelected;
+ set
+ {
+ anneeSelected = value;
+ if (typeEvolutionChoisi == "Produit")
+ {
+ InitStatOfProduct(currentEvolProduct.Id);
+ }
+ else
+ {
+ InitStatOfAcompte(currentEvolAcompte.Id);
+ }
+ }
+
+ }
+
+ public AccountViewModel CurrentEvolAccount
+ {
+ get => currentEvolAcompte;
+ set
+ {
+ currentEvolAcompte = value;
+ InitStatOfAcompte(currentEvolAcompte.Id);
+ NotifyPropertyChanged(nameof(this.TitreEvolution));
+ }
+ }
+ #endregion
#region constructor
///
/// Constructeur du statistique vue modele
///
- public StatistiqueViewModel(ProductManager produtManager,AcompteManager acompteManager,StatAcompteManager statAcompte,StatProduitManager statProduit)
+ public StatistiqueViewModel(ProductManager produtManager,AccountManager accountManager,StatAccountManager statAccount,StatProduitManager statProduit)
{
// Initialisation des objets métiers
this.statProduitManager = statProduit;
- this.statAcompteManager = statAcompte;
+ this.statAccountManager = statAccount;
this.productManager = produtManager;
- this.acompteManager = acompteManager;
+ this.accountManager = accountManager;
+ this.typeEvolutions = new List() { "Produit", "Acompte" };
+ this.typeEvolutionChoisi = typeEvolutions[0];
+
+ // Initialisation des events
+ this.FindProduct = new RelayCommand(product => GoToProductDetails((ProductViewModel)product));
+ this.FindAccount = new RelayCommand(acompte => GoToAccountDetails((AccountViewModel)acompte));
+ this.Next = new RelayCommand(x => GetStatNext());
+ this.Previous = new RelayCommand(x => GetStatPrevious());
+
+ DayOfWeek firstDay = DayOfWeek.Monday;
+ int diff = date.DayOfWeek - firstDay;
+ if (diff < 0)
+ {
+ diff += 7;
+ }
+ date = date.AddDays(-diff);
+
+
+
// Initialisation des datas
InitStatsProduit();
- InitStatsAcompte();
+ InitStatsAccount();
+ this.evolProducts = new ObservableCollection();
+ this.evolAcomptes = new ObservableCollection();
+ this.TypeRechercheStat = "Par semaine";
+ this.anneeSelected = this.AnneeList[0];
+
}
#endregion
#region methods
+ ///
+ /// Permet d'obtenir les stats d'apres
+ ///
+ private void GetStatNext()
+ {
+ switch(typeRechercheStat)
+ {
+ case "Par semaine":
+ date = date.AddDays(7);
+ break;
+ case "Par mois":
+ date = date.AddMonths(1);
+ break;
+ case "Par année":
+ date = date.AddYears(1);
+ break;
+ }
+ NotifyPropertyChanged(nameof(this.BestAcomptes));
+ NotifyPropertyChanged(nameof(this.BestProducts));
+ NotifyPropertyChanged(nameof(this.DateIHM));
+ }
+
+ ///
+ /// Permet d'obtenir les stats du jour d'avant
+ ///
+ private void GetStatPrevious()
+ {
+ switch (typeRechercheStat)
+ {
+ case "Par semaine":
+ date = date.AddDays(-7);
+ break;
+ case "Par mois":
+ date = date.AddMonths(-1);
+ break;
+ case "Par année":
+ date = date.AddYears(-1);
+ break;
+ }
+
+ NotifyPropertyChanged(nameof(this.BestAcomptes));
+ NotifyPropertyChanged(nameof(this.BestProducts));
+ NotifyPropertyChanged(nameof(this.DateIHM));
+ }
+ ///
+ /// Permet de retrouver l'acompte en liant avec la stat et de redirigier sur ses détails
+ ///
+ private void GoToAccountDetails(AccountViewModel acompte)
+ {
+ MainWindowViewModel.Instance.Frame = Frame.FRAMEACCOUNT;
+ MainWindowViewModel.Instance.AccountsViewModel.CurrentAccount = MainWindowViewModel.Instance.AccountsViewModel.Accounts.ToList().Find(x => x.Id == acompte.Id);
+ }
+ ///
+ /// Permet de retrouver le produit en liant avec la stat et de redirigier sur ses détails
+ ///
+ private void GoToProductDetails(ProductViewModel product)
+ {
+ MainWindowViewModel.Instance.Frame = Frame.FRAMESTOCK;
+ MainWindowViewModel.Instance.ProductViewModel.CurrentProduct = MainWindowViewModel.Instance.ProductViewModel.GetProducts().Find(x => x.Id == product.Id);
+ }
+
///
/// Permet d'ajouter une stat de produit
///
@@ -96,18 +448,18 @@ public void AddStatProduit(StatProduit stat)
///
/// Permet d'ajouter une stat d'acompte
///
- public void AddStatAcompte(StatAcompte stat)
+ public void AddStatAccount(StatAccount stat)
{
- StatAcompteViewModel? acompteStat = this.statsAcompte.Find(x => x.AdherentViewModel.Id == stat.Acompte_Id);
+ StatAccountViewModel? acompteStat = this.statsAccount.Find(x => x.AccountsViewModel.Id == stat.Account_Id);
if (acompteStat != null)
{
acompteStat.Argent += stat.Money;
}
else
{
- this.statsAcompte.Add(new StatAcompteViewModel(stat, new AcompteViewModel(acompteManager.GetAdhérents().Find(x => x.Id == stat.Acompte_Id),null)));
+ this.statsAccount.Add(new StatAccountViewModel(stat, new AccountViewModel(accountManager.GetAdhérents().Find(x => x.Id == stat.Account_Id),this.accountManager)));
}
- NotifyPropertyChanged(nameof(this.PodiumAcompte));
+ NotifyPropertyChanged(nameof(this.PodiumAccount));
}
///
@@ -116,26 +468,80 @@ public void AddStatAcompte(StatAcompte stat)
public void InitStatsProduit()
{
this.statsProduit.Clear();
- List statProduit = this.statProduitManager.GetStats();
+ CultureInfo ci = CultureInfo.CurrentCulture;
+ CalendarWeekRule rule = ci.DateTimeFormat.CalendarWeekRule;
+ DayOfWeek firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
+ int currentWeek = ci.Calendar.GetWeekOfYear(DateTime.Now, rule, firstDayOfWeek) - 1;
+ List statProduit = this.statProduitManager.GetStatsByWeek(currentWeek, DateTime.Now.Year);
foreach (StatProduit stat in statProduit)
{
- this.statsProduit.Add(new StatProduitViewModel(stat, new ProductViewModel(productManager.GetProducts().Find(x => x.ID == stat.Product_id), null, null, null)));
+ if (productManager.GetProducts().Find(x => x.ID == stat.Product_id) is Product productLogic)
+ {
+ this.statsProduit.Add(new StatProduitViewModel(stat, new ProductViewModel(productLogic, null, null, null)));
+ }
}
+ NotifyPropertyChanged(nameof(this.PodiumProduits));
+
}
+ ///
+ /// Permet d'initialiser les statistiques d'un produit
+ ///
+ /// id du produit
+ public void InitStatOfProduct(int product_id)
+ {
+ this.evolProducts.Clear();
+ List statProduit = this.statProduitManager.GetStatBOfProductByMonth(anneeSelected,product_id);
+ foreach (StatProduit stat in statProduit)
+ {
+ if (productManager.GetProducts().Find(x => x.ID == stat.Product_id) is Product productLogic)
+ {
+ this.evolProducts.Add(new StatProduitViewModel(stat, new ProductViewModel(productLogic, null, null, null)));
+ }
+ }
+ NotifyPropertyChanged(nameof(this.EvolProducts));
+ }
+
+ ///
+ /// Permet d'initialiser les statistiques d'un acompte
+ ///
+ /// id de l'acompte
+ public void InitStatOfAcompte(int acompte_id)
+ {
+ this.evolAcomptes.Clear();
+ List statAcomptes = this.statAccountManager.GetStatBOfAcompteByMonth(anneeSelected, acompte_id);
+ foreach (StatAccount stat in statAcomptes)
+ {
+ if (accountManager.GetAdhérents().Find(x => x.Id == stat.Account_Id) is Account acompte)
+ {
+ this.evolAcomptes.Add(new StatAccountViewModel(stat, new AccountViewModel(acompte, this.accountManager)));
+ }
+ }
+ NotifyPropertyChanged(nameof(this.EvolAcomptes));
+ }
///
/// Permet d'initialiser les stats des acomptes
///
- public void InitStatsAcompte()
+ public void InitStatsAccount()
{
- this.statsAcompte.Clear();
- List statAcompte = this.statAcompteManager.GetStats();
- foreach (StatAcompte stat in statAcompte)
+ this.statsAccount.Clear();
+ CultureInfo ci = CultureInfo.CurrentCulture;
+ CalendarWeekRule rule = ci.DateTimeFormat.CalendarWeekRule;
+ DayOfWeek firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
+ int currentWeek = ci.Calendar.GetWeekOfYear(DateTime.Now, rule, firstDayOfWeek) - 1;
+ List statAccount = this.statAccountManager.GetStatsByWeek(currentWeek,DateTime.Now.Year);
+ foreach (StatAccount stat in statAccount)
{
- this.statsAcompte.Add(new StatAcompteViewModel(stat, new AcompteViewModel(acompteManager.GetAdhérents().Find(x => x.Id == stat.Acompte_Id), null)));
+ if (accountManager.GetAdhérents().Find(x => x.Id == stat.Account_Id) is Account acompte)
+ {
+ this.statsAccount.Add(new StatAccountViewModel(stat, new AccountViewModel(acompte, this.accountManager)));
+ }
}
+ NotifyPropertyChanged(nameof(this.PodiumAccount));
}
+
+
#endregion
}
}
diff --git a/Couche IHM/Couche IHM/VueModeles/UserViewModel.cs b/Couche IHM/Couche IHM/VueModeles/UserViewModel.cs
deleted file mode 100644
index 35ebbdf..0000000
--- a/Couche IHM/Couche IHM/VueModeles/UserViewModel.cs
+++ /dev/null
@@ -1,294 +0,0 @@
-
-using Couche_Métier.Manager;
-using Couche_Métier.Utilitaire;
-using Modeles;
-using System;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using System.Windows;
-
-namespace Couche_IHM.VueModeles
-{
- public class UserViewModel : INotifyPropertyChanged
- {
-
- #region notify
- public event PropertyChangedEventHandler? PropertyChanged;
- private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- #endregion
-
- #region attributes
- private User user;
- private string nom;
- private string prenom;
- private string email;
- private string mdpIHM1 = "";
- private string mdpIHM2 = "";
- private string action;
- private Role role;
- private bool showConfirmationDelete;
- private UserManager userManager;
-
- #endregion
-
- #region events
- public RelayCommand ShowUpdate { get; set; }
- public RelayCommand ResetU { get; set; }
- public RelayCommand UpdateU { get; set; }
- public RelayCommand DeleteU { get; set; }
- public RelayCommand CancelDeleteU { get; set; }
- public RelayCommand PreviewDeleteU { get; set; }
- public RelayCommand CreateU { get;set; }
-
- #endregion
-
- #region properties
- ///
- /// Nom de l'utilisateur
- ///
- public string NomIHM { get => nom; set => nom = value; }
- ///
- /// Prénom de l'utilisateur
- ///
- public string PrenomIHM { get => prenom; set => prenom = value; }
- ///
- /// Mail de l'utilisateur
- ///
- public string EmailIHM { get => email; set => email = value; }
- ///
- /// Nom complet de l'utilisateur
- ///
- public string NomCompletIHM
- {
- get => prenom + " " + nom;
- }
- ///
- /// Role de l'utilisateur
- ///
- public Role RoleIHM { get => role; set => role = value; }
- ///
- /// Nouveau mot de passe 1
- ///
- public string MdpIHM2 { get => mdpIHM2; set => mdpIHM2 = value; }
- ///
- /// Nouveau mot de passe 2
- ///
- public string MdpIHM1 { get => mdpIHM1; set => mdpIHM1 = value; }
- ///
- /// Action à réaliser sur l'utilisateur
- ///
- public string Action
- {
- get => action;
- set { action = value;
- NotifyPropertyChanged();
- }
- }
-
- ///
- /// Permet de montrer le popup de confirmation de suppression
- ///
- public bool ShowConfirmationDelete
- {
- get => showConfirmationDelete;
- set
- {
- showConfirmationDelete = value;
- NotifyPropertyChanged();
- }
- }
-
-
- ///
- /// Est ce que l'utilisateur a accès aux comptes
- ///
- public bool CanSeeCompteBool
- {
- get
- {
- return (role.Name == "Administrateur");
-
- }
- }
-
-
- ///
- /// Est ce que l'utilisateur a accès aux comptes
- ///
- public double CanSeeCompte
- {
- get
- {
- double d = 0.5;
- if (role.Name == "Administrateur")
- {
- d = 1;
- }
- return d;
- }
- }
-
- #endregion
-
- #region constructor
- ///
- /// Constructeur de l'utilisateur vue modele
- ///
- public UserViewModel(User user, UserManager userManager)
- {
- // Initialisation des datas
- this.action = "UPDATE";
- this.user = user;
- this.nom = user.Nom;
- this.prenom = user.Prenom;
- this.email = user.Mail;
- this.role = userManager.GetRoles().Find(x => x.Id == user.IdRole);
- this.userManager = userManager;
-
- // Initialisation des events
- this.ResetU = new RelayCommand(x => this.ResetUser());
- this.ShowUpdate = new RelayCommand(x =>
- {
- MainWindowViewModel.Instance.UserViewModel.CurrentUser = this;
- MainWindowViewModel.Instance.UserViewModel.OpenUserDetails("UPDATE"); });
- this.UpdateU = new RelayCommand(x => this.UpdateUser());
- this.CreateU = new RelayCommand(x => this.CreateUser());
- this.DeleteU = new RelayCommand(x => this.DeleteUser());
- this.CancelDeleteU= new RelayCommand(x => ShowConfirmationDelete = false);
- this.PreviewDeleteU = new RelayCommand(x => this.ShowConfirmationDelete = true);
- }
- #endregion
-
- #region methods
- ///
- /// Permet de mettre à jour visuellement les modifications de l'user
- ///
- public void UpdateUser()
- {
- if (this.mdpIHM1 == this.mdpIHM2)
- {
- // Changer la data
- this.user.Nom = this.nom;
- this.user.Prenom = this.prenom;
- this.user.Mail = this.email;
- this.user.IdRole = this.role.Id;
- if (this.mdpIHM1 != "")
- {
- this.user.HashedPassword = CryptString.Hash(this.mdpIHM2);
- }
- this.userManager.UpdateCompte(this.user);
- this.MdpIHM1 = "";
- this.MdpIHM2 = "";
-
- // Log l'action
- Log log = new Log(DateTime.Now, 6, $"Modification du compte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
-
- // Notifier la vue
- NotifyPropertyChanged(nameof(this.NomCompletIHM));
- NotifyPropertyChanged(nameof(this.NomIHM));
- NotifyPropertyChanged(nameof(this.PrenomIHM));
- NotifyPropertyChanged(nameof(this.EmailIHM));
- NotifyPropertyChanged(nameof(this.RoleIHM));
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
- MainWindowViewModel.Instance.UserViewModel.ShowModifCreateUser = false;
- }
- else
- {
- MessageBox.Show("Les deux mots de passe ne correspondent pas");
- }
-
- }
-
- ///
- /// Permet de créer visuellement les modifications de l'user
- ///
- public void CreateUser()
- {
- if (this.mdpIHM1 == this.mdpIHM2)
- {
- // Changer la data
- this.user.Nom = this.nom;
- this.user.Prenom = this.prenom;
- this.user.Mail = this.email;
- this.user.IdRole = this.role.Id;
- if (this.mdpIHM1 != "")
- {
- this.user.HashedPassword = CryptString.Hash(this.mdpIHM2);
- this.userManager.CreateCompte(this.user);
- this.MdpIHM1 = "";
- this.MdpIHM2 = "";
- this.action = "UPDATE";
-
- // Log l'action
- Log log = new Log(DateTime.Now, 6, $"Création du compte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
-
- // Notifier la vue
- NotifyPropertyChanged(nameof(this.NomIHM));
- NotifyPropertyChanged(nameof(this.PrenomIHM));
- NotifyPropertyChanged(nameof(this.EmailIHM));
- NotifyPropertyChanged(nameof(this.RoleIHM));
- MainWindowViewModel.Instance.UserViewModel.AddUser(this);
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
- MainWindowViewModel.Instance.UserViewModel.ShowModifCreateUser = false;
- }
- else
- {
- MessageBox.Show("Les deux mots de passe sont vides");
- }
-
- }
- else
- {
- MessageBox.Show("Les deux mots de passe ne correspondent pas");
- }
-
- }
-
-
- ///
- /// Permet de reset les propriétés de l'user
- ///
- public void ResetUser()
- {
- // Initialisation propriétés
- this.nom = user.Nom;
- this.prenom = user.Prenom;
- this.email = user.Mail;
- this.role = userManager.GetRoles().Find(x => x.Id == user.IdRole);
-
- // Notifier la vue
- NotifyPropertyChanged(nameof(NomIHM));
- NotifyPropertyChanged(nameof(PrenomIHM));
- NotifyPropertyChanged(nameof(EmailIHM));
- NotifyPropertyChanged(nameof(RoleIHM));
-
- MainWindowViewModel.Instance.UserViewModel.ShowModifCreateUser = false;
- }
-
- ///
- /// Permet de reset les propriétés de l'user
- ///
- public void DeleteUser()
- {
- // Initialisation propriétés
- this.userManager.RemoveCompte(this.user);
-
- // Log l'action
- Log log = new Log(DateTime.Now, 6, $"Suppression du compte : {this.NomCompletIHM}", MainWindowViewModel.Instance.CompteConnected.NomCompletIHM);
- MainWindowViewModel.Instance.LogManager.CreateLog(log);
-
- // Notifier la vue
- MainWindowViewModel.Instance.UserViewModel.RemoveUser(this);
- MainWindowViewModel.Instance.LogsViewModel.AddLog(new LogViewModel(log));
- MainWindowViewModel.Instance.UserViewModel.ShowModifCreateUser = false;
- ShowConfirmationDelete = false;
- }
- #endregion
-
- }
-}
diff --git a/Couche IHM/Couche IHM/VueModeles/UsersViewModel.cs b/Couche IHM/Couche IHM/VueModeles/UsersViewModel.cs
deleted file mode 100644
index 08f4a46..0000000
--- a/Couche IHM/Couche IHM/VueModeles/UsersViewModel.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-
-using Couche_Métier.Manager;
-using Modeles;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace Couche_IHM.VueModeles
-{
- public class UsersViewModel : INotifyPropertyChanged
- {
-
- #region notify
- public event PropertyChangedEventHandler? PropertyChanged;
- private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- #endregion
-
- #region attributes
- private List roles;
- private ObservableCollection users = new ObservableCollection();
- private UserManager userManager;
-
- private UserViewModel currentUser;
-
- private bool showDeleteUser;
- private bool showModifCreateUser = false;
-
-
- #endregion
-
- #region properties
- ///
- /// Liste des utilisateurs
- ///
- public ObservableCollection Users
- {
- get => users;
- set => users = value;
- }
-
- ///
- /// Permet de montrer la fenetre pour modifier et créer un user
- ///
- public bool ShowModifCreateUser
- {
- get => showModifCreateUser;
- set
- {
- showModifCreateUser = value;
- NotifyPropertyChanged();
- }
- }
-
- ///
- /// Liste des roles disponibles aux users
- ///
- public List Roles { get => roles; set => roles = value; }
-
- ///
- /// Utilisateur sélectionné
- ///
- public UserViewModel CurrentUser
- {
- get => currentUser;
- set
- {
- currentUser = value;
- NotifyPropertyChanged();
- }
- }
- ///
- /// Permet d'afficher l'option pour supprimer un utilisateur
- ///
- public bool ShowDeleteUser
- {
- get => showDeleteUser;
- set
- {
- showDeleteUser = value;
- NotifyPropertyChanged();
- }
- }
-
- #endregion
-
- #region events
- public RelayCommand OpenUser { get; set; }
- #endregion
-
- #region constructor
- ///
- /// Constructeur de l'utilisateur vue modele
- ///
- public UsersViewModel(UserManager userManager)
- {
- // Initialisation des datas
- this.userManager = userManager;
- this.roles = userManager.GetRoles();
- InitUsers();
-
- // Initialisation des events
- this.OpenUser = new RelayCommand(x => this.OpenUserDetails((string)x));
- }
- #endregion
-
- #region methods
-
- ///
- /// Permet de récupérer la liste des users
- ///
- private void InitUsers()
- {
- List users = this.userManager.GetComptes();
-
- foreach (User user in users)
- {
- this.users.Add(new UserViewModel(user, this.userManager));
- }
- }
-
- ///
- /// Permet d'ouvrir les détails du compte
- ///
- public void OpenUserDetails(string action)
- {
- if (action == "NEW")
- {
- ShowDeleteUser = false;
- CurrentUser = new UserViewModel(new User(), this.userManager);
- CurrentUser.Action = "NEW";
- }
- else
- {
- ShowDeleteUser = true;
- }
-
- ShowModifCreateUser = true;
- }
-
-
- ///
- /// Permet d'ajouter un compte
- ///
- public void AddUser(UserViewModel user)
- {
- this.users.Add(user);
- NotifyPropertyChanged(nameof(Users));
-
- }
-
- ///
- /// Permet de supprimer un compte
- ///
- ///
- public void RemoveUser(UserViewModel user)
- {
- this.users.Remove(user);
- NotifyPropertyChanged(nameof(Users));
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git "a/Couche IHM/Couche M\303\251tier/Couche M\303\251tier.csproj" "b/Couche IHM/Couche M\303\251tier/Couche M\303\251tier.csproj"
index a947149..bd80607 100644
--- "a/Couche IHM/Couche M\303\251tier/Couche M\303\251tier.csproj"
+++ "b/Couche IHM/Couche M\303\251tier/Couche M\303\251tier.csproj"
@@ -10,10 +10,14 @@
+
+
+
+
diff --git "a/Couche IHM/Couche M\303\251tier/DevelopmentInfo.cs" "b/Couche IHM/Couche M\303\251tier/DevelopmentInfo.cs"
new file mode 100644
index 0000000..dd8508f
--- /dev/null
+++ "b/Couche IHM/Couche M\303\251tier/DevelopmentInfo.cs"
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Couche_Métier
+{
+ public static class DevelopmentInfo
+ {
+ public static bool isDevelopment;
+ }
+}
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/AccountManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/AccountManager.cs"
new file mode 100644
index 0000000..d38b840
--- /dev/null
+++ "b/Couche IHM/Couche M\303\251tier/Manager/AccountManager.cs"
@@ -0,0 +1,151 @@
+using Couche_Data.Dao;
+using Couche_Data.Interfaces;
+using DocumentFormat.OpenXml.Spreadsheet;
+using GalliumPlusApi.Dao;
+using Modeles;
+
+namespace Couche_Métier.Manager
+{
+ public class AccountManager
+ {
+ #region attributes
+ ///
+ /// Dao permettant de gérer les données des acomptes
+ ///
+ private IAccountDao adhérentDao;
+
+ ///
+ /// Liste des acomptes
+ ///
+ private List adhérents = new List();
+
+ ///
+ /// Liste des rôles
+ ///
+ private List roles;
+ #endregion
+
+ #region constructor
+ ///
+ /// Constructeur de la classe adhérentManager
+ ///
+ public AccountManager()
+ {
+ if (DevelopmentInfo.isDevelopment)
+ {
+ this.adhérentDao = new AccountDAO();
+ }
+ else
+ {
+ this.adhérentDao = new AccountDao();
+ }
+
+
+ // Récupération des adhérents
+ this.roles = adhérentDao.GetRoles();
+ this.adhérents = adhérentDao.GetAdhérents();
+ }
+ #endregion
+
+ #region methods
+ ///
+ /// Permet de récupérer la liste des roles
+ ///
+ /// les roles
+ public List GetRoles()
+ {
+ return this.roles;
+ }
+ ///
+ /// Permet de créer un nouvel adhérent
+ ///
+ /// adhérent à créer
+ public void CreateAdhérent(Account adhérent)
+ {
+ adhérentDao.CreateAdhérent(adhérent);
+ adhérents.Add(adhérent);
+ }
+
+ ///
+ /// Permet de supprimer un adhérent
+ ///
+ /// adhérent à supprimer
+ public void RemoveAdhérent(Account adhérent)
+ {
+ adhérentDao.RemoveAdhérent(adhérent);
+ adhérents.Remove(adhérent);
+ }
+
+
+ ///
+ /// Permet de mettre à jour les adhérents
+ ///
+ /// adhérent à modifier
+ public void UpdateAdhérent(Account adhérent)
+ {
+ adhérentDao.UpdateAdhérent(adhérent);
+ Account adhér = adhérents.Find(adh => adh.Id == adhérent.Id);
+ adhér.Nom = adhérent.Nom;
+ adhér.Prenom = adhérent.Prenom;
+ adhér.Mail = adhérent.Mail;
+ adhér.RoleId = adhérent.RoleId;
+ adhér.Identifiant = adhérent.Identifiant;
+ adhér.Argent = adhérent.Argent;
+ adhér.IsMember = adhérent.IsMember;
+ adhér.Formation = adhérent.Formation;
+ }
+
+
+ ///
+ /// Permet de récupérer tous les adhérents
+ ///
+ /// tous les adhérents
+ public List GetAdhérents()
+ {
+ return this.adhérents;
+ }
+
+ ///
+ /// Permet de récupérer tous les membres du CA / Bureau
+ ///
+ /// tous les membres du bureau et du ca
+ public List GetAdmins()
+ {
+ return this.adhérents.FindAll(x => x.RoleId != 2);
+ }
+
+ ///
+ /// Permet de se connecter à un utilisatuer
+ ///
+ ///
+ ///
+ ///
+ public static Account ConnectCompte(string identifiant, string password)
+ {
+ SessionDao dao = new();
+
+ var result = dao.LogIn(identifiant, password);
+ Account? user = result?.Item1;
+
+ if (user == null)
+ {
+ throw new Exception("Mauvaise combinaison identifiant/mot de passe");
+ }
+
+ Role? role = result?.Item2;
+ user.RoleId = role.Id;
+
+ if (role?.Name == "Adhérent")
+ {
+ throw new Exception("Le compte n'a pas les permissions pour se connecter");
+ }
+
+ DevelopmentInfo.isDevelopment = user.RoleId == 11 ? true : false;
+
+ return user;
+ }
+
+ #endregion
+
+ }
+}
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/AcompteManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/AcompteManager.cs"
deleted file mode 100644
index ab9ee39..0000000
--- "a/Couche IHM/Couche M\303\251tier/Manager/AcompteManager.cs"
+++ /dev/null
@@ -1,86 +0,0 @@
-
-using Couche_Data.Dao;
-using Couche_Data.Interfaces;
-using Modeles;
-
-namespace Couche_Métier.Manager
-{
- public class AcompteManager
- {
- #region attributes
- ///
- /// Dao permettant de gérer les données des acomptes
- ///
- private IAcompteDao adhérentDao;
-
- ///
- /// Liste des acomptes
- ///
- private List adhérents = new List();
- #endregion
-
- #region constructor
- ///
- /// Constructeur de la classe adhérentManager
- ///
- public AcompteManager()
- {
- this.adhérentDao = new AcompteDAO();
-
- // Récupération des adhérents
- adhérents = adhérentDao.GetAdhérents();
-
- }
- #endregion
-
- #region methods
- ///
- /// Permet de créer un nouvel adhérent
- ///
- /// adhérent à créer
- public void CreateAdhérent(Acompte adhérent)
- {
- adhérentDao.CreateAdhérent(adhérent);
- adhérents.Add(adhérent);
- }
-
- ///
- /// Permet de supprimer un adhérent
- ///
- /// adhérent à supprimer
- public void RemoveAdhérent(Acompte adhérent)
- {
- adhérentDao.RemoveAdhérent(adhérent);
- adhérents.Remove(adhérent);
- }
-
-
- ///
- /// Permet de mettre à jour les adhérents
- ///
- /// adhérent à modifier
- public void UpdateAdhérent(Acompte adhérent)
- {
- adhérentDao.UpdateAdhérent(adhérent);
- Acompte adhér = adhérents.Find(adh => adh.Id == adhérent.Id);
- adhér.Nom = adhérent.Nom;
- adhér.Prenom = adhérent.Prenom;
- adhér.Argent = adhérent.Argent;
- adhér.StillAdherent = adhérent.StillAdherent;
- adhér.Formation = adhérent.Formation;
- }
-
-
- ///
- /// Permet de récupérer tous les adhérents
- ///
- /// tous les adhérents
- public List GetAdhérents()
- {
- return this.adhérents;
- }
-
-#endregion
-
- }
-}
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/CategoryManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/CategoryManager.cs"
index 9451f7e..50e6192 100644
--- "a/Couche IHM/Couche M\303\251tier/Manager/CategoryManager.cs"
+++ "b/Couche IHM/Couche M\303\251tier/Manager/CategoryManager.cs"
@@ -1,6 +1,5 @@
-
-using Couche_Data.Dao;
-using Couche_Data.Interfaces;
+using Couche_Data.Interfaces;
+using GalliumPlusApi.Dao;
using Modeles;
namespace Couche_Métier.Manager
@@ -29,7 +28,7 @@ public class CategoryManager
///
public CategoryManager()
{
- this.iCategory = new CategoryDAO();
+ this.iCategory = new CategoryDao();
categories = this.iCategory.ListALlCategory();
}
#endregion
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/LogManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/LogManager.cs"
index 866f22f..a0d3772 100644
--- "a/Couche IHM/Couche M\303\251tier/Manager/LogManager.cs"
+++ "b/Couche IHM/Couche M\303\251tier/Manager/LogManager.cs"
@@ -1,8 +1,8 @@
-using Couche_Data;
-using Couche_Data.Dao;
+using Couche_Data.Dao;
+using Couche_Data.Interfaces;
+using GalliumPlusApi.Dao;
using Modeles;
-
namespace Couche_Métier.Manager
{
public class LogManager
@@ -11,7 +11,7 @@ public class LogManager
///
/// Permet d'accéder aux données
///
- private LogDAO logDao;
+ private ILogDAO logDao;
///
/// Liste des logs
@@ -23,32 +23,41 @@ public class LogManager
///
/// Constructeur du log Manager
///
- public LogManager()
+ public LogManager(AccountManager users)
{
- logDao = new LogDAO();
+ if (DevelopmentInfo.isDevelopment)
+ {
+
+ logDao = new LogDAO();
+ }
+ else
+ {
+ logDao = new LogDao(users.GetAdmins());
+ }
+
+
Task.Run(() =>
{
- int annee = Convert.ToInt16(DateTime.Now.ToString("yyyy"));
- int mois = Convert.ToInt16(DateTime.Now.ToString("MM"));
+ int annee = Convert.ToInt32(DateTime.Now.ToString("yyyy"));
+ int mois = Convert.ToInt32(DateTime.Now.ToString("MM"));
this.logs = this.logDao.GetLogs(mois, annee);
});
-
}
#endregion
#region methods
public List GetLogs(int mois = 0,int annee=0)
{
- List logs = new List();
+ List logsList;
if (mois == 0 || annee == 0)
{
- logs = this.logs;
+ logsList = this.logs;
}
else
{
- logs = this.logDao.GetLogs(mois, annee);
+ logsList = this.logDao.GetLogs(mois, annee);
}
- return logs;
+ return logsList;
}
@@ -57,6 +66,12 @@ public void CreateLog(Log log)
this.logs.Insert(0, log);
this.logDao.CreateLog(log);
}
+
+ public IPaginatedLogReader GetLogsReader(int mois, int annee)
+ {
+ return this.logDao.GetLogsReader(mois, annee);
+ }
+
#endregion
}
}
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/OrderManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/OrderManager.cs"
new file mode 100644
index 0000000..7120a44
--- /dev/null
+++ "b/Couche IHM/Couche M\303\251tier/Manager/OrderManager.cs"
@@ -0,0 +1,50 @@
+using Couche_Data.Dao;
+using Couche_Data.Interfaces;
+using DocumentFormat.OpenXml.Presentation;
+using GalliumPlusApi.Dao;
+using Modeles;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Couche_Métier.Manager
+{
+ public class OrderManager
+ {
+ private IOrderDao dao;
+ private Order? currentOrder;
+
+ public Order CurrentOrder => currentOrder!;
+
+ public OrderManager()
+ {
+ if (DevelopmentInfo.isDevelopment)
+ {
+ dao = new OrderDAO();
+ }
+ else
+ {
+ dao = new OrderDao();
+ }
+
+ }
+
+ public void NewOrder(string paymentMethod, string customer = null)
+ {
+ currentOrder = new Order(paymentMethod, customer);
+ }
+
+ public void ClearOrder()
+ {
+ currentOrder = null;
+ }
+
+ public void ProcessOrder()
+ {
+ dao.ProcessOrder(currentOrder!);
+ ClearOrder();
+ }
+ }
+}
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/ProductManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/ProductManager.cs"
index 3b4d749..3f3e898 100644
--- "a/Couche IHM/Couche M\303\251tier/Manager/ProductManager.cs"
+++ "b/Couche IHM/Couche M\303\251tier/Manager/ProductManager.cs"
@@ -1,6 +1,7 @@
using Couche_Data.Dao;
using Couche_Data.Interfaces;
+using GalliumPlusApi.Dao;
using Modeles;
@@ -29,7 +30,15 @@ public class ProductManager
///
public ProductManager()
{
- this.productDAO = new ProductDAO();
+ if (DevelopmentInfo.isDevelopment)
+ {
+ this.productDAO = new ProductDAO();
+ }
+ else
+ {
+ this.productDAO = new ProductDao();
+ }
+
this.products = new List(this.productDAO.GetProducts());
}
#endregion
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/StatAcompteManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/StatAcompteManager.cs"
index 6fd0a61..757be84 100644
--- "a/Couche IHM/Couche M\303\251tier/Manager/StatAcompteManager.cs"
+++ "b/Couche IHM/Couche M\303\251tier/Manager/StatAcompteManager.cs"
@@ -1,44 +1,76 @@
-using Couche_Data;
-using Couche_Data.Dao;
+using Couche_Data.Dao;
+using Couche_Data.Interfaces;
+using GalliumPlusApi.Dao;
using Modeles;
namespace Couche_Métier.Manager
{
- public class StatAcompteManager
+ public class StatAccountManager
{
#region attributes
///
/// Dao permettant de gérer les données des stats d'acompte
///
- private StatAcompteDAO dao;
+ private IStatAccountDAO dao;
///
/// Liste des stats d'acompte
///
- private List statAcompteList;
+ private List statAccountList;
#endregion
#region constructor
///
/// Constructeur du statProduit Manager
///
- public StatAcompteManager()
+ public StatAccountManager()
{
- dao = new StatAcompteDAO();
- Task.Run(() => this.statAcompteList = dao.GetStat());
+ if (DevelopmentInfo.isDevelopment)
+ {
+ dao = new StatAccountDAO();
+ }
+ else
+ {
+ dao = new StatAccountDao();
+ }
+
+ this.statAccountList = new List();
+
}
#endregion
#region methods
- public void CreateStat(StatAcompte stat)
+ public void CreateStat(StatAccount stat)
{
dao.CreateStat(stat);
}
- public List GetStats()
+ public List GetStatsByWeek(int semaine, int year )
{
- return this.statAcompteList;
+
+ this.statAccountList = dao.GetStatByWeek(semaine,year);
+ return this.statAccountList;
+ }
+
+ public List GetStatsByMonth(int month, int year)
+ {
+
+ this.statAccountList = dao.GetStatByMonth(month, year);
+ return this.statAccountList;
+ }
+
+ public List GetStatBOfAcompteByMonth(int year, int acompte_id)
+ {
+ statAccountList = dao.GetStatBOfAcompteByMonth(year, acompte_id);
+ return this.statAccountList;
+ }
+
+ public List GetStatsByYear(int year)
+ {
+
+ this.statAccountList = dao.GetStatByYear(year);
+ return this.statAccountList;
}
#endregion
}
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/StatProduitManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/StatProduitManager.cs"
index ee1155e..1f25f84 100644
--- "a/Couche IHM/Couche M\303\251tier/Manager/StatProduitManager.cs"
+++ "b/Couche IHM/Couche M\303\251tier/Manager/StatProduitManager.cs"
@@ -1,6 +1,7 @@
-using Couche_Data;
-using Couche_Data.Dao;
+using GalliumPlusApi.Dao;
+using Couche_Data.Interfaces;
using Modeles;
+using Couche_Data.Dao;
namespace Couche_Métier.Manager
{
@@ -10,7 +11,7 @@ public class StatProduitManager
///
/// Dao permettant de gérer les données des stats produits
///
- private StatProduitDAO dao;
+ private IStatProduitDAO dao;
///
/// Liste des stats des produits
@@ -24,8 +25,16 @@ public class StatProduitManager
///
public StatProduitManager()
{
- dao = new StatProduitDAO();
- Task.Run(()=> statProduitList = dao.GetStat());
+ if (DevelopmentInfo.isDevelopment)
+ {
+ dao = new StatProduitDAO();
+ }
+ else
+ {
+ dao = new StatProduitDao();
+ }
+
+
}
#endregion
@@ -35,8 +44,27 @@ public void CreateStat(StatProduit stat)
dao.CreateStat(stat);
}
- public List GetStats()
+ public List GetStatsByWeek(int semaine,int year)
+ {
+ statProduitList = dao.GetStatByWeek(semaine,year);
+ return this.statProduitList;
+ }
+
+ public List GetStatsByMonth(int month, int year)
+ {
+ statProduitList = dao.GetStatByMonth(month, year);
+ return this.statProduitList;
+ }
+
+ public List GetStatBOfProductByMonth(int year,int product_id)
+ {
+ statProduitList = dao.GetStatBOfProductByMonth(year,product_id);
+ return this.statProduitList;
+ }
+
+ public List GetStatsByYear(int year)
{
+ statProduitList = dao.GetStatByYear(year);
return this.statProduitList;
}
#endregion
diff --git "a/Couche IHM/Couche M\303\251tier/Manager/UserManager.cs" "b/Couche IHM/Couche M\303\251tier/Manager/UserManager.cs"
deleted file mode 100644
index a4217a8..0000000
--- "a/Couche IHM/Couche M\303\251tier/Manager/UserManager.cs"
+++ /dev/null
@@ -1,117 +0,0 @@
-
-using Couche_Data.Dao;
-using Couche_Data.Interfaces;
-using Couche_Métier.Utilitaire;
-using Modeles;
-
-
-namespace Couche_Métier.Manager
-{
- ///
- /// Manager des utilisateurs gallium
- ///
- public class UserManager
- {
- #region attributes
- ///
- /// Dao pour gérer les données des users
- ///
- private IUserDAO userDao;
-
- ///
- /// Liste des comptes
- ///
- private List comptes;
-
- ///
- /// Liste des rôles
- ///
- private List roles;
- #endregion
-
- #region constructor
- ///
- /// Constructeur du manager des comptes
- ///
- public UserManager()
- {
- this.userDao = new UserDAO();
- this.comptes = this.userDao.GetComptes();
- this.roles = this.userDao.GetRoles();
- }
- #endregion
-
- #region methods
-
- ///
- /// Permet de créer un compte
- ///
- /// compte à créer
- public void CreateCompte(User compte)
- {
- userDao.CreateCompte(compte);
- comptes.Add(compte);
- }
-
- ///
- /// Permet d'obtenir tous les comptes
- ///
- /// tous les comptes
- public List GetComptes()
- {
- return comptes;
- }
-
- /// Permet d'obtenir tous les comptes
- ///
- /// tous les comptes
- public List GetRoles()
- {
- return roles;
- }
-
- ///
- /// Permet de supprimer un compte
- ///
- /// compte à supprimer
- public void RemoveCompte(User compte)
- {
- userDao.RemoveCompte(compte);
- comptes.Remove(compte);
- }
-
- ///
- /// Permet de mettre à jour un compte
- ///
- /// compte à modifier
- public void UpdateCompte(User compte)
- {
- userDao.UpdateCompte(compte);
- User comp =comptes.Find(x => x.ID == compte.ID);
- comp.HashedPassword = compte.HashedPassword;
- comp.Nom = compte.Nom;
- comp.Prenom = compte.Prenom;
- comp.Mail = compte.Mail;
- comp.IdRole = compte.IdRole;
- }
-
- ///
- /// Permet de se connecter à un utilisatuer
- ///
- ///
- ///
- ///
- public User? ConnectCompte(string identifiant,string password)
- {
- User? user = this.comptes.Find(x => x.Mail == identifiant);
- User? userFinal = null;
- if (user != null &&CryptString.Verify(password, user.HashedPassword))
- {
- userFinal = user;
- }
-
- return userFinal;
- }
- #endregion
- }
-}
diff --git "a/Couche IHM/Couche M\303\251tier/Utilitaire/CryptString.cs" "b/Couche IHM/Couche M\303\251tier/Utilitaire/CryptString.cs"
index 8140ebd..51e54a1 100644
--- "a/Couche IHM/Couche M\303\251tier/Utilitaire/CryptString.cs"
+++ "b/Couche IHM/Couche M\303\251tier/Utilitaire/CryptString.cs"
@@ -1,5 +1,8 @@
+using System.Text;
using BC = BCrypt.Net.BCrypt;
+using Konscious.Security.Cryptography;
+using System.Security.Cryptography;
namespace Couche_Métier.Utilitaire
{
@@ -25,5 +28,16 @@ public static bool Verify(string message,string encoded)
{
return BC.Verify(message, encoded);
}
+
+ public static byte[] SaltAndHash(string password, string salt)
+ {
+
+ byte[] saltedPassword = Encoding.UTF8.GetBytes(password + salt);
+ Argon2id argon2id = new(saltedPassword);
+ argon2id.MemorySize = 19456;
+ argon2id.Iterations = 2;
+ argon2id.DegreeOfParallelism = 1;
+ return argon2id.GetBytes(32);
+ }
}
}
diff --git a/Couche IHM/GalliumPlus.sln b/Couche IHM/GalliumPlus.sln
index 19291f6..e6bb851 100644
--- a/Couche IHM/GalliumPlus.sln
+++ b/Couche IHM/GalliumPlus.sln
@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Couche Data", "Couche Data\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Modeles", "Modeles\Modeles.csproj", "{2DB5D1B3-23F7-4588-AF56-DF548D681ED9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GalliumPlusApi", "GalliumPlusApi\GalliumPlusApi.csproj", "{B71AFCAA-E57B-45D9-989B-6C9A01F62E95}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,6 +35,10 @@ Global
{2DB5D1B3-23F7-4588-AF56-DF548D681ED9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DB5D1B3-23F7-4588-AF56-DF548D681ED9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DB5D1B3-23F7-4588-AF56-DF548D681ED9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B71AFCAA-E57B-45D9-989B-6C9A01F62E95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B71AFCAA-E57B-45D9-989B-6C9A01F62E95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B71AFCAA-E57B-45D9-989B-6C9A01F62E95}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B71AFCAA-E57B-45D9-989B-6C9A01F62E95}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Couche IHM/GalliumPlusApi/ApiConfig.cs b/Couche IHM/GalliumPlusApi/ApiConfig.cs
new file mode 100644
index 0000000..8e83ded
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/ApiConfig.cs
@@ -0,0 +1,32 @@
+namespace GalliumPlusApi
+{
+ internal class ApiConfig
+ {
+ private static ApiConfig? current;
+
+ public static ApiConfig Current
+ {
+ get
+ {
+ if (current == null)
+ {
+ current = new();
+ }
+ return current;
+ }
+ }
+
+ private string apiKey;
+ private string host;
+
+ public string ApiKey => apiKey;
+
+ public string Host => host;
+
+ private ApiConfig()
+ {
+ apiKey = "galliumv2";
+ host = "api.gallium.etiq-dijon.fr";
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/CompatibilityHelpers/Format.cs b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/Format.cs
new file mode 100644
index 0000000..5334cf9
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/Format.cs
@@ -0,0 +1,12 @@
+namespace GalliumPlusApi.CompatibilityHelpers
+{
+ internal static class Format
+ {
+ public static decimal? FloatToMonetary(float value)
+ {
+ if (value < 0) return null;
+ string roundedRepr = value.ToString("0.00");
+ return decimal.Parse(roundedRepr);
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/CompatibilityHelpers/LogThemeMapper.cs b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/LogThemeMapper.cs
new file mode 100644
index 0000000..bd97987
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/LogThemeMapper.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GalliumPlusApi.CompatibilityHelpers
+{
+ public static class LogThemeMapper
+ {
+ public static int? ActionKindToLogTheme(string actionKind)
+ {
+ return actionKind switch
+ {
+ "LogIn" => 1,
+ "EditProductsOrCategories" => 3,
+ "EditUsersOrRoles" => 6,
+ "Purchase" => 5,
+ "Deposit" => 2,
+ _ => null
+ };
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/CompatibilityHelpers/Random.cs b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/Random.cs
new file mode 100644
index 0000000..d23c04f
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/Random.cs
@@ -0,0 +1,18 @@
+using System.Text;
+
+namespace GalliumPlusApi.CompatibilityHelpers
+{
+ internal static class RandomHelper
+ {
+ public static string RandomUsername()
+ {
+ Random rng = new();
+ StringBuilder sb = new("user");
+ for (int i = 0; i < 6; i++)
+ {
+ sb.Append(rng.Next(0, 10));
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/CompatibilityHelpers/UserIdMapper.cs b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/UserIdMapper.cs
new file mode 100644
index 0000000..554ea95
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/CompatibilityHelpers/UserIdMapper.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Buffers.Text;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GalliumPlusApi.CompatibilityHelpers
+{
+ internal class UserIdMapper
+ {
+ private static UserIdMapper? current;
+
+ public static UserIdMapper Current
+ {
+ get
+ {
+ if (current == null)
+ {
+ current = new UserIdMapper();
+ }
+ return current;
+ }
+ }
+
+ private Dictionary ids;
+
+ private UserIdMapper()
+ {
+ ids = new Dictionary();
+ }
+
+ public int GetIdFor(string username)
+ {
+ lock (ids)
+ {
+ if (ids.ContainsKey(username))
+ {
+ return ids[username];
+ }
+ else
+ {
+ int id = HashUsername(username);
+ ids[username] = id;
+ return id;
+ }
+ }
+ }
+
+ public string FindUsernameOf(int numericId)
+ {
+ lock (ids)
+ {
+ return ids.First(kvp => kvp.Value == numericId).Key;
+ }
+ }
+
+ private static readonly string BASE64_DU_BLED = "0123456789azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN";
+
+ private static int HashUsername(string username)
+ {
+ int result = 0;
+
+ foreach(char c in username.Take(4))
+ {
+ result += BASE64_DU_BLED.IndexOf(c);
+ result <<= 6;
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/AcompteDao.cs b/Couche IHM/GalliumPlusApi/Dao/AcompteDao.cs
new file mode 100644
index 0000000..8fa45e3
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/AcompteDao.cs
@@ -0,0 +1,82 @@
+using Couche_Data.Interfaces;
+using GalliumPlusApi.CompatibilityHelpers;
+using GalliumPlusApi.Dto;
+using GalliumPlusApi.Exceptions;
+using GalliumPlusApi.ModelDecorators;
+using Modeles;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace GalliumPlusApi.Dao
+{
+ public class AccountDao : IAccountDao
+ {
+ private UserSummary.AccountMapper mapper = new();
+ private RoleDetails.Mapper roleMapper = new();
+
+ public void CreateAdhérent(Account adhérent)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Post("v1/users", mapper.FromModel(adhérent));
+ }
+
+
+ public List GetRoles()
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ try
+ {
+ var roles = client.Get>("v1/roles");
+
+ return roleMapper.ToModel(roles).ToList();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Exception non gérée lors de la récupération des rôles : {ex}");
+ return new List();
+ }
+ }
+
+ public List GetAdhérents()
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ try
+ {
+ var users = client.Get>("v1/users")
+ .Where(user => user.Deposit != null);
+
+ return mapper.ToModel(users).ToList();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Exception non gérée lors de la récupération des acomptes : {ex}");
+ return new List();
+ }
+ }
+
+ public void RemoveAdhérent(Account adhérent)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ var existingUser = client.Get($"v1/users/{adhérent.Identifiant}");
+ existingUser.Deposit = null;
+
+ client.Put($"v1/users/{adhérent.Identifiant}", existingUser.AsUserSummary);
+ }
+
+ public void UpdateAdhérent(Account adhérent)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Put($"v1/users/{adhérent.Identifiant}", mapper.FromModel(adhérent));
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/CategoryDao.cs b/Couche IHM/GalliumPlusApi/Dao/CategoryDao.cs
new file mode 100644
index 0000000..61bb620
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/CategoryDao.cs
@@ -0,0 +1,54 @@
+using Couche_Data.Interfaces;
+using GalliumPlusApi.Dto;
+using Modeles;
+using System.Diagnostics;
+
+namespace GalliumPlusApi.Dao
+{
+ public class CategoryDao : ICategoryDao
+ {
+ private CategoryDetails.Mapper mapper = new();
+
+ public void CreateCategory(Category cat)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Post($"v1/categories", mapper.FromModel(cat));
+ }
+
+ public void DeleteCategory(Category cat)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Delete($"v1/categories/{cat.IdCat}");
+ }
+
+ public List ListALlCategory()
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ try
+ {
+ var categories = client.Get>("v1/categories");
+
+ return mapper.ToModel(categories).ToList();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Exception non gérée lors de la récupération des catégories : {ex}");
+ return new List();
+ }
+ }
+
+ public void UpdateCategory(Category category)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Put($"v1/categories/{category.IdCat}", mapper.FromModel(category));
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/LogDAO.cs b/Couche IHM/GalliumPlusApi/Dao/LogDAO.cs
new file mode 100644
index 0000000..0c8c44e
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/LogDAO.cs
@@ -0,0 +1,56 @@
+using Couche_Data.Interfaces;
+using Couche_Data.Dao;
+using GalliumPlusApi.CompatibilityHelpers;
+using GalliumPlusApi.Dto;
+using Modeles;
+using System.Diagnostics;
+
+namespace GalliumPlusApi.Dao
+{
+ public class LogDao : ILogDAO
+ {
+ private HistoryActionDetails.Mapper mapper;
+
+ public LogDao(IEnumerable users)
+ {
+ Dictionary knownUsers = new();
+ foreach (Account user in users)
+ {
+ knownUsers[UserIdMapper.Current.FindUsernameOf(user.Id)] = user;
+ }
+ this.mapper = new(knownUsers);
+ }
+
+ public void CreateLog(Log log) { /* non */ }
+
+ public List GetLogs(int mois, int annee)
+ {
+ DateTime debutMois = new DateTime(annee, mois, 1);
+ DateTime finMois = new DateTime(annee, mois, DateTime.DaysInMonth(annee, mois));
+
+ string search = $"?from={debutMois:s}&to={finMois:s}&pageSize=99999";
+
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ try
+ {
+ var products = client.Get>("v1/history" + search);
+
+ List logList = mapper.ToModel(products).ToList();
+ logList.Sort((log1, log2) => log2.Date.CompareTo(log1.Date));
+ return logList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Exception non gérée lors de la récupération des logs : {ex}");
+ return new List();
+ }
+ }
+
+ public IPaginatedLogReader GetLogsReader(int mois, int annee)
+ {
+ return new CachedLogReader(20, this.GetLogs(mois, annee));
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/OrderDao.cs b/Couche IHM/GalliumPlusApi/Dao/OrderDao.cs
new file mode 100644
index 0000000..28fa2ff
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/OrderDao.cs
@@ -0,0 +1,19 @@
+using Couche_Data.Interfaces;
+using GalliumPlusApi.Dto;
+using Modeles;
+
+namespace GalliumPlusApi.Dao
+{
+ public class OrderDao : IOrderDao
+ {
+ private OrderSummary.Mapper mapper = new();
+
+ public void ProcessOrder(Order order)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Post($"v1/orders", mapper.FromModel(order));
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/ProductDao.cs b/Couche IHM/GalliumPlusApi/Dao/ProductDao.cs
new file mode 100644
index 0000000..47e3bad
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/ProductDao.cs
@@ -0,0 +1,63 @@
+using Couche_Data.Interfaces;
+using GalliumPlusApi.Dto;
+using GalliumPlusApi.ModelDecorators;
+using Modeles;
+using System.Diagnostics;
+
+namespace GalliumPlusApi.Dao
+{
+ public class ProductDao : IProductDAO
+ {
+ private ProductSummary.Mapper mapper = new();
+
+ public void CreateProduct(Product product)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Post("v1/products", mapper.FromModel(product));
+ }
+
+ public List GetProducts()
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ try
+ {
+ var products = client.Get>("v1/products");
+
+ return mapper.ToModel(products).ToList();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Exception non gérée lors de la récupération des produits : {ex}");
+ return new List();
+ }
+ }
+
+ public void RemoveProduct(Product product)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ client.Delete($"v1/products/{product.ID}");
+ }
+
+ public void UpdateProduct(Product product)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.UseSessionToken(SessionStorage.Current.Get("token"));
+
+ if (product is DecoratedProduct deco)
+ {
+ client.Put($"v1/products/{product.ID}", mapper.FromModel(deco));
+ }
+ else
+ {
+ var original = client.Get($"v1/products/{product.ID}");
+ client.Put($"v1/products/{product.ID}", mapper.PatchWithModel(original, product));
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/SessionDao.cs b/Couche IHM/GalliumPlusApi/Dao/SessionDao.cs
new file mode 100644
index 0000000..9d4e2ec
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/SessionDao.cs
@@ -0,0 +1,34 @@
+using GalliumPlusApi.Dto;
+using GalliumPlusApi.Exceptions;
+using Modeles;
+using System.Text.Json;
+
+namespace GalliumPlusApi.Dao
+{
+ public class SessionDao
+ {
+ private UserDetails.Mapper detailsMapper = new();
+ private RoleDetails.Mapper roleMapper = new();
+
+ public (Account, Role)? LogIn(string username, string password)
+ {
+ using var client = new GalliumPlusHttpClient();
+ client.JsonOptions.PropertyNamingPolicy = null; // pas de casse chameau en sortie
+
+ try
+ {
+ var loggedIn = client.Post("v1/login", new { Username = username, Password = password });
+
+ SessionStorage.Current.Put("token", loggedIn.Token);
+
+ if (loggedIn.User == null) return null;
+
+ return (detailsMapper.ToModel(loggedIn.User), roleMapper.ToModel(loggedIn.User.Role));
+ }
+ catch (UnauthenticatedException)
+ {
+ return null;
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/StatAcompteDao.cs b/Couche IHM/GalliumPlusApi/Dao/StatAcompteDao.cs
new file mode 100644
index 0000000..ba81bff
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/StatAcompteDao.cs
@@ -0,0 +1,179 @@
+using Couche_Data.Dao;
+using Couche_Data.Interfaces;
+using Modeles;
+using MySql.Data.MySqlClient;
+using System.Diagnostics;
+
+namespace GalliumPlusApi.Dao
+{
+ public class StatAccountDao : IStatAccountDAO
+ {
+
+ public List GetStatByWeek(int semaine, int year )
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE WEEK(date) = {semaine} AND " +
+ $"YEAR(date) = {year} group by acompte_id order by argent desc";
+
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatByMonth(int month, int year)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE month(date) = {month} AND " +
+ $"YEAR(date) = {year} group by acompte_id order by argent desc";
+
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatByYear(int year)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT acompte_id,sum(amount) as argent FROM best_acomptes WHERE " +
+ $"YEAR(date) = {year} group by acompte_id order by argent desc";
+
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, DateTime.Now, rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatBOfAcompteByMonth(int year, int acompte_id)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+
+ string stm = $"SELECT NVL(acompte_id,{acompte_id}) as acompte_id,lm.mois as date,NVL(SUM(bs.amount), 0) AS argent FROM ( SELECT 1 AS mois UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) lm LEFT JOIN best_acomptes bs ON MONTH(bs.date) = lm.mois AND YEAR(bs.date) = {year} AND bs.acompte_id = {acompte_id} GROUP BY lm.mois ORDER BY lm.mois;";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statAccountList = new List();
+ while (rdr.Read())
+ {
+ statAccountList.Add(new StatAccount(0, new DateTime(year, rdr.GetInt16("date"), 1), rdr.GetFloat("argent"), rdr.GetInt32("acompte_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statAccountList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats acompte : {ex.Message}");
+ return new();
+ }
+ }
+
+ public void CreateStat(StatAccount stat)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string formattedDate = stat.Date.ToString("yyyy-MM-dd");
+ string formattedAmountMoney = stat.Money.ToString(System.Globalization.CultureInfo.InvariantCulture);
+ string stm = $"INSERT INTO best_acomptes VALUES(0,{formattedAmountMoney},'{formattedDate}',{stat.Account_Id})";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ cmd.ExecuteNonQuery();
+
+ sql.Close();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant l'ajout d'une stat acompte : {ex.Message}");
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dao/StatProduitDao.cs b/Couche IHM/GalliumPlusApi/Dao/StatProduitDao.cs
new file mode 100644
index 0000000..1900581
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dao/StatProduitDao.cs
@@ -0,0 +1,167 @@
+using Couche_Data.Dao;
+using Couche_Data.Interfaces;
+using Modeles;
+using MySql.Data.MySqlClient;
+using System.Diagnostics;
+
+namespace GalliumPlusApi.Dao
+{
+ public class StatProduitDao : IStatProduitDAO
+ {
+
+ public List GetStatByMonth(int month, int year)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE month(date_sale) = {month} AND YEAR(date_sale) = {year} group by product_id order by nb desc";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatBOfProductByMonth(int year, int product_id)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT NVL(product_id,{product_id}) as product_id,lm.mois as date,NVL(SUM(bs.number_sales), 0) AS nb FROM ( SELECT 1 AS mois UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) lm LEFT JOIN best_sales bs ON MONTH(bs.date_sale) = lm.mois AND YEAR(bs.date_sale) = {year} AND bs.product_id = {product_id} GROUP BY lm.mois ORDER BY lm.mois;";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, new DateTime(year,rdr.GetInt16("date"),1), rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatByYear(int year)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE YEAR(date_sale) = {year} group by product_id order by nb desc";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
+ }
+
+ public List GetStatByWeek(int semaine,int year)
+ {
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string stm = $"SELECT product_id,sum(number_sales) as nb FROM best_sales WHERE week(date_sale) = {semaine} AND YEAR(date_sale) = {year} group by product_id order by nb desc";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ MySqlDataReader rdr = cmd.ExecuteReader();
+
+ List statProduitList = new List();
+ while (rdr.Read())
+ {
+ statProduitList.Add(new StatProduit(0, DateTime.Now, rdr.GetInt16("nb"), rdr.GetInt16("product_id")));
+ }
+
+ rdr.Close();
+ sql.Close();
+ return statProduitList;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant le chargement des stats produit : {ex.Message}");
+ return new();
+ }
+ }
+
+ public void CreateStat(StatProduit stat)
+ {
+ //Connection
+ MySqlConnection sql = new MySqlConnection(dbsDAO.ConnectionStringV);
+ try
+ {
+ sql.Open();
+
+ //Requette SQL
+ string formattedDate = stat.Date.ToString("yyyy-MM-dd");
+ string stm = $"INSERT INTO best_sales VALUES(0,'{formattedDate}',{stat.Number_sales},{stat.Product_id})";
+ MySqlCommand cmd = new MySqlCommand(stm, sql);
+ cmd.Prepare();
+
+ //lecture de la requette
+ cmd.ExecuteNonQuery();
+
+ sql.Close();
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Erreur pendant l'ajout d'une stat produit : {ex.Message}");
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dto/CategoryDetails.cs b/Couche IHM/GalliumPlusApi/Dto/CategoryDetails.cs
new file mode 100644
index 0000000..12397f4
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/CategoryDetails.cs
@@ -0,0 +1,23 @@
+using Modeles;
+
+namespace GalliumPlusApi.Dto
+{
+ public class CategoryDetails
+ {
+ public int Id { get; set; } = -1;
+ public string Name { get; set; } = String.Empty;
+
+ public class Mapper : Mapper
+ {
+ public override CategoryDetails FromModel(Category model)
+ {
+ return new CategoryDetails { Id = model.IdCat, Name = model.NomCategory };
+ }
+
+ public override Category ToModel(CategoryDetails dto)
+ {
+ return new Category(dto.Id, dto.Name, dto.Name != "Hidden");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/Error.cs b/Couche IHM/GalliumPlusApi/Dto/Error.cs
new file mode 100644
index 0000000..d3583ca
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/Error.cs
@@ -0,0 +1,37 @@
+using System.Diagnostics;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace GalliumPlusApi.Dto
+{
+ public class Error
+ {
+ public string Code { get; set; } = "UNKNOWN";
+
+ public string Message { get; set; } = "Erreur inconnue.";
+
+ public object? DebugInfo { get; set; } = null;
+
+ public string DetailedMessage
+ {
+ get
+ {
+ StringBuilder sb = new();
+ sb.Append(Message);
+#if DEBUG
+ if (DebugInfo != null)
+ {
+ sb.Append("\n\nInformations de débogage:\n");
+ sb.Append(JsonSerializer.Serialize(DebugInfo, new JsonSerializerOptions { WriteIndented = true }));
+ }
+ else
+ {
+ sb.Append("\n\nAucune informations de débogage.");
+ }
+#endif
+ return sb.ToString();
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dto/HistoryActionDetails.cs b/Couche IHM/GalliumPlusApi/Dto/HistoryActionDetails.cs
new file mode 100644
index 0000000..c7a3e12
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/HistoryActionDetails.cs
@@ -0,0 +1,86 @@
+using GalliumPlusApi.CompatibilityHelpers;
+using Modeles;
+using Org.BouncyCastle.Asn1.Crmf;
+using System.Diagnostics;
+using System.Text.Json.Serialization;
+
+namespace GalliumPlusApi.Dto
+{
+ public class HistoryActionDetails
+ {
+ public string ActionKind { get; set; } = string.Empty;
+
+ public string Text { get; set; } = string.Empty;
+
+ public DateTime Time { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? Actor { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? Target { get; set; }
+
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public decimal? NumericValue { get; set; }
+
+ public class Mapper : Mapper
+ {
+ private Dictionary knownUsers;
+
+ public Mapper(Dictionary knownUsers)
+ {
+ this.knownUsers = knownUsers;
+ }
+
+ public override HistoryActionDetails FromModel(Log? model)
+ {
+ throw new InvalidOperationException("Les données de l'historique ne peuvent pas sortir.");
+ }
+
+ private string GetUserFullName(string? userId)
+ {
+ if (userId == null)
+ {
+ return "Personne";
+ }
+ if (this.knownUsers.TryGetValue(userId, out Account? user))
+ {
+ return $"{user.Prenom} {user.Nom}";
+ }
+ else
+ {
+ return userId;
+ }
+ }
+
+ public override Log? ToModel(HistoryActionDetails dto)
+ {
+ if (LogThemeMapper.ActionKindToLogTheme(dto.ActionKind) is int theme)
+ {
+ return new Log(
+ date: dto.Time,
+ theme: theme,
+ message: dto.Text,
+ auteur: this.GetUserFullName(dto.Actor)
+ );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public new IEnumerable ToModel(IEnumerable dtos)
+ {
+ foreach (var dto in dtos)
+ {
+ if (this.ToModel(dto) is Log log)
+ {
+ yield return log;
+ }
+ }
+ yield break;
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dto/LoggedIn.cs b/Couche IHM/GalliumPlusApi/Dto/LoggedIn.cs
new file mode 100644
index 0000000..b946630
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/LoggedIn.cs
@@ -0,0 +1,18 @@
+namespace GalliumPlusApi.Dto
+{
+ public class LoggedIn
+ {
+ public string Token { get; set; }
+ public DateTime Expiration { get; set; }
+ public UserDetails? User { get; set; }
+ public uint Permissions { get; set; }
+
+ public LoggedIn()
+ {
+ Token = "";
+ Expiration = new(0);
+ User = new();
+ Permissions = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/Mapper.cs b/Couche IHM/GalliumPlusApi/Dto/Mapper.cs
new file mode 100644
index 0000000..fda55f4
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/Mapper.cs
@@ -0,0 +1,25 @@
+namespace GalliumPlusApi.Dto
+{
+ public abstract class Mapper
+ {
+ public virtual TModel ToModel(TDto dto)
+ {
+ throw new InvalidOperationException("Ce DTO ne doit pas entrer !! >:(");
+ }
+
+ public IEnumerable ToModel(IEnumerable dtos)
+ {
+ foreach (TDto dto in dtos) yield return ToModel(dto);
+ }
+
+ public virtual TDto FromModel(TModel model)
+ {
+ throw new InvalidOperationException("Ce DTO ne doit pas sortir !! >:(");
+ }
+
+ public IEnumerable FromModel(IEnumerable models)
+ {
+ foreach (TModel model in models) yield return FromModel(model);
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Dto/OrderItemSummary.cs b/Couche IHM/GalliumPlusApi/Dto/OrderItemSummary.cs
new file mode 100644
index 0000000..6360969
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/OrderItemSummary.cs
@@ -0,0 +1,16 @@
+namespace GalliumPlusApi.Dto
+{
+ public class OrderItemSummary
+ {
+ public int Product { get; set; }
+ public int Quantity { get; set; }
+
+ public class Mapper : Mapper, OrderItemSummary>
+ {
+ public override OrderItemSummary FromModel(KeyValuePair model)
+ {
+ return new OrderItemSummary { Product = model.Key, Quantity = model.Value };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/OrderSummary.cs b/Couche IHM/GalliumPlusApi/Dto/OrderSummary.cs
new file mode 100644
index 0000000..899d3e7
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/OrderSummary.cs
@@ -0,0 +1,26 @@
+using Modeles;
+
+namespace GalliumPlusApi.Dto
+{
+ public class OrderSummary
+ {
+ public string PaymentMethod { get; set; } = String.Empty;
+ public string? Customer { get; set; }
+ public List Items { get; set; } = new();
+
+ public class Mapper : Mapper
+ {
+ private OrderItemSummary.Mapper orderItemMapper = new();
+
+ public override OrderSummary FromModel(Order model)
+ {
+ return new OrderSummary
+ {
+ Customer = model.Customer,
+ PaymentMethod = model.PaymentMethod,
+ Items = orderItemMapper.FromModel(model.OrderedProducts).ToList(),
+ };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/PasswordModification.cs b/Couche IHM/GalliumPlusApi/Dto/PasswordModification.cs
new file mode 100644
index 0000000..69863d2
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/PasswordModification.cs
@@ -0,0 +1,21 @@
+/*using System.ComponentModel.DataAnnotations;
+
+namespace GalliumPlus.WebApi.Dto
+{
+ public class PasswordModification
+ {
+ public string? CurrentPassword { get; }
+
+ public string? ResetToken { get; }
+
+ [Required] public string NewPassword { get; }
+
+ public PasswordModification(string newPassword, string? currentPassword, string? resetToken)
+ {
+ this.CurrentPassword = currentPassword;
+ this.ResetToken = resetToken;
+ this.NewPassword = newPassword;
+ }
+ }
+}
+*/
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/ProductDetails.cs b/Couche IHM/GalliumPlusApi/Dto/ProductDetails.cs
new file mode 100644
index 0000000..a416980
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/ProductDetails.cs
@@ -0,0 +1,14 @@
+namespace GalliumPlusApi.Dto
+{
+ public class ProductDetails
+ {
+ public int Id { get; set; } = -1;
+ public string Name { get; set; } = "";
+ public int Stock { get; set; } = 0;
+ public decimal NonMemberPrice { get; set; } = -1;
+ public decimal MemberPrice { get; set; } = -1;
+ public string Availability { get; set; } = "";
+ public bool Available { get; set; } = true;
+ public CategoryDetails Category { get; set; } = new();
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/ProductSummary.cs b/Couche IHM/GalliumPlusApi/Dto/ProductSummary.cs
new file mode 100644
index 0000000..72738ab
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/ProductSummary.cs
@@ -0,0 +1,66 @@
+using GalliumPlusApi.CompatibilityHelpers;
+using GalliumPlusApi.ModelDecorators;
+using Modeles;
+
+namespace GalliumPlusApi.Dto
+{
+ public class ProductSummary
+ {
+ public int Id { get; set; } = -1;
+ public string Name { get; set; } = "";
+ public int Stock { get; set; } = 0;
+ public decimal NonMemberPrice { get; set; } = -1;
+ public decimal MemberPrice { get; set; } = -1;
+ public string Availability { get; set; } = "";
+ public int Category { get; set; } = -1;
+
+ public class Mapper : Mapper
+ {
+ public override ProductSummary FromModel(Product model)
+ {
+ string availability = "AUTO";
+ if (model is DecoratedProduct deco)
+ {
+ availability = deco.Availability;
+ }
+
+ return new ProductSummary
+ {
+ Id = model.ID,
+ Name = model.NomProduit,
+ Stock = model.Quantite,
+ NonMemberPrice = Format.FloatToMonetary(model.PrixNonAdherent)!.Value,
+ MemberPrice = Format.FloatToMonetary(model.PrixAdherent)!.Value,
+ Availability = availability,
+ Category = model.Categorie
+ };
+ }
+
+ public ProductSummary PatchWithModel(ProductDetails originalProduct, Product patch)
+ {
+ return new ProductSummary
+ {
+ Id = patch.ID,
+ Name = patch.NomProduit,
+ Stock = patch.Quantite,
+ NonMemberPrice = Format.FloatToMonetary(patch.PrixNonAdherent)!.Value,
+ MemberPrice = Format.FloatToMonetary(patch.PrixAdherent)!.Value,
+ Availability = originalProduct.Availability,
+ Category = patch.Categorie
+ };
+ }
+
+ public override Product ToModel(ProductSummary dto)
+ {
+ return new Product(
+ id: dto.Id,
+ nomProduit: dto.Name,
+ quantite: dto.Stock,
+ prixAdherent: (float)dto.MemberPrice,
+ prixNonAdherent: (float)dto.NonMemberPrice,
+ categorie: dto.Category
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/RoleDetails.cs b/Couche IHM/GalliumPlusApi/Dto/RoleDetails.cs
new file mode 100644
index 0000000..dd526bc
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/RoleDetails.cs
@@ -0,0 +1,26 @@
+using Modeles;
+
+namespace GalliumPlusApi.Dto
+{
+ public class RoleDetails
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public uint Permissions { get; set; }
+
+ public RoleDetails()
+ {
+ this.Id = -1;
+ this.Name = String.Empty;
+ this.Permissions = 0;
+ }
+
+ public class Mapper : Mapper
+ {
+ public override Role ToModel(RoleDetails dto)
+ {
+ return new Role(dto.Id, dto.Name);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/UserDetails.cs b/Couche IHM/GalliumPlusApi/Dto/UserDetails.cs
new file mode 100644
index 0000000..d584a19
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/UserDetails.cs
@@ -0,0 +1,49 @@
+using GalliumPlusApi.CompatibilityHelpers;
+using Modeles;
+using System.Text.Json.Serialization;
+
+namespace GalliumPlusApi.Dto
+{
+ public class UserDetails
+ {
+ public string Id { get; set; } = "";
+ public string FirstName { get; set; } = "";
+ public string LastName { get; set; } = "";
+ public string Email { get; set; } = "";
+ public RoleDetails Role { get; set; } = new();
+ public string Year { get; set; } = "";
+ public decimal? Deposit { get; set; } = null;
+ public bool IsMember { get; set; } = false;
+
+ [JsonIgnore]
+ public UserSummary AsUserSummary => new()
+ {
+ Deposit = Deposit,
+ Email = Email,
+ FirstName = FirstName,
+ LastName = LastName,
+ Id = Id,
+ IsMember = IsMember,
+ Role = Role.Id,
+ Year = Year,
+ };
+
+ public class Mapper : Mapper
+ {
+ public override Account ToModel(UserDetails details)
+ {
+ return new Account(
+ UserIdMapper.Current.GetIdFor(details.Id),
+ details.Id,
+ details.LastName,
+ details.FirstName,
+ details.Email,
+ (float)(details.Deposit ?? -1m),
+ details.Year,
+ details.IsMember,
+ details.Role.Id
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Dto/UserSummary.cs b/Couche IHM/GalliumPlusApi/Dto/UserSummary.cs
new file mode 100644
index 0000000..7941ddb
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Dto/UserSummary.cs
@@ -0,0 +1,53 @@
+using GalliumPlusApi.CompatibilityHelpers;
+using GalliumPlusApi.ModelDecorators;
+using Microsoft.VisualBasic;
+using Modeles;
+using System.ComponentModel.DataAnnotations;
+
+namespace GalliumPlusApi.Dto
+{
+ public class UserSummary
+ {
+ public string Id { get; set; } = string.Empty;
+ public string FirstName { get; set; } = string.Empty;
+ public string LastName { get; set; } = string.Empty;
+ public string Email { get; set; } = string.Empty;
+ public int Role { get; set; } = -1;
+ public string Year { get; set; } = string.Empty;
+ public decimal? Deposit { get; set; } = null;
+ public bool IsMember { get; set; } = false;
+
+ public class AccountMapper : Mapper
+ {
+ public override UserSummary FromModel(Account model)
+ {
+ return new UserSummary
+ {
+ Deposit = Format.FloatToMonetary(model.Argent),
+ Email = model.Mail,
+ FirstName = model.Prenom,
+ Id = model.Identifiant,
+ IsMember = model.IsMember,
+ LastName = model.Nom,
+ Role = model.RoleId,
+ Year = model.Formation,
+ };
+ }
+
+ public override Account ToModel(UserSummary dto)
+ {
+ return new Account(
+ id: UserIdMapper.Current.GetIdFor(dto.Id),
+ identifiant: dto.Id,
+ nom: dto.LastName,
+ prenom: dto.FirstName,
+ argent: (float)(dto.Deposit ?? -1m),
+ year: dto.Year,
+ isMember: dto.IsMember,
+ mail: dto.Email,
+ role: dto.Role
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/CantSellException.cs b/Couche IHM/GalliumPlusApi/Exceptions/CantSellException.cs
new file mode 100644
index 0000000..c1bdd1f
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/CantSellException.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GalliumPlusApi.Exceptions
+{
+ internal class CantSellException : GalliumPlusHttpException
+ {
+ public CantSellException() : base("Impossible de passer la commande") { }
+
+ public CantSellException(string message) : base(message) { }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/ExceptionFactory.cs b/Couche IHM/GalliumPlusApi/Exceptions/ExceptionFactory.cs
new file mode 100644
index 0000000..a9eed2b
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/ExceptionFactory.cs
@@ -0,0 +1,46 @@
+using GalliumPlusApi.Dto;
+using System.Net;
+using System.Net.Http.Json;
+using System.Text.Json;
+
+namespace GalliumPlusApi.Exceptions
+{
+ internal static class ExceptionFactory
+ {
+ public static void ThrowForStatus(HttpResponseMessage response, JsonSerializerOptions? jsonOptions = null)
+ {
+ if (!response.IsSuccessStatusCode)
+ {
+ throw response.StatusCode switch
+ {
+ HttpStatusCode.Unauthorized => new UnauthenticatedException(),
+ HttpStatusCode.BadRequest => ResponseToException(response, jsonOptions) ?? new InvalidItemException(),
+ HttpStatusCode.Forbidden => ResponseToException(response, jsonOptions) ?? new PermissionDeniedException(),
+ HttpStatusCode.NotFound => ResponseToException(response, jsonOptions) ?? new ItemNotFoundException(),
+ _ => new GalliumPlusHttpException($"Erreur HTTP non gérée : {(int)response.StatusCode} {response.ReasonPhrase}"),
+ };
+ }
+ }
+
+ private static GalliumPlusHttpException? ResponseToException(HttpResponseMessage response, JsonSerializerOptions? jsonOptions)
+ {
+ Task task = response.Content.ReadFromJsonAsync(jsonOptions);
+ task.Wait();
+ if (task.Result is Error error)
+ {
+ return error.Code switch
+ {
+ "InvalidItem" => new InvalidItemException(error.DetailedMessage),
+ "PermissionDenied" => new PermissionDeniedException(error.DetailedMessage),
+ "ItemNotFound" => new ItemNotFoundException(error.DetailedMessage),
+ "CantSell" => new CantSellException(error.DetailedMessage),
+ _ => throw new NotImplementedException($"Code d'erreur non géré : « {error.Code} »")
+ };
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/GalliumPlusHttpException.cs b/Couche IHM/GalliumPlusApi/Exceptions/GalliumPlusHttpException.cs
new file mode 100644
index 0000000..340a0a7
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/GalliumPlusHttpException.cs
@@ -0,0 +1,9 @@
+namespace GalliumPlusApi.Exceptions
+{
+ public class GalliumPlusHttpException : Exception
+ {
+ public GalliumPlusHttpException() : base() { }
+
+ public GalliumPlusHttpException(string message) : base(message) { }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/InvalidItemException.cs b/Couche IHM/GalliumPlusApi/Exceptions/InvalidItemException.cs
new file mode 100644
index 0000000..2ec7eb6
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/InvalidItemException.cs
@@ -0,0 +1,9 @@
+namespace GalliumPlusApi.Exceptions
+{
+ public class InvalidItemException : GalliumPlusHttpException
+ {
+ public InvalidItemException() : base("Ressource invalide") { }
+
+ public InvalidItemException(string message) : base(message) { }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/ItemNotFoundException.cs b/Couche IHM/GalliumPlusApi/Exceptions/ItemNotFoundException.cs
new file mode 100644
index 0000000..11e4c9a
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/ItemNotFoundException.cs
@@ -0,0 +1,9 @@
+namespace GalliumPlusApi.Exceptions
+{
+ internal class ItemNotFoundException : GalliumPlusHttpException
+ {
+ public ItemNotFoundException() : base("Le ressource demandée n'existe pas") { }
+
+ public ItemNotFoundException(string message) : base(message) { }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/PermissionDeniedException.cs b/Couche IHM/GalliumPlusApi/Exceptions/PermissionDeniedException.cs
new file mode 100644
index 0000000..6b6b92e
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/PermissionDeniedException.cs
@@ -0,0 +1,9 @@
+namespace GalliumPlusApi.Exceptions
+{
+ public class PermissionDeniedException : GalliumPlusHttpException
+ {
+ public PermissionDeniedException() : base("Permission refusée.") { }
+
+ public PermissionDeniedException(string message) : base(message) { }
+ }
+}
\ No newline at end of file
diff --git a/Couche IHM/GalliumPlusApi/Exceptions/UnauthenticatedException.cs b/Couche IHM/GalliumPlusApi/Exceptions/UnauthenticatedException.cs
new file mode 100644
index 0000000..47c6425
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/Exceptions/UnauthenticatedException.cs
@@ -0,0 +1,7 @@
+namespace GalliumPlusApi.Exceptions
+{
+ public class UnauthenticatedException : GalliumPlusHttpException
+ {
+ public UnauthenticatedException() : base("Requête non authentifiée.") { }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/GalliumPlusApi.csproj b/Couche IHM/GalliumPlusApi/GalliumPlusApi.csproj
new file mode 100644
index 0000000..0730339
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/GalliumPlusApi.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net6.0-windows
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Couche IHM/GalliumPlusApi/GalliumPlusHttpClient.cs b/Couche IHM/GalliumPlusApi/GalliumPlusHttpClient.cs
new file mode 100644
index 0000000..42be45c
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/GalliumPlusHttpClient.cs
@@ -0,0 +1,93 @@
+using GalliumPlusApi.Dto;
+using GalliumPlusApi.Exceptions;
+using MySqlX.XDevAPI;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net.Http.Json;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace GalliumPlusApi
+{
+ internal class GalliumPlusHttpClient : HttpClient
+ {
+ private JsonSerializerOptions jsonOptions;
+
+ public JsonSerializerOptions JsonOptions => jsonOptions;
+
+ public GalliumPlusHttpClient()
+ {
+ BaseAddress = new Uri("https://" + ApiConfig.Current.Host);
+ DefaultRequestHeaders.Add("X-Api-Key", ApiConfig.Current.ApiKey);
+ jsonOptions = new JsonSerializerOptions();
+ jsonOptions.PropertyNameCaseInsensitive = true;
+ }
+
+ public void UseSessionToken(string token)
+ {
+ DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
+ }
+
+ private static T WaitForTask(Task task)
+ {
+ task.Wait();
+
+ if (task.IsFaulted)
+ {
+ throw task.Exception ?? new Exception("Unknown error in task");
+ }
+
+ return task.Result;
+ }
+
+ public async Task LookUpVersionAsync()
+ {
+ var response = await this.GetAsync("");
+ return response.Headers.GetValues("x-gallium-version").First();
+ }
+
+ public T Get(string resource)
+ {
+ var response = WaitForTask(this.GetAsync(resource));
+
+ ExceptionFactory.ThrowForStatus(response);
+
+ return WaitForTask(response.Content.ReadFromJsonAsync(jsonOptions))
+ ?? throw new NullReferenceException("Json deserialisation return null");
+ }
+
+ public T Post(string resource, object data)
+ {
+ var response = WaitForTask(this.PostAsJsonAsync(resource, data, jsonOptions));
+
+ ExceptionFactory.ThrowForStatus(response);
+
+ return WaitForTask(response.Content.ReadFromJsonAsync(jsonOptions))
+ ?? throw new NullReferenceException("Json deserialisation return null");
+ }
+
+ public void Post(string resource, object data)
+ {
+ var response = WaitForTask(this.PostAsJsonAsync(resource, data, jsonOptions));
+
+ ExceptionFactory.ThrowForStatus(response);
+ }
+
+ public void Put(string resource, object data)
+ {
+ var response = WaitForTask(this.PutAsJsonAsync(resource, data, jsonOptions));
+
+ ExceptionFactory.ThrowForStatus(response);
+ }
+
+ public void Delete(string resource)
+ {
+ var response = WaitForTask(this.DeleteAsync(resource));
+
+ ExceptionFactory.ThrowForStatus(response);
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/ModelDecorators/DecoratedProduct.cs b/Couche IHM/GalliumPlusApi/ModelDecorators/DecoratedProduct.cs
new file mode 100644
index 0000000..fca1b24
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/ModelDecorators/DecoratedProduct.cs
@@ -0,0 +1,25 @@
+using Modeles;
+
+namespace GalliumPlusApi.ModelDecorators
+{
+ internal class DecoratedProduct : Product
+ {
+ private string availability;
+
+ public string Availability => availability;
+
+ public DecoratedProduct(
+ int id,
+ string nomProduit,
+ int quantite,
+ float prixAdherent,
+ float prixNonAdherent,
+ int categorie,
+ string availability
+ )
+ : base (id, nomProduit, quantite, prixAdherent, prixNonAdherent, categorie)
+ {
+ this.availability = availability;
+ }
+ }
+}
diff --git a/Couche IHM/GalliumPlusApi/SessionStorage.cs b/Couche IHM/GalliumPlusApi/SessionStorage.cs
new file mode 100644
index 0000000..f1131b2
--- /dev/null
+++ b/Couche IHM/GalliumPlusApi/SessionStorage.cs
@@ -0,0 +1,50 @@
+using System.Collections.Concurrent;
+
+namespace GalliumPlusApi
+{
+ public class SessionStorage
+ {
+ private static SessionStorage? current;
+
+ public static SessionStorage Current
+ {
+ get
+ {
+ if (current == null)
+ {
+ current = new SessionStorage();
+ }
+ return current;
+ }
+ }
+
+ ConcurrentDictionary storage;
+
+ private SessionStorage()
+ {
+ storage = new();
+ }
+
+ public SessionStorage Put(string key, object value)
+ {
+ storage[key] = value;
+ return this;
+ }
+
+ public object Get(string key)
+ {
+ return storage[key];
+ }
+
+ public T Get(string key)
+ {
+ return (T)storage[key];
+ }
+
+ public SessionStorage Remove(string key)
+ {
+ storage.TryRemove(key, out var _);
+ return this;
+ }
+ }
+}
diff --git a/Couche IHM/Modeles/Acompte.cs b/Couche IHM/Modeles/Account.cs
similarity index 58%
rename from Couche IHM/Modeles/Acompte.cs
rename to Couche IHM/Modeles/Account.cs
index cb7ca61..0ccaf3d 100644
--- a/Couche IHM/Modeles/Acompte.cs
+++ b/Couche IHM/Modeles/Account.cs
@@ -1,45 +1,47 @@
namespace Modeles
{
- public class Acompte
+ public class Account
{
#region attributes
private int id;
private string identifiant;
private string nom = "";
private string prenom = "";
+ private string mail = "";
private float argent;
- private bool stillAdherent;
- private string formation;
+ private bool isMember;
+ private string year;
+ private int roleId;
+ private string hashedPassword;
#endregion
#region constructeurs
///
/// Constructeur de la classe adhérent
///
- /// id de l'adhérent
- /// nom de l'adhérent
- /// prenom de l'adhérent
- /// si le mdp peut être skip
- /// argent de l'adhérent
- public Acompte(int id, string identifiant, string nom, string prenom, float argent,string formation,bool stillAdherent = true)
+ public Account(int id, string identifiant, string nom, string prenom,string mail, float argent,string year,bool isMember = true,int role = 2)
{
this.id = id;
this.identifiant = identifiant;
- this.nom = nom.ToUpper();
+ this.nom = nom;
this.prenom = prenom;
this.argent = argent;
- this.stillAdherent = stillAdherent;
- this.formation = formation;
+ this.year = year;
+ this.mail = mail;
+ this.roleId = role;
+ this.isMember = isMember;
}
///
/// Constructeur vide pour créer des adhérents
///
- public Acompte()
+ public Account()
{
- this.stillAdherent = true;
+ this.isMember = true;
+ this.roleId = 2;
+ this.argent = 0;
}
#endregion
@@ -74,12 +76,21 @@ public Acompte()
///
/// Est ce que le compte est toujours adhérent
///
- public bool StillAdherent { get => stillAdherent; set => stillAdherent = value; }
+ public bool IsMember { get => isMember; set => isMember = value; }
///
/// Formation de l'adhérent
///
- public string Formation { get => formation; set => formation = value; }
+ public string Formation { get => year; set => year = value; }
+ public int RoleId { get => roleId; set => roleId = value; }
+ public string Mail { get => mail; set => mail = value; }
+ public string HashedPassword { get => hashedPassword; set => hashedPassword = value; }
+
+ public override bool Equals(object? obj)
+ {
+ return obj is Account account &&
+ identifiant == account.identifiant;
+ }
#endregion
diff --git a/Couche IHM/Modeles/Category.cs b/Couche IHM/Modeles/Category.cs
index c1cc2e4..7a85f96 100644
--- a/Couche IHM/Modeles/Category.cs
+++ b/Couche IHM/Modeles/Category.cs
@@ -1,5 +1,4 @@
-
-namespace Modeles
+namespace Modeles
{
public class Category
{
diff --git a/Couche IHM/Modeles/Modeles.csproj b/Couche IHM/Modeles/Modeles.csproj
index 132c02c..21783f7 100644
--- a/Couche IHM/Modeles/Modeles.csproj
+++ b/Couche IHM/Modeles/Modeles.csproj
@@ -6,4 +6,9 @@
enable
+
+
+
+
+
diff --git a/Couche IHM/Modeles/Order.cs b/Couche IHM/Modeles/Order.cs
new file mode 100644
index 0000000..2f9dc22
--- /dev/null
+++ b/Couche IHM/Modeles/Order.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Modeles
+{
+ public class Order
+ {
+ private Dictionary orderedProducts;
+ private string? customer;
+ private string paymentMethod;
+
+ public static readonly string ANONYMOUS_MEMBER = "@anonymousmember";
+
+ public IDictionary OrderedProducts => orderedProducts;
+
+ public string? Customer => customer;
+
+ public string PaymentMethod => paymentMethod;
+
+ public Order(string paymentMethod, string? customer = null)
+ {
+ this.paymentMethod = paymentMethod;
+ this.customer = customer;
+ orderedProducts = new Dictionary();
+ }
+
+ public void AddProduct(int productId, int quantity)
+ {
+ orderedProducts[productId] = quantity;
+ }
+ }
+}
diff --git a/Couche IHM/Modeles/Role.cs b/Couche IHM/Modeles/Role.cs
index 29b3df5..a3cd8f4 100644
--- a/Couche IHM/Modeles/Role.cs
+++ b/Couche IHM/Modeles/Role.cs
@@ -27,6 +27,12 @@ public Role(int id, string name)
///
public string Name { get => name; set => name = value; }
+ public override bool Equals(object? obj)
+ {
+ return obj is Role role &&
+ name == role.name;
+ }
+
///
///
///
diff --git a/Couche IHM/Modeles/StatAcompte.cs b/Couche IHM/Modeles/StatAcompte.cs
index 6db4a2a..9b275df 100644
--- a/Couche IHM/Modeles/StatAcompte.cs
+++ b/Couche IHM/Modeles/StatAcompte.cs
@@ -1,7 +1,7 @@
namespace Modeles
{
- public class StatAcompte
+ public class StatAccount
{
#region attributes
private int id;
@@ -18,7 +18,7 @@ public class StatAcompte
/// date de la stat
/// argent de la stat
/// numéro de l'acompte
- public StatAcompte(int id, DateTime date, float money, int acompte_id)
+ public StatAccount(int id, DateTime date, float money, int acompte_id)
{
this.acompte_id = acompte_id;
this.money = money;
@@ -28,7 +28,7 @@ public StatAcompte(int id, DateTime date, float money, int acompte_id)
#endregion
#region properties
- public int Acompte_Id { get => acompte_id; set => acompte_id = value; }
+ public int Account_Id { get => acompte_id; set => acompte_id = value; }
public float Money { get => money; set => money = value; }
public int Id { get => id; set => id = value; }
public DateTime Date { get => date; set => date = value; }
diff --git a/Couche IHM/Modeles/User.cs b/Couche IHM/Modeles/User.cs
deleted file mode 100644
index 014de83..0000000
--- a/Couche IHM/Modeles/User.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-namespace Modeles
-{
- ///
- /// Utilisateur de l'application
- ///
- public class User
- {
- #region attributes
- private int id;
- private string nom;
- private string prenom;
- private string mail;
- private int role = 8;
- private string hashedPassword;
- #endregion
-
- #region constructors
- ///
- /// Constructeur naturelle
- ///
- /// nom de l'utilisateur
- /// prénom de l'utilisateur
- /// mail de l'utilisateur
- /// role de l'utilisateur
- public User(int id, string nom, string prenom, string mail, string password, int role)
- {
- this.id = id;
- this.nom = nom;
- this.prenom = prenom;
- this.mail = mail;
- this.hashedPassword = password;
- this.role = role;
- }
-
-
- ///
- /// Constructeur vide de l'utilisateur
- ///
- public User() { }
- #endregion
-
- #region properties
- ///
- /// ID de l'utilisateur
- ///
- public int ID
- {
- get => id;
- set => id = value;
- }
-
- ///
- /// Nom de l'utilisateur
- ///
- public string Nom
- {
- get => nom;
- set => nom = value;
- }
-
- ///
- /// Prénom de l'utilisateur
- ///
- public string Prenom
- {
- get => prenom;
- set => prenom = value;
- }
-
- ///
- /// mail de l'utilisateur
- ///
- public string Mail
- {
- get => mail;
- set => mail = value;
- }
-
- ///
- /// Role de l'utilisateur
- ///
- public int IdRole
- {
- get => role;
- set => role = value;
- }
-
- ///
- /// Mot de passe hashé de l'utilisateur
- ///
- public string HashedPassword
- {
- get => hashedPassword;
- set => hashedPassword = value;
- }
- #endregion
- }
-}