Compare commits
No commits in common. "master" and "feature/Victor" have entirely different histories.
master
...
feature/Vi
@ -66,4 +66,8 @@
|
||||
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Services\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -17,7 +17,4 @@ public class Chambre
|
||||
public int NbPersonne { get; set; }
|
||||
|
||||
public int StatusId { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public Status Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class Reservation
|
||||
|
||||
public string? DemandeSpecifique { get; set; }
|
||||
|
||||
public int NbInvite { get; set; }
|
||||
public int NbPersonnes { get; set; }
|
||||
|
||||
public int ClientId { get; set; }
|
||||
public int ChambreId { get; set; }
|
||||
|
46
Readme.md
46
Readme.md
@ -1,46 +0,0 @@
|
||||
# HegreHotel
|
||||
|
||||
**Projet de gestion hôtelière développé avec MAUI pour les réceptionnistes.**
|
||||
Permet la gestion des clients, des chambres, des réservations, et des réceptionnistes via une application mobile Android.
|
||||
|
||||
## 🔧 Installation
|
||||
|
||||
Cloner le projet :
|
||||
```bash
|
||||
git clone https://gitea.btssio-poitiers.fr/allavenavr/HegreHotel.git
|
||||
cd HegreHotel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 Fonctionnalités principales
|
||||
|
||||
| Fonction | Description |
|
||||
|------------------------|-----------------------------------------------------------------------------|
|
||||
| Gestion des utilisateurs | Ajout, modification et suppression des clients et réceptionnistes |
|
||||
| Gestion des chambres | Création, modification, suppression, visualisation, blocage/déblocage |
|
||||
| Réservations | Création/modification avec dates, nombre d'invités, demandes spécifiques |
|
||||
| Historique client | Accès à l'historique complet des séjours, y compris les réservations annulées |
|
||||
| Affichage | Vue d’ensemble des chambres disponibles/occupées, filtrage par période |
|
||||
|
||||
---
|
||||
|
||||
## ▶️ Lancement de l’application
|
||||
|
||||
1. Sélectionner la plateforme cible : **Android**.
|
||||
2. Brancher un appareil ou utiliser un émulateur.
|
||||
3. Cliquer sur **Run** (ou `F5`) dans Visual Studio.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Contraintes techniques
|
||||
|
||||
- Application mobile sous Android
|
||||
- Développée avec .NET MAUI
|
||||
- Utilisation d'une base de données SQLite
|
||||
|
||||
---
|
||||
|
||||
## 🕓 Deadline
|
||||
|
||||
- Livraison finale prévue : **9 mai 2025**
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB |
@ -6,7 +6,7 @@ namespace HegreHotel
|
||||
{
|
||||
public class SingletonConnection : SQLiteAsyncConnection
|
||||
{
|
||||
private static SingletonConnection? _instance;
|
||||
private static SingletonConnection instance;
|
||||
|
||||
private SingletonConnection(string dbPath) : base(dbPath)
|
||||
{
|
||||
@ -14,11 +14,11 @@ namespace HegreHotel
|
||||
|
||||
public static SingletonConnection GetInstance(string dbPath)
|
||||
{
|
||||
if (_instance == null)
|
||||
if (instance == null)
|
||||
{
|
||||
_instance = new SingletonConnection(dbPath);
|
||||
instance = new SingletonConnection(dbPath);
|
||||
}
|
||||
return _instance;
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="HegreHotel.Views.Chambre.ChambresPage"
|
||||
Title="Gestion des Chambres"
|
||||
Appearing="ChambresPage_OnAppearing">
|
||||
<StackLayout Padding="10">
|
||||
|
||||
<Picker x:Name="PickerFiltreStatus" Title="Filtrer par statut" SelectedIndexChanged="OnFiltreChanged"/>
|
||||
|
||||
<Button Text="Ajouter Chambre"
|
||||
@ -16,34 +18,26 @@
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell>
|
||||
<StackLayout Orientation="Horizontal" Padding="5" Spacing="10">
|
||||
<!-- Nom de la chambre -->
|
||||
<StackLayout Orientation="Horizontal" Padding="5">
|
||||
<Label Text="{Binding Nom}"
|
||||
FontAttributes="Bold"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="120"/> <!-- Ajusté pour laisser de la place -->
|
||||
|
||||
<!-- Statut de la chambre -->
|
||||
<Label Text="{Binding Status.Libelle}"
|
||||
FontAttributes="Italic"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="100"/>
|
||||
<Label Text="{Binding Description}"
|
||||
WidthRequest="150"/>
|
||||
<Label Text="{Binding Status.Libelle}"
|
||||
TextColor="Gray"/>
|
||||
|
||||
<Button Text="Modifier"
|
||||
CommandParameter="{Binding .}"
|
||||
Clicked="OnModifierChambreClicked"
|
||||
HorizontalOptions="EndAndExpand"
|
||||
Margin="5,0"/>
|
||||
|
||||
<!-- Icônes Modifier / Supprimer -->
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="EndAndExpand" Spacing="5">
|
||||
<ImageButton Source="edit_icon.png"
|
||||
Clicked="OnModifierChambreClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HeightRequest="30"
|
||||
WidthRequest="30"
|
||||
BackgroundColor="Transparent"/>
|
||||
<ImageButton Source="delete_icon.png"
|
||||
Clicked="OnSupprimerChambreClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HeightRequest="30"
|
||||
WidthRequest="30"
|
||||
BackgroundColor="Transparent"/>
|
||||
</StackLayout>
|
||||
<Button Text="Supprimer"
|
||||
CommandParameter="{Binding .}"
|
||||
Clicked="OnSupprimerChambreClicked"
|
||||
HorizontalOptions="End"
|
||||
Margin="5,0"/>
|
||||
</StackLayout>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
|
@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Maui.Storage;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HegreHotel.Views.Chambre
|
||||
{
|
||||
@ -25,47 +24,12 @@ namespace HegreHotel.Views.Chambre
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
|
||||
_statuts = await db.Table<Status>().ToListAsync();
|
||||
|
||||
var statutsAvecTous = new List<string> { "Tous" };
|
||||
statutsAvecTous.AddRange(_statuts.Select(s => s.Libelle));
|
||||
|
||||
PickerFiltreStatus.ItemsSource = statutsAvecTous;
|
||||
|
||||
var chambresList = await db.Table<Models.Chambre>().ToListAsync();
|
||||
var reservationsList = await db.Table<Models.Reservation>().ToListAsync();
|
||||
|
||||
DateTime today = DateTime.Today;
|
||||
|
||||
foreach (var chambre in chambresList)
|
||||
{
|
||||
var chambreReservee = reservationsList
|
||||
.Where(r => r.ChambreId == chambre.Id && r.DateDebut <= today && r.DateFin >= today)
|
||||
.OrderByDescending(r => r.DateFin)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (chambreReservee != null)
|
||||
{
|
||||
chambre.StatusId = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
var chambreFinieRecemment = reservationsList
|
||||
.Where(r => r.ChambreId == chambre.Id && r.DateFin >= today.AddDays(-2) && r.DateFin < today)
|
||||
.OrderByDescending(r => r.DateFin)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (chambreFinieRecemment != null)
|
||||
{
|
||||
chambre.StatusId = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
chambre.StatusId = 1;
|
||||
}
|
||||
}
|
||||
chambre.Status = _statuts.FirstOrDefault(s => s.Id == chambre.StatusId);
|
||||
await db.UpdateAsync(chambre);
|
||||
}
|
||||
|
||||
_toutesLesChambres.Clear();
|
||||
foreach (var chambre in chambresList)
|
||||
{
|
||||
@ -74,7 +38,7 @@ namespace HegreHotel.Views.Chambre
|
||||
|
||||
FiltrerChambres();
|
||||
}
|
||||
|
||||
|
||||
private void OnFiltreChanged(object sender, EventArgs e)
|
||||
{
|
||||
FiltrerChambres();
|
||||
@ -88,17 +52,8 @@ namespace HegreHotel.Views.Chambre
|
||||
}
|
||||
else
|
||||
{
|
||||
string statutSelectionne = PickerFiltreStatus.SelectedItem.ToString();
|
||||
var statut = _statuts.FirstOrDefault(s => s.Libelle == statutSelectionne);
|
||||
|
||||
if (statut != null)
|
||||
{
|
||||
ChambresListView.ItemsSource = _toutesLesChambres.Where(c => c.StatusId == statut.Id).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"⚠ Filtrage impossible : statut '{statutSelectionne}' introuvable.");
|
||||
}
|
||||
var statutSelectionne = _statuts[PickerFiltreStatus.SelectedIndex - 1].Id;
|
||||
ChambresListView.ItemsSource = _toutesLesChambres.Where(c => c.StatusId == statutSelectionne).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +64,8 @@ namespace HegreHotel.Views.Chambre
|
||||
|
||||
private async void OnModifierChambreClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ImageButton imageButton && imageButton.CommandParameter is Models.Chambre chambre)
|
||||
var chambre = ((Button)sender).CommandParameter as Models.Chambre;
|
||||
if (chambre != null)
|
||||
{
|
||||
await Navigation.PushAsync(new ModifierChambrePage(chambre));
|
||||
}
|
||||
@ -117,7 +73,8 @@ namespace HegreHotel.Views.Chambre
|
||||
|
||||
private async void OnSupprimerChambreClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ImageButton imageButton && imageButton.CommandParameter is Models.Chambre chambre)
|
||||
var chambre = ((Button)sender).CommandParameter as Models.Chambre;
|
||||
if (chambre != null)
|
||||
{
|
||||
bool confirmation = await DisplayAlert("Suppression", "Voulez-vous vraiment supprimer cette chambre ?", "Oui", "Non");
|
||||
if (confirmation)
|
||||
|
@ -4,44 +4,11 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="HegreHotel.Views.Chambre.ModifierChambrePage"
|
||||
Title="Modifier la Chambre">
|
||||
|
||||
<ScrollView>
|
||||
<VerticalStackLayout Padding="20" Spacing="15">
|
||||
|
||||
<!-- Champ Nom -->
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryNom" Placeholder="Nom de la chambre"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Champ Description -->
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Editor x:Name="EntryDescription" Placeholder="Description" AutoSize="TextChanges"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Champ Tarif -->
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryTarif" Placeholder="Tarif (€)" Keyboard="Numeric"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Champ Nombre de personnes -->
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryNbPersonne" Placeholder="Nombre de personnes" Keyboard="Numeric"/>
|
||||
</Frame>
|
||||
|
||||
<Label Text="Modifier le Statut" Margin="10,0,0,0"/>
|
||||
<Picker x:Name="PickerStatut" Title=""/>
|
||||
|
||||
<!-- Bouton Enregistrer -->
|
||||
<Button Text="Enregistrer les modifications"
|
||||
Clicked="OnEnregistrerClicked"
|
||||
BackgroundColor="#007AFF"
|
||||
TextColor="White"
|
||||
CornerRadius="10"
|
||||
Padding="12"
|
||||
FontAttributes="Bold"
|
||||
HorizontalOptions="Center"/>
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
|
||||
<StackLayout Padding="10">
|
||||
<Entry x:Name="EntryNom" Placeholder="Nom de la chambre"/>
|
||||
<Entry x:Name="EntryDescription" Placeholder="Description"/>
|
||||
<Entry x:Name="EntryTarif" Placeholder="Tarif" Keyboard="Numeric"/>
|
||||
<Entry x:Name="EntryNbPersonne" Placeholder="Nombre de personnes" Keyboard="Numeric"/>
|
||||
<Button Text="Enregistrer les modifications" Clicked="OnEnregistrerClicked" Margin="0,20"/>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
||||
|
@ -8,8 +8,6 @@ namespace HegreHotel.Views.Chambre
|
||||
public partial class ModifierChambrePage : ContentPage
|
||||
{
|
||||
Models.Chambre _chambre;
|
||||
private List<Status> _statuts;
|
||||
|
||||
public ModifierChambrePage(Models.Chambre chambre)
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -19,40 +17,17 @@ namespace HegreHotel.Views.Chambre
|
||||
EntryDescription.Text = _chambre.Description;
|
||||
EntryTarif.Text = _chambre.Tarif.ToString();
|
||||
EntryNbPersonne.Text = _chambre.NbPersonne.ToString();
|
||||
|
||||
LoadStatuts();
|
||||
}
|
||||
|
||||
private async void LoadStatuts()
|
||||
{
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
|
||||
_statuts = await db.Table<Status>().ToListAsync();
|
||||
|
||||
PickerStatut.ItemsSource = _statuts.Select(s => s.Libelle).ToList();
|
||||
PickerStatut.SelectedIndex = _statuts.FindIndex(s => s.Id == _chambre.StatusId);
|
||||
}
|
||||
|
||||
private async void OnEnregistrerClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (PickerStatut.SelectedIndex == -1)
|
||||
{
|
||||
await DisplayAlert("Erreur", "Veuillez sélectionner un statut", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
_chambre.Nom = EntryNom.Text;
|
||||
_chambre.Description = EntryDescription.Text;
|
||||
_chambre.Tarif = decimal.TryParse(EntryTarif.Text, out decimal tarif) ? tarif : _chambre.Tarif;
|
||||
_chambre.NbPersonne = int.TryParse(EntryNbPersonne.Text, out int nb) ? nb : _chambre.NbPersonne;
|
||||
|
||||
_chambre.StatusId = _statuts[PickerStatut.SelectedIndex].Id;
|
||||
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
|
||||
Console.WriteLine(_chambre.StatusId);
|
||||
await db.UpdateAsync(_chambre);
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
|
@ -1,69 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="HegreHotel.Views.Client.ClientsPage"
|
||||
Title="Gestion des Clients"
|
||||
Appearing="ClientsPage_OnAppearing">
|
||||
|
||||
<StackLayout Padding="15" Spacing="10">
|
||||
<Button Text="Ajouter Client"
|
||||
Clicked="OnAjouterClientClicked"
|
||||
HorizontalOptions="Center"
|
||||
BackgroundColor="#007AFF"
|
||||
TextColor="White"
|
||||
CornerRadius="10"
|
||||
Padding="10"
|
||||
FontAttributes="Bold"
|
||||
WidthRequest="200" />
|
||||
|
||||
<CollectionView x:Name="ClientsCollectionView"
|
||||
SelectionMode="None">
|
||||
<CollectionView.ItemTemplate>
|
||||
<StackLayout Padding="10">
|
||||
<Button Text="Ajouter Client"
|
||||
Clicked="OnAjouterClientClicked"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0,10"/>
|
||||
|
||||
<ListView x:Name="ClientsListView" HasUnevenRows="True">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Frame Padding="10"
|
||||
CornerRadius="10"
|
||||
BackgroundColor="White"
|
||||
BorderColor="#E5E7EB"
|
||||
Margin="0,5"
|
||||
BindingContext="{Binding .}">
|
||||
<Frame.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="OnClientTapped" />
|
||||
</Frame.GestureRecognizers>
|
||||
|
||||
<StackLayout Orientation="Horizontal" Spacing="15">
|
||||
<Image Source="user_icon.png"
|
||||
WidthRequest="40"
|
||||
HeightRequest="40" />
|
||||
|
||||
<VerticalStackLayout>
|
||||
<Label Text="{Binding Nom}"
|
||||
FontAttributes="Bold"
|
||||
FontSize="16" />
|
||||
<Label Text="{Binding Prenom}"
|
||||
FontSize="14"
|
||||
TextColor="Gray" />
|
||||
</VerticalStackLayout>
|
||||
|
||||
<StackLayout Orientation="Horizontal"
|
||||
HorizontalOptions="EndAndExpand"
|
||||
Spacing="5">
|
||||
<ImageButton Source="edit_icon.png"
|
||||
Clicked="OnModifierClientClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HeightRequest="30"
|
||||
WidthRequest="30"
|
||||
BackgroundColor="Transparent" />
|
||||
<ImageButton Source="delete_icon.png"
|
||||
Clicked="OnSupprimerClientClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HeightRequest="30"
|
||||
WidthRequest="30"
|
||||
BackgroundColor="Transparent" />
|
||||
</StackLayout>
|
||||
<ViewCell>
|
||||
<StackLayout Orientation="Horizontal" Padding="5">
|
||||
<Label Text="{Binding Nom}"
|
||||
VerticalOptions="Center"
|
||||
FontAttributes="Bold"
|
||||
WidthRequest="100"/>
|
||||
<Label Text="{Binding Prenom}"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="100"/>
|
||||
|
||||
<Button Text="Modifier"
|
||||
Clicked="OnModifierClientClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HorizontalOptions="EndAndExpand"
|
||||
Margin="5,0"/>
|
||||
|
||||
<Button Text="Supprimer"
|
||||
Clicked="OnSupprimerClientClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HorizontalOptions="End"
|
||||
Margin="5,0"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
||||
</ContentPage>
|
||||
|
@ -18,25 +18,15 @@ namespace HegreHotel.Views.Client
|
||||
|
||||
private async void LoadClients()
|
||||
{
|
||||
try
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
var clientsList = await db.Table<Models.Client>().ToListAsync();
|
||||
Clients.Clear();
|
||||
foreach (var client in clientsList)
|
||||
{
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
var clientsList = await db.Table<Models.Client>().ToListAsync();
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
Clients.Clear();
|
||||
foreach (var client in clientsList)
|
||||
Clients.Add(client);
|
||||
|
||||
ClientsCollectionView.ItemsSource = Clients;
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erreur lors du chargement des clients : {ex.Message}");
|
||||
Clients.Add(client);
|
||||
}
|
||||
ClientsListView.ItemsSource = Clients;
|
||||
}
|
||||
|
||||
private async void OnAjouterClientClicked(object sender, EventArgs e)
|
||||
@ -46,7 +36,8 @@ namespace HegreHotel.Views.Client
|
||||
|
||||
private async void OnModifierClientClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ImageButton imageButton && imageButton.CommandParameter is Models.Client client)
|
||||
var client = ((Button)sender).CommandParameter as Models.Client;
|
||||
if (client != null)
|
||||
{
|
||||
await Navigation.PushAsync(new ModifierClientPage(client));
|
||||
}
|
||||
@ -54,7 +45,8 @@ namespace HegreHotel.Views.Client
|
||||
|
||||
private async void OnSupprimerClientClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ImageButton imageButton && imageButton.CommandParameter is Models.Client client)
|
||||
var client = ((Button)sender).CommandParameter as Models.Client;
|
||||
if (client != null)
|
||||
{
|
||||
bool confirmation = await DisplayAlert("Suppression", "Voulez-vous vraiment supprimer ce client ?", "Oui", "Non");
|
||||
if (confirmation)
|
||||
@ -62,26 +54,14 @@ namespace HegreHotel.Views.Client
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
await db.DeleteAsync(client);
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
Clients.Remove(client);
|
||||
});
|
||||
LoadClients();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientsPage_OnAppearing(object sender, EventArgs e)
|
||||
private void ClientsPage_OnAppearing(object? sender, EventArgs e)
|
||||
{
|
||||
LoadClients();
|
||||
}
|
||||
|
||||
private async void OnClientTapped(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is Frame frame && frame.BindingContext is Models.Client client)
|
||||
{
|
||||
await Navigation.PushAsync(new DetailsClientPage(client));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="HegreHotel.Views.Client.DetailsClientPage"
|
||||
Title="Détails du Client">
|
||||
<ScrollView>
|
||||
<VerticalStackLayout Padding="20" Spacing="15">
|
||||
|
||||
<!-- Nom et prénom -->
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="#F3F4F6">
|
||||
<HorizontalStackLayout Spacing="10">
|
||||
<Label Text="{Binding Nom}" FontAttributes="Bold" FontSize="22"/>
|
||||
<Label Text="{Binding Prenom}" FontSize="22"/>
|
||||
</HorizontalStackLayout>
|
||||
</Frame>
|
||||
|
||||
<!-- Coordonnées -->
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="#F9FAFB">
|
||||
<VerticalStackLayout Spacing="5">
|
||||
<HorizontalStackLayout Spacing="10">
|
||||
<Image Source="email_icon.png" WidthRequest="20" HeightRequest="20"/>
|
||||
<Label Text="{Binding Email}" FontSize="16"/>
|
||||
</HorizontalStackLayout>
|
||||
<HorizontalStackLayout Spacing="10">
|
||||
<Image Source="phone_icon.png" WidthRequest="20" HeightRequest="20"/>
|
||||
<Label Text="{Binding Telephone}" FontSize="16"/>
|
||||
</HorizontalStackLayout>
|
||||
</VerticalStackLayout>
|
||||
</Frame>
|
||||
|
||||
<!-- Historique des réservations -->
|
||||
<Label Text="Historique des réservations :" FontAttributes="Bold" FontSize="18" Margin="0,10,0,5"/>
|
||||
<CollectionView x:Name="ListeReservations">
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB" Margin="0,5">
|
||||
<VerticalStackLayout Spacing="5">
|
||||
<Label Text="{Binding ChambreNom}" FontAttributes="Bold" FontSize="16"/>
|
||||
<HorizontalStackLayout Spacing="10">
|
||||
<Label Text="Début :" FontAttributes="Bold"/>
|
||||
<Label Text="{Binding DateDebut, StringFormat='{0:dd/MM/yyyy}'}"/>
|
||||
</HorizontalStackLayout>
|
||||
<HorizontalStackLayout Spacing="10">
|
||||
<Label Text="Fin :" FontAttributes="Bold"/>
|
||||
<Label Text="{Binding DateFin, StringFormat='{0:dd/MM/yyyy}'}"/>
|
||||
</HorizontalStackLayout>
|
||||
<HorizontalStackLayout Spacing="10">
|
||||
<Label Text="Invités :" FontAttributes="Bold"/>
|
||||
<Label Text="{Binding NbInvite}"/>
|
||||
</HorizontalStackLayout>
|
||||
</VerticalStackLayout>
|
||||
</Frame>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</ContentPage>
|
@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HegreHotel.Views.Client;
|
||||
|
||||
public partial class DetailsClientPage : ContentPage
|
||||
{
|
||||
public Models.Client Client { get; set; }
|
||||
|
||||
public DetailsClientPage(Models.Client client)
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = client;
|
||||
Client = client;
|
||||
LoadReservations();
|
||||
}
|
||||
|
||||
private async void LoadReservations()
|
||||
{
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
List<Models.Reservation> reservationsList = await db.Table<Models.Reservation>().Where(x => x.ClientId == Client.Id).ToListAsync();
|
||||
List<Models.Chambre> cahmbresList = await db.Table<Models.Chambre>().ToListAsync();
|
||||
List<ReservationInfo> reservationInfoList = new List<ReservationInfo>();
|
||||
|
||||
if (reservationsList is null)
|
||||
{
|
||||
await DisplayAlert("Aucune réservation", "Le client n'a pas de réservations", "OK");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Models.Reservation reservation in reservationsList)
|
||||
{
|
||||
ReservationInfo reservationInfo = new ReservationInfo()
|
||||
{
|
||||
DateDebut = reservation.DateDebut,
|
||||
DateFin = reservation.DateFin,
|
||||
DemandeSpecifique = reservation.DemandeSpecifique,
|
||||
NbInvite = reservation.NbInvite
|
||||
};
|
||||
foreach (Models.Chambre chambre in cahmbresList)
|
||||
{
|
||||
if (reservation.ChambreId == chambre.Id)
|
||||
{
|
||||
reservationInfo.ChambreNom = chambre.Nom;
|
||||
}
|
||||
}
|
||||
reservationInfoList.Add(reservationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
ListeReservations.ItemsSource = reservationInfoList;
|
||||
}
|
||||
|
||||
public class ReservationInfo
|
||||
{
|
||||
public DateTime DateDebut { get; set; }
|
||||
|
||||
public DateTime DateFin { get; set; }
|
||||
|
||||
public string? DemandeSpecifique { get; set; }
|
||||
|
||||
public int NbInvite { get; set; }
|
||||
|
||||
public string? ChambreNom { get; set; }
|
||||
}
|
||||
}
|
@ -1,47 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="HegreHotel.Views.Client.ModifierClientPage"
|
||||
Title="Modifier le Client">
|
||||
|
||||
<ScrollView>
|
||||
<VerticalStackLayout Padding="20" Spacing="15">
|
||||
|
||||
<!-- Champ Nom -->
|
||||
<Label Text="Nom du client" FontAttributes="Bold" FontSize="16"/>
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryNom" Placeholder="Entrez le nom du client"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Champ Prénom -->
|
||||
<Label Text="Prénom" FontAttributes="Bold" FontSize="16"/>
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryPrenom" Placeholder="Entrez le prénom"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Champ Email -->
|
||||
<Label Text="Email" FontAttributes="Bold" FontSize="16"/>
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryEmail" Placeholder="Entrez l'email" Keyboard="Email"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Champ Téléphone -->
|
||||
<Label Text="Téléphone" FontAttributes="Bold" FontSize="16"/>
|
||||
<Frame Padding="10" CornerRadius="10" BackgroundColor="White" BorderColor="#E5E7EB">
|
||||
<Entry x:Name="EntryTelephone" Placeholder="Entrez le téléphone" Keyboard="Telephone"/>
|
||||
</Frame>
|
||||
|
||||
<!-- Bouton Enregistrer -->
|
||||
<Button Text="Enregistrer les modifications"
|
||||
Clicked="OnEnregistrerClicked"
|
||||
BackgroundColor="#007AFF"
|
||||
TextColor="White"
|
||||
CornerRadius="10"
|
||||
Padding="12"
|
||||
FontAttributes="Bold"
|
||||
HorizontalOptions="Center"/>
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
|
||||
</ContentPage>
|
||||
<StackLayout Padding="10">
|
||||
<Entry x:Name="EntryNom" Placeholder="Nom du client"/>
|
||||
<Entry x:Name="EntryPrenom" Placeholder="Prenom"/>
|
||||
<Entry x:Name="EntryEmail" Placeholder="Email" />
|
||||
<Entry x:Name="EntryTelephone" Placeholder="Téléphone" Keyboard="Numeric"/>
|
||||
<Button Text="Enregistrer" Clicked="OnEnregistrerClicked" Margin="0,20"/>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
@ -5,28 +5,13 @@
|
||||
x:Class="HegreHotel.Views.Reservation.AjouterReservationPage"
|
||||
Title="Ajouter une Réservation">
|
||||
<StackLayout Padding="10">
|
||||
<Label Text="Sélectionnez la période" FontAttributes="Bold"/>
|
||||
<Picker x:Name="PickerClient" Title="Sélectionner un client"/>
|
||||
<Picker x:Name="PickerChambre" Title="Sélectionner une chambre"/>
|
||||
|
||||
<Entry x:Name="EntryNbPersonne" Placeholder="Nombre d'invités" Keyboard="Numeric"/>
|
||||
<DatePicker x:Name="DatePickerDebut" />
|
||||
<DatePicker x:Name="DatePickerFin" />
|
||||
|
||||
<Button Text="Vérifier Disponibilité"
|
||||
Clicked="OnVerifierDisponibiliteClicked"
|
||||
Margin="10,0"/>
|
||||
|
||||
<StackLayout x:Name="SelectionSection" IsVisible="False">
|
||||
|
||||
<Label Text="Sélectionnez un client" FontAttributes="Bold"/>
|
||||
<Picker x:Name="PickerClient" Title="Sélectionner un client"/>
|
||||
|
||||
<Label Text="Sélectionnez une chambre disponible" FontAttributes="Bold"/>
|
||||
<Picker x:Name="PickerChambre" Title="Sélectionner une chambre"/>
|
||||
|
||||
<Entry x:Name="EntryNbInvite" Placeholder="Nombre de personnes" Keyboard="Numeric"/>
|
||||
<Entry x:Name="EntryDemandeSpecifique" Placeholder="Demandes spécifiques"/>
|
||||
|
||||
<Button Text="Enregistrer" Clicked="OnEnregistrerClicked" Margin="0,20"/>
|
||||
</StackLayout>
|
||||
|
||||
<Entry x:Name="EntryDemandeSpecifique" Placeholder="Demandes spécifiques"/>
|
||||
<Button Text="Enregistrer" Clicked="OnEnregistrerClicked" Margin="0,20"/>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
||||
|
||||
|
@ -10,55 +10,28 @@ namespace HegreHotel.Views.Reservation
|
||||
public partial class AjouterReservationPage : ContentPage
|
||||
{
|
||||
private List<Models.Client> _clients;
|
||||
private List<Models.Chambre> _chambresDispo;
|
||||
private bool _datesValidees = false;
|
||||
private List<Models.Chambre> _chambres;
|
||||
|
||||
public AjouterReservationPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
LoadClientsAndChambres();
|
||||
}
|
||||
|
||||
private async void OnVerifierDisponibiliteClicked(object sender, EventArgs e)
|
||||
private async void LoadClientsAndChambres()
|
||||
{
|
||||
if (DatePickerDebut.Date > DatePickerFin.Date)
|
||||
{
|
||||
await DisplayAlert("Erreur", "La date de début doit être avant la date de fin.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
|
||||
var reservations = await db.Table<Models.Reservation>().ToListAsync();
|
||||
var chambresReservees = reservations
|
||||
.Where(r => !(DatePickerFin.Date <= r.DateDebut || DatePickerDebut.Date >= r.DateFin))
|
||||
.Select(r => r.ChambreId)
|
||||
.ToList();
|
||||
|
||||
_chambresDispo = await db.Table<Models.Chambre>().Where(c => !chambresReservees.Contains(c.Id)).ToListAsync();
|
||||
|
||||
if (_chambresDispo.Count == 0)
|
||||
{
|
||||
await DisplayAlert("Aucune chambre disponible", "Aucune chambre n'est disponible pour cette période.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
_clients = await db.Table<Models.Client>().ToListAsync();
|
||||
PickerClient.ItemsSource = _clients.Select(c => $"{c.Nom} {c.Prenom}").ToList();
|
||||
PickerChambre.ItemsSource = _chambresDispo.Select(ch => ch.Nom).ToList();
|
||||
_chambres = await db.Table<Models.Chambre>().ToListAsync();
|
||||
|
||||
SelectionSection.IsVisible = true;
|
||||
_datesValidees = true;
|
||||
PickerClient.ItemsSource = _clients.Select(c => $"{c.Nom} {c.Prenom}").ToList();
|
||||
PickerChambre.ItemsSource = _chambres.Select(ch => ch.Nom).ToList();
|
||||
}
|
||||
|
||||
private async void OnEnregistrerClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (!_datesValidees)
|
||||
{
|
||||
await DisplayAlert("Erreur", "Veuillez d'abord vérifier la disponibilité des chambres.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
if (PickerClient.SelectedIndex == -1 || PickerChambre.SelectedIndex == -1)
|
||||
{
|
||||
await DisplayAlert("Erreur", "Veuillez sélectionner un client et une chambre", "OK");
|
||||
@ -68,8 +41,8 @@ namespace HegreHotel.Views.Reservation
|
||||
var reservation = new Models.Reservation
|
||||
{
|
||||
ClientId = _clients[PickerClient.SelectedIndex].Id,
|
||||
ChambreId = _chambresDispo[PickerChambre.SelectedIndex].Id,
|
||||
NbInvite = int.TryParse(EntryNbInvite.Text, out int nb) ? nb : 0,
|
||||
ChambreId = _chambres[PickerChambre.SelectedIndex].Id,
|
||||
NbPersonnes = int.TryParse(EntryNbPersonne.Text, out int nb) ? nb : 0,
|
||||
DateDebut = DatePickerDebut.Date,
|
||||
DateFin = DatePickerFin.Date,
|
||||
DemandeSpecifique = EntryDemandeSpecifique.Text
|
||||
@ -78,8 +51,6 @@ namespace HegreHotel.Views.Reservation
|
||||
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "HegreHotel.db3");
|
||||
var db = SingletonConnection.GetInstance(dbPath);
|
||||
await db.InsertAsync(reservation);
|
||||
|
||||
await DisplayAlert("Succès", "Réservation ajoutée avec succès.", "OK");
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<Picker x:Name="PickerClient" Title="Sélectionner un client"/>
|
||||
<Picker x:Name="PickerChambre" Title="Sélectionner une chambre"/>
|
||||
|
||||
<Entry x:Name="EntryNbInvite" Placeholder="Nombre d'invités" Keyboard="Numeric"/>
|
||||
<Entry x:Name="EntryNbPersonne" Placeholder="Nombre d'invités" Keyboard="Numeric"/>
|
||||
<DatePicker x:Name="DatePickerDebut" />
|
||||
<DatePicker x:Name="DatePickerFin" />
|
||||
<Entry x:Name="EntryDemandeSpecifique" Placeholder="Demandes spécifiques"/>
|
||||
|
@ -34,7 +34,7 @@ namespace HegreHotel.Views.Reservation
|
||||
PickerClient.SelectedIndex = _clients.FindIndex(c => c.Id == _reservation.ClientId);
|
||||
PickerChambre.SelectedIndex = _chambres.FindIndex(ch => ch.Id == _reservation.ChambreId);
|
||||
|
||||
EntryNbInvite.Text = _reservation.NbInvite.ToString();
|
||||
EntryNbPersonne.Text = _reservation.NbPersonnes.ToString();
|
||||
DatePickerDebut.Date = _reservation.DateDebut;
|
||||
DatePickerFin.Date = _reservation.DateFin;
|
||||
EntryDemandeSpecifique.Text = _reservation.DemandeSpecifique;
|
||||
@ -50,7 +50,7 @@ namespace HegreHotel.Views.Reservation
|
||||
|
||||
_reservation.ClientId = _clients[PickerClient.SelectedIndex].Id;
|
||||
_reservation.ChambreId = _chambres[PickerChambre.SelectedIndex].Id;
|
||||
_reservation.NbInvite = int.TryParse(EntryNbInvite.Text, out int nb) ? nb : _reservation.NbInvite;
|
||||
_reservation.NbPersonnes = int.TryParse(EntryNbPersonne.Text, out int nb) ? nb : _reservation.NbPersonnes;
|
||||
_reservation.DateDebut = DatePickerDebut.Date;
|
||||
_reservation.DateFin = DatePickerFin.Date;
|
||||
_reservation.DemandeSpecifique = EntryDemandeSpecifique.Text;
|
||||
|
@ -1,20 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="HegreHotel.Views.Reservation.ReservationsPage"
|
||||
Title="Gestion des Réservations"
|
||||
Appearing="ReservationsPage_OnAppearing">
|
||||
<StackLayout Padding="10">
|
||||
|
||||
<Button Text="Ajouter Réservation"
|
||||
Clicked="OnAjouterReservationClicked"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0,10"/>
|
||||
|
||||
|
||||
<ListView x:Name="ReservationsListView" HasUnevenRows="True">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell>
|
||||
<StackLayout Orientation="Horizontal" Padding="5" Spacing="10">
|
||||
<StackLayout Orientation="Horizontal" Padding="5">
|
||||
|
||||
<Label Text="{Binding NbInvite}"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="50"/>
|
||||
@ -25,20 +29,17 @@
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="100"/>
|
||||
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="EndAndExpand" Spacing="5">
|
||||
<ImageButton Source="edit_icon.png"
|
||||
Clicked="OnModifierReservationClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HeightRequest="30"
|
||||
WidthRequest="30"
|
||||
BackgroundColor="Transparent"/>
|
||||
<ImageButton Source="delete_icon.png"
|
||||
Clicked="OnSupprimerReservationClicked"
|
||||
CommandParameter="{Binding .}"
|
||||
HeightRequest="30"
|
||||
WidthRequest="30"
|
||||
BackgroundColor="Transparent"/>
|
||||
</StackLayout>
|
||||
<Button Text="Modifier"
|
||||
CommandParameter="{Binding .}"
|
||||
Clicked="OnModifierReservationClicked"
|
||||
HorizontalOptions="EndAndExpand"
|
||||
Margin="5,0"/>
|
||||
|
||||
<Button Text="Supprimer"
|
||||
CommandParameter="{Binding .}"
|
||||
Clicked="OnSupprimerReservationClicked"
|
||||
HorizontalOptions="End"
|
||||
Margin="5,0"/>
|
||||
</StackLayout>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
|
@ -36,7 +36,8 @@ namespace HegreHotel.Views.Reservation
|
||||
|
||||
private async void OnModifierReservationClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ImageButton imageButton && imageButton.CommandParameter is Models.Reservation reservation)
|
||||
var reservation = ((Button)sender).CommandParameter as Models.Reservation;
|
||||
if (reservation != null)
|
||||
{
|
||||
await Navigation.PushAsync(new ModifierReservationPage(reservation));
|
||||
}
|
||||
@ -44,7 +45,8 @@ namespace HegreHotel.Views.Reservation
|
||||
|
||||
private async void OnSupprimerReservationClicked(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ImageButton imageButton && imageButton.CommandParameter is Models.Reservation reservation)
|
||||
var reservation = ((Button)sender).CommandParameter as Models.Reservation;
|
||||
if (reservation != null)
|
||||
{
|
||||
bool confirmation = await DisplayAlert("Suppression", "Voulez-vous vraiment supprimer cette réservation ?", "Oui", "Non");
|
||||
if (confirmation)
|
||||
|
Loading…
x
Reference in New Issue
Block a user