Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Composants UI

Utiliser les points d'extension client

Bloquer ou confirmer l'ouverture d'un document créé par mapping (bouton « Créer ») avec les gardes JavaScript frappe.model.add_mapped_doc_guard.

Utiliser les points d'extension client

Un document « mappé » est créé à partir d'un autre : une facture depuis une commande, un bon de livraison depuis une commande… Le desk appelle frappe.model.open_mapped_doc. Le serveur prépare le nouveau document sans l'enregistrer, puis le desk l'ouvre.

Une garde est une fonction JavaScript appelée entre ces deux étapes. Elle peut empêcher l'ouverture du nouveau document.

Fonctions

FonctionRôle
frappe.model.add_mapped_doc_guard(fn)Enregistre une garde. La même fonction n'est enregistrée qu'une fois.
frappe.model.remove_mapped_doc_guard(fn)Retire une garde.
frappe.model.should_open_mapped_doc(mapped_doc, opts)Exécute les gardes dans l'ordre. Renvoie une promesse de true si aucune ne bloque.

Une garde reçoit (mapped_doc, opts) :

  • mapped_doc : le nouveau document, pas encore enregistré. Son name est provisoire.
  • opts : les options passées à open_mapped_doc (method, frm, source_name, args…).

Elle renvoie true (ou une promesse de true) pour laisser ouvrir le document, false pour bloquer.

Déroulement

  • La première garde qui renvoie false arrête la suite. Le desk reste sur le document source.
  • Une garde qui lève une erreur est ignorée. L'erreur s'affiche dans la console. Une garde en erreur ne bloque donc jamais la création.
  • Pendant l'exécution des gardes, l'écran n'est pas gelé : une garde peut ouvrir une boîte de dialogue. Un nouveau clic sur « Créer » est ignoré jusqu'à la fin des gardes.
  • Les gardes ne concernent que open_mapped_doc. Un document créé avec Nouveau ne passe pas par elles.

Exemple : confirmer avant de créer un deuxième bon de livraison

Placez le code dans un fichier JavaScript chargé par le desk (app_include_js dans le hooks.py de votre application).

frappe.model.add_mapped_doc_guard(async (mapped_doc, opts) => {
    if (mapped_doc.doctype !== "Delivery Note" || !opts.frm) return true;

    const count = await frappe.db.count("Delivery Note", {
        filters: [
            ["Delivery Note Item", "against_sales_order", "=", opts.frm.doc.name],
            ["Delivery Note", "docstatus", "!=", 2],
        ],
    });
    if (!count) return true;

    return new Promise((resolve) => {
        frappe.confirm(
            __("Un bon de livraison existe déjà pour cette commande. Continuer ?"),
            () => resolve(true),
            () => resolve(false)
        );
    });
});

frappe.confirm ne renvoie pas de promesse. Enveloppez-la dans une promesse comme ci-dessus. La fonction de refus est appelée aussi quand l'utilisateur ferme la boîte.

Bonnes pratiques

  • Testez mapped_doc.doctype en premier : une garde s'applique à tous les mappings.
  • Une garde ne doit pas modifier mapped_doc. Pour préremplir des champs, utilisez le script client du document cible (onload, refresh) ou la méthode de mapping côté serveur.
  • Résolvez toujours la promesse. Sinon, les clics suivants sur « Créer » restent ignorés.