Item: bouton raccourci '💲 Prix de vente' (Client Script) → ouvre/crée l'Item Price Standard Selling en 1 clic
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>
This commit is contained in:
parent
aad579d8bb
commit
49721eae8e
66
frappe-setup/setup_item_price_button.py
Normal file
66
frappe-setup/setup_item_price_button.py
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
"""
|
||||||
|
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")
|
||||||
Loading…
Reference in New Issue
Block a user