OSS-BSS-Field-Dispatch/frappe-setup/setup_store_erpnext.py
louispaulb 4760ae5e73 Store setup: champ store_regular_price (prix barré boutique, inline-editable)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 21:55:59 -04:00

74 lines
3.2 KiB
Python

"""
Boutique matériel (/store) — configuration ERPNext, idempotent.
==============================================================
Mécanisme de curation du Webstore : un seul champ `show_in_store` sur l'Item.
- Coché = visible dans la boutique (hub: lib/store.js → GET /store/catalog).
- Rendu filtrable + visible en colonne dans la liste Item (édition en lot).
- Rapport nommé « Produits Boutique » pré-filtré pour gérer le catalogue.
Catégorie = item_group · Prix = Item Price (Standard Selling) · Stock = Bin live
· Variantes = template + Item Attribute · Bundles = Product Bundle.
Exécution :
docker cp setup_store_erpnext.py erpnext-backend-1:/tmp/
docker exec erpnext-backend-1 sh -lc \
"cd /home/frappe/frappe-bench && env/bin/python /tmp/setup_store_erpnext.py"
"""
import json as J
import frappe
frappe.init(site="erp.gigafibre.ca", sites_path="sites")
frappe.connect()
frappe.flags.ignore_permissions = True
# 1) Champ de curation + visibilité liste/filtre
CF = "Item-show_in_store"
if not frappe.db.exists("Custom Field", CF):
frappe.get_doc({
"doctype": "Custom Field", "dt": "Item", "fieldname": "show_in_store",
"label": "Afficher dans la boutique", "fieldtype": "Check",
"insert_after": "is_sales_item",
"description": "Coché = visible dans la boutique matériel (/store).",
}).insert()
print("CHAMP créé")
cf = frappe.get_doc("Custom Field", CF)
cf.in_list_view = 1 # colonne dans la liste Item
cf.in_standard_filter = 1 # filtre rapide dans la barre
cf.save()
print("CHAMP show_in_store: in_list_view + in_standard_filter OK")
# 1b) Prix barré boutique (marketing). Si > prix de vente (Item Price) → affiché barré.
CFR = "Item-store_regular_price"
if not frappe.db.exists("Custom Field", CFR):
frappe.get_doc({
"doctype": "Custom Field", "dt": "Item", "fieldname": "store_regular_price",
"label": "Prix barré (boutique)", "fieldtype": "Currency", "insert_after": "show_in_store",
"in_list_view": 1, "in_standard_filter": 1,
"description": "Prix de référence barré en boutique. Si > prix de vente (Item Price) il s'affiche barré. Vide = aucun barré.",
}).insert()
print("CHAMP store_regular_price créé")
else:
print("CHAMP store_regular_price déjà là")
# 2) Rapport nommé pré-filtré (liste gérable du catalogue)
if not frappe.db.exists("Report", "Produits Boutique"):
frappe.get_doc({
"doctype": "Report", "report_name": "Produits Boutique", "ref_doctype": "Item",
"report_type": "Report Builder", "is_standard": "No",
"json": J.dumps({
"filters": [["Item", "show_in_store", "=", 1]],
"columns": [["item_code", "Item"], ["item_name", "Item"], ["item_group", "Item"],
["standard_rate", "Item"], ["has_variants", "Item"], ["variant_of", "Item"],
["disabled", "Item"]],
"sort_by": "item_group", "sort_order": "asc", "page_length": 100,
}),
}).insert()
print("RAPPORT 'Produits Boutique' créé")
else:
print("RAPPORT 'Produits Boutique' déjà là")
frappe.db.commit()
print("show_in_store=1 :", frappe.db.count("Item", {"show_in_store": 1}))
print("DONE")