Expense Category Documentation¶
Overview¶
The Expense Category model (expense.categ) provides a way to categorize and organize expense records in the system. Categories help with reporting, analysis, and budgeting by grouping similar types of expenses together.
Model Information¶
Model Name: expense.categ
Display Name: Expense Category
Key Fields: None (no unique constraint defined)
Features¶
- ❌ Audit logging enabled (
_audit_log) - ❌ Multi-company support (
company_id) - ❌ Full-text content search (
_content_search) - ✅ Simple lookup model for categorization
Key Fields Reference¶
All Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
Char | ✅ | Category name displayed in selection lists |
description |
Text | ❌ | Detailed description of what expenses belong to this category |
Default Ordering¶
Records are ordered by name alphabetically:
API Methods¶
1. Create Category¶
Method: create(vals, context)
Creates a new expense category.
Parameters:
vals = {
"name": "Travel", # Required: Category name
"description": "Travel-related expenses including transport and accommodation" # Optional
}
Returns: int - New record ID
Example:
# Create a new expense category
categ_id = get_model("expense.categ").create({
"name": "Office Supplies",
"description": "Stationery, paper, pens, and other office consumables"
})
2. Search Categories¶
Method: search(condition, context)
Search for expense categories.
Example:
# Find all categories
all_categs = get_model("expense.categ").search([])
# Find category by name
categ_ids = get_model("expense.categ").search([["name", "=", "Travel"]])
# Find categories containing 'Office'
categ_ids = get_model("expense.categ").search([["name", "ilike", "%Office%"]])
3. Browse Categories¶
Method: browse(ids, context)
Retrieve category records for reading.
Example:
# Get category details
categs = get_model("expense.categ").browse(categ_ids)
for categ in categs:
print(f"Category: {categ.name}")
print(f"Description: {categ.description}")
4. Update Category¶
Method: write(ids, vals, context)
Update existing category records.
Example:
# Update category description
get_model("expense.categ").write([categ_id], {
"description": "Updated description for the category"
})
5. Delete Category¶
Method: delete(ids, context)
Delete expense categories.
Example:
Related Models¶
| Model | Relationship | Description |
|---|---|---|
expense |
Many2One (categ_id) | Individual expense records linked to this category |
Common Use Cases¶
Use Case 1: Set Up Standard Expense Categories¶
# Create standard expense categories for a company
categories = [
{"name": "Travel", "description": "Transportation, flights, accommodation"},
{"name": "Meals", "description": "Business meals and entertainment"},
{"name": "Office Supplies", "description": "Stationery and office consumables"},
{"name": "Software", "description": "Software licenses and subscriptions"},
{"name": "Training", "description": "Professional development and courses"},
{"name": "Equipment", "description": "Hardware and equipment purchases"},
{"name": "Communication", "description": "Phone, internet, and communication costs"},
{"name": "Miscellaneous", "description": "Other uncategorized expenses"},
]
for cat in categories:
get_model("expense.categ").create(cat)
Use Case 2: List All Categories for Dropdown¶
# Get all categories for a selection field
categ_ids = get_model("expense.categ").search([])
categs = get_model("expense.categ").search_browse([])
options = []
for categ in categs:
options.append({
"id": categ.id,
"name": categ.name,
"description": categ.description
})
Use Case 3: Get Expenses by Category¶
# Find all expenses in a specific category
categ_id = get_model("expense.categ").search([["name", "=", "Travel"]])[0]
expense_ids = get_model("expense").search([["categ_id", "=", categ_id]])
expenses = get_model("expense").browse(expense_ids)
total = sum(exp.amount for exp in expenses)
print(f"Total Travel Expenses: {total}")
Best Practices¶
1. Use Descriptive Names¶
# Good: Clear and specific
get_model("expense.categ").create({
"name": "Client Entertainment",
"description": "Meals and activities with clients for business development"
})
# Bad: Vague and ambiguous
get_model("expense.categ").create({
"name": "Other"
})
2. Maintain Consistent Naming Conventions¶
- Use Title Case for category names
- Keep names concise but descriptive
- Add detailed descriptions for clarity
3. Check for Existing Categories Before Creating¶
# Check if category exists before creating
name = "Travel"
existing = get_model("expense.categ").search([["name", "=", name]])
if not existing:
get_model("expense.categ").create({"name": name})
Troubleshooting¶
"Category name is required"¶
Cause: Attempting to create a category without a name
Solution: Always provide the name field when creating a category
"Cannot delete category with linked expenses"¶
Cause: Trying to delete a category that has expenses referencing it Solution: Either reassign expenses to another category or delete the expenses first
"Duplicate category name"¶
Cause: Creating a category with a name that already exists (if custom validation added) Solution: Use a unique name or update the existing category
Testing Examples¶
Unit Test: Create and Retrieve Category¶
def test_create_expense_category():
# Create category
categ_id = get_model("expense.categ").create({
"name": "Test Category",
"description": "Category for testing"
})
# Verify creation
assert categ_id is not None
# Retrieve and verify
categ = get_model("expense.categ").browse([categ_id])[0]
assert categ.name == "Test Category"
assert categ.description == "Category for testing"
# Cleanup
get_model("expense.categ").delete([categ_id])
Security Considerations¶
Permission Model¶
- Read access typically granted to all users who can create expenses
- Write/Delete access typically restricted to accounting or admin users
Data Access¶
- Categories are shared across the system (no multi-company restriction)
- Changes to categories affect all users
Version History¶
Last Updated: December 2024 Model Version: expense_categ.py Framework: Netforce
Additional Resources¶
- Expense Documentation:
expense - Expense Claim Documentation:
expense.claim - Account Expense Documentation:
account.expense
This documentation is generated for developer onboarding and reference purposes.