Seller Commission Documentation¶
Overview¶
The Seller Commission module (seller.commission) defines commission rate structures and rules for sellers. It enables flexible commission configurations including tiered rates, customer-specific rates, minimum thresholds, and customer group-based commissions. This model works in conjunction with the seller model to calculate accurate commission payments.
Model Information¶
Model Name: seller.commission
Display Name: Seller Commission
Key Fields: seller_id, sequence
Features¶
- ❌ Audit logging enabled (
_audit_log) - ❌ Multi-company support (
company_id) - ❌ Full-text content search (
_content_search) - ❌ Unique key constraint
- ✅ Customer-specific commission rates
- ✅ Customer group-based commissions
- ✅ Threshold-based commission activation
- ✅ Sequential rule ordering
Key Fields Reference¶
Core Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
seller_id |
Many2One | ✅ | Reference to the seller this commission rule applies to (searchable) |
sequence |
Integer | ❌ | Order in which rules are evaluated (lower numbers first) |
commission_percent |
Decimal | ❌ | Commission percentage (e.g., 5.0 for 5%) |
min_amount |
Decimal | ❌ | Minimum sales amount threshold before commission applies |
Targeting Fields¶
| Field | Type | Description |
|---|---|---|
customer_id |
Many2One | Specific customer this rule applies to (optional - leave empty for general rule) |
customer_group_id |
Many2One | Customer group this rule applies to (optional - for group-based commissions) |
Understanding Commission Rules¶
Commission Rule Types¶
The seller.commission model supports three types of commission rules:
1. General Commission Rules¶
Applied to all customers unless a more specific rule exists.
{
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0,
"min_amount": 0
# No customer_id or customer_group_id
}
2. Customer-Specific Commission Rules¶
Applied only to sales for a specific customer.
{
"seller_id": seller_id,
"sequence": 2,
"customer_id": customer_id, # Specific customer
"commission_percent": 6.0,
"min_amount": 0
}
3. Customer Group Commission Rules¶
Applied to all customers in a specific group.
{
"seller_id": seller_id,
"sequence": 3,
"customer_group_id": group_id, # Customer group
"commission_percent": 5.5,
"min_amount": 0
}
Commission Matching Priority¶
When calculating commissions, the system matches rules in this priority order:
- Customer-specific rules (customer_id is set)
- Customer group rules (customer_group_id is set)
- General rules (neither customer_id nor customer_group_id is set)
Within each category, rules are ordered by the sequence field (lower numbers first).
Threshold-Based Commissions¶
How Minimum Amount Works¶
The min_amount field creates a threshold that must be exceeded before commission is earned:
- Sales below threshold: No commission paid
- Sales at or above threshold: Commission paid on amount above threshold
Calculation Formula¶
if total_sales >= min_amount:
commission = (total_sales - min_amount) × (commission_percent / 100)
else:
commission = 0
Example¶
Commission rule: 5% on sales above $10,000
# Scenario 1: Sales = $15,000
commission = (15,000 - 10,000) × 5% = $250
# Scenario 2: Sales = $8,000
commission = $0 # Below threshold
# Scenario 3: Sales = $10,000
commission = (10,000 - 10,000) × 5% = $0
API Methods¶
1. Create Commission Rule¶
Method: create(vals, context)
Creates a new commission rule for a seller.
Parameters:
vals = {
"seller_id": seller_id, # Required: Seller this rule applies to
"sequence": 1, # Optional: Evaluation order
"commission_percent": 5.0, # Optional: Commission percentage
"min_amount": 0, # Optional: Minimum threshold
"customer_id": customer_id, # Optional: Specific customer
"customer_group_id": group_id # Optional: Customer group
}
Returns: int - New commission rule ID
Example:
# Create general commission rule
rule_id = get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0,
"min_amount": 0
})
2. Update Commission Rule¶
Method: write(ids, vals, context)
Updates existing commission rules.
Example:
# Update commission percentage
get_model("seller.commission").write([rule_id], {
"commission_percent": 5.5
})
# Update minimum threshold
get_model("seller.commission").write([rule_id], {
"min_amount": 20000
})
3. Delete Commission Rule¶
Method: delete(ids, context)
Deletes commission rules.
Example:
Common Use Cases¶
Use Case 1: Single-Tier General Commission¶
Scenario: All sellers earn 5% on all sales with no minimum threshold.
# Create seller
seller_id = get_model("seller").create({
"name": "John Smith",
"code": "JS001"
})
# Create single commission rule
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 5.0,
"min_amount": 0
})
Result: Seller earns 5% on every sale to any customer.
Use Case 2: Multi-Tier Commission Structure¶
Scenario: Progressive commission rates based on sales volume per customer.
seller_id = get_model("seller").create({
"name": "Jane Doe",
"code": "JD001"
})
# Tier 1: 3% on sales up to $50,000
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 3.0,
"min_amount": 0
})
# Tier 2: 5% on sales from $50,000 to $100,000
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 2,
"commission_percent": 5.0,
"min_amount": 50000
})
# Tier 3: 7% on sales above $100,000
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 3,
"commission_percent": 7.0,
"min_amount": 100000
})
How It Works: - Customer with $30,000 in sales: Uses Tier 1 → $30,000 × 3% = $900 - Customer with $75,000 in sales: Uses Tier 2 → ($75,000 - $50,000) × 5% = $1,250 - Customer with $150,000 in sales: Uses Tier 3 → ($150,000 - $100,000) × 7% = $3,500
Use Case 3: Customer-Specific VIP Rates¶
Scenario: Key accounts receive preferential commission rates to incentivize focus.
seller_id = get_model("seller").create({
"name": "Bob Wilson",
"code": "BW001"
})
# General rule: 4% for all customers
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0,
"min_amount": 0
})
# VIP Customer A: 7% commission
vip_customer_a_id = 123
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 10,
"customer_id": vip_customer_a_id,
"commission_percent": 7.0,
"min_amount": 0
})
# VIP Customer B: 8% on sales above $25,000
vip_customer_b_id = 456
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 11,
"customer_id": vip_customer_b_id,
"commission_percent": 8.0,
"min_amount": 25000
})
Result: - Sales to Customer A: 7% on all sales - Sales to Customer B: 8% on sales above $25,000 - Sales to any other customer: 4% on all sales
Use Case 4: Threshold-Based Commission (No Small Orders)¶
Scenario: Only pay commission on significant sales to focus seller efforts.
seller_id = get_model("seller").create({
"name": "Alice Johnson",
"code": "AJ001"
})
# Only pay commission on orders above $5,000
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 6.0,
"min_amount": 5000
})
Result: - Order for $10,000: Commission = ($10,000 - $5,000) × 6% = $300 - Order for $3,000: Commission = $0 (below threshold)
Use Case 5: Customer Group-Based Commissions¶
Scenario: Different commission rates for wholesale vs retail customers.
seller_id = get_model("seller").create({
"name": "Chris Brown",
"code": "CB001"
})
# Get customer groups
wholesale_group_id = get_model("contact.group").search([["name", "=", "Wholesale"]])[0]
retail_group_id = get_model("contact.group").search([["name", "=", "Retail"]])[0]
# Default commission: 4%
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0,
"min_amount": 0
})
# Wholesale customers: 3% (lower margin)
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 2,
"customer_group_id": wholesale_group_id,
"commission_percent": 3.0,
"min_amount": 0
})
# Retail customers: 6% (higher margin)
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 3,
"customer_group_id": retail_group_id,
"commission_percent": 6.0,
"min_amount": 0
})
Result: - Sales to wholesale customers: 3% commission - Sales to retail customers: 6% commission - Sales to ungrouped customers: 4% default commission
Use Case 6: Updating Commission Rates¶
Scenario: Annual commission structure adjustment.
# Find all commission rules for a seller
seller_id = 123
rules = get_model("seller.commission").search_browse([
["seller_id", "=", seller_id]
])
# Increase all rates by 0.5%
for rule in rules:
new_rate = rule.commission_percent + 0.5
get_model("seller.commission").write([rule.id], {
"commission_percent": new_rate
})
print(f"Updated {len(rules)} commission rules for seller")
Use Case 7: Seasonal/Promotional Higher Rates¶
Scenario: Create temporary higher commission rate for a promotional period.
# Add temporary high commission rule
promo_rule_id = get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 0, # Highest priority
"commission_percent": 10.0,
"min_amount": 0
})
# After promotion ends, remove the rule
get_model("seller.commission").delete([promo_rule_id])
Note: This example demonstrates creating/deleting rules. In practice, you might want to use date-based filtering in your commission calculation logic.
Commission Calculation Examples¶
Example 1: Simple Flat Rate¶
Commission Rules:
Sales: - Customer A: $20,000 - Customer B: $30,000
Calculation:
Example 2: Tiered Structure¶
Commission Rules:
[
{"sequence": 1, "commission_percent": 3.0, "min_amount": 0},
{"sequence": 2, "commission_percent": 5.0, "min_amount": 50000},
{"sequence": 3, "commission_percent": 7.0, "min_amount": 100000}
]
Sales: - Customer A: $40,000 - Customer B: $80,000 - Customer C: $120,000
Calculation:
Customer A ($40,000):
- Uses Tier 1 (highest applicable where 40,000 >= min_amount)
- Commission: 40,000 × 3% = $1,200
Customer B ($80,000):
- Uses Tier 2 (highest applicable where 80,000 >= min_amount)
- Commission: (80,000 - 50,000) × 5% = $1,500
Customer C ($120,000):
- Uses Tier 3 (highest applicable where 120,000 >= min_amount)
- Commission: (120,000 - 100,000) × 7% = $1,400
Total Commission: $4,100
Example 3: Mixed Rules (General + Customer-Specific)¶
Commission Rules:
[
{"sequence": 1, "commission_percent": 4.0, "min_amount": 0},
{"sequence": 2, "customer_id": 100, "commission_percent": 6.0, "min_amount": 0},
{"sequence": 3, "customer_id": 200, "commission_percent": 8.0, "min_amount": 20000}
]
Sales: - Customer 100: $50,000 - Customer 200: $35,000 - Customer 300: $25,000
Calculation:
Customer 100 ($50,000):
- Uses customer-specific rule (6%)
- Commission: 50,000 × 6% = $3,000
Customer 200 ($35,000):
- Uses customer-specific rule (8% above $20,000)
- Commission: (35,000 - 20,000) × 8% = $1,200
Customer 300 ($25,000):
- Uses general rule (4%)
- Commission: 25,000 × 4% = $1,000
Total Commission: $5,200
Best Practices¶
1. Use Sequence Numbers Strategically¶
# Good: Logical sequence numbering
# General rules: 1-9
# Customer group rules: 10-99
# Customer-specific rules: 100+
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1, # General rule
"commission_percent": 4.0
})
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 50, # Group rule
"customer_group_id": group_id,
"commission_percent": 5.0
})
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 100, # Customer-specific rule
"customer_id": customer_id,
"commission_percent": 6.0
})
# Bad: Random sequence numbers
# Makes it hard to understand rule priority
Why This Matters: Organized sequence numbering makes commission structures easier to understand, maintain, and debug.
2. Always Have a Default General Rule¶
# Good: Start with a general rule
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0, # Default for all customers
"min_amount": 0
})
# Then add exceptions
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 100,
"customer_id": vip_customer_id,
"commission_percent": 7.0
})
# Bad: Only customer-specific rules
# Customers without specific rules get no commission
Why This Matters: A default general rule ensures all sales generate commission unless explicitly configured otherwise.
3. Document Commission Structures¶
# Good: Use descriptive comments or descriptions
# Create tiered structure with documentation
tiers = [
{
"sequence": 1,
"commission_percent": 3.0,
"min_amount": 0,
"description": "Base tier: 3% on all sales"
},
{
"sequence": 2,
"commission_percent": 5.0,
"min_amount": 50000,
"description": "Mid tier: 5% on sales above $50k"
},
{
"sequence": 3,
"commission_percent": 7.0,
"min_amount": 100000,
"description": "Top tier: 7% on sales above $100k"
}
]
for tier in tiers:
get_model("seller.commission").create({
"seller_id": seller_id,
**tier
})
Why This Matters: Clear documentation helps future administrators understand the commission logic and business rules.
4. Test Commission Calculations¶
# Good: Verify commission rules work as expected
def verify_commission_structure(seller_id):
# Get all rules
rules = get_model("seller.commission").search_browse([
["seller_id", "=", seller_id]
])
print(f"Commission Rules for Seller {seller_id}:")
print("-" * 60)
for rule in rules:
rule_type = "General"
if rule.customer_id:
rule_type = f"Customer: {rule.customer_id.name}"
elif rule.customer_group_id:
rule_type = f"Group: {rule.customer_group_id.name}"
print(f"Seq {rule.sequence:3d} | {rule_type:20s} | "
f"{rule.commission_percent}% above ${rule.min_amount:,.0f}")
verify_commission_structure(seller_id)
Why This Matters: Regular verification prevents commission calculation errors and ensures rules match business agreements.
5. Avoid Overlapping Rules¶
# Good: Clear, non-overlapping tiers
tiers = [
{"min_amount": 0, "commission_percent": 3.0},
{"min_amount": 50000, "commission_percent": 5.0},
{"min_amount": 100000, "commission_percent": 7.0}
]
# Confusing: Overlapping thresholds with different rates
# Can lead to unexpected commission calculations
overlapping = [
{"min_amount": 0, "commission_percent": 3.0},
{"min_amount": 40000, "commission_percent": 4.0}, # Overlaps with tier above
{"min_amount": 50000, "commission_percent": 5.0} # Creates confusion
]
Why This Matters: The system selects the highest applicable tier, so overlapping rules should increase commission rates, not create confusion.
Related Models¶
| Model | Relationship | Description |
|---|---|---|
seller |
Many2One | The seller this commission rule belongs to |
contact |
Many2One | Optional customer this rule specifically applies to |
contact.group |
Many2One | Optional customer group this rule applies to |
sale.order |
Indirect | Sales orders used in commission calculation |
Search Functions¶
Search by Seller¶
# Get all commission rules for a specific seller
rules = get_model("seller.commission").search_browse([
["seller_id", "=", seller_id]
])
Search by Customer¶
# Find customer-specific commission rules
customer_rules = get_model("seller.commission").search_browse([
["customer_id", "=", customer_id]
])
Search General Rules¶
# Find general commission rules (not customer-specific)
general_rules = get_model("seller.commission").search_browse([
["customer_id", "=", None]
])
Troubleshooting¶
"Seller not earning expected commission"¶
Cause: Commission rules may not be configured correctly, or sales may be below minimum thresholds.
Solution:
# Check seller's commission rules
seller_id = 123
rules = get_model("seller.commission").search_browse([
["seller_id", "=", seller_id]
])
if not rules:
print("ERROR: No commission rules found for seller!")
else:
print(f"Found {len(rules)} commission rules:")
for rule in rules:
print(f" - {rule.commission_percent}% above ${rule.min_amount:,.0f}")
if rule.customer_id:
print(f" (Customer-specific: {rule.customer_id.name})")
"Customer-specific rule not being applied"¶
Cause: Customer ID mismatch or sequence order issue.
Solution:
# Verify customer-specific rules
customer_id = 456
rules = get_model("seller.commission").search_browse([
["seller_id", "=", seller_id],
["customer_id", "=", customer_id]
])
if rules:
print(f"Found customer-specific rule: {rules[0].commission_percent}%")
else:
print("No customer-specific rule found - will use general rule")
"Commission changes not taking effect"¶
Cause: Existing sales orders may have already been calculated, or caching issues.
Solution: - Commission rules affect future calculations only - Re-run commission calculation for the period - Verify rule changes were saved correctly
# Verify rule was updated
rule = get_model("seller.commission").browse(rule_id)
print(f"Current rate: {rule.commission_percent}%")
Performance Tips¶
1. Minimize Number of Rules¶
- Keep commission structures as simple as possible
- Use tiered structures instead of many overlapping rules
- Consolidate similar customer rules using customer groups
2. Optimize Rule Ordering¶
- Use sequence numbers to ensure most common rules are checked first
- General rules should have lower sequence numbers
- Customer-specific exceptions should have higher sequence numbers
3. Regular Cleanup¶
- Remove obsolete commission rules
- Archive or delete rules for inactive sellers
- Consolidate redundant rules
Testing Examples¶
Unit Test: Commission Rule Creation¶
def test_commission_rule_creation():
# Create test seller
seller_id = get_model("seller").create({
"name": "Test Seller",
"code": "TEST-001"
})
# Create commission rule
rule_id = get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 5.0,
"min_amount": 10000
})
# Verify rule was created
rule = get_model("seller.commission").browse(rule_id)
assert rule.seller_id.id == seller_id
assert rule.commission_percent == 5.0
assert rule.min_amount == 10000
print("Commission rule creation test passed!")
# Cleanup
get_model("seller.commission").delete([rule_id])
get_model("seller").delete([seller_id])
Security Considerations¶
Permission Model¶
- Create/Edit Commission Rules: Restricted to Sales Managers
- View Commission Data: May be restricted based on user role
- Delete Commission Rules: Requires manager approval
Data Access¶
- Commission rules contain sensitive business logic
- Commission percentages should be confidential
- Access should be logged for audit purposes
Version History¶
Last Updated: 2025-01-05 Model Version: seller_commission.py Framework: Netforce
Additional Resources¶
- Seller Documentation:
seller - Sale Order Documentation:
sale.order - Contact Documentation:
contact - Contact Group Documentation:
contact.group
Support & Feedback¶
For issues or questions about this module: 1. Verify commission rules are properly configured 2. Check sequence numbers for correct priority 3. Ensure min_amount thresholds are set appropriately 4. Test calculations with known test data 5. Review seller documentation for commission calculation algorithm
This documentation is generated for developer onboarding and reference purposes.