Cette page montre un exemple de customizer pour l'écran de modification d'un picking dans MercatorPenguin. Le code source est fourni dans le zip disponible ci-dessous.
Le code repris ci-dessous montre comment :
- Demander une confirmation de suppression de ligne dans le picking.
- Exécuter du code après la suppression d'une ligne.
- Permettre à l'utilisateur de confirmer une modification de ligne.
- Exécuter du code après modification d'une ligne.
- Mettre en place une extension de OutOfDocBehavior du picking de MercatorPenguin : dans le cas où la raison est "Article de remplacement", le code propose la liste des articles qui doivent encore être pickés et présents dans le document, pour que l'utilisateur indique l'article qu'il remplace. La raison est alors complétée avec le nom et l'identifiant de l'article qu'il remplace.
- Demander une confirmation avant la sauvegarde.
- Exécuter du code après sauvegarde.
using MercatorPenguin;
using MercatorPenguin.EditCustomizers;
using MercatorExtensions;
namespace TestPenguinCustomizerPicking
{
public class CustomizerPicking : BaseEditPickingCustomizer
{
public CustomizerPicking(ConstructorParams constructorParams) :
base(constructorParams)
{ }
public override async Task OnBeforeDeleteLineAsync(BeforeDeleteLineEventArgs e)
{
if (!await Dialogs.AnswerYesNo(Page, $"Voulez-vous vraiment supprimer cette ligne {e.Ligne["id_article"]} sur ce picking ?"))
{
e.CancelDeleteLine = true;
}
}
public override async void OnAfterDeleteLine(AfterDeleteLineEventArgs e)
{
await Dialogs.Stop(Page, $"La ligne a été sumprimée avec succès !");
}
public override async Task OnBeforeChangeLineAsync(BeforeChangeLineEventArgs e)
{
if (!await Dialogs.AnswerYesNo(Page, $"Voulez-vous vraiment modifier la colonne {e.ColumnToChange} de cette ligne {e.Line["id_article"]} avec cette nouvelle valeur {e.NewValue} ?"))
{
e.CancelChangeLine = true;
}
}
public override async Task OnAfterChangeLineAsync(AfterChangeLineEventArgs e)
{
await Dialogs.Stop(Page, $"Cette ligne {e.Line["id_article"]} vient de modifier cette colonne {e.ColumnToChange} depuis cette valeur {e.OldValue} vers {e.Line[e.ColumnToChange]}?");
}
public override async Task OnAfterInsertItemAsync(AfterInsertItemEventArgs e)
{
var editEntryBehavior = Controls.OfType<IEditPickingBehavior>().FirstOrDefault();
if (editEntryBehavior == null)
return;
var editEntry = Controls.OfType<IEditEntry>().FirstOrDefault(c => c.Source?.Equals(editEntryBehavior.OutOfDocReasonSource, StringComparison.InvariantCultureIgnoreCase) ?? false);
if (editEntry.Text == "Article de remplacement")
{
List<ItemString> items = new List<ItemString>();
foreach (var d in Lignes.DataTable.RowsEnumerable(r => r.Value<double>("Q_ORI").CompareTo(0, 2) != 0))
items.Add(new ItemString() { Id = d["id_article"].ToString(), Lib = d["designatio"].ToString() });
var ret = await Dialogs.AskList(Page, "Remplace quel article ?", items);
if (ret != null)
{
editEntry.Text = editEntry.Text + $" pour l'article : {ret.Lib}({ret.Id})";
}
}
}
public override async Task OnBeforeSaveAsync(BeforeSaveEventArgs e)
{
if (!await Dialogs.AnswerYesNo(Page, "Voulez-vous vraiment enregistrer les modifications sur ce picking ?"))
{
e.CancelSave = true;
}
}
public override async Task OnAfterSaveAsync(AfterSaveEventArgs e)
{
await Dialogs.Stop(Page, "Le picking a été enregistrée avec succès !");
}
}
public class ItemString
{
public string Id { get; set; }
public string Lib { get; set; }
public override string ToString()
{
return Lib;
}
}
}
A télécharger :
0000003451.zip (1 Kb - 13/05/2026)