Seller Documentation¶
Overview¶
The Seller module (seller) manages sales representatives, channel partners, and other sales personnel within the system. It provides comprehensive functionality for seller profile management, commission calculation, and integration with HR employee records and sales orders.
Model Information¶
Model Name: seller
Display Name: Seller
Key Fields: name, code
Features¶
- ❌ Audit logging enabled (
_audit_log) - ❌ Multi-company support (
company_id) - ❌ Full-text content search (
_content_search) - ❌ Unique key constraint
- ✅ Commission calculation engine
- ✅ HR employee integration
- ✅ Multi-tier commission structure support
- ✅ Customer-specific commission rates
Seller Types¶
The seller model supports different types of sales personnel to accommodate various business models:
| Type | Code | Description |
|---|---|---|
| Internal | internal |
Direct employees of the company (e.g., in-house sales team) |
| Channel Partner | channel_partner |
External partners who sell on behalf of the company |
| Retails | retails |
Retail store or outlet sellers |
| Consignment | consignment |
Consignment-based sellers |
Key Fields Reference¶
Basic Information Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
Char | ✅ | Seller's full name or display name (searchable) |
code |
Char | ❌ | Unique identifier code for the seller (searchable) |
type |
Selection | ❌ | Type of seller (internal, channel_partner, retails, consignment) |
description |
Text | ❌ | Additional notes or description about the seller (searchable) |
Integration Fields¶
| Field | Type | Description |
|---|---|---|
employee_id |
Many2One | Link to hr.employee record (optional) - allows integration with HR module |
Relationship Fields¶
| Field | Type | Description |
|---|---|---|
commissions |
One2Many | Collection of seller.commission records defining commission rules |
Note: The seller model is referenced from sale.order and sale.quot through the seller_id field, automatically tracking which seller is responsible for each sale.
Commission Calculation Algorithm¶
Understanding the Commission Engine¶
The seller model includes a sophisticated commission calculation method (calc_commission) that computes total commissions earned by a seller over a specified date range.
How Commission Calculation Works¶
The commission calculation follows this algorithm:
1. Filter sales orders by seller and date range (only "confirmed" or "done" states)
2. Group order amounts by customer
3. For each customer:
a. Find matching commission rule (customer-specific first, then general)
b. Calculate amount above threshold
c. Apply commission percentage
4. Sum all commission amounts
Commission Matching Logic¶
The system uses a priority-based matching algorithm:
- Customer-specific commissions are checked first
- If found, that commission rule is used
- If no customer-specific rule exists, the first general commission (no customer_id) is used
- Commission rules are ordered by
sequencefield
Threshold-Based Calculation¶
Commissions are only calculated on amounts above the minimum threshold:
If total sales are below the threshold, no commission is earned for that customer.
API Methods¶
1. Create Seller¶
Method: create(vals, context)
Creates a new seller record.
Parameters:
vals = {
"name": "John Smith", # Required: Seller name
"code": "JS001", # Optional: Seller code
"type": "internal", # Optional: Seller type
"employee_id": 5, # Optional: Link to HR employee
"description": "Senior Sales Rep", # Optional: Description
"commissions": [ # Optional: Commission rules
("create", {
"commission_percent": 5.0,
"min_amount": 0
})
]
}
Returns: int - New seller record ID
Example:
# Create an internal seller with basic commission structure
seller_id = get_model("seller").create({
"name": "John Smith",
"code": "JS001",
"type": "internal",
"employee_id": 5,
"commissions": [
("create", {
"sequence": 1,
"commission_percent": 5.0,
"min_amount": 0
}),
("create", {
"sequence": 2,
"commission_percent": 7.5,
"min_amount": 100000
})
]
})
2. Calculate Commission¶
Method: calc_commission(ids, date_from=None, date_to=None, context={})
Calculates total commission earned by a seller for a specified period based on confirmed/completed sales orders.
Parameters:
- ids (list): Single-item list containing the seller ID
- date_from (str): Optional start date in format "YYYY-MM-DD" (inclusive)
- date_to (str): Optional end date in format "YYYY-MM-DD" (inclusive)
- context (dict): Optional context dictionary
Behavior: - Only includes sales orders in "confirmed" or "done" state - Groups sales by customer before applying commission rules - Applies customer-specific commission rates when available - Falls back to general commission rates for customers without specific rules - Only calculates commission on amounts above the minimum threshold - Returns the total commission amount across all customers
Returns: Decimal - Total commission amount earned
Example:
# Calculate commission for January 2025
seller_id = 123
commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-01-31"
)
print(f"Total commission: {commission}")
# Calculate commission for all time
total_commission = get_model("seller").calc_commission([seller_id])
# Calculate commission for Q1 2025
q1_commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-03-31"
)
Detailed Algorithm:
# Step 1: Gather all confirmed/done sales for the seller in date range
sales = sale.order.search_browse([
["seller_id", "=", seller_id],
["state", "in", ["confirmed", "done"]],
["date", ">=", date_from],
["date", "<=", date_to]
])
# Step 2: Group sales amounts by customer
customer_totals = {}
for sale in sales:
customer_id = sale.contact_id.id
customer_totals[customer_id] += sale.amount_total
# Step 3: Calculate commission per customer
total_commission = 0
for customer_id, customer_total in customer_totals.items():
# Find applicable commission rule (customer-specific first)
commission_rule = find_matching_commission(seller, customer_id)
if commission_rule:
# Only pay commission on amount above threshold
amount_above = customer_total - (commission_rule.min_amount or 0)
commission_amt = amount_above * (commission_rule.commission_percent or 0) / 100
total_commission += commission_amt
return total_commission
Search Functions¶
Search by Name¶
# Find sellers by name (case-insensitive partial match)
sellers = get_model("seller").search_browse([["name", "ilike", "%smith%"]])
Search by Code¶
Search by Employee¶
# Find seller linked to specific employee
seller = get_model("seller").search_browse([["employee_id", "=", employee_id]])
Search by Type¶
# Find all internal sellers
internal_sellers = get_model("seller").search_browse([["type", "=", "internal"]])
# Find all channel partners
partners = get_model("seller").search_browse([["type", "=", "channel_partner"]])
Related Models¶
| Model | Relationship | Description |
|---|---|---|
seller.commission |
One2Many (parent) | Commission rules and rate structures for this seller |
hr.employee |
Many2One | Optional link to employee record for internal sellers |
sale.order |
Many2One (inverse) | Sales orders assigned to this seller |
sale.quot |
Many2One (inverse) | Sales quotations assigned to this seller |
contact |
Indirect (via commissions) | Customers with specific commission rates |
shop |
Indirect | Shop/location assignments (referenced elsewhere) |
Common Use Cases¶
Use Case 1: Setting Up a New Seller with Tiered Commissions¶
# Create a seller with progressive commission tiers
# 1. Create the seller record
seller_id = get_model("seller").create({
"name": "Jane Doe",
"code": "JD001",
"type": "internal",
"employee_id": 42, # Link to HR employee record
"description": "Territory: North Region"
})
# 2. Add tiered commission structure
# 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 between 50,000 and 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
})
# 3. Verify setup
seller = get_model("seller").browse(seller_id)
print(f"Seller: {seller.name}")
print(f"Commission tiers: {len(seller.commissions)}")
for com in seller.commissions:
print(f" {com.commission_percent}% above {com.min_amount}")
How This Works:
When calculating commissions for sales totaling 75,000 to a single customer: - The system finds the highest applicable tier where 75,000 >= min_amount - This would be Tier 2 (min_amount: 50,000) - Commission = (75,000 - 50,000) × 5% = 1,250
Use Case 2: Setting Up Customer-Specific Commission Rates¶
# Give special commission rates for key accounts
# 1. Create seller
seller_id = get_model("seller").create({
"name": "Bob Johnson",
"code": "BJ001",
"type": "channel_partner"
})
# 2. Set general commission rate (default for all customers)
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0,
"min_amount": 0
})
# 3. Set special rate for key customer
key_customer_id = 789
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 2,
"customer_id": key_customer_id, # Customer-specific rule
"commission_percent": 6.0, # Higher rate for this customer
"min_amount": 0
})
# 4. Another key customer with threshold
another_customer_id = 456
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 3,
"customer_id": another_customer_id,
"commission_percent": 7.5,
"min_amount": 25000 # Only pay commission above 25,000
})
How Customer-Specific Rules Work:
When calculating commission: - Sales to customer 789: Uses 6% rate (customer-specific rule) - Sales to customer 456: Uses 7.5% rate on amounts above 25,000 - Sales to any other customer: Uses default 4% rate
Use Case 3: Calculating Monthly Commission Report¶
# Generate commission report for a seller for a specific month
seller_id = 123
month = "2025-01"
# Calculate commission for the month
commission = get_model("seller").calc_commission(
[seller_id],
date_from=f"{month}-01",
date_to=f"{month}-31"
)
# Get seller details
seller = get_model("seller").browse(seller_id)
# Get sales breakdown by customer
sales = get_model("sale.order").search_browse([
["seller_id", "=", seller_id],
["state", "in", ["confirmed", "done"]],
["date", ">=", f"{month}-01"],
["date", "<=", f"{month}-31"]
])
# Group by customer
from collections import defaultdict
customer_sales = defaultdict(lambda: {"total": 0, "count": 0})
for sale in sales:
cust_id = sale.contact_id.id
cust_name = sale.contact_id.name
customer_sales[cust_name]["total"] += sale.amount_total
customer_sales[cust_name]["count"] += 1
# Print report
print(f"Commission Report for {seller.name}")
print(f"Period: {month}")
print(f"Total Commission: ${commission:,.2f}")
print("\nSales Breakdown:")
print("-" * 60)
for customer, data in sorted(customer_sales.items()):
print(f"{customer:30s} {data['count']:3d} orders ${data['total']:10,.2f}")
Use Case 4: Quarterly Performance Tracking¶
# Track seller performance across quarters
seller_id = 123
# Define quarters
quarters = [
("Q1 2025", "2025-01-01", "2025-03-31"),
("Q2 2025", "2025-04-01", "2025-06-30"),
("Q3 2025", "2025-07-01", "2025-09-30"),
("Q4 2025", "2025-10-01", "2025-12-31"),
]
seller = get_model("seller").browse(seller_id)
print(f"Performance Report: {seller.name}")
print("=" * 70)
for quarter_name, date_from, date_to in quarters:
# Calculate commission for quarter
commission = get_model("seller").calc_commission(
[seller_id],
date_from=date_from,
date_to=date_to
)
# Get sales count and total
sales = get_model("sale.order").search_browse([
["seller_id", "=", seller_id],
["state", "in", ["confirmed", "done"]],
["date", ">=", date_from],
["date", "<=", date_to]
])
total_sales = sum(sale.amount_total for sale in sales)
print(f"\n{quarter_name}")
print(f" Orders: {len(sales)}")
print(f" Total Sales: ${total_sales:,.2f}")
print(f" Commission: ${commission:,.2f}")
if total_sales > 0:
print(f" Effective Rate: {(commission/total_sales*100):.2f}%")
Use Case 5: Migrating Seller to Different Employee¶
# Update seller when employee changes
seller_id = 123
new_employee_id = 456
# Update the seller record
get_model("seller").write([seller_id], {
"employee_id": new_employee_id
})
# Optionally update description
old_seller = get_model("seller").browse(seller_id)
get_model("seller").write([seller_id], {
"description": f"Transferred from previous employee on 2025-01-05"
})
print(f"Seller {old_seller.name} reassigned to employee {new_employee_id}")
Use Case 6: Finding Top Performers¶
# Identify top-performing sellers for a period
date_from = "2025-01-01"
date_to = "2025-12-31"
# Get all sellers
sellers = get_model("seller").search_browse([])
# Calculate commission for each
performance = []
for seller in sellers:
commission = get_model("seller").calc_commission(
[seller.id],
date_from=date_from,
date_to=date_to
)
if commission > 0:
performance.append({
"seller": seller.name,
"code": seller.code,
"type": seller.type,
"commission": commission
})
# Sort by commission (descending)
performance.sort(key=lambda x: x["commission"], reverse=True)
# Print top 10
print("Top 10 Sellers by Commission")
print("=" * 70)
for i, data in enumerate(performance[:10], 1):
print(f"{i:2d}. {data['seller']:20s} ({data['code']:10s}) ${data['commission']:12,.2f}")
Commission Calculation Examples¶
Example 1: Single-Tier Commission¶
Setup: - Commission: 5% on all sales - No minimum threshold
Commission Rules:
Sales in January: - Customer A: $10,000 - Customer B: $15,000 - Customer C: $5,000 - Total: $30,000
Commission Calculation:
Customer A: (10,000 - 0) × 5% = $500
Customer B: (15,000 - 0) × 5% = $750
Customer C: (5,000 - 0) × 5% = $250
Total Commission: $1,500
Example 2: Multi-Tier Commission¶
Setup: - Tier 1: 3% on sales up to $50,000 (per customer) - Tier 2: 5% on sales from $50,000 to $100,000 - Tier 3: 7% on sales above $100,000
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 in January: - Customer A: $75,000 - Customer B: $120,000 - Customer C: $30,000
Commission Calculation:
Customer A ($75,000):
- Applies Tier 2 (highest tier where 75,000 >= min_amount)
- Commission: (75,000 - 50,000) × 5% = $1,250
Customer B ($120,000):
- Applies Tier 3 (highest tier where 120,000 >= min_amount)
- Commission: (120,000 - 100,000) × 7% = $1,400
Customer C ($30,000):
- Applies Tier 1 (highest tier where 30,000 >= min_amount)
- Commission: (30,000 - 0) × 3% = $900
Total Commission: $3,550
Example 3: Customer-Specific Rates¶
Setup: - Default: 4% on all sales - Customer X: 6% on all sales (key account) - Customer Y: 8% on sales above $20,000 (strategic account)
Commission Rules:
[
{"sequence": 1, "commission_percent": 4.0, "min_amount": 0},
{"sequence": 2, "customer_id": X, "commission_percent": 6.0, "min_amount": 0},
{"sequence": 3, "customer_id": Y, "commission_percent": 8.0, "min_amount": 20000}
]
Sales in January: - Customer X: $50,000 - Customer Y: $35,000 - Customer Z: $25,000
Commission Calculation:
Customer X ($50,000):
- Uses customer-specific rule (6%)
- Commission: (50,000 - 0) × 6% = $3,000
Customer Y ($35,000):
- Uses customer-specific rule (8% above $20,000)
- Commission: (35,000 - 20,000) × 8% = $1,200
Customer Z ($25,000):
- Uses default rule (4%)
- Commission: (25,000 - 0) × 4% = $1,000
Total Commission: $5,200
Example 4: Threshold-Based Commission¶
Setup: - Commission: 5% on sales above $10,000 per customer - No commission on sales below threshold
Commission Rules:
Sales in January: - Customer A: $15,000 - Customer B: $8,000 - Customer C: $25,000
Commission Calculation:
Customer A ($15,000):
- Above threshold: 15,000 - 10,000 = $5,000
- Commission: 5,000 × 5% = $250
Customer B ($8,000):
- Below threshold: 8,000 < 10,000
- Commission: $0 (no commission earned)
Customer C ($25,000):
- Above threshold: 25,000 - 10,000 = $15,000
- Commission: 15,000 × 5% = $750
Total Commission: $1,000
Best Practices¶
1. Commission Structure Setup¶
# Good: Use sequence to control commission rule priority
# Step 1: Create general rules first (lower sequence numbers)
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1, # General rule
"commission_percent": 4.0,
"min_amount": 0
})
# Step 2: Add customer-specific rules (higher sequence numbers)
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 10, # Customer-specific rule
"customer_id": customer_id,
"commission_percent": 6.0,
"min_amount": 0
})
# Bad: Random sequence numbers without logic
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 99, # Arbitrary number
"commission_percent": 4.0
})
Why This Matters: The commission calculation engine uses the sequence field to order commission rules. While customer-specific rules take priority, proper sequencing makes the commission structure easier to understand and maintain.
2. Linking Sellers to Employees¶
# Good: Link internal sellers to HR employees for proper tracking
seller_id = get_model("seller").create({
"name": "John Smith",
"code": "JS001",
"type": "internal",
"employee_id": employee_id # Link to HR record
})
# Bad: Creating internal seller without employee link
seller_id = get_model("seller").create({
"name": "John Smith",
"type": "internal"
# No employee_id - can't link to HR data
})
Why This Matters: Linking sellers to employee records enables: - Unified reporting across HR and Sales - Automatic payroll integration - Employee hierarchy and territory management - Leave/absence tracking impact on sales
3. Commission Date Ranges¶
# Good: Use explicit date ranges for accurate reporting
commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-01-31"
)
# Bad: Calculating commission without date boundaries
commission = get_model("seller").calc_commission([seller_id])
# Returns ALL-TIME commission (could be huge dataset)
Why This Matters: Always specify date ranges to: - Improve query performance - Get accurate period-specific results - Avoid processing unnecessary historical data - Enable consistent month-over-month comparisons
4. Seller Code Conventions¶
# Good: Use consistent, meaningful seller codes
sellers = [
{"name": "John Smith", "code": "INT-001", "type": "internal"},
{"name": "Jane Doe", "code": "INT-002", "type": "internal"},
{"name": "ABC Corp", "code": "CP-001", "type": "channel_partner"},
{"name": "XYZ Retail", "code": "RET-001", "type": "retails"}
]
# Bad: Inconsistent or meaningless codes
sellers = [
{"name": "John Smith", "code": "A1"},
{"name": "Jane Doe", "code": "seller2"},
{"name": "ABC Corp", "code": "x"}
]
Why This Matters: Consistent seller codes: - Make reporting and filtering easier - Enable quick identification of seller types - Support automated integrations - Improve data quality and searchability
5. Testing Commission Structures¶
# Good: Test commission calculations before deploying
def test_seller_commission():
# Create test seller
seller_id = get_model("seller").create({
"name": "Test Seller",
"code": "TEST-001"
})
# Create test commission rules
get_model("seller.commission").create({
"seller_id": seller_id,
"commission_percent": 5.0,
"min_amount": 10000
})
# Create test sale order
order_id = get_model("sale.order").create({
"contact_id": customer_id,
"seller_id": seller_id,
"date": "2025-01-15",
"state": "confirmed",
"amount_total": 20000
})
# Calculate commission
commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-01-31"
)
# Verify: (20,000 - 10,000) × 5% = 500
assert commission == 500, f"Expected 500, got {commission}"
# Cleanup test data
get_model("sale.order").delete([order_id])
get_model("seller").delete([seller_id])
# Run test
test_seller_commission()
Performance Tips¶
1. Optimize Commission Calculations¶
- Use date ranges: Always specify date_from and date_to to limit dataset size
- Batch calculations: Calculate commissions for multiple periods at once if needed
- Index seller_id: Ensure sale.order.seller_id field is indexed for fast lookups
2. Commission Rule Optimization¶
# Good: Minimal, well-organized commission rules
# 1 general rule + customer-specific overrides as needed
# Bad: Excessive overlapping rules
# Multiple rules with complex conditions that slow down matching
3. Large Volume Scenarios¶
For sellers with thousands of orders:
# Consider creating a materialized report table
# Run commission calculations in batch processes
# Use background jobs for historical commission reports
Integration with Sale Orders¶
How Sellers are Assigned to Sales¶
When creating a sale order, assign a seller:
order_id = get_model("sale.order").create({
"contact_id": customer_id,
"seller_id": seller_id, # Assigns seller to this sale
"date": "2025-01-15",
"lines": [
("create", {
"product_id": product_id,
"qty": 10,
"unit_price": 100
})
]
})
Tracking Sales by Seller¶
# Get all sales for a specific seller
sales = get_model("sale.order").search_browse([
["seller_id", "=", seller_id],
["state", "in", ["confirmed", "done"]]
])
# Get sales statistics
total_orders = len(sales)
total_value = sum(sale.amount_total for sale in sales)
avg_order_value = total_value / total_orders if total_orders > 0 else 0
print(f"Seller: {seller.name}")
print(f"Total Orders: {total_orders}")
print(f"Total Value: ${total_value:,.2f}")
print(f"Average Order: ${avg_order_value:,.2f}")
Troubleshooting¶
"Commission calculation returns 0 for active seller"¶
Cause: One or more of these conditions: - No sale orders in specified date range - Sale orders not in "confirmed" or "done" state - No commission rules defined for the seller - Sales amounts below minimum thresholds
Solution:
# Debug step by step:
# 1. Check if seller has sales
sales = get_model("sale.order").search_browse([
["seller_id", "=", seller_id],
["date", ">=", date_from],
["date", "<=", date_to]
])
print(f"Found {len(sales)} sales")
# 2. Check sale states
for sale in sales:
print(f"Order {sale.number}: state={sale.state}, amount={sale.amount_total}")
# 3. Check commission rules
seller = get_model("seller").browse(seller_id)
print(f"Commission rules: {len(seller.commissions)}")
for com in seller.commissions:
print(f" {com.commission_percent}% above {com.min_amount}")
"Customer-specific commission not being applied"¶
Cause: Commission rule matching logic prioritizes customer-specific rules, but requires exact customer_id match.
Solution:
# Verify customer IDs match exactly
seller = get_model("seller").browse(seller_id)
for com in seller.commissions:
if com.customer_id:
print(f"Customer-specific rule: customer_id={com.customer_id.id}")
# Check sale order customer IDs
sales = get_model("sale.order").search_browse([["seller_id", "=", seller_id]])
for sale in sales:
print(f"Order {sale.number}: customer_id={sale.contact_id.id}")
"Commission calculation takes too long"¶
Cause: Large number of sale orders without date filtering, or inefficient database queries.
Solution: - Always specify date_from and date_to - Ensure sale.order.seller_id field is indexed - Consider creating summary tables for historical data - Use background jobs for large date ranges
# Bad: No date filter (processes all history)
commission = get_model("seller").calc_commission([seller_id])
# Good: Specific date range
commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-01-31"
)
Testing Examples¶
Unit Test: Commission Calculation with Tiers¶
def test_tiered_commission():
# Create test seller
seller_id = get_model("seller").create({
"name": "Test Seller",
"code": "TEST-001"
})
# Create tiered commission structure
# Tier 1: 3% on all sales
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 3.0,
"min_amount": 0
})
# Tier 2: 5% on sales above 50,000
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 2,
"commission_percent": 5.0,
"min_amount": 50000
})
# Create test customer
customer_id = get_model("contact").create({
"name": "Test Customer"
})
# Create sale order for 75,000 (should use Tier 2)
order_id = get_model("sale.order").create({
"contact_id": customer_id,
"seller_id": seller_id,
"date": "2025-01-15",
"state": "confirmed",
"amount_total": 75000
})
# Calculate commission
commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-01-31"
)
# Expected: (75,000 - 50,000) × 5% = 1,250
assert commission == 1250, f"Expected 1,250, got {commission}"
print("Tiered commission test passed!")
# Cleanup
get_model("sale.order").delete([order_id])
get_model("contact").delete([customer_id])
get_model("seller").delete([seller_id])
Unit Test: Customer-Specific Commission¶
def test_customer_specific_commission():
# Create test seller
seller_id = get_model("seller").create({
"name": "Test Seller",
"code": "TEST-002"
})
# Create test customers
customer_a_id = get_model("contact").create({"name": "Customer A"})
customer_b_id = get_model("contact").create({"name": "Customer B"})
# General commission: 4%
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 1,
"commission_percent": 4.0,
"min_amount": 0
})
# Customer A specific: 6%
get_model("seller.commission").create({
"seller_id": seller_id,
"sequence": 2,
"customer_id": customer_a_id,
"commission_percent": 6.0,
"min_amount": 0
})
# Create sales
order_a_id = get_model("sale.order").create({
"contact_id": customer_a_id,
"seller_id": seller_id,
"date": "2025-01-15",
"state": "confirmed",
"amount_total": 10000
})
order_b_id = get_model("sale.order").create({
"contact_id": customer_b_id,
"seller_id": seller_id,
"date": "2025-01-15",
"state": "confirmed",
"amount_total": 10000
})
# Calculate commission
commission = get_model("seller").calc_commission(
[seller_id],
date_from="2025-01-01",
date_to="2025-01-31"
)
# Expected:
# Customer A: 10,000 × 6% = 600
# Customer B: 10,000 × 4% = 400
# Total: 1,000
assert commission == 1000, f"Expected 1,000, got {commission}"
print("Customer-specific commission test passed!")
# Cleanup
get_model("sale.order").delete([order_a_id, order_b_id])
get_model("contact").delete([customer_a_id, customer_b_id])
get_model("seller").delete([seller_id])
Security Considerations¶
Permission Model¶
- Create/Edit Sellers: Typically restricted to Sales Managers and HR
- View Commission Data: May be restricted to seller themselves + management
- Calculate Commissions: Should be audited for financial tracking
Data Access¶
- Sellers should typically only see their own commission data
- Management reports may aggregate data across all sellers
- Commission rules may contain sensitive business logic
- Integration with payroll systems requires secure data transfer
Version History¶
Last Updated: 2025-01-05 Model Version: seller.py (from contact.py with calc_commission method) Framework: Netforce
Additional Resources¶
- Seller Commission Documentation:
seller.commission - Shop Documentation:
shop - Sale Order Documentation:
sale.order - HR Employee Documentation:
hr.employee
Support & Feedback¶
For issues or questions about this module: 1. Check seller.commission documentation for commission rule setup 2. Review sale order documentation for seller assignment 3. Verify sale order states (must be "confirmed" or "done") 4. Test commission calculations with known test data 5. Check date ranges and customer IDs for accuracy
This documentation is generated for developer onboarding and reference purposes.