Compare commits

...

17 Commits

Author SHA1 Message Date
68245f71d7 Release v1.0.0 2021-01-24 18:27:03 +01:00
6e097ba621 Ajout d'images pour la documentation 2021-01-24 18:00:55 +01:00
e521a17d65 Ajout d'images pour la documentation 2021-01-24 17:24:13 +01:00
9055f65471 Ajout d'images pour la documentation 2021-01-24 17:16:18 +01:00
d51eb5f0d2 Ajout d'images pour la documentation 2021-01-22 18:04:36 +01:00
99114085d0 Ajout d'images pour la documentation 2021-01-13 22:14:13 +01:00
b6882f0088 Ajout d'images pour la documentation 2021-01-13 20:57:38 +01:00
4dff0306c3 Retouche de l'écran de démarrage + amélioration de la gestion d'erreur pour l'envoi de SMS 2021-01-01 17:30:11 +01:00
b456708d48 Amélioration de la gestion d'erreur + Ajout du nombre d'éléments affichés et sélectionnés en ba de la fenêtre principale 2021-01-01 16:28:38 +01:00
e81b0b000a Ajout d'une fonctionnalité d'import/export CSV + amélioration de l'écran de démarrage 2021-01-01 00:54:03 +01:00
d68c6b0f8a Ajout d'un écran de démarrage + simplification du publipostage 2020-12-30 18:46:39 +01:00
06cb964d6c Ajout de la persistence des paramètres d'affichage et de la taille de la fenêtre principale 2020-12-29 22:56:32 +01:00
794ad8342d Correction de nommage de données de paramétrage + correction de la fonction d'import 2020-12-28 18:56:26 +01:00
f4aac126eb Réécriture de l'envoi de SMS (OVH) + Ajout d'une fonction d'import depuis des fichiers Excel + Ajout d'une donnée pour le numéro d'appartement. 2020-12-28 00:24:12 +01:00
22de04c0c9 Renommage du menu édition multiple 2020-12-19 14:40:06 +01:00
b55087da71 Limitation à une seule instance. close #5 2020-12-06 23:04:04 +01:00
3efd7948a0 Traitement des tickets : #2 , #6 , #7 , #8 2020-12-06 21:54:59 +01:00
57 changed files with 1565 additions and 330 deletions

View File

@ -1,9 +1,14 @@
using System.Windows;
using System.Threading;
using System.Windows;
namespace Hermes {
/// <summary>
/// Logique d'interaction pour App.xaml
/// </summary>
public partial class App : Application {
private Mutex instanceMutex = new Mutex(true, "HERMES_INSTANCE_MUTEX");
public App() {
if(!instanceMutex.WaitOne(0)) {
MessageBox.Show("Hermes est déjà en cours d'exécution.", "Hermes", MessageBoxButton.OK, MessageBoxImage.Information);
Shutdown();
}
}
}
}

View File

@ -1,96 +0,0 @@
using Hermes.Model;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Hermes {
public partial class CitoyenModal : Window {
private ModelContext dbContext = null;
private Citoyen citoyen = null;
private List<object> _isInvalidElements = new List<object>();
private bool _modeCreate = true;
public static List<string> Civilites = new List<string>();
public CitoyenModal() {
dbContext = ModelContext.Getinstance();
DataContext = new Citoyen();
Civilites.Add("M");
Civilites.Add("Mme");
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
civiliteComboBox.ItemsSource = Civilites;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
e.Cancel = true;
this.Hide();
}
private void ValidationError(object sender, ValidationErrorEventArgs e) {
if(!_isInvalidElements.Contains(sender)) {
_isInvalidElements.Add(sender);
}
}
private void BindingTargetUpdated(object sender, DataTransferEventArgs e) {
if(_isInvalidElements.Contains(sender)) {
_isInvalidElements.Remove(sender);
}
}
private void BindingSourceUpdated(object sender, DataTransferEventArgs e) {
if(_isInvalidElements.Contains(sender)) {
_isInvalidElements.Remove(sender);
}
}
public void EnableCreateMode() {
DataContext = new Citoyen();
civiliteComboBox.SelectedIndex = 0;
_modeCreate = true;
}
public void EnableEditMode(Citoyen citoyen) {
this.citoyen = citoyen;
Citoyen citoyenContext = new Citoyen();
this.citoyen.Copyto(citoyenContext);
DataContext = citoyenContext;
_modeCreate = false;
}
public void Save_Click(object sender, RoutedEventArgs e) {
nomTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
nomNaissanceTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
prenomTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
ageTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
adresseTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if(_isInvalidElements.Count == 0) {
if(_modeCreate) {
((Citoyen) DataContext).DateCreation = DateTime.Now;
((Citoyen) DataContext).DateModification = DateTime.Now;
dbContext.CitoyenSet.Add((Citoyen) DataContext);
} else {
Citoyen citoyenContext = (Citoyen) DataContext;
citoyenContext.Copyto(citoyen);
citoyen.DateModification = DateTime.Now;
citoyen = null;
}
DataContext = null;
dbContext.SaveChanges();
Close();
}
}
public void Cancel_Click(object sender, RoutedEventArgs e) {
DataContext = null;
citoyen = null;
Close();
}
}
}

View File

@ -1,4 +1,4 @@
<Window x:Class="Hermes.CitoyenModal"
<Window x:Class="Hermes.CitoyenWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@ -9,9 +9,7 @@
ResizeMode="NoResize"
xmlns:Validation="clr-namespace:Hermes.Validation"
xmlns:Converter="clr-namespace:Hermes.Converter"
Loaded="Window_Loaded"
WindowStartupLocation="CenterOwner"
Closing="Window_Closing">
WindowStartupLocation="CenterOwner">
<Window.Resources>
<Converter:NegateBoolean x:Key="NegateBoolean"/>
@ -39,15 +37,7 @@
<Label>Nom de naissance :</Label>
<TextBox Name="nomNaissanceTextBox" Text="{Binding Path=NomNaissance}" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150"/>
<Label>Prénom :</Label>
<TextBox Name="prenomTextBox" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" Validation.Error="ValidationError" Binding.TargetUpdated="BindingTargetUpdated" Binding.SourceUpdated="BindingSourceUpdated" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150">
<TextBox.Text>
<Binding Path="Prenom" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="true" NotifyOnValidationError="true">
<Binding.ValidationRules>
<Validation:MandatoryString/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="prenomTextBox" Text="{Binding Path=Prenom}" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150"/>
<Label>Age :</Label>
<TextBox Name="ageTextBox" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" Validation.Error="ValidationError" Binding.TargetUpdated="BindingTargetUpdated" Binding.SourceUpdated="BindingSourceUpdated" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="30">
<TextBox.Text>
@ -71,17 +61,11 @@
<GroupBox Header="Adresse Locale" Margin="10,10,0,0" VerticalAlignment="Top">
<StackPanel>
<Label>Numéro et rue :</Label>
<TextBox Name="adresseTextBox" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" Validation.Error="ValidationError" Binding.TargetUpdated="BindingTargetUpdated" Binding.SourceUpdated="BindingSourceUpdated" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150">
<TextBox.Text>
<Binding Path="Adresse" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="true" NotifyOnValidationError="true">
<Binding.ValidationRules>
<Validation:MandatoryString/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="adresseTextBox" Text="{Binding Path=Adresse}" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150"/>
<Label>Bâtiment :</Label>
<TextBox Name="adresseBatimentTextBox" Text="{Binding Path=AdresseBatiment}" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150"/>
<Label>Numéro d'appartement:</Label>
<TextBox Name="adresseNumeroBatimentTextBox" Text="{Binding Path=AdresseNumeroBatiment}" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150"/>
<Label>Quartier :</Label>
<TextBox Name="quartierTextBox" Text="{Binding Path=Quartier}" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="150"/>
</StackPanel>

73
CitoyenWindow.xaml.cs Normal file
View File

@ -0,0 +1,73 @@
using Hermes.Model;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Hermes {
public partial class CitoyenWindow : Window {
private Citoyen editRef = null;
private List<object> _isInvalidElements = new List<object>();
public CitoyenWindow(Window parent, Citoyen context = null) {
InitializeComponent();
DataContext = new Citoyen();
Owner = parent;
if(context != null) {
editRef = context;
editRef.Copyto((Citoyen) DataContext);
} else {
((Citoyen) DataContext).Civilite = "Monsieur";
}
List<string> civilites = new List<string>();
civilites.Add("Monsieur");
civilites.Add("Madame");
civiliteComboBox.ItemsSource = civilites;
}
private void ValidationError(object sender, ValidationErrorEventArgs e) {
if(!_isInvalidElements.Contains(sender)) {
_isInvalidElements.Add(sender);
}
}
private void BindingTargetUpdated(object sender, DataTransferEventArgs e) {
if(_isInvalidElements.Contains(sender)) {
_isInvalidElements.Remove(sender);
}
}
private void BindingSourceUpdated(object sender, DataTransferEventArgs e) {
if(_isInvalidElements.Contains(sender)) {
_isInvalidElements.Remove(sender);
}
}
public void Save_Click(object sender, RoutedEventArgs e) {
nomTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
ageTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if(_isInvalidElements.Count == 0) {
ModelContext dbContext = ModelContext.Getinstance();
if(editRef == null) {
((Citoyen) DataContext).DateCreation = DateTime.Now;
((Citoyen) DataContext).DateModification = DateTime.Now;
dbContext.CitoyenSet.Add((Citoyen) DataContext);
} else {
Citoyen context = (Citoyen) DataContext;
context.Copyto(editRef);
editRef.DateModification = DateTime.Now;
}
dbContext.SaveChanges();
Close();
}
}
public void Cancel_Click(object sender, RoutedEventArgs e) {
Close();
}
}
}

342
CitoyensSerializer.cs Normal file
View File

