Contourne l'UX peu intuitive d'ERPNext (prix dans doctype séparé). Variantes → bouton 'Variantes & prix'. Stocké en base (survit aux recreate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
2.6 KiB
Python
67 lines
2.6 KiB
Python
"""
|
|
Raccourci prix sur la fiche Item (Client Script) — idempotent.
|
|
==============================================================
|
|
ERPNext stocke le prix de vente dans un doctype séparé (Item Price), pas en
|
|
champ direct → peu intuitif. Ce Client Script ajoute un bouton sur la fiche Item :
|
|
|
|
• Item simple / bundle → « 💲 Prix de vente » : ouvre l'Item Price (Standard
|
|
Selling) existant, ou en crée un pré-rempli (item_code + price_list + selling).
|
|
• Item template variantes → « Variantes & prix » : liste les variantes (chacune
|
|
a son propre prix via le même bouton).
|
|
|
|
Stocké en base (doctype Client Script) → survit aux recreate de conteneur
|
|
(contrairement aux patchs de fichiers). S'applique sans rebuild ni restart ;
|
|
recharger la fiche Item (hard refresh) suffit.
|
|
|
|
Exécution :
|
|
docker cp setup_item_price_button.py erpnext-backend-1:/tmp/
|
|
docker exec erpnext-backend-1 sh -lc \
|
|
"cd /home/frappe/frappe-bench && env/bin/python /tmp/setup_item_price_button.py"
|
|
"""
|
|
import frappe
|
|
|
|
frappe.init(site="erp.gigafibre.ca", sites_path="sites")
|
|
frappe.connect()
|
|
frappe.flags.ignore_permissions = True
|
|
|
|
CS_NAME = "Item - Prix de vente (bouton)"
|
|
JS = r"""
|
|
// PRIX_VENTE_BTN — raccourci vers l'Item Price (Standard Selling) depuis la fiche Item
|
|
frappe.ui.form.on('Item', {
|
|
refresh(frm) {
|
|
if (frm.is_new()) return;
|
|
if (frm.doc.has_variants) {
|
|
frm.add_custom_button('Variantes & prix', function() {
|
|
frappe.set_route('List', 'Item', { variant_of: frm.doc.name });
|
|
});
|
|
return;
|
|
}
|
|
frm.add_custom_button('💲 Prix de vente', function() {
|
|
frappe.db.get_value('Item Price',
|
|
{ item_code: frm.doc.name, price_list: 'Standard Selling', selling: 1 }, 'name'
|
|
).then(function(r) {
|
|
var name = r.message && r.message.name;
|
|
if (name) { frappe.set_route('Form', 'Item Price', name); return; }
|
|
frappe.model.with_doctype('Item Price', function() {
|
|
var d = frappe.model.get_new_doc('Item Price');
|
|
d.item_code = frm.doc.name;
|
|
d.price_list = 'Standard Selling';
|
|
d.selling = 1;
|
|
frappe.set_route('Form', 'Item Price', d.name);
|
|
});
|
|
});
|
|
}).addClass('btn-primary');
|
|
}
|
|
});
|
|
"""
|
|
|
|
if frappe.db.exists("Client Script", CS_NAME):
|
|
frappe.db.set_value("Client Script", CS_NAME, {"script": JS, "enabled": 1})
|
|
print("MAJ:", CS_NAME)
|
|
else:
|
|
frappe.get_doc({"doctype": "Client Script", "name": CS_NAME, "dt": "Item",
|
|
"view": "Form", "enabled": 1, "script": JS}).insert()
|
|
print("CRÉÉ:", CS_NAME)
|
|
frappe.db.commit()
|
|
print("DONE")
|