Messenger Documentation¶
Overview¶
The Messenger module (messenger) tracks messenger and courier companies with both name and code identifiers. This provides a more structured approach than the courier model, supporting code-based lookups and organization.
Model Information¶
Model Name: messenger
Display Name: Messenger
Key Fields: None
Features¶
- ❌ No audit logging
- ❌ No multi-company support
- ❌ No full-text search
- ❌ No unique constraints
Key Fields Reference¶
Header Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
Char | ✅ | Messenger company name |
code |
Char | ❌ | Short reference code |
Default Order: Ordered by name alphabetically
API Methods¶
1. Create Messenger¶
Method: create(vals, context)
Creates a new messenger record with name and optional code.
Parameters:
Returns: int - New record ID
Example:
# Create messenger with code
messenger_id = get_model("messenger").create({
"name": "Flash Delivery Service",
"code": "FLASH"
})
# Create messenger without code
messenger_id = get_model("messenger").create({
"name": "Local Express Courier"
})
2. Search by Name¶
Method: search_browse(condition, context)
Search messengers by name (case-insensitive).
Example:
# Search by partial name match
messengers = get_model("messenger").search_browse([
["name", "ilike", "flash"]
])
for m in messengers:
print(f"{m.code}: {m.name}")
3. Search by Code¶
Method: search_browse(condition, context)
Search messengers by exact code match.
Example:
# Find specific messenger by code
messenger = get_model("messenger").search_browse([
["code", "=", "FLASH"]
])
if messenger:
print(f"Found: {messenger[0].name}")
Common Use Cases¶
Use Case 1: Setup Messenger Services¶
# Setup company messenger services with codes
messengers_data = [
{"name": "Flash Delivery", "code": "FLASH"},
{"name": "Quick Courier", "code": "QUICK"},
{"name": "Express Messenger", "code": "EXPRESS"},
{"name": "Same Day Service", "code": "SAME"},
{"name": "Overnight Delivery", "code": "OVER"}
]
messenger_ids = []
for data in messengers_data:
messenger_id = get_model("messenger").create(data)
messenger_ids.append(messenger_id)
print(f"Created: [{data['code']}] {data['name']}")
Use Case 2: List All Messengers¶
# Get all messengers ordered by name
messengers = get_model("messenger").search_browse([])
print("Registered Messengers:")
print("-" * 40)
for messenger in messengers:
code_display = f"[{messenger.code}]" if messenger.code else "[NO CODE]"
print(f"{code_display} {messenger.name}")
Use Case 3: Update Messenger Information¶
# Update messenger name and code
messenger_id = 1
get_model("messenger").write([messenger_id], {
"name": "Flash Delivery Express",
"code": "FLASHEXP"
})
Use Case 4: Find Messenger by Code for Integration¶
def get_messenger_id_by_code(code):
"""Helper function to get messenger ID by code"""
messenger = get_model("messenger").search([
["code", "=", code]
])
if messenger:
return messenger[0]
else:
raise ValueError(f"Messenger with code '{code}' not found")
# Usage in integration
try:
messenger_id = get_messenger_id_by_code("FLASH")
# Use messenger_id in order processing
except ValueError as e:
print(f"Error: {e}")
Search Functions¶
Search by Name Pattern¶
# Case-insensitive partial match
condition = [["name", "ilike", "%delivery%"]]
results = get_model("messenger").search_browse(condition)
Search by Exact Code¶
# Exact code match (case-sensitive)
condition = [["code", "=", "FLASH"]]
results = get_model("messenger").search_browse(condition)
Search for Messengers Without Code¶
# Find messengers missing codes
condition = [["code", "=", False]]
results = get_model("messenger").search_browse(condition)
print(f"Found {len(results)} messengers without codes")
Related Models¶
| Model | Relationship | Description |
|---|---|---|
stock.picking |
Referenced by | Stock pickings may specify messenger |
sale.order |
Referenced by | Sales orders may reference messenger |
courier |
Similar | Alternative simpler courier model |
Best Practices¶
1. Use Consistent Code Format¶
# Good: Uppercase, short codes
get_model("messenger").create({
"name": "Flash Delivery",
"code": "FLASH"
})
# Avoid: Mixed case, long codes
get_model("messenger").create({
"name": "Flash Delivery",
"code": "flash_delivery_service" # Too long
})
2. Always Provide Codes for Integration¶
# Good: Code provided for API/integration use
get_model("messenger").create({
"name": "Express Service",
"code": "EXP"
})
# Bad: No code makes lookups harder
get_model("messenger").create({
"name": "Express Service"
# Missing code field
})
3. Check for Existing Records¶
# Good: Check before creating to avoid duplicates
def create_or_get_messenger(name, code):
# Check by code first
existing = get_model("messenger").search([
["code", "=", code]
])
if existing:
return existing[0]
# Check by name
existing = get_model("messenger").search([
["name", "=", name]
])
if existing:
# Update with code
get_model("messenger").write([existing[0]], {"code": code})
return existing[0]
# Create new
return get_model("messenger").create({
"name": name,
"code": code
})
Performance Tips¶
1. Cache Messenger Mappings¶
# Good: Cache code-to-ID mappings
class MessengerCache:
_cache = {}
@classmethod
def get_by_code(cls, code):
if code not in cls._cache:
messenger = get_model("messenger").search([
["code", "=", code]
])
if messenger:
cls._cache[code] = messenger[0]
return cls._cache.get(code)
@classmethod
def clear(cls):
cls._cache = {}
# Usage
messenger_id = MessengerCache.get_by_code("FLASH")
2. Batch Load Messengers¶
# Good: Load all messengers once
messengers = get_model("messenger").search_browse([])
messenger_map = {m.code: m.id for m in messengers if m.code}
# Use map for lookups
flash_id = messenger_map.get("FLASH")
quick_id = messenger_map.get("QUICK")
Troubleshooting¶
"Messenger not found by code"¶
Cause: Code doesn't exist or is misspelled
Solution: Verify code exists and matches exactly
# Check if code exists
code = "FLASH"
messenger = get_model("messenger").search([["code", "=", code]])
if not messenger:
print(f"Code '{code}' not found. Available codes:")
all_messengers = get_model("messenger").search_browse([])
for m in all_messengers:
if m.code:
print(f" - {m.code}")
Duplicate messenger names¶
Cause: No unique constraint on name field
Solution: Check before creating
# Check for duplicate names
name = "Flash Delivery"
existing = get_model("messenger").search([["name", "=", name]])
if existing:
print(f"Messenger '{name}' already exists")
# Use existing or choose different name
Messengers not ordered correctly¶
Cause: Model uses name ordering by default
Solution: This is expected behavior, messengers sorted alphabetically
Testing Examples¶
Unit Test: Create and Retrieve Messenger¶
def test_messenger_crud():
# Create
messenger_id = get_model("messenger").create({
"name": "Test Messenger",
"code": "TEST"
})
# Verify creation
assert messenger_id is not None
# Read by ID
messenger = get_model("messenger").browse(messenger_id)
assert messenger.name == "Test Messenger"
assert messenger.code == "TEST"
# Search by code
found = get_model("messenger").search([["code", "=", "TEST"]])
assert len(found) == 1
assert found[0] == messenger_id
# Update
get_model("messenger").write([messenger_id], {
"name": "Updated Test Messenger"
})
# Verify update
messenger = get_model("messenger").browse(messenger_id)
assert messenger.name == "Updated Test Messenger"
# Delete
get_model("messenger").delete([messenger_id])
# Verify deletion
found = get_model("messenger").search([["id", "=", messenger_id]])
assert len(found) == 0
Unit Test: Search Operations¶
def test_messenger_search():
# Create test data
test_messengers = [
{"name": "Alpha Delivery", "code": "ALPHA"},
{"name": "Beta Courier", "code": "BETA"},
{"name": "Gamma Express", "code": "GAMMA"}
]
created_ids = []
for data in test_messengers:
mid = get_model("messenger").create(data)
created_ids.append(mid)
# Test search by name
results = get_model("messenger").search([
["name", "ilike", "alpha"]
])
assert len(results) == 1
# Test search by code
results = get_model("messenger").search([
["code", "=", "BETA"]
])
assert len(results) == 1
# Cleanup
get_model("messenger").delete(created_ids)
Security Considerations¶
Permission Model¶
- Standard model permissions apply
- Create/write typically requires admin or manager role
- Read access for users needing to select messengers
Data Access¶
- No sensitive data stored
- Public information (company names)
- No multi-company isolation
Integration Points¶
External Systems¶
- Shipping APIs: Messenger codes may map to external courier APIs
- Tracking Systems: Codes used for shipment tracking integration
Internal Modules¶
- Stock Management: Pickings reference messengers
- Sales: Orders may specify preferred messenger
- Delivery Planning: Route assignments by messenger
Version History¶
Last Updated: October 2025
Model File: messenger.py
Framework: Netforce
Additional Resources¶
- Courier Documentation:
courier - Shipping Method Documentation:
ship.method - Stock Picking Documentation:
stock.picking
This documentation is generated for developer onboarding and reference purposes.