@ -0,0 +1,342 @@
using Hermes.Model;
using System;
using System.Text;
using Microsoft.VisualBasic.FileIO;
using System.IO;
namespace Hermes {
class CitoyensSerializer {
public const string CIVILITE_FIELD = "Civilité";
public const string NOM_FIELD = "Nom";
public const string NOM_NAISSANCE_FIELD = "Nom de naissance";
public const string PRENOM_FIELD = "Prénom";
public const string DATE_NAISSANCE_FIELD = "Date de naissance";
public const string PROFESSION_FIELD = "Profession";
public const string TYPE_RESIDENCE_FIELD = "Résidence secondaire";
public const string MAIL_FIELD = "E-Mail";
public const string TEL_FIELD = "Téléphone";
public const string TEL_PORT_FIELD = "Mobile";
public const string QUARTIER_FIELD = "Quartier";
public const string ADRESSE_FIELD = "Adresse locale";
public const string ADRESSE_BATIMENT_FIELD = "Bâtiment";
public const string ADRESSE_NUMERO_BATIMENT_FIELD = "Numéro d'appartement";
public const string ADRESSE_EXT_FIELD = "Adresse";
public const string ADRESSE_EXT_CP_FIELD = "Code postal";
public const string ADRESSE_EXT_VILLE_FIELD = "Ville";
public const string DATE_CREATION_FIELD = "Date de création";
public const string DATE_MODIFICATION_FIELD = "Date de modification";
public const string TYPE_RESIDENCE_LABEL_FIELD = "Résidence";
public const string AGE_FIELD = "Age";
public const string ADRESSE_CP_FIELD = "Code postal local";
public const string ADRESSE_VILLE_FIELD = "Ville locale";
public const string ADRESSE_PRINCIPALE_FIELD = "Adresse principale";
public const string ADRESSE_PRINCIPALE_CP_FIELD = "Code postal principal";
public const string ADRESSE_PRINCIPALE_VILLE_FIELD = "Ville principale";
public const string ADRESSE_SECONDAIRE_FIELD = "Adresse secondaire";
public const string ADRESSE_SECONDAIRE_CP_FIELD = "Code postal secondaire";
public const string ADRESSE_SECONDAIRE_VILLE_FIELD = "Ville secondaire";
public const string UNKNOWN_FIELD = "unknown";
private string[] fields = null;
public CitoyensSerializer(string[] pField) {
fields = pField;
}
public CitoyensSerializer() {
fields = new string[] {
CIVILITE_FIELD,
NOM_FIELD,
NOM_NAISSANCE_FIELD,
PRENOM_FIELD,
DATE_NAISSANCE_FIELD,
PROFESSION_FIELD,
TYPE_RESIDENCE_FIELD,
MAIL_FIELD,
TEL_FIELD,
TEL_PORT_FIELD,
QUARTIER_FIELD,
ADRESSE_FIELD,
ADRESSE_BATIMENT_FIELD,
ADRESSE_NUMERO_BATIMENT_FIELD,
ADRESSE_EXT_FIELD,
ADRESSE_EXT_CP_FIELD,
ADRESSE_EXT_VILLE_FIELD,
DATE_CREATION_FIELD,
DATE_MODIFICATION_FIELD
};
}
public string GetCsvHeader() {
StringBuilder sb = new StringBuilder();
if(fields != null) {
for(int i = 0; i < fields.Length; i++) {
sb.Append($"\"{fields[i]}\"");
if(i < fields.Length - 1) {
sb.Append(";");
}
}
}
return sb.ToString();
}
public string Serialize(Citoyen citoyen) {
StringBuilder sb = new StringBuilder();
if(fields != null) {
for(int i = 0; i < fields.Length; i++) {
sb.Append("\"");
switch(fields[i]) {
case CIVILITE_FIELD:
sb.Append(citoyen.Civilite == null ? "" : citoyen.Civilite.Replace("\"", ""));
break;
case NOM_FIELD:
sb.Append(citoyen.Nom == null ? "" : citoyen.Nom.Replace("\"", ""));
break;
case NOM_NAISSANCE_FIELD:
sb.Append(citoyen.NomNaissance == null ? "" : citoyen.NomNaissance.Replace("\"", ""));
break;
case PRENOM_FIELD:
sb.Append(citoyen.Prenom == null ? "" : citoyen.Prenom.Replace("\"", ""));
break;
case DATE_NAISSANCE_FIELD:
sb.Append(citoyen.DateNaissance == null ? "" : (new DateTimeOffset(citoyen.DateNaissance.Value)).ToUnixTimeSeconds().ToString());
break;
case PROFESSION_FIELD:
sb.Append(citoyen.Profession == null ? "" : citoyen.Profession.Replace("\"", ""));
break;
case TYPE_RESIDENCE_FIELD:
sb.Append(citoyen.TypeResidence.ToString());
break;
case MAIL_FIELD:
sb.Append(citoyen.Mail == null ? "" : citoyen.Mail.Replace("\"", ""));
break;
case TEL_FIELD:
sb.Append(citoyen.Tel == null ? "" : citoyen.Tel.Replace("\"", ""));
break;
case TEL_PORT_FIELD:
sb.Append(citoyen.TelPort == null ? "" : citoyen.TelPort.Replace("\"", ""));
break;
case QUARTIER_FIELD:
sb.Append(citoyen.Quartier == null ? "" : citoyen.Quartier.Replace("\"", ""));
break;
case ADRESSE_FIELD:
sb.Append(citoyen.Adresse == null ? "" : citoyen.Adresse.Replace("\"", ""));
break;
case ADRESSE_BATIMENT_FIELD:
sb.Append(citoyen.AdresseBatiment == null ? "" : citoyen.AdresseBatiment.Replace("\"", ""));
break;
case ADRESSE_NUMERO_BATIMENT_FIELD:
sb.Append(citoyen.AdresseNumeroBatiment == null ? "" : citoyen.AdresseNumeroBatiment.Replace("\"", ""));
break;
case ADRESSE_EXT_FIELD:
sb.Append(citoyen.AdresseExt == null ? "" : citoyen.AdresseExt.Replace("\"", ""));
break;
case ADRESSE_EXT_CP_FIELD:
sb.Append(citoyen.AdresseExtCP == null ? "" : citoyen.AdresseExtCP.Replace("\"", ""));
break;
case ADRESSE_EXT_VILLE_FIELD:
sb.Append(citoyen.AdresseExtVille == null ? "" : citoyen.AdresseExtVille.Replace("\"", ""));
break;
case DATE_CREATION_FIELD:
sb.Append((new DateTimeOffset(citoyen.DateCreation)).ToUnixTimeSeconds().ToString());
break;
case DATE_MODIFICATION_FIELD:
sb.Append((new DateTimeOffset(citoyen.DateModification)).ToUnixTimeSeconds().ToString());
break;
case AGE_FIELD:
sb.Append(citoyen.Age);
break;
case ADRESSE_CP_FIELD:
sb.Append(citoyen.AdresseCP == null ? "" : citoyen.AdresseCP.Replace("\"", ""));
break;
case ADRESSE_VILLE_FIELD:
sb.Append(citoyen.AdresseVille == null ? "" : citoyen.AdresseVille.Replace("\"", ""));
break;
case ADRESSE_PRINCIPALE_FIELD:
sb.Append(citoyen.AdressePrincipale == null ? "" : citoyen.AdressePrincipale.Replace("\"", ""));
break;
case ADRESSE_PRINCIPALE_CP_FIELD:
sb.Append(citoyen.AdressePrincipaleCP == null ? "" : citoyen.AdressePrincipaleCP.Replace("\"", ""));
break;
case ADRESSE_PRINCIPALE_VILLE_FIELD:
sb.Append(citoyen.AdressePrincipaleVille == null ? "" : citoyen.AdressePrincipaleVille.Replace("\"", ""));
break;
case ADRESSE_SECONDAIRE_FIELD:
sb.Append(citoyen.AdresseSecondaire == null ? "" : citoyen.AdresseSecondaire.Replace("\"", ""));
break;
case ADRESSE_SECONDAIRE_CP_FIELD:
sb.Append(citoyen.AdresseSecondaireCP == null ? "" : citoyen.AdresseSecondaireCP.Replace("\"", ""));
break;
case ADRESSE_SECONDAIRE_VILLE_FIELD:
sb.Append(citoyen.AdresseSecondaireVille == null ? "" : citoyen.AdresseSecondaireVille.Replace("\"", ""));
break;
default:
break;
}
sb.Append("\"");
if(i < fields.Length - 1) {
sb.Append(";");
}
}
}
return sb.ToString();
}
public static string[] ParseHeader(string line) {
TextFieldParser parser = new TextFieldParser(new StringReader(line));
parser.HasFieldsEnclosedInQuotes = true;
parser.SetDelimiters(";");
return parser.ReadFields();
}
public Citoyen Deserialize(string line) {
TextFieldParser parser = new TextFieldParser(new StringReader(line));
parser.HasFieldsEnclosedInQuotes = true;
parser.SetDelimiters(";");
string[] props = parser.ReadFields();
if(props == null || props.Length != fields.Length) {
return null;
}
Citoyen citoyen = new Citoyen();
for(int i = 0; i < fields.Length; i++) {
switch(fields[i]) {
case CIVILITE_FIELD:
citoyen.Civilite = props[i];
break;
case NOM_FIELD:
citoyen.Nom = props[i];
break;
case NOM_NAISSANCE_FIELD:
citoyen.NomNaissance = props[i];
break;
case PRENOM_FIELD:
citoyen.Prenom = props[i];
break;
case DATE_NAISSANCE_FIELD:
if(!string.IsNullOrWhiteSpace(props[i])) {
try {
citoyen.DateNaissance = DateTimeOffset.FromUnixTimeSeconds(long.Parse(props[i])).LocalDateTime;
} catch(Exception) {}
}
break;
case PROFESSION_FIELD:
citoyen.Profession = props[i];
break;
case TYPE_RESIDENCE_FIELD:
try {
citoyen.TypeResidence = bool.Parse(props[i]);
} catch(Exception) {}
break;
case MAIL_FIELD:
citoyen.Mail = props[i];
break;
case TEL_FIELD:
citoyen.Tel = props[i];
break;
case TEL_PORT_FIELD:
citoyen.TelPort = props[i];
break;
case QUARTIER_FIELD:
citoyen.Quartier = props[i];
break;
case ADRESSE_FIELD:
citoyen.Adresse = props[i];
break;
case ADRESSE_BATIMENT_FIELD:
citoyen.AdresseBatiment = props[i];
break;
case ADRESSE_NUMERO_BATIMENT_FIELD:
citoyen.AdresseNumeroBatiment = props[i];
break;
case ADRESSE_EXT_FIELD:
citoyen.AdresseExt = props[i];
break;
case ADRESSE_EXT_CP_FIELD:
citoyen.AdresseExtCP = props[i];
break;
case ADRESSE_EXT_VILLE_FIELD:
citoyen.AdresseExtVille = props[i];
break;
case DATE_CREATION_FIELD:
try {
citoyen.DateCreation = DateTimeOffset.FromUnixTimeSeconds(long.Parse(props[i])).LocalDateTime;
} catch(Exception) {
citoyen.DateCreation = DateTime.Now;
}
break;
case DATE_MODIFICATION_FIELD:
try {
citoyen.DateModification = DateTimeOffset.FromUnixTimeSeconds(long.Parse(props[i])).LocalDateTime;
} catch(Exception) {
citoyen.DateModification = DateTime.Now;
}
break;
default:
break;
}
}
return citoyen;
}
}
}

View File

