""" 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") # 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")