Signaler les doublons à l'ajout d'un livre, sans jamais les refuser
Rien n'empêchait de rescanner un livre déjà catalogué. Plutôt qu'un index unique — qui interdirait le second exemplaire, cas parfaitement légitime — la création répond 409 avec les fiches semblables, et « confirmerDoublon » enregistre la même saisie. Deux critères, dont aucun n'est une clé : ISBN identique, ou clé d'œuvre et auteur communs. La clé d'œuvre étant un préfixe de TitreNormalise, SQL dégrossit sur la colonne indexée et l'égalité exacte se vérifie ensuite en mémoire. Vérifié en exécution : avertissement, retour au formulaire intact, et ajout confirmé créant bien un second exemplaire. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -145,17 +145,30 @@
|
||||
|
||||
@if (_etape == Etape.Formulaire)
|
||||
{
|
||||
<p class="message-discret">
|
||||
Vérifiez et complétez la fiche : tout reste modifiable.
|
||||
</p>
|
||||
@* Le doublon prend toute la place tant qu'il n'est pas tranché : la fiche revient intacte
|
||||
si l'on renonce. C'est ici que le cas se présente le plus — scanner deux fois le même
|
||||
livre est précisément ce qui crée les fiches en double. *@
|
||||
@if (_doublons is { } doublons)
|
||||
{
|
||||
<AvertissementDoublon Doublons="doublons"
|
||||
EnCours="_enregistrement"
|
||||
OnConfirmer="ConfirmerAsync"
|
||||
OnRenoncer="() => _doublons = null" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="message-discret">
|
||||
Vérifiez et complétez la fiche : tout reste modifiable.
|
||||
</p>
|
||||
|
||||
<FormulaireLivre Saisie="_saisie"
|
||||
LibelleValidation="Ajouter au catalogue"
|
||||
Erreur="@_erreurFormulaire"
|
||||
EnCours="_enregistrement"
|
||||
MessageBlocage="@MotifBlocage"
|
||||
OnValider="EnregistrerAsync"
|
||||
OnAnnuler="Recommencer" />
|
||||
<FormulaireLivre Saisie="_saisie"
|
||||
LibelleValidation="Ajouter au catalogue"
|
||||
Erreur="@_erreurFormulaire"
|
||||
EnCours="_enregistrement"
|
||||
MessageBlocage="@MotifBlocage"
|
||||
OnValider="EnregistrerAsync"
|
||||
OnAnnuler="Recommencer" />
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
@@ -177,6 +190,7 @@
|
||||
private IReadOnlyList<CandidatLivre> _candidats = [];
|
||||
private IReadOnlyList<string> _avertissements = [];
|
||||
private EnregistrementLivre _saisie = new();
|
||||
private DoublonsLivre? _doublons;
|
||||
|
||||
protected override void OnInitialized() => Reseau.Change += SurChangementReseau;
|
||||
|
||||
@@ -358,19 +372,35 @@
|
||||
_erreur = null;
|
||||
_messagePeriodique = null;
|
||||
_erreurFormulaire = null;
|
||||
_doublons = null;
|
||||
_candidats = [];
|
||||
RevenirALaSaisie();
|
||||
}
|
||||
|
||||
private async Task EnregistrerAsync()
|
||||
private Task EnregistrerAsync() => AjouterAsync(false);
|
||||
|
||||
/// <summary>Ajout maintenu après avoir vu ce que le catalogue contenait déjà.</summary>
|
||||
private Task ConfirmerAsync() => AjouterAsync(true);
|
||||
|
||||
private async Task AjouterAsync(bool confirmerDoublon)
|
||||
{
|
||||
_enregistrement = true;
|
||||
_erreurFormulaire = null;
|
||||
|
||||
var resultat = await Api.CreerAsync(_saisie);
|
||||
var resultat = await Api.CreerAsync(_saisie, confirmerDoublon);
|
||||
|
||||
_enregistrement = false;
|
||||
|
||||
// Rien n'a été écrit : le catalogue contient déjà quelque chose de semblable, et c'est
|
||||
// à l'utilisateur de dire s'il s'agit du même livre. Voir AvertissementDoublon.
|
||||
if (resultat.Doublons is { } doublons)
|
||||
{
|
||||
_doublons = doublons;
|
||||
return;
|
||||
}
|
||||
|
||||
_doublons = null;
|
||||
|
||||
if (!resultat.EstOk)
|
||||
{
|
||||
_erreurFormulaire = resultat.Erreur;
|
||||
|
||||
@@ -12,13 +12,28 @@
|
||||
Pour les livres sans ISBN, ou dont aucune notice ne convient. L'ISBN reste facultatif.
|
||||
</p>
|
||||
|
||||
<FormulaireLivre Saisie="_saisie"
|
||||
LibelleValidation="Ajouter au catalogue"
|
||||
Erreur="@_erreur"
|
||||
EnCours="_enregistrement"
|
||||
MessageBlocage="@(Reseau.EnLigne ? null : EtatReseau.MotifHorsLigne)"
|
||||
OnValider="EnregistrerAsync"
|
||||
OnAnnuler="Retour" />
|
||||
@*
|
||||
Le formulaire s'efface pendant qu'on tranche le doublon : la saisie n'est pas perdue pour
|
||||
autant, elle attend dans « _saisie » et revient telle quelle si l'on renonce. Laisser les
|
||||
deux à l'écran donnerait deux boutons d'ajout, dont un seul confirme.
|
||||
*@
|
||||
@if (_doublons is { } doublons)
|
||||
{
|
||||
<AvertissementDoublon Doublons="doublons"
|
||||
EnCours="_enregistrement"
|
||||
OnConfirmer="ConfirmerAsync"
|
||||
OnRenoncer="() => _doublons = null" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<FormulaireLivre Saisie="_saisie"
|
||||
LibelleValidation="Ajouter au catalogue"
|
||||
Erreur="@_erreur"
|
||||
EnCours="_enregistrement"
|
||||
MessageBlocage="@(Reseau.EnLigne ? null : EtatReseau.MotifHorsLigne)"
|
||||
OnValider="EnregistrerAsync"
|
||||
OnAnnuler="Retour" />
|
||||
}
|
||||
|
||||
@code {
|
||||
private readonly EnregistrementLivre _saisie = new();
|
||||
@@ -31,16 +46,32 @@
|
||||
|
||||
private bool _enregistrement;
|
||||
private string? _erreur;
|
||||
private DoublonsLivre? _doublons;
|
||||
|
||||
private async Task EnregistrerAsync()
|
||||
private Task EnregistrerAsync() => AjouterAsync(false);
|
||||
|
||||
/// <summary>Ajout maintenu après avoir vu ce que le catalogue contenait déjà.</summary>
|
||||
private Task ConfirmerAsync() => AjouterAsync(true);
|
||||
|
||||
private async Task AjouterAsync(bool confirmerDoublon)
|
||||
{
|
||||
_enregistrement = true;
|
||||
_erreur = null;
|
||||
|
||||
var resultat = await Api.CreerAsync(_saisie);
|
||||
var resultat = await Api.CreerAsync(_saisie, confirmerDoublon);
|
||||
|
||||
_enregistrement = false;
|
||||
|
||||
// Un doublon signalé n'est pas un échec : rien n'a été écrit, et la même saisie
|
||||
// confirmée s'enregistrera telle quelle.
|
||||
if (resultat.Doublons is { } doublons)
|
||||
{
|
||||
_doublons = doublons;
|
||||
return;
|
||||
}
|
||||
|
||||
_doublons = null;
|
||||
|
||||
if (!resultat.EstOk)
|
||||
{
|
||||
_erreur = resultat.Erreur;
|
||||
|
||||
Reference in New Issue
Block a user