@ -65,8 +65,9 @@
<Reference Include="EntityFramework.SqlServerCompact, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>packages\EntityFramework.SqlServerCompact.6.4.4\lib\net45\EntityFramework.SqlServerCompact.dll</HintPath>
</Reference>
<Reference Include="isendpro, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\iSendProSMS.1.1.3\lib\isendpro.dll</HintPath>
<Reference Include="Microsoft.Office.Interop.Excel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Office.Interop.Excel.15.0.4795.1000\lib\net20\Microsoft.Office.Interop.Excel.dll</HintPath>
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.Office.Interop.Outlook, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Office.Interop.Outlook.15.0.4797.1003\lib\net20\Microsoft.Office.Interop.Outlook.dll</HintPath>
@ -76,12 +77,10 @@
<HintPath>packages\Microsoft.Office.Interop.Word.15.0.4797.1003\lib\net20\Microsoft.Office.Interop.Word.dll</HintPath>
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="RestSharp.Net2, Version=102.7.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\RestSharp.Net2.1.1.11\lib\net20\RestSharp.Net2.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
@ -109,17 +108,30 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="CitoyensSerializer.cs" />
<Compile Include="Converter\NegateBoolean.cs" />
<Compile Include="Migrations\202012051414539_V1.cs" />
<Compile Include="Migrations\202012051414539_V1.designer.cs">
<DependentUpon>202012051414539_V1.cs</DependentUpon>
<Compile Include="ImportWindow.xaml.cs">
<DependentUpon>ImportWindow.xaml</DependentUpon>
</Compile>
<Compile Include="InputWindow.xaml.cs">
<DependentUpon>InputWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Migrations\202012281505590_V1.cs" />
<Compile Include="Migrations\202012281505590_V1.designer.cs">
<DependentUpon>202012281505590_V1.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\202012292127194_V2.cs" />
<Compile Include="Migrations\202012292127194_V2.designer.cs">
<DependentUpon>202012292127194_V2.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Model\Citoyen.cs" />
<Compile Include="Model\Preferences.cs" />
<Compile Include="Model\ModelContext.cs" />
<Compile Include="PreferencesModal.xaml.cs">
<DependentUpon>PreferencesModal.xaml</DependentUpon>
<Compile Include="OVHQueryBody.cs" />
<Compile Include="OVHResponseBody.cs" />
<Compile Include="PreferencesWindow.xaml.cs">
<DependentUpon>PreferencesWindow.xaml</DependentUpon>
</Compile>
<Compile Include="SmsSendingStatus.cs" />
<Compile Include="SmsWindow.xaml.cs">
@ -127,7 +139,15 @@
</Compile>
<Compile Include="Validation\Age.cs" />
<Compile Include="Validation\MandatoryString.cs" />
<Page Include="CitoyenModal.xaml">
<Page Include="CitoyenWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ImportWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="InputWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@ -139,14 +159,14 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="CitoyenModal.xaml.cs">
<DependentUpon>CitoyenModal.xaml</DependentUpon>
<Compile Include="CitoyenWindow.xaml.cs">
<DependentUpon>CitoyenWindow.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="PreferencesModal.xaml">
<Page Include="PreferencesWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@ -169,8 +189,11 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Migrations\202012051414539_V1.resx">
<DependentUpon>202012051414539_V1.cs</DependentUpon>
<EmbeddedResource Include="Migrations\202012281505590_V1.resx">
<DependentUpon>202012281505590_V1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\202012292127194_V2.resx">
<DependentUpon>202012292127194_V2.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
@ -204,6 +227,43 @@
<ItemGroup>
<Resource Include="hermes.ico" />
</ItemGroup>
<ItemGroup>
<SplashScreen Include="hermes_splash.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="doc\img\main.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="doc\img\add.png" />
<Resource Include="doc\img\first_launch_1.png" />
<Resource Include="doc\img\first_launch_2.png" />
<Resource Include="doc\img\list_1.png" />
<Resource Include="doc\img\list_2.png" />
<Resource Include="doc\img\menu_display.png" />
<Resource Include="doc\img\menu_edit.png" />
<Resource Include="doc\img\menu_file.png" />
<Resource Include="doc\img\menu_tools.png" />
<Resource Include="doc\img\smartscreen_1.png" />
<Resource Include="doc\img\smartscreen_2.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="doc\img\publi_1.png" />
<Resource Include="doc\img\publi_2.png" />
<Resource Include="doc\img\publi_3.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="doc\img\ovh_1.png" />
<Resource Include="doc\img\ovh_2.png" />
<Resource Include="doc\img\ovh_3.png" />
<Resource Include="doc\img\ovh_4.png" />
<Resource Include="doc\img\ovh_5.png" />
<Resource Include="doc\img\ovh_6.png" />
<Resource Include="doc\img\ovh_7.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="doc\img\sms_1.png" />
<Resource Include="doc\img\sms_2.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>

View File

@ -18,7 +18,9 @@ Global
{2F7FDF03-5F05-438E-9C90-F926B40DCC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F7FDF03-5F05-438E-9C90-F926B40DCC6D}.Release|Any CPU.Build.0 = Release|Any CPU
{F2D85CBF-A3A1-41CE-BE80-502C0DD4024D}.Debug|Any CPU.ActiveCfg = Debug
{F2D85CBF-A3A1-41CE-BE80-502C0DD4024D}.Debug|Any CPU.Build.0 = Debug
{F2D85CBF-A3A1-41CE-BE80-502C0DD4024D}.Release|Any CPU.ActiveCfg = Release
{F2D85CBF-A3A1-41CE-BE80-502C0DD4024D}.Release|Any CPU.Build.0 = Release
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

33
ImportWindow.xaml Normal file
View File

@ -0,0 +1,33 @@
<Window x:Class="Hermes.ImportWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Hermes"
mc:Ignorable="d"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Title="Importer" Height="310" Width="230"
Closing="Window_Closing">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="45"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="5,5,5,0">
<Label>Feuille à importer :</Label>
<ComboBox Name="sheetComboBox" Height="23"/>
<Label>Quartier à définir</Label>
<TextBox Name="quartierTextBox" VerticalContentAlignment="Center" Height="23"/>
<Label>Nom de rue à définir</Label>
<TextBox Name="adresseTextBox" VerticalContentAlignment="Center" Height="23"/>
<Label>Bâtiment à définir</Label>
<TextBox Name="batimentTextBox" VerticalContentAlignment="Center" Height="23"/>
<WrapPanel>
<Label>Résidence</Label>
<CheckBox Name="residenceCheckBox" VerticalAlignment="Center"/>
</WrapPanel>
</StackPanel>
<Button Name="importButton" IsDefault="true" Grid.Row="1" Width="100" Height="25" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,5,0" Click="Importer_Click">Importer</Button>
</Grid>
</Window>

139
ImportWindow.xaml.cs Normal file
View File

@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows;
using Hermes.Model;
using Excel = Microsoft.Office.Interop.Excel;
namespace Hermes {
public partial class ImportWindow : Window {
private bool importing = false;
private Excel.Application xlApp;
private Excel.Workbook xlWb;
private static Regex communeRgx = new Regex(@"(\d{5})(.*)");
private static string prepareValue(object value, bool notNull = false) {
if(value != null) {
return value.ToString().Trim();
}
if(notNull) {
return "";
} else {
return null;
}
}
public ImportWindow(Window parent, string filepath) {
InitializeComponent();
Owner = parent;
List<string> sheets = new List<string>();
adresseTextBox.Text = Path.GetFileNameWithoutExtension(filepath);
xlApp = new Excel.Application();
xlWb = xlApp.Workbooks.Open(filepath);
for(int i = 1; i <= xlWb.Sheets.Count; i++) {
Excel.Worksheet sheet = xlWb.Sheets.Item[i];
sheets.Add(sheet.Name);
}
sheetComboBox.ItemsSource = sheets;
if(sheets.Count == 0) {
importButton.IsEnabled = false;
} else {
sheetComboBox.SelectedIndex = 0;
}
}
private void Importer_Click(object sender, RoutedEventArgs e) {
importing = true;
Excel.Worksheet sheet = xlWb.Sheets.Item[sheetComboBox.SelectedIndex + 1];
string cell = prepareValue(sheet.Cells[1, "J"].Value);
bool complement = false;
string rue = adresseTextBox.Text == null ? "" : adresseTextBox.Text;
if(!string.IsNullOrEmpty(cell)) {
complement = true;
}
for(int i = 2; string.IsNullOrEmpty(prepareValue(sheet.Cells[i, "A"].Value)) != true ; i++) {
Citoyen citoyen = new Citoyen();
citoyen.Nom = prepareValue(sheet.Cells[i, "A"].Value);
citoyen.Prenom = prepareValue(sheet.Cells[i, "B"].Value);
if(complement) {
string num = prepareValue(sheet.Cells[i, "D"].Value);
if(residenceCheckBox.IsChecked == true) {
citoyen.Adresse = rue;
citoyen.AdresseNumeroBatiment = num;
} else {
citoyen.Adresse = $"{num} {rue}";
}
citoyen.Mail = prepareValue(sheet.Cells[i, "E"].Value);
citoyen.Tel = prepareValue(sheet.Cells[i, "F"].Value);
citoyen.TelPort = prepareValue(sheet.Cells[i, "G"].Value);
string res = prepareValue(sheet.Cells[i, "H"].Value, true);
if(res.ToLower().Replace(" ", "").Equals("r.secondaire")) {
citoyen.TypeResidence = true;
} else {
citoyen.TypeResidence = false;
}
if(citoyen.TypeResidence == true) {
citoyen.AdresseExt = prepareValue(sheet.Cells[i, "I"].Value);
Match m = communeRgx.Match(prepareValue(sheet.Cells[i, "J"].Value, true));
if(m.Success) {
citoyen.AdresseExtCP = m.Groups[1].Value.Trim();
citoyen.AdresseExtVille = m.Groups[2].Value.Trim();
}
}
} else {
string num = prepareValue(sheet.Cells[i, "C"].Value);
if(residenceCheckBox.IsChecked == true) {
citoyen.Adresse = rue;
citoyen.AdresseNumeroBatiment = num;
} else {
citoyen.Adresse = $"{num} {rue}";
}
citoyen.Mail = prepareValue(sheet.Cells[i, "D"].Value);
citoyen.Tel = prepareValue(sheet.Cells[i, "E"].Value);
citoyen.TelPort = prepareValue(sheet.Cells[i, "F"].Value);
string res = prepareValue(sheet.Cells[i, "G"].Value, true);
if(res.ToLower().Replace(" ", "").Equals("r.secondaire")) {
citoyen.TypeResidence = true;
} else {
citoyen.TypeResidence = false;
}
if(citoyen.TypeResidence == true) {
citoyen.AdresseExt = prepareValue(sheet.Cells[i, "H"].Value);
Match m = communeRgx.Match(prepareValue(sheet.Cells[i, "I"].Value, true));
if(m.Success) {
citoyen.AdresseExtCP = m.Groups[1].Value.Trim();
citoyen.AdresseExtVille = m.Groups[2].Value.Trim();
}
}
}
citoyen.AdresseBatiment = batimentTextBox.Text;
citoyen.Quartier = quartierTextBox.Text;
citoyen.DateCreation = DateTime.Now;
citoyen.DateModification = DateTime.Now;
ModelContext.Getinstance().CitoyenSet.Add(citoyen);
}
ModelContext.Getinstance().SaveChanges();
Marshal.FinalReleaseComObject(sheet);
importing = false;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
if(importing) {
e.Cancel = true;
return;
}
xlWb.Close();
Marshal.FinalReleaseComObject(xlWb);
xlApp.Quit();
Marshal.FinalReleaseComObject(xlApp);
}
}
}

25
InputWindow.xaml Normal file
View File

@ -0,0 +1,25 @@
<Window x:Class="Hermes.InputWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Hermes"
mc:Ignorable="d"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Title="" Height="140" Width="250">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="10" VerticalAlignment="Center">
<TextBlock Name="msgTextBlock" Margin="0,0,0,10"/>
<TextBox Name="inputTextBox" Height="23" HorizontalAlignment="Left" Width="200"/>
</StackPanel>
<WrapPanel Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0">
<Button Margin="0,0,10,0" Height="25" Width="80" IsDefault="True" Click="Valider_Click">Valider</Button>
<Button Height="25" Width="80" Click="Annuler_Click">Annuler</Button>
</WrapPanel>
</Grid>
</Window>

26
InputWindow.xaml.cs Normal file
View File

@ -0,0 +1,26 @@
using System.Windows;
namespace Hermes {
public partial class InputWindow : Window {
private string inputText = null;
public InputWindow(string title, string message, Window parent) {
InitializeComponent();
msgTextBlock.Text = message;
Title = title;
Owner = parent;
}
private void Valider_Click(object sender, RoutedEventArgs e) {
inputText = inputTextBox.Text;
DialogResult = true;
Close();
}
private void Annuler_Click(object sender, RoutedEventArgs e) {
Close();
}
public string InputText => inputText;
}
}

