Jump to content

Repo comfac-webshop ExtensionPoints

From Game in the Brain Wiki
Revision as of 16:33, 9 March 2026 by Ocjustin260223 (talk | contribs) ("Repo analysis: comfac-hrms and comfac-webshop (14 pages)")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Repo:comfac-webshop/ExtensionPoints — Extension and Customization Points

The Safe Edit Zone

Frappe Override Pattern

Like comfac-hrms, webshop uses the "override instead of modify" pattern:

Location What to Put There
webshop/webshop/doctype/override_doctype/ Override ERPNext classes
webshop/webshop/crud_events/ Event handlers for sync logic
webshop/public/js/ Custom client-side JavaScript
webshop/templates/ Custom Jinja templates
webshop/www/ New web pages or route overrides
Custom Fields (via UI) Non-core fields

Files You Should NOT Edit Directly

  • ERPNext core (Item, Quotation, etc.)
  • Frappe framework
  • Third-party libraries

Hooks & Events

Current Hooks in webshop/hooks.py

Hook Type Purpose Current Usage
after_install Post-install setup Create default Webshop Settings
on_logout Cleanup Clear cart count cookie
on_session_creation Initialize Update debtors account, set cart count
update_website_context Template data Add cart info to all pages
website_generators Auto-routes Website Item, Item Group pages
override_doctype_class Class overrides Item, Item Group, Payment Request
doctype_js Client scripts Item, Homepage forms
doc_events Server events Item sync, Quotation validation
has_website_permission Access control Website Item, Item Group visibility

Document Event Hooks

DocType Event Handler Purpose
Item on_update crud_events.item.update_website_item Sync to Website Item
Item on_update crud_events.item.invalidate_item_variants_cache Clear cache
Item before_rename crud_events.item.validate_duplicate_website_item Prevent conflicts
Item after_rename crud_events.item.invalidate_item_variants_cache Clear cache
Sales Taxes Template on_update webshop_settings.validate_cart_settings Validate config
Quotation validate crud_events.quotation.validate_shopping_cart_items Cart validation
Price List validate crud_events.price_list.check_impact_on_cart Warn users
Tax Rule validate crud_events.tax_rule.validate_use_for_cart Compatibility check

Session Hooks

Hook When Fired Handler
on_session_creation User logs in Update debtors account, set cart count
on_logout User logs out Clear cart count cookie

Override Patterns

Pattern 1: Override ERPNext DocType

Current: Item override in webshop/webshop/doctype/override_doctype/item.py

```python from erpnext.stock.doctype.item.item import Item

class WebshopItem(Item):

   def on_update(self):
       super().on_update()  # Call parent
       # Custom: Auto-create Website Item
       self.create_website_item()
   
   def create_website_item(self):
       if not frappe.db.exists("Website Item", {"item_code": self.name}):
           # Create logic here
           pass

```

Registration in hooks.py:

```python override_doctype_class = {

   "Item": "webshop.webshop.doctype.override_doctype.item.WebshopItem",

} ```

Pattern 2: Add Custom Cart Validation

Goal: Minimum order amount check

Steps:

  1. Edit webshop/webshop/crud_events/quotation.py:

```python def validate_shopping_cart_items(doc, method=None):

   """Existing validation"""
   # ... existing code ...
   
   # Add custom validation
   if doc.order_type == "Shopping Cart":
       minimum_order = 1000  # PHP
       if doc.total < minimum_order:
           frappe.throw(_(
               f"Minimum order amount is {minimum_order} PHP"
           ))

```

  1. Already registered in hooks.py:

```python doc_events = {

   "Quotation": {
       "validate": ["webshop.webshop.crud_events.quotation.validate_shopping_cart_items"]
   }

} ```

Pattern 3: Custom Product Filter

Goal: Add "New Arrivals" filter

Create: webshop/webshop/product_data_engine/filters.py

```python def apply_new_arrivals_filter(query, filters):

   """Show items created in last 30 days"""
   from datetime import datetime, timedelta
   
   thirty_days_ago = datetime.now() - timedelta(days=30)
   query = query.where(
       frappe.qb.DocType("Website Item").creation >= thirty_days_ago
   )
   return query

```

Use in template:

Add to product listing template to call custom filter.

Pattern 4: Custom Payment Gateway Integration

Goal: Add Philippines-specific payment method (e.g., GCash)

Override Payment Request:

Edit webshop/webshop/doctype/override_doctype/payment_request.py:

```python from erpnext.accounts.doctype.payment_request.payment_request import PaymentRequest

class WebshopPaymentRequest(PaymentRequest):

   def on_submit(self):
       super().on_submit()
       
       if self.payment_gateway == "GCash":
           # Generate GCash payment URL
           self.payment_url = generate_gcash_url(self)
   
   def get_payment_url(self):
       if self.payment_gateway == "GCash":
           return self.payment_url
       return super().get_payment_url()

```

Adding New Web Pages

Create a New Page: Order Tracking

Step 1: Create controller webshop/www/track-order/index.py:

```python import frappe from frappe import _

def get_context(context):

   context.no_cache = 1
   
   order_id = frappe.form_dict.get('order')
   if order_id:
       context.order = frappe.get_doc("Sales Order", order_id)
       context.tracking_info = get_tracking_info(order_id)
   
   return context

def get_tracking_info(order_id):

   # Custom tracking logic
   pass

```

Step 2: Create template webshop/www/track-order/index.html:

```html {% extends "templates/web_base.html" %}

{% block page_content %}

Track Your Order

   {% if order %}
   {% else %}
       <form method="GET">
           <input type="text" name="order" placeholder="Enter Order Number">
           <button type="submit">Track</button>
       </form>
   {% endif %}

{% endblock %} ```

Step 3: Access at /track-order

Custom Fields Best Practice

Approach When to Use How
Custom Field (UI) Quick additions Desk → Customize Form
Fixtures Version-controlled fields Add to hooks.py fixtures
DocType JSON edit Core app changes Edit .json, migrate

Export Custom Fields as Fixtures

In webshop/hooks.py:

```python fixtures = [

   {
       "dt": "Custom Field",
       "filters": "module", "=", "Webshop"
   }

] ```

Then run: bench export-fixtures

Template Overrides

Override Product Card

Create: webshop/templates/webshop/item_card.html

Copy original from Frappe and modify:

```html

```

JavaScript Customization

Add Custom Cart Behavior

Edit webshop/public/js/cart.js:

```javascript // Add to existing file or create new frappe.ready(function() {

   // Custom: Show confirmation modal for expensive items
   $('.add-to-cart').on('click', function(e) {
       var price = $(this).data('price');
       if (price > 50000) {  // PHP 50,000
           if (!confirm('This item costs ₱' + price + '. Add to cart?')) {
               e.preventDefault();
               return false;
           }
       }
   });

}); ```

Register in webshop/hooks.py:

```python web_include_js = [

   "web.bundle.js",
   "webshop/js/cart.js"  # Add custom file

] ```