View File

@ -147,6 +147,12 @@
}
"Entry"
{
"MsmKey" = "8:_F434633E0B073F068C7E19B9E5AB2EC4"
"OwnerKey" = "8:_EDA497A114444E23814EEE023731C727"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_EDA497A114444E23814EEE023731C727"
"MsmSig" = "8:_UNDEFINED"
@ -154,6 +160,12 @@
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_F434633E0B073F068C7E19B9E5AB2EC4"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_F0A5B43231BDF6E8358EE22CD3E2D5F2"
"MsmSig" = "8:_UNDEFINED"
}
@ -208,10 +220,10 @@
"ComponentsUrl" = "8:"
"Items"
{
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.8"
{
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
"Name" = "8:Microsoft .NET Framework 4.8 (x86 et x64)"
"ProductCode" = "8:.NETFramework,Version=v4.8"
}
}
}
@ -233,7 +245,7 @@
"InstallerBootstrapper" = "3:2"
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
{
"Enabled" = "11:TRUE"
"Enabled" = "11:FALSE"
"PromptEnabled" = "11:TRUE"
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
@ -691,6 +703,37 @@
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_F434633E0B073F068C7E19B9E5AB2EC4"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
"AssemblyAsmDisplayName" = "8:Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"
"ScatterAssemblies"
{
"_F434633E0B073F068C7E19B9E5AB2EC4"
{
"Name" = "8:Newtonsoft.Json.dll"
"Attributes" = "3:512"
}
}
"SourcePath" = "8:Newtonsoft.Json.dll"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_358759A83B6F4CD5AEAA9CCDB02A52A0"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
}
"FileType"
{
@ -769,15 +812,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:Hermes"
"ProductCode" = "8:{458A9AC9-956F-44DC-86F1-6C59FCEC0001}"
"PackageCode" = "8:{C3692850-4A0E-43FE-B6D1-0FFE749C3562}"
"ProductCode" = "8:{3B44B09A-1491-4CE0-A6A5-ABD54F4C14F8}"
"PackageCode" = "8:{618674BD-7E73-4707-ABF3-4183A348D565}"
"UpgradeCode" = "8:{A8FB75F3-57A5-4B7D-A0AE-9E87F69529B0}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:0.9.0"
"ProductVersion" = "8:1.0.0"
"Manufacturer" = "8:Aztrom"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"

View File

@ -7,7 +7,7 @@
mc:Ignorable="d"
Loaded="Window_Loaded"
WindowStartupLocation="CenterScreen"
Title="Hermes" Height="640" Width="1024">
Title="Hermes" MinHeight="360" MinWidth="1010">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="Bool2VisibilityConv"/>
<CollectionViewSource x:Key="citoyenCollectionViewSource"/>
@ -17,34 +17,43 @@
<RowDefinition Height="20"/>
<RowDefinition Height="90"/>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Menu Grid.Row="0" Background="White">
<MenuItem Header="Fichier">
<MenuItem Header="Exporter" Click="Exporter_Click"/>
<MenuItem Header="Importer" Click="Importer_Click" />
<MenuItem Header="Quitter" Click="Quitter_Click"/>
</MenuItem>
<MenuItem Header="Edition">
<MenuItem Header="Édition">
<MenuItem Header="Ajouter..." Click="Ajouter_Click"/>
<MenuItem Header="Édition multiple">
<MenuItem Header="Adresse" Click="GroupEdit_Adresse"/>
<MenuItem Header="Quartier" Click="GroupEdit_Quartier"/>
<MenuItem Header="Bâtiment" Click="GroupEdit_Batiment"/>
</MenuItem>
<MenuItem Header="Supprimer" Click="Supprimer_Click"/>
</MenuItem>
<MenuItem Header="Affichage">
<MenuItem Name="civiliteViewCheckBox" Header="Civilité" IsCheckable="true"/>
<MenuItem Name="nomViewCheckBox" Header="Nom" IsCheckable="true" IsChecked="True"/>
<MenuItem Name="nomNaissanceViewCheckBox" Header="Nom de naissance" IsCheckable="true"/>
<MenuItem Name="prenomViewCheckBox" Header="Prénom" IsCheckable="true" IsChecked="True"/>
<MenuItem Name="ageViewCheckBox" Header="Age" IsCheckable="true" IsChecked="True"/>
<MenuItem Name="professionViewCheckBox" Header="Profession" IsCheckable="true"/>
<MenuItem Name="typeResidenceViewCheckBox" Header="Résidence" IsCheckable="true" IsChecked="True"/>
<MenuItem Name="quartierViewCheckBox" Header="Quartier" IsCheckable="true"/>
<MenuItem Name="adresseViewCheckBox" Header="Adresse locale" IsCheckable="true" IsChecked="True"/>
<MenuItem Name="adresseBatimentViewCheckBox" Header="Bâtiment" IsCheckable="true"/>
<MenuItem Name="adresseExtViewCheckBox" Header="Adresse" IsCheckable="true"/>
<MenuItem Name="adresseExtCPViewCheckBox" Header="Code postal" IsCheckable="true"/>
<MenuItem Name="adresseExtVilleViewCheckBox" Header="Ville" IsCheckable="true"/>
<MenuItem Name="mailViewCheckBox" Header="E-Mail" IsCheckable="true"/>
<MenuItem Name="telViewCheckBox" Header="Téléphone" IsCheckable="true"/>
<MenuItem Name="telPortViewCheckBox" Header="Mobile" IsCheckable="true"/>
<MenuItem Name="dateCreationViewCheckBox" Header="Date de création" IsCheckable="true"/>
<MenuItem Name="dateModificationViewCheckBox" Header="Date de modification" IsCheckable="true"/>
<MenuItem Name="viewMenu" Header="Affichage">
<MenuItem Name="civiliteViewCheckBox" Header="Civilité" IsCheckable="true" IsChecked="{Binding Path=civiliteViewEnabled}"/>
<MenuItem Name="nomViewCheckBox" Header="Nom" IsCheckable="true" IsChecked="{Binding Path=nomViewEnabled}"/>
<MenuItem Name="nomNaissanceViewCheckBox" Header="Nom de naissance" IsCheckable="true" IsChecked="{Binding Path=nomNaissanceViewEnabled}"/>
<MenuItem Name="prenomViewCheckBox" Header="Prénom" IsCheckable="true" IsChecked="{Binding Path=prenomViewEnabled}"/>
<MenuItem Name="ageViewCheckBox" Header="Age" IsCheckable="true" IsChecked="{Binding Path=ageViewEnabled}"/>
<MenuItem Name="professionViewCheckBox" Header="Profession" IsCheckable="true" IsChecked="{Binding Path=professionViewEnabled}"/>
<MenuItem Name="typeResidenceViewCheckBox" Header="Résidence" IsCheckable="true" IsChecked="{Binding Path=typeResidenceViewEnabled}"/>
<MenuItem Name="quartierViewCheckBox" Header="Quartier" IsCheckable="true" IsChecked="{Binding Path=quartierViewEnabled}"/>
<MenuItem Name="adresseViewCheckBox" Header="Adresse locale" IsCheckable="true" IsChecked="{Binding Path=adresseViewEnabled}"/>
<MenuItem Name="adresseBatimentViewCheckBox" Header="Bâtiment" IsCheckable="true" IsChecked="{Binding Path=adresseBatimentViewEnabled}"/>
<MenuItem Name="adresseNumeroBatimentViewCheckBox" Header="Numéro d'appartement" IsCheckable="true" IsChecked="{Binding Path=adresseNumeroBatimentViewEnabled}"/>
<MenuItem Name="adresseExtViewCheckBox" Header="Adresse" IsCheckable="true" IsChecked="{Binding Path=adresseExtViewEnabled}"/>
<MenuItem Name="adresseExtCPViewCheckBox" Header="Code postal" IsCheckable="true" IsChecked="{Binding Path=adresseExtCPViewEnabled}"/>
<MenuItem Name="adresseExtVilleViewCheckBox" Header="Ville" IsCheckable="true" IsChecked="{Binding Path=adresseExtVilleViewEnabled}"/>
<MenuItem Name="mailViewCheckBox" Header="E-Mail" IsCheckable="true" IsChecked="{Binding Path=mailViewEnabled}"/>
<MenuItem Name="telViewCheckBox" Header="Téléphone" IsCheckable="true" IsChecked="{Binding Path=telViewEnabled}"/>
<MenuItem Name="telPortViewCheckBox" Header="Mobile" IsCheckable="true" IsChecked="{Binding Path=telPortViewEnabled}"/>
<MenuItem Name="dateCreationViewCheckBox" Header="Date de création" IsCheckable="true" IsChecked="{Binding Path=dateCreationViewEnabled}"/>
<MenuItem Name="dateModificationViewCheckBox" Header="Date de modification" IsCheckable="true" IsChecked="{Binding Path=dateModificationViewEnabled}"/>
</MenuItem>
<MenuItem Header="Communication">
<MenuItem Header="Courriel..." Click="Courriel_Click"/>
@ -106,6 +115,7 @@
<DataGridTextColumn Header="Quartier" Visibility="{Binding Source={x:Reference quartierViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding Quartier}" Width="*"/>
<DataGridTextColumn Header="Adresse Locale" Visibility="{Binding Source={x:Reference adresseViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding Adresse}" Width="*"/>
<DataGridTextColumn Header="Bâtiment" Visibility="{Binding Source={x:Reference adresseBatimentViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding AdresseBatiment}" Width="*"/>
<DataGridTextColumn Header="Numéro d'appartement" Visibility="{Binding Source={x:Reference adresseNumeroBatimentViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding AdresseNumeroBatiment}" Width="*"/>
<DataGridTextColumn Header="Adresse" Visibility="{Binding Source={x:Reference adresseExtViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding AdresseExt}" Width="*"/>
<DataGridTextColumn Header="Code postal" Visibility="{Binding Source={x:Reference adresseExtCPViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding AdresseExtCP}" Width="*"/>
<DataGridTextColumn Header="Ville" Visibility="{Binding Source={x:Reference adresseExtVilleViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding AdresseExtVille}" Width="*"/>
@ -116,5 +126,21 @@
<DataGridTextColumn Header="Date de modification" Visibility="{Binding Source={x:Reference dateModificationViewCheckBox}, Path=IsChecked, Converter={StaticResource Bool2VisibilityConv}}" Binding="{Binding DateModification, StringFormat='dd/MM/yyyy HH:mm'}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<StatusBar Grid.Row="3">
<StatusBarItem Margin="0,0,30,0">
<TextBlock>
<Run Text="Affichés : "/>
<Run Text="{Binding ElementName=dgCitoyens, Path=Items.Count, Mode=OneWay}"/>
<Run Text=" éléments"/>
</TextBlock>
</StatusBarItem>
<StatusBarItem>
<TextBlock>
<Run Text="Sélectionnés : "/>
<Run Text="{Binding ElementName=dgCitoyens, Path=SelectedItems.Count, Mode=OneWay}"/>
<Run Text=" éléments"/>
</TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>

View File

@ -12,44 +12,127 @@ using Microsoft.Win32;
namespace Hermes {
public partial class MainWindow : Window {
private ModelContext dbContext = null;
private CitoyenModal citoyenModal = new CitoyenModal();
private PreferencesModal preferencesModal = new PreferencesModal();
private SmsWindow smsModal = new SmsWindow();
private CollectionViewSource citoyenCollectionViewSource = null;
private bool isEnabledFilter = false;
private Preferences pref = null;
public MainWindow() {
dbContext = ModelContext.Getinstance();
//dbContext.Database.Log = log => System.Console.WriteLine(log);
dbContext.Database.CreateIfNotExists();
dbContext.CitoyenSet.Load();
dbContext.Preferences.Load();
if(dbContext.Preferences.Local.Count == 0) {
pref = new Preferences();
pref.civiliteViewEnabled = false;
pref.nomViewEnabled = true;
pref.nomNaissanceViewEnabled = false;
pref.prenomViewEnabled = true;
pref.ageViewEnabled = false;
pref.professionViewEnabled = false;
pref.typeResidenceViewEnabled = false;
pref.mailViewEnabled = false;
pref.telViewEnabled = false;
pref.telPortViewEnabled = false;
pref.quartierViewEnabled = false;
pref.adresseViewEnabled = true;
pref.adresseBatimentViewEnabled = false;
pref.adresseNumeroBatimentViewEnabled = false;
pref.adresseExtViewEnabled = false;
pref.adresseExtCPViewEnabled = false;
pref.adresseExtVilleViewEnabled = false;
pref.dateCreationViewEnabled = false;
pref.dateModificationViewEnabled = false;
pref.windowWidth = 1024;
pref.windowHeight = 640;
pref.windowMaximized = false;
dbContext.Preferences.Add(pref);
dbContext.SaveChanges();
}
pref = dbContext.Preferences.Local[0];
InitializeComponent();
Height = pref.windowHeight;
Width = pref.windowWidth;
if(pref.windowMaximized) {
WindowState = WindowState.Maximized;
} else {
WindowState = WindowState.Normal;
}
viewMenu.DataContext = pref;
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
citoyenModal.Owner = this;
preferencesModal.Owner = this;
smsModal.Owner = this;
dbContext.CitoyenSet.Load();
dbContext.Preferences.Load();
citoyenCollectionViewSource = (CollectionViewSource) this.FindResource("citoyenCollectionViewSource");
citoyenCollectionViewSource.Source = dbContext.CitoyenSet.Local;
if(dbContext.Preferences.Local.Count == 0) {
if(string.IsNullOrWhiteSpace(pref.VilleCP) || string.IsNullOrWhiteSpace(pref.Ville)) {
MessageBox.Show("Il s'agit du premier lancement de Hermes. Veuillez renseigner les informations sur votre commune.", "Premier lancement", MessageBoxButton.OK, MessageBoxImage.None);
preferencesModal.LoadPreferences();
preferencesModal.ShowDialog();
PreferencesWindow preferencesWindow = new PreferencesWindow(this);
preferencesWindow.ShowDialog();
}
}
private void Options_Click(object sender, RoutedEventArgs e) {
preferencesModal.LoadPreferences();
preferencesModal.ShowDialog();
PreferencesWindow preferencesWindow = new PreferencesWindow(this);
preferencesWindow.ShowDialog();
}
private void Ajouter_Click(object sender, RoutedEventArgs e) {
citoyenModal.EnableCreateMode();
citoyenModal.ShowDialog();
CitoyenWindow citoyenWindow = new CitoyenWindow(this);
citoyenWindow.ShowDialog();
}
private void GroupEdit_Batiment(object sender, RoutedEventArgs e) {
if(dgCitoyens.SelectedItems.Count == 0) {
MessageBox.Show("Aucun citoyen sélectionné.", "Édition multiple", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
InputWindow inputBox = new InputWindow("Associer un bâtiment :", "Entrez le nom d'un bâtiment :", this);
if(inputBox.ShowDialog() == true) {
foreach(Citoyen citoyen in dgCitoyens.SelectedItems) {
citoyen.AdresseBatiment = inputBox.InputText;
citoyen.DateModification = DateTime.Now;
}
dbContext.SaveChanges();
}
}
private void GroupEdit_Quartier(object sender, RoutedEventArgs e) {
if(dgCitoyens.SelectedItems.Count == 0) {
MessageBox.Show("Aucun citoyen sélectionné.", "Édition multiple", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
InputWindow inputBox = new InputWindow("Associer un quartier :", "Entrez le nom d'un quartier :", this);
if(inputBox.ShowDialog() == true) {
foreach(Citoyen citoyen in dgCitoyens.SelectedItems) {
citoyen.Quartier = inputBox.InputText;
citoyen.DateModification = DateTime.Now;
}
dbContext.SaveChanges();
}
}
private void GroupEdit_Adresse(object sender, RoutedEventArgs e) {
if(dgCitoyens.SelectedItems.Count == 0) {
MessageBox.Show("Aucun citoyen sélectionné.", "Édition multiple", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
InputWindow inputBox = new InputWindow("Associer une adresse :", "Entrez un numéro et un nom de rue :", this);
if(inputBox.ShowDialog() == true) {
foreach(Citoyen citoyen in dgCitoyens.SelectedItems) {
citoyen.Adresse = inputBox.InputText;
citoyen.DateModification = DateTime.Now;
}
dbContext.SaveChanges();
}
}
private void Supprimer_Click(object sender, RoutedEventArgs e) {
@ -66,7 +149,7 @@ namespace Hermes {
dbContext.SaveChanges();
}
} else {
MessageBox.Show("Aucun citoyen sélectionné", "Suppression", MessageBoxButton.OK, MessageBoxImage.Exclamation);
MessageBox.Show("Aucun citoyen sélectionné.", "Suppression", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
@ -85,16 +168,19 @@ namespace Hermes {
}
if(rcps.Count > 0) {
if(noTel) {
MessageBox.Show("Certains des citoyens sélectionnés ne disposent pas d'un numéro de mobile", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Exclamation);
result = MessageBox.Show("Certains des citoyens sélectionnés ne disposent pas d'un numéro de mobile. Voulez-vous continuer ?", "Envoi de SMS", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if(result == MessageBoxResult.No) {
return;
}
}
smsModal.LoadCitoyens(rcps);
smsModal.ShowDialog();
SmsWindow smsWindow = new SmsWindow(this, rcps);
smsWindow.ShowDialog();
} else {
MessageBox.Show("Aucun des citoyens sélectionnés ne disposent d'un numéro de mobile", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Exclamation);
MessageBox.Show("Aucun des citoyens sélectionnés ne disposent d'un numéro de mobile.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
} else {
MessageBox.Show("Aucun citoyen sélectionné", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Exclamation);
MessageBox.Show("Aucun citoyen sélectionné.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
@ -114,7 +200,10 @@ namespace Hermes {
}
if(mails.Count > 0) {
if(noMail) {
MessageBox.Show("Certains des citoyens sélectionnés ne disposent pas d'une adresse E-Mail", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
result = MessageBox.Show("Certains des citoyens sélectionnés ne disposent pas d'une adresse E-Mail. Voulez-vous continuer ?", "Envoi de courriel", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if(result == MessageBoxResult.No) {
return;
}
}
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem mailItem = app.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
@ -123,14 +212,14 @@ namespace Hermes {
rcp.Type = (int) Microsoft.Office.Interop.Outlook.OlMailRecipientType.olBCC;
}
mailItem.Recipients.ResolveAll();
MessageBox.Show("Assurez-vous que Microsoft OutLook soit démarré avant de continuer", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.None);
MessageBox.Show("Assurez-vous que Microsoft OutLook soit démarré avant de continuer.", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.None);
mailItem.Display(true);
} else {
MessageBox.Show("Aucun des citoyens sélectionnés ne disposent d'une adresse E-Mail", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
MessageBox.Show("Aucun des citoyens sélectionnés ne disposent d'une adresse E-Mail.", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
} else {
MessageBox.Show("Aucun citoyen sélectionné", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
MessageBox.Show("Aucun citoyen sélectionné.", "Envoi de courriel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
@ -139,7 +228,7 @@ namespace Hermes {
MessageBoxResult result = MessageBox.Show("Voulez-vous réaliser une tâche de publipostage pour ces citoyens ?", "Publipostage", MessageBoxButton.YesNo, MessageBoxImage.Question);
if(result == MessageBoxResult.Yes) {
string csvPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "hermes_tmp_datasource.csv");
string csvHeader = "\"Civilité\";\"Nom\";\"Nom de naissance\";\"Prénom\";\"Profession\";\"Type de résidence\";\"E-Mail\";\"Téléphone\";\"Mobile\";\"Quartier\";\"Bâtiment\";\"Adresse principale\";\"Code postal principal\";\"Ville principale\";\"Adresse secondaire\";\"Code postal secondaire\";\"Ville secondaire\"";
string csvHeader = "\"Civilité\";\"Nom\";\"Nom de naissance\";\"Prénom\";\"Profession\";\"Type de résidence\";\"E-Mail\";\"Téléphone\";\"Mobile\";\"Quartier\";\"Bâtiment\";\"Numéro appartement\";\"Adresse locale\";\"Code postal local\";\"Ville locale\";\"Adresse principale\";\"Code postal principal\";\"Ville principale\";\"Adresse secondaire\";\"Code postal secondaire\";\"Ville secondaire\"";
StringBuilder sb = new StringBuilder();
sb.AppendLine(csvHeader);
foreach(Citoyen citoyen in dgCitoyens.SelectedItems) {
@ -154,6 +243,10 @@ namespace Hermes {
string telPort = citoyen.TelPort == null ? "" : citoyen.TelPort;
string quartier = citoyen.Quartier == null ? "" : citoyen.Quartier;
string batiment = citoyen.AdresseBatiment == null ? "" : citoyen.AdresseBatiment;
string numeroBatiment = citoyen.AdresseNumeroBatiment == null ? "" : citoyen.AdresseNumeroBatiment;
string adresseLocale = citoyen.Adresse == null ? "" : citoyen.Adresse;
string cpLocal = citoyen.AdresseCP == null ? "" : citoyen.AdresseCP;
string villeLocale = citoyen.AdresseVille == null ? "" : citoyen.AdresseVille;
string adressePrincipale = citoyen.AdressePrincipale == null ? "" : citoyen.AdressePrincipale;
string cpPrincipal = citoyen.AdressePrincipaleCP == null ? "" : citoyen.AdressePrincipaleCP;
string villePrincipale = citoyen.AdressePrincipaleVille == null ? "" : citoyen.AdressePrincipaleVille;
@ -161,9 +254,14 @@ namespace Hermes {
string cpSecondaire = citoyen.AdresseSecondaireCP == null ? "" : citoyen.AdresseSecondaireCP;
string villeSecondaire = citoyen.AdresseSecondaireVille == null ? "" : citoyen.AdresseSecondaireVille;
sb.AppendLine($"\"{civilite}\";\"{nom}\";\"{nomNaissance}\";\"{prenom}\";\"{profession}\";\"{typeResidence}\";\"{mail}\";\"{tel}\";\"{telPort}\";\"{quartier}\";\"{batiment}\";\"{adressePrincipale}\";\"{cpPrincipal}\";\"{villePrincipale}\";\"{adresseSecondaire}\";\"{cpSecondaire}\";\"{villeSecondaire}\"");
sb.AppendLine($"\"{civilite}\";\"{nom}\";\"{nomNaissance}\";\"{prenom}\";\"{profession}\";\"{typeResidence}\";\"{mail}\";\"{tel}\";\"{telPort}\";\"{quartier}\";\"{batiment}\";\"{numeroBatiment}\";\"{adresseLocale}\";\"{cpLocal}\";{villeLocale};\"{adressePrincipale}\";\"{cpPrincipal}\";\"{villePrincipale}\";\"{adresseSecondaire}\";\"{cpSecondaire}\";\"{villeSecondaire}\"");
}
try {
File.WriteAllText(csvPath, sb.ToString(), Encoding.GetEncoding("ISO-8859-1"));
} catch(Exception) {
MessageBox.Show("Erreur lors de la préparation des données pour le publipostage.", "Publipostage", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
OpenFileDialog ofd = new OpenFileDialog();
@ -177,14 +275,92 @@ namespace Hermes {
}
}
} else {
MessageBox.Show("Aucun citoyen sélectionné", "Publipostage", MessageBoxButton.OK, MessageBoxImage.Exclamation);
MessageBox.Show("Aucun citoyen sélectionné.", "Publipostage", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
}
private void Importer_Click(object sender, RoutedEventArgs e) {
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Fichiers de données|*.csv|Tous les fichiers|*.*";
if(ofd.ShowDialog() == true) {
if(Path.GetExtension(ofd.FileName).ToLower().Equals(".csv")) {
StreamReader reader = null;
Cursor previousCursor = Mouse.OverrideCursor;
Mouse.OverrideCursor = Cursors.Wait;
try {
reader = File.OpenText(ofd.FileName);
string csvHeader = reader.ReadLine();
if(csvHeader == null) {
return;
}
string[] fields = CitoyensSerializer.ParseHeader(csvHeader);
CitoyensSerializer serializer = new CitoyensSerializer(fields);
while(!reader.EndOfStream) {
string line = reader.ReadLine();
Citoyen citoyen = serializer.Deserialize(line);
if(citoyen != null) {
dbContext.CitoyenSet.Add(citoyen);
}
}
} catch(Exception ex) {
if(ex is IOException || ex is UnauthorizedAccessException) {
MessageBox.Show("Impossible d'ouvrir le fichier. Il est possible qu'il soit déjà utilisé par un autre programme ou que le chemin d'accès soit incorrect.", "Importer", MessageBoxButton.OK, MessageBoxImage.Error);
} else {
MessageBox.Show("Erreur lors de l'import des données.", "Importer", MessageBoxButton.OK, MessageBoxImage.Error);
}
} finally {
Mouse.OverrideCursor = previousCursor;
if(reader != null) {
reader.Close();
}
dbContext.SaveChanges();
}
} else {
ImportWindow importWindow = new ImportWindow(this, ofd.FileName);
importWindow.ShowDialog();
}
}
}
private void Exporter_Click(object sender, RoutedEventArgs e) {
if(dgCitoyens.SelectedItems.Count == 0) {
MessageBox.Show("Aucun citoyen sélectionné.", "Exporter", MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Fichier CSV|*.csv";
sfd.OverwritePrompt = true;
if(sfd.ShowDialog() == true) {
StreamWriter s = null;
Cursor previousCursor = Mouse.OverrideCursor;
Mouse.OverrideCursor = Cursors.Wait;
try {
s = File.CreateText(sfd.FileName);
CitoyensSerializer serializer = new CitoyensSerializer();
s.WriteLine(serializer.GetCsvHeader());
foreach(Citoyen citoyen in dgCitoyens.SelectedItems) {
s.WriteLine(serializer.Serialize(citoyen));
}
} catch(Exception ex) {
if(ex is IOException || ex is UnauthorizedAccessException) {
MessageBox.Show("Impossible d'ouvrir ou de créer le fichier. Il est possible qu'il soit déjà utilisé par un autre programme ou que le chemin d'accès soit incorrect.", "Importer", MessageBoxButton.OK, MessageBoxImage.Error);
} else {
MessageBox.Show("Erreur lors de l'export des données.", "Exporter", MessageBoxButton.OK, MessageBoxImage.Error);
}
} finally {
Mouse.OverrideCursor = previousCursor;
if(s != null) {
s.Close();
}
}
}
}
private void DgCitoyen_DoubleClick(object sender, MouseButtonEventArgs e) {
if(dgCitoyens.SelectedItem != null) {
citoyenModal.EnableEditMode((Citoyen) dgCitoyens.SelectedItem);
citoyenModal.ShowDialog();
CitoyenWindow citoyenWindow = new CitoyenWindow(this, (Citoyen) dgCitoyens.SelectedItem);
citoyenWindow.ShowDialog();
}
}
@ -215,6 +391,14 @@ namespace Hermes {
}
protected override void OnClosed(EventArgs e) {
if(WindowState == WindowState.Maximized) {
pref.windowMaximized = true;
} else {
pref.windowMaximized = false;
}
pref.windowHeight = (int) Height;
pref.windowWidth = (int) Width;
dbContext.SaveChanges();
dbContext.Dispose();
base.OnClosed(e);
Application.Current.Shutdown();
@ -249,10 +433,12 @@ namespace Hermes {
}
}
string addrBat = citoyen.AdresseBatiment == null ? "" : citoyen.AdresseBatiment;
string addr = $"{citoyen.Adresse} {addrBat}".ToLower();
if(!String.IsNullOrEmpty(adresseFilterTextBox.Text)) {
if(!addr.Contains(adresseFilterTextBox.Text.ToLower())) {
string addrNumBat = citoyen.AdresseNumeroBatiment == null ? "" : citoyen.AdresseNumeroBatiment;
string addrBat = citoyen.AdresseBatiment == null ? "" : citoyen.AdresseBatiment;
string addr = citoyen.Adresse == null ? "" : citoyen.Adresse;
string addrFull = $"{addr} {addrNumBat} {addrBat}".ToLower();
if(!addrFull.Contains(adresseFilterTextBox.Text.ToLower())) {
e.Accepted = false;
return;
}

View File

@ -13,7 +13,7 @@ namespace Hermes.Migrations
string IMigrationMetadata.Id
{
get { return "202012051414539_V1"; }
get { return "202012281505590_V1"; }
}
string IMigrationMetadata.Source

View File

@ -25,6 +25,7 @@
Quartier = c.String(maxLength: 4000),
Adresse = c.String(maxLength: 4000),
AdresseBatiment = c.String(maxLength: 4000),
AdresseNumeroBatiment = c.String(maxLength: 4000),
AdresseExt = c.String(maxLength: 4000),
AdresseExtCP = c.String(maxLength: 4000),
AdresseExtVille = c.String(maxLength: 4000),
@ -40,7 +41,10 @@
Id = c.Int(nullable: false, identity: true),
VilleCP = c.String(maxLength: 4000),
Ville = c.String(maxLength: 4000),
SmsApiKey = c.String(maxLength: 4000),
ovhSmsServiceName = c.String(maxLength: 4000),
ovhSmsApplicationKey = c.String(maxLength: 4000),
ovhSmsApplicationSecret = c.String(maxLength: 4000),
ovhSmsConsumerKey = c.String(maxLength: 4000),
})
.PrimaryKey(t => t.Id);

View File

@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Target" xml:space="preserve">
<value>H4sIAAAAAAAEAO2a3VLrNhCA7zvTd/D4mhMHOBc9THLOQICW6eGnGLhX7E3QVJZdSWbIs/Wij9RX6Mr/lk2wg+PpdHqHV9K3q7/V7pK///xr9u01YNYLCElDPrcPJ1PbAu6FPuXruR2r1aef7G9ff/xhduEHr9ZT3u9Y98ORXM7tZ6WiE8eR3jMERE4C6olQhis18cLAIX7oHE2nX5zDQwcQYSPLsmb3MVc0gOQDPxch9yBSMWHXoQ9MZnJscROqdUMCkBHxYG7/AgL/niQdbeuUUYI2uMBWtkU4DxVRaOHJowRXiZCv3QgFhD1sIsB+K8IkZJaflN27TmJ6pCfhlANzlBdLFQY9gYfH2ao45vCd1tYuVg3X7QLXV230rJO1m9sLqsININnUdbJgQverr+wk639gpdKDYu+nky+T6WR6YC1ipmIBcw6xEoQdWHfxklHvV9g8hL8Dn/OYsapNaBW21QQouhNhBEJt7mGVWXrl25ZTH+eYA4thlTHpJK64Oj6yrRtUTpYMii2vTNhVoYCfgYMgCvw7ohQIrhmQLFpDu6FrQV8oowpyjXjO8LLY1jV5/Q58rZ7n9ufpFO/HJX0FPxdlZjxyipcLRykRw3uabsJgFCU3hEpJ8AruX9udAD7GrM5xaxvT0sIHdDvvGxmuQMrkIu7bUM2/B0nx8JWGnoUhA8JbjvF22DWhbASTYRwld6FQ+1f0W0yEoiD2r+nUF3iqRrhkmaIzot9YPsIaZgovXkfVtbgbU9sTZWyEvdM+aiEgCwNMv9XTH+iB+JzTFfV2Ac6cMozYGlygV1+B0B5Mdg4wKmP+DzIaupLTNsYBH+lYu4E8jSiu8NCqtp9RTCwUobgJ+QOpj54WgnZVjZOKWUN2WGWmqz6pFOqCqgfVKLCt0ow0HZkUEbezHVK7PA1KrbVt4sUUy6TJSbOmPLty3kivZtckinATKulWJrHcNNdafHL7pyJBynA82ZKRFNYWmvCekDUYragaLb2kQir0VWRJ9ClY+EGjW21D31jnXFVjz0w3US5+PkT/nQ5rS45MQLmAlzgn/fQm04PCkjINa4xMcl3CiGhxOouQxQF/y3FtG13mKlVGKe1OSnKRKiQR9BpficcNUKWlOzFPJaqsXNadYiQKVZjR1MeyMn+oW1fKu9OMDKEKNJq6M9NEoYpKJT2sAgOQCHqNT+N7g5EKu3PK8L0KKqXdSUV4XgUVwt6cMvpu4ZWNvblJkN2CTOS70HSU0c7TLbsQs5iiHZo19ruhZURsXtCypR+xHhab1HprkzxzDEdvPiVO4y0xgk3zder0dlWDgZ0fry2QDg/Y1tH7ecSKWLiKKIQ9OS2UPoxKHFvlVMQjH5ZGGGh2KbQX4aAR9s2yEOz90nsjJku72BYu0gs+QhiPuRupIJjoDhP3D+aCeAGxgMln/Q+DvNs14RQfQpWmcHbSVivk/3uK6o6UPutWWR89C6X6/Xg3z+xZMjCr2/yFCO+ZiJZMrST3LGYPyWwUeQeD10vVg2FbK9M+CpVRkOlmo1mpHszO1sL0kqoPFaWHsw72wqyWnAfjmhXmwcBGQXlorlk/HppfKRfvAV0Wz/YAr1XNBnUNZu23zTN8qPbbEbhT7fe/8QQatdfBtnc/h6ZRWd2R3K+Q2izPdaqUbiuTpsEkHtBliFNJzcwaZWMRPlBEbdMzRJW1GUbPnOrvXGbn+JquS4T+1QsHT9/NEpr3ueKrMN9onGXVoryL+cyCIni3ySm+NSviKWz2dGigi+xPhMXY5SJYgn/Fb2MVxeoUPVmwZLWMZeZs15+Ukus2z24j/SWHmAKaSbV7uuVnMWV+Yfdli3t6A6HPZeYK0CpXaZew3hSkm5B3BGXLdw4RcO1IHiCIGMLkLXfJC+xi26OE77Am3ibPg96GvL8R9WWfnVOyFiSQGaMcj594hv3g9es/4ocTwO4lAAA=</value>
<value>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</value>
</data>
<data name="DefaultSchema" xml:space="preserve">
<value>dbo</value>

View File

@ -0,0 +1,29 @@
// <auto-generated />
namespace Hermes.Migrations
{
using System.CodeDom.Compiler;
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
using System.Resources;
[GeneratedCode("EntityFramework.Migrations", "6.4.4")]
public sealed partial class V2 : IMigrationMetadata
{
private readonly ResourceManager Resources = new ResourceManager(typeof(V2));
string IMigrationMetadata.Id
{
get { return "202012292127194_V2"; }
}
string IMigrationMetadata.Source
{
get { return null; }
}
string IMigrationMetadata.Target
{
get { return Resources.GetString("Target"); }
}
}
}

View File

@ -0,0 +1,60 @@
namespace Hermes.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class V2 : DbMigration
{
public override void Up()
{
AddColumn("dbo.Preferences", "civiliteViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "nomViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "nomNaissanceViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "prenomViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "ageViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "professionViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "typeResidenceViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "mailViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "telViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "telPortViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "quartierViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "adresseViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "adresseBatimentViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "adresseNumeroBatimentViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "adresseExtViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "adresseExtCPViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "adresseExtVilleViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "dateCreationViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "dateModificationViewEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.Preferences", "windowHeight", c => c.Int(nullable: false));
AddColumn("dbo.Preferences", "windowWidth", c => c.Int(nullable: false));
AddColumn("dbo.Preferences", "windowMaximized", c => c.Boolean(nullable: false));
}
public override void Down()
{
DropColumn("dbo.Preferences", "windowMaximized");
DropColumn("dbo.Preferences", "windowWidth");
DropColumn("dbo.Preferences", "windowHeight");
DropColumn("dbo.Preferences", "dateModificationViewEnabled");
DropColumn("dbo.Preferences", "dateCreationViewEnabled");
DropColumn("dbo.Preferences", "adresseExtVilleViewEnabled");
DropColumn("dbo.Preferences", "adresseExtCPViewEnabled");
DropColumn("dbo.Preferences", "adresseExtViewEnabled");
DropColumn("dbo.Preferences", "adresseNumeroBatimentViewEnabled");
DropColumn("dbo.Preferences", "adresseBatimentViewEnabled");
DropColumn("dbo.Preferences", "adresseViewEnabled");
DropColumn("dbo.Preferences", "quartierViewEnabled");
DropColumn("dbo.Preferences", "telPortViewEnabled");
DropColumn("dbo.Preferences", "telViewEnabled");
DropColumn("dbo.Preferences", "mailViewEnabled");
DropColumn("dbo.Preferences", "typeResidenceViewEnabled");
DropColumn("dbo.Preferences", "professionViewEnabled");
DropColumn("dbo.Preferences", "ageViewEnabled");
DropColumn("dbo.Preferences", "prenomViewEnabled");
DropColumn("dbo.Preferences", "nomNaissanceViewEnabled");
DropColumn("dbo.Preferences", "nomViewEnabled");
DropColumn("dbo.Preferences", "civiliteViewEnabled");
}
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Target" xml:space="preserve">
<value>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</value>
</data>
<data name="DefaultSchema" xml:space="preserve">
<value>dbo</value>
</data>
</root>

View File

@ -3,7 +3,8 @@
namespace Hermes.Migrations {
internal sealed class Configuration : DbMigrationsConfiguration<Hermes.Model.ModelContext> {
public Configuration() {
AutomaticMigrationsEnabled = false;
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "Hermes";
}

View File

@ -20,6 +20,7 @@ namespace Hermes.Model {
private string _quartier;
private string _adresse;
private string _adresseBatiment;
private string _adresseNumeroBatiment;
private string _adresseExt;
private string _adresseExtCP;
private string _adresseExtVille;
@ -127,6 +128,13 @@ namespace Hermes.Model {
OnPropertyChanged();
}
}
public string AdresseNumeroBatiment {
get => _adresseNumeroBatiment;
set {
_adresseNumeroBatiment = value;
OnPropertyChanged();
}
}
public string AdresseExt {
get => TypeResidence == false ? null : _adresseExt;
set {
@ -294,6 +302,7 @@ namespace Hermes.Model {
citoyen.Quartier = Quartier;
citoyen.Adresse = Adresse;
citoyen.AdresseBatiment = AdresseBatiment;
citoyen.AdresseNumeroBatiment = AdresseNumeroBatiment;
citoyen.AdresseExt = AdresseExt;
citoyen.AdresseExtCP = AdresseExtCP;
citoyen.AdresseExtVille = AdresseExtVille;

View File

@ -11,7 +11,82 @@ namespace Hermes.Model {
public string Ville {
get; set;
}
public string SmsApiKey {
public string ovhSmsServiceName {
get; set;
}
public string ovhSmsApplicationKey {
get; set;
}
public string ovhSmsApplicationSecret {
get; set;
}
public string ovhSmsConsumerKey {
get; set;
}
public bool civiliteViewEnabled {
get; set;
}
public bool nomViewEnabled {
get; set;
}
public bool nomNaissanceViewEnabled {
get; set;
}
public bool prenomViewEnabled {
get; set;
}
public bool ageViewEnabled {
get; set;
}
public bool professionViewEnabled {
get; set;
}
public bool typeResidenceViewEnabled {
get; set;
}
public bool mailViewEnabled {
get; set;
}
public bool telViewEnabled {
get; set;
}
public bool telPortViewEnabled {
get; set;
}
public bool quartierViewEnabled {
get; set;
}
public bool adresseViewEnabled {
get; set;
}
public bool adresseBatimentViewEnabled {
get; set;
}
public bool adresseNumeroBatimentViewEnabled {
get; set;
}
public bool adresseExtViewEnabled {
get; set;
}
public bool adresseExtCPViewEnabled {
get; set;
}
public bool adresseExtVilleViewEnabled {
get; set;
}
public bool dateCreationViewEnabled {
get; set;
}
public bool dateModificationViewEnabled {
get; set;
}
public int windowHeight {
get; set;
}
public int windowWidth {
get; set;
}
public bool windowMaximized {
get; set;
}
}

19
OVHQueryBody.cs Normal file
View File

@ -0,0 +1,19 @@
namespace Hermes {
class OVHQueryBody {
public string charset {
get; set;
}
public string[] receivers {
get; set;
}
public string message {
get; set;
}
public string priority {
get; set;
}
public bool senderForResponse {
get; set;
}
}
}

16
OVHResponseBody.cs Normal file
View File

@ -0,0 +1,16 @@
namespace Hermes {
class OVHResponseBody {
public int totalCreditsRemoved {
get; set;
}
public string[] invalidReceivers {
get; set;
}
public string[] validReceivers {
get; set;
}
public int[] ids {
get; set;
}
}
}

View File

@ -1,59 +0,0 @@
using Hermes.Model;
using System;
using System.Windows;
namespace Hermes {
public partial class PreferencesModal : Window {
private ModelContext dbContext = null;
public PreferencesModal() {
dbContext = ModelContext.Getinstance();
InitializeComponent();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
e.Cancel = true;
this.Hide();
}
public void LoadPreferences() {
if(dbContext.Preferences.Local.Count > 0) {
Preferences pref = dbContext.Preferences.Local[0];
villeTextBox.Text = pref.Ville;
villeCPTextBox.Text = pref.VilleCP;
cleApiISendProTextBox.Text = pref.SmsApiKey;
}
}
public void Enregistrer_Click(object sender, RoutedEventArgs e) {
if(String.IsNullOrWhiteSpace(villeCPTextBox.Text) || String.IsNullOrWhiteSpace(villeTextBox.Text)) {
MessageBox.Show("La saisie d'information sur la commune est obligatoire.", "Saisie obligatoire", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if(dbContext.Preferences.Local.Count == 0) {
Preferences pref = new Preferences();
pref.Ville = villeTextBox.Text;
pref.VilleCP = villeCPTextBox.Text;
pref.SmsApiKey = cleApiISendProTextBox.Text;
dbContext.Preferences.Add(pref);
} else {
Preferences pref = dbContext.Preferences.Local[0];
pref.Ville = villeTextBox.Text;
pref.VilleCP = villeCPTextBox.Text;
pref.SmsApiKey = cleApiISendProTextBox.Text;
}
dbContext.SaveChanges();
Close();
}
public void Annuler_Click(object sender, RoutedEventArgs e) {
if(dbContext.Preferences.Local.Count == 0) {
MessageBox.Show("La saisie d'information sur la commune est obligatoire.", "Saisie obligatoire", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Close();
}
}
}

View File

@ -1,18 +1,18 @@
<Window x:Class="Hermes.PreferencesModal"
<Window x:Class="Hermes.PreferencesWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Hermes"
mc:Ignorable="d"
Title="Options" Height="250" Width="300"
Title="Options" Height="330" Width="300"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Closing="Window_Closing">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
<RowDefinition Height="160"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TabControl Grid.Row="0" Margin="5,5,5,0">
<TabItem Header="Général">
@ -25,8 +25,14 @@
</TabItem>
<TabItem Header="Envoi de SMS">
<StackPanel Margin="5,5,5,5" VerticalAlignment="Top">
<Label>Clé API ISendPro :</Label>
<TextBox Name="cleApiISendProTextBox" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="250"/>
<Label>OVH ServiceName :</Label>
<TextBox Name="ovhSmsServiceNameTextBox" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="250"/>
<Label>OVH ApplicationKey :</Label>
<TextBox Name="ovhSmsApplicationKeyTextBox" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="250"/>
<Label>OVH ApplicationSecret :</Label>
<TextBox Name="ovhSmsApplicationSecretTextBox" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="250"/>
<Label>OVH ConsumerKey :</Label>
<TextBox Name="ovhSmsConsumerKeyTextBox" HorizontalAlignment="Left" VerticalContentAlignment="Center" Height="23" Width="250"/>
</StackPanel>
</TabItem>
</TabControl>

56
PreferencesWindow.xaml.cs Normal file
View File

@ -0,0 +1,56 @@
using Hermes.Model;
using System;
using System.Windows;
namespace Hermes {
public partial class PreferencesWindow : Window {
private ModelContext dbContext = null;
public PreferencesWindow(Window parent) {
InitializeComponent();
Owner = parent;
dbContext = ModelContext.Getinstance();
Preferences pref = dbContext.Preferences.Local[0];
villeTextBox.Text = pref.Ville;
villeCPTextBox.Text = pref.VilleCP;
ovhSmsServiceNameTextBox.Text = pref.ovhSmsServiceName;
ovhSmsApplicationKeyTextBox.Text = pref.ovhSmsApplicationKey;
ovhSmsApplicationSecretTextBox.Text = pref.ovhSmsApplicationSecret;
ovhSmsConsumerKeyTextBox.Text = pref.ovhSmsConsumerKey;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
Preferences pref = dbContext.Preferences.Local[0];
if(string.IsNullOrWhiteSpace(pref.VilleCP) || string.IsNullOrWhiteSpace(pref.Ville)) {
MessageBox.Show("La saisie d'information sur la commune est obligatoire.", "Saisie obligatoire", MessageBoxButton.OK, MessageBoxImage.Warning);
e.Cancel = true;
return;
}
}
public void Enregistrer_Click(object sender, RoutedEventArgs e) {
if(String.IsNullOrWhiteSpace(villeCPTextBox.Text) || String.IsNullOrWhiteSpace(villeTextBox.Text)) {
MessageBox.Show("La saisie d'information sur la commune est obligatoire.", "Saisie obligatoire", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Preferences pref = dbContext.Preferences.Local[0];
pref.Ville = villeTextBox.Text;
pref.VilleCP = villeCPTextBox.Text;
pref.ovhSmsServiceName = ovhSmsServiceNameTextBox.Text;
pref.ovhSmsApplicationKey = ovhSmsApplicationKeyTextBox.Text;
pref.ovhSmsApplicationSecret = ovhSmsApplicationSecretTextBox.Text;
pref.ovhSmsConsumerKey = ovhSmsConsumerKeyTextBox.Text;
dbContext.SaveChanges();
Close();
}
public void Annuler_Click(object sender, RoutedEventArgs e) {
Close();
}
}
}

View File

@ -51,6 +51,6 @@ using System.Windows;
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
// en utilisant '*', comme indiqué ci-dessous :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.0.0")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: NeutralResourcesLanguage("fr-FR")]

View File

@ -8,7 +8,6 @@
ResizeMode="NoResize"
Title="Envoi de SMS" Height="490" Width="700"
WindowStartupLocation="CenterOwner"
Loaded="Window_Loaded"
Closing="Window_Closing">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
@ -27,7 +26,7 @@
<GridViewColumn Header="Nom" DisplayMemberBinding="{Binding Nom}" Width="120"/>
<GridViewColumn Header="Prénom" DisplayMemberBinding="{Binding Prenom}" Width="120"/>
<GridViewColumn Header="Mobile" DisplayMemberBinding="{Binding Mobile}" Width="120"/>
<GridViewColumn Header="Statut de l'envoi" DisplayMemberBinding="{Binding Status}" Width="290"/>
<GridViewColumn Header="Statut de l'envoi" DisplayMemberBinding="{Binding Status}" Width="280"/>
</GridView>
</ListView.View>
</ListView>

View File

@ -1,60 +1,75 @@
using Hermes.Model;
using IO.Swagger.Api;
using IO.Swagger.Client;
using IO.Swagger.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
namespace Hermes {
public partial class SmsWindow : Window {
private ObservableCollection<SmsSendingStatus> status = new ObservableCollection<SmsSendingStatus>();
private ModelContext dbContext = null;
private ApiClient apiClient = new ApiClient();
private SmsApi smsApi = null;
private bool sending = false;
private static Regex telFrRgx = new Regex(@"^0\d{9}");
private static Regex telFrPrefixRgx = new Regex(@"^0");
public SmsWindow() {
dbContext = ModelContext.Getinstance();
smsApi = new SmsApi(apiClient);
InitializeComponent();
public static string HashSHA1(string input) {
SHA1 sha = SHA1.Create();
byte[] bHash = sha.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for(int i = 0; i < bHash.Length; i++) {
sBuilder.Append(bHash[i].ToString("x2"));
}
return sBuilder.ToString();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
public SmsWindow(Window parent, List<Citoyen> rcps) {
InitializeComponent();
Owner = parent;
foreach(Citoyen rcp in rcps) {
SmsSendingStatus s = new SmsSendingStatus();
s.Nom = rcp.Nom;
s.Prenom = rcp.Prenom;
s.Mobile = rcp.TelPort.Replace(" ", "").Replace(".", "");
Match m = telFrRgx.Match(s.Mobile);
if(m.Success) {
// numéro FR (+33)
s.Mobile = telFrPrefixRgx.Replace(s.Mobile, "+33");
}
s.Status = "En attente";
status.Add(s);
}
lvLog.ItemsSource = status;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
e.Cancel = true;
if(sending) {
e.Cancel = true;
return;
}
messageTextBox.Document.Blocks.Clear();
status.Clear();
this.Hide();
}
public void LoadCitoyens(List<Citoyen> citoyens) {
foreach(Citoyen citoyen in citoyens) {
SmsSendingStatus s = new SmsSendingStatus();
s.Nom = citoyen.Nom;
s.Prenom = citoyen.Prenom;
s.Mobile = citoyen.TelPort.Replace(" ", "");
s.Status = "En attente";
status.Add(s);
}
}
public void Envoyer_Click(object sender, RoutedEventArgs e) {
ModelContext dbContext = ModelContext.Getinstance();
bool error = false;
string message = new TextRange(messageTextBox.Document.ContentStart, messageTextBox.Document.ContentEnd).Text;
string apiKey = dbContext.Preferences.Local[0].SmsApiKey;
Preferences pref = dbContext.Preferences.Local[0];
if(String.IsNullOrWhiteSpace(apiKey)) {
MessageBox.Show("Erreur lors de la tentative d'envoi : Clé ISendPro invalide", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Error);
if(String.IsNullOrWhiteSpace(pref.ovhSmsServiceName) || String.IsNullOrWhiteSpace(pref.ovhSmsApplicationKey)
|| String.IsNullOrWhiteSpace(pref.ovhSmsApplicationSecret) || String.IsNullOrWhiteSpace(pref.ovhSmsConsumerKey)) {
MessageBox.Show("Erreur lors de la tentative d'envoi : Clés d'accès invalides.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
@ -67,43 +82,74 @@ namespace Hermes {
annulerButton.IsEnabled = false;
messageTextBox.IsEnabled = false;
sending = true;
Cursor previousCursor = Mouse.OverrideCursor;
Mouse.OverrideCursor = Cursors.Wait;
string query = $"https://eu.api.ovh.com/1.0/sms/{pref.ovhSmsServiceName}/jobs";
foreach(SmsSendingStatus stat in status) {
if(!stat.Status.Equals("Envoyé")) {
SmsUniqueRequest req = new SmsUniqueRequest();
req.Keyid = apiKey;
req.Sms = message;
req.Smslong = "999";
req.Num = stat.Mobile;
OVHQueryBody body = new OVHQueryBody();
body.charset = "UTF-8";
body.receivers = new string[] { stat.Mobile };
body.message = message;
body.priority = "high";
body.senderForResponse = true;
string bodyStr = JsonConvert.SerializeObject(body);
string ts = ((Int32) DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString();
string signature = "$1$" + HashSHA1(pref.ovhSmsApplicationSecret + "+" + pref.ovhSmsConsumerKey + "+" + "POST" + "+" + query + "+" + bodyStr + "+" + ts);
try {
SMSReponse resp = smsApi.SendSms(req);
if(resp != null && resp.Etat != null && resp.Etat.Etat != null && resp.Etat.Etat.Count > 0) {
SMSReponseEtatEtat eta = resp.Etat.Etat[0];
if(eta.Code != null && eta.Code == 0 && eta.Tel != null) {
HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create(query);
req.Method = "POST";
req.ContentType = "application/json";
req.Headers.Add("X-Ovh-Application:" + pref.ovhSmsApplicationKey);
req.Headers.Add("X-Ovh-Consumer:" + pref.ovhSmsConsumerKey);
req.Headers.Add("X-Ovh-Signature:" + signature);
req.Headers.Add("X-Ovh-Timestamp:" + ts);
using(System.IO.Stream s = req.GetRequestStream()) {
using(System.IO.StreamWriter sw = new System.IO.StreamWriter(s)) {
sw.Write(bodyStr);
}
}
HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
using(var stream = resp.GetResponseStream()) {
var reader = new StreamReader(stream);
OVHResponseBody rb = JsonConvert.DeserializeObject<OVHResponseBody>(reader.ReadToEnd().Trim());
if(rb.validReceivers.Length > 0 && rb.validReceivers[0] != null && rb.validReceivers[0].Equals(stat.Mobile)) {
stat.Status = "Envoyé";
} else {
error = true;
stat.Status = eta.Message;
stat.Status = "Numéro de mobile invalide";
}
} else {
error = true;
stat.Status = "Erreur technique";
}
} catch(ApiException ex) {
resp.Close();
} catch(WebException ex) {
error = true;
SMSReponse resp = JsonConvert.DeserializeObject<SMSReponse>((String) ex.ErrorContent);
if(resp != null && resp.Etat != null && resp.Etat.Etat != null && resp.Etat.Etat.Count > 0) {
SMSReponseEtatEtat eta = resp.Etat.Etat[0];
if(eta.Code != null && eta.Code == 0 && eta.Tel != null) {
stat.Status = "Envoyé";
} else {
error = true;
stat.Status = eta.Message;
}
} else {
error = true;
stat.Status = "Erreur technique";
WebResponse resp = ex.Response;
if(resp == null) {
string errorMsg = ex.Message == null ? "" : ex.Message;
stat.Status = $"Erreur de transmission : {errorMsg}";
continue;
}
try {
using(var stream = resp.GetResponseStream()) {
StreamReader reader = new StreamReader(stream);
String result = reader.ReadToEnd().Trim();
stat.Status = result;
}
} catch(Exception) {
stat.Status = $"Erreur de transmission";
}
} catch(Exception ex) {
error = true;
string errorMsg = ex.Message == null ? "" : ex.Message;
stat.Status = $"Erreur de transmission : {errorMsg}";
}
}
}
@ -112,9 +158,10 @@ namespace Hermes {
annulerButton.IsEnabled = true;
messageTextBox.IsEnabled = true;
sending = false;
Mouse.OverrideCursor = previousCursor;
if(error) {
MessageBox.Show("Plusieurs envois se sont mal déroulés. Vérifiez la validité des numéros de téléphone.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show("Plusieurs envois se sont mal déroulés. Certains numéros de téléphone ne sont peut-être pas valides.", "Envoi de SMS", MessageBoxButton.OK, MessageBoxImage.Error);
}
}

BIN
doc/img/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
doc/img/first_launch_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
doc/img/first_launch_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
doc/img/list_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
doc/img/list_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
doc/img/main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
doc/img/menu_display.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
doc/img/menu_edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
doc/img/menu_file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
doc/img/menu_tools.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
doc/img/ovh_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
doc/img/ovh_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
doc/img/ovh_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
doc/img/ovh_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
doc/img/ovh_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
doc/img/ovh_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
doc/img/ovh_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
doc/img/publi_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
doc/img/publi_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
doc/img/publi_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
doc/img/smartscreen_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
doc/img/smartscreen_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
doc/img/sms_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
doc/img/sms_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
hermes_splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -2,10 +2,9 @@
<packages>
<package id="EntityFramework" version="6.4.4" targetFramework="net48" />
<package id="EntityFramework.SqlServerCompact" version="6.4.4" targetFramework="net48" />
<package id="iSendProSMS" version="1.1.3" targetFramework="net48" />
<package id="Microsoft.Office.Interop.Excel" version="15.0.4795.1000" targetFramework="net48" />
<package id="Microsoft.Office.Interop.Outlook" version="15.0.4797.1003" targetFramework="net48" />
<package id="Microsoft.Office.Interop.Word" version="15.0.4797.1003" targetFramework="net48" />
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net48" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net48" />
<package id="RestSharp.Net2" version="1.1.11" targetFramework="net48" />
</packages>