Salary Structure & Rules in Odoo 18
By Braincuber Team
Published on January 5, 2026
HR departments struggle with payroll complexity: manufacturing workers earn hourly rates with overtime multipliers, sales team receives base salary plus commission, senior managers have fixed monthly compensation with housing allowances—each requiring different calculation logic. Without structured rules, payroll becomes a spreadsheet nightmare of manual formulas, cross-references, and calculation errors that frustrate employees and create compliance risks with each pay cycle.
Odoo 18 Payroll module provides Salary Structures and Salary Rules that systematically define how compensation is calculated for each employee category. Create structure types for hourly vs salaried workers, build salary structures containing rule hierarchies, configure individual rules with conditions and Python formulas for basic pay, allowances, deductions, and net calculations—then assign structures to contracts. The system automatically applies the correct rules when generating payslips, eliminating manual calculation while ensuring consistency, accuracy, and compliance across your entire workforce.
Core Benefit: Structure Type defines the category (hourly/monthly) → Salary Structure groups related rules → Salary Rules contain calculation logic → Contract links employee to structure → Payslip applies all rules automatically. Configure once, calculate correctly forever.
Understanding the Payroll Hierarchy
Salary Structure Type
Top-level classification defining wage type (hourly or monthly), payment schedule (weekly, monthly, bi-weekly), and default working hours. Examples: "Regular Employee", "Hourly Worker", "Trainee".
Salary Structure
Container grouping related salary rules for specific employee types. Links to structure type and contains all rules for calculating payslip components. Examples: "Sales Compensation", "Manufacturing Pay".
Salary Rules
Individual calculation formulas for each payslip line item. Define category (basic, allowance, deduction), conditions, computation method (fixed, percentage, Python), and accounting entries.
Rule Parameters
Configurable values referenced by rules for dynamic calculations. Define tax rates, allowance amounts, contribution percentages as parameters that rules reference—update once, apply everywhere.
Configuring Salary Structure Types
Salary Structure Types define the foundation for employee compensation categories. Navigate to Payroll → Configuration → Salary Structure Types to create or manage types.
Create New Structure Type
Click New to create a structure type with these key fields:
- Structure Type Name: Descriptive identifier (e.g., "Regular Salaried Employee")
- Country: Jurisdiction for tax and compliance rules
- Wage Type: Monthly Fixed Wage or Hourly Wage
- Default Scheduled Pay: Monthly, Weekly, Bi-weekly, Bi-monthly, Quarterly, Annually
- Default Working Hours: Standard schedule (e.g., "40 Hours/Week")
- Default Work Entry Type: How attendance is categorized
Structure Type Examples:
STRUCTURE TYPE 1: Regular Salaried Employee ═══════════════════════════════════════════════════════════ Name: Regular Salaried Employee Country: United States Wage Type: Monthly Fixed Wage Default Scheduled Pay: Monthly Default Working Hours: Standard 40 hours/week Work Entry Type: Attendance Use Case: Full-time office employees, managers, administrative staff Linked Structures: Office Worker, Management, Executive STRUCTURE TYPE 2: Hourly Worker ═══════════════════════════════════════════════════════════ Name: Hourly Production Worker Country: United States Wage Type: Hourly Wage Default Scheduled Pay: Weekly Default Working Hours: Flexible (varies) Work Entry Type: Attendance Use Case: Manufacturing floor workers, warehouse staff, contractors Linked Structures: Production Worker, Warehouse Staff STRUCTURE TYPE 3: Trainee/Intern ═══════════════════════════════════════════════════════════ Name: Trainee Program Country: United States Wage Type: Monthly Fixed Wage Default Scheduled Pay: Monthly Default Working Hours: Standard 40 hours/week Work Entry Type: Attendance Use Case: Interns, trainees, apprentices Linked Structures: Intern Compensation STRUCTURE TYPE 4: Commission-Based ═══════════════════════════════════════════════════════════ Name: Sales Commission Structure Country: United States Wage Type: Monthly Fixed Wage Default Scheduled Pay: Monthly Default Working Hours: Standard 40 hours/week Work Entry Type: Attendance Use Case: Sales representatives, account executives Linked Structures: Sales Rep Compensation, Account Executive Pay
Creating Salary Structures
Salary Structures group salary rules together for specific employee categories. Navigate to Payroll → Configuration → Structures to create structures.
Create New Salary Structure
Click New and configure these fields:
- Structure Name: Descriptive name (e.g., "Manufacturing Worker Pay Structure")
- Structure Type: Link to appropriate structure type
- Country: Jurisdiction for compliance
- Scheduled Pay: Payment frequency (inherits from type or override)
- Payslip Report: Template for printed payslips
- Salary Journal: Accounting journal for payroll entries
Add Salary Rules
Under Salary Rules tab, add rules for this structure:
- Click Add a line to include existing rules
- Or create new rules directly from the structure
- Rules are executed in sequence order during payslip computation
- Each rule calculates one payslip line item
Configure Unpaid Work Entry Types
Link work entry types that should reduce pay:
- Unpaid Leave: Days without pay deducted from salary
- Absence: Unauthorized absences with deductions
- System automatically applies deductions based on these entries
Complete Salary Structure Example:
SALARY STRUCTURE: Manufacturing Worker Pay ═══════════════════════════════════════════════════════════ General Information ─────────────────────────────────────────────────────────── Name: Manufacturing Worker Pay Structure Structure Type: Hourly Production Worker Country: United States Scheduled Pay: Weekly Salary Journal: Payroll Journal (PAY) Salary Rules (Executed in Sequence Order) ─────────────────────────────────────────────────────────── Seq | Code | Rule Name | Category | Computation 1 | BASIC | Basic Hourly Wage | Basic | Hours × Hourly Rate 2 | OT | Overtime Pay (1.5x) | Allowance | OT Hours × Rate × 1.5 3 | SHIFT | Shift Differential | Allowance | Night Hours × $2.50 4 | TRANS | Transport Allowance | Allowance | Fixed $150/week 5 | MEAL | Meal Allowance | Allowance | Working Days × $12 100 | GROSS | Gross Salary | Gross | Sum of BASIC + ALW 110 | TAX | Federal Income Tax | Deduction | GROSS × Tax Rate 111 | SS | Social Security | Deduction | GROSS × 6.2% 112 | MED | Medicare | Deduction | GROSS × 1.45% 115 | UNPD | Unpaid Absence Deduct | Deduction | Unpaid Hours × Rate 200 | NET | Net Salary | Net | GROSS - Deductions Unpaid Work Entry Types ─────────────────────────────────────────────────────────── • Unpaid Leave (LEAVE200) • Unauthorized Absence (ABS100) Associated Employee Contracts ─────────────────────────────────────────────────────────── • Marcus Thompson (Warehouse Technician) • Jennifer Lopez (Production Line Operator) • David Chen (Quality Inspector)
Configuring Salary Rules
Salary Rules define the actual calculation logic for each payslip component. Navigate to Payroll → Configuration → Salary Rules to create and manage rules.
General Rule Information
Configure basic rule properties:
- Name: Displayed on payslip (e.g., "Basic Hourly Wage")
- Code: Unique identifier for referencing in formulas (e.g., "BASIC")
- Sequence: Execution order (lower numbers run first)
- Category: Classification - Basic, Allowance (ALW), Deduction (DED), Gross, Net
- Salary Structure: Which structure(s) this rule belongs to
Define Conditions
Set when the rule applies:
- Always True: Rule always executes for this structure
- Range: Rule applies when base amount falls within specified range
- Python Expression: Custom condition code (e.g.,
worked_days.OVERTIME.number_of_hours > 0) - Condition determines whether the rule calculates a value or produces zero
Configure Computation
Define how the amount is calculated:
- Amount Type - Fixed: Constant value (e.g., $500 transport allowance)
- Amount Type - Percentage: Percentage of base (e.g., 10% of GROSS)
- Amount Type - Python Code: Custom formula using Python expression
- Quantity: Multiplier for the amount (usually 1.0 or calculated)
- Percentage Based On: For percentage type, which category to base on
Accounting Configuration
Link to accounting entries:
- Debit Account: Account debited (usually expense accounts)
- Credit Account: Account credited (usually liability/payable)
- Analytic Account: For cost center tracking
- These create automatic journal entries when payslip is validated
Complete Salary Rule Examples:
SALARY RULE 1: Basic Hourly Wage
═══════════════════════════════════════════════════════════
General
Name: Basic Hourly Wage
Code: BASIC
Sequence: 1
Category: Basic
Structure: Manufacturing Worker Pay Structure
Conditions
Condition Type: Always True
Computation
Amount Type: Python Code
Python Code:
result = worked_days.WORK100.number_of_hours * contract.hourly_wage
Accounting
Debit Account: 621000 - Salary Expense
Credit Account: 230000 - Salaries Payable
───────────────────────────────────────────────────────────
SALARY RULE 2: Overtime Pay (1.5x)
═══════════════════════════════════════════════════════════
General
Name: Overtime Pay
Code: OT
Sequence: 2
Category: Allowance (ALW)
Structure: Manufacturing Worker Pay Structure
Conditions
Condition Type: Python Expression
Python Code:
result = worked_days.OVERTIME.number_of_hours > 0
Computation
Amount Type: Python Code
Python Code:
result = worked_days.OVERTIME.number_of_hours * contract.hourly_wage * 1.5
Accounting
Debit Account: 621100 - Overtime Expense
Credit Account: 230000 - Salaries Payable
───────────────────────────────────────────────────────────
SALARY RULE 3: Transport Allowance (Fixed)
═══════════════════════════════════════════════════════════
General
Name: Transport Allowance
Code: TRANS
Sequence: 4
Category: Allowance (ALW)
Structure: Manufacturing Worker Pay Structure
Conditions
Condition Type: Always True
Computation
Amount Type: Fixed Amount
Fixed Amount: 150.00
Quantity: 1.0
Accounting
Debit Account: 621200 - Employee Benefits
Credit Account: 230000 - Salaries Payable
───────────────────────────────────────────────────────────
SALARY RULE 4: Federal Income Tax
═══════════════════════════════════════════════════════════
General
Name: Federal Income Tax
Code: TAX
Sequence: 110
Category: Deduction (DED)
Structure: Manufacturing Worker Pay Structure
Conditions
Condition Type: Always True
Computation
Amount Type: Python Code
Python Code:
# Progressive tax calculation
gross = categories.GROSS
if gross <= 1000:
result = gross * 0.10
elif gross <= 3000:
result = 100 + (gross - 1000) * 0.15
else:
result = 400 + (gross - 3000) * 0.22
Accounting
Debit Account: (None - withheld from employee)
Credit Account: 231000 - Tax Withholding Payable
───────────────────────────────────────────────────────────
SALARY RULE 5: Net Salary
═══════════════════════════════════════════════════════════
General
Name: Net Salary
Code: NET
Sequence: 200
Category: Net
Structure: Manufacturing Worker Pay Structure
Conditions
Condition Type: Always True
Computation
Amount Type: Python Code
Python Code:
result = categories.GROSS - categories.DED
Accounting
Debit Account: 230000 - Salaries Payable
Credit Account: 110000 - Bank Account
Python Formula Reference
Salary rules support Python expressions for complex calculations. Here are the key objects and properties available in rule formulas.
# ═══════════════════════════════════════════════════════════
# CONTRACT DATA (from employee's current contract)
# ═══════════════════════════════════════════════════════════
contract.wage # Monthly fixed wage
contract.hourly_wage # Hourly rate (for hourly employees)
contract.hours_per_day # Standard daily hours (e.g., 8)
contract.hours_per_week # Standard weekly hours (e.g., 40)
contract.date_start # Contract start date
contract.date_end # Contract end date (if applicable)
# ═══════════════════════════════════════════════════════════
# WORKED DAYS DATA (from work entries for the period)
# ═══════════════════════════════════════════════════════════
worked_days.WORK100.number_of_hours # Regular attendance hours
worked_days.WORK100.number_of_days # Regular attendance days
worked_days.OVERTIME.number_of_hours # Overtime hours
worked_days.LEAVE110.number_of_hours # Paid Time Off hours
worked_days.LEAVE200.number_of_hours # Unpaid leave hours
worked_days.SICK.number_of_hours # Sick leave hours
# ═══════════════════════════════════════════════════════════
# CATEGORY TOTALS (sum of rules in each category)
# ═══════════════════════════════════════════════════════════
categories.BASIC # Total of all Basic category rules
categories.ALW # Total of all Allowance rules
categories.DED # Total of all Deduction rules
categories.GROSS # Gross salary (usually BASIC + ALW)
categories.NET # Net salary (usually GROSS - DED)
# ═══════════════════════════════════════════════════════════
# RULE RESULTS (reference other rules by code)
# ═══════════════════════════════════════════════════════════
rules.BASIC # Result of rule with code 'BASIC'
rules.OT # Result of rule with code 'OT'
# ═══════════════════════════════════════════════════════════
# EMPLOYEE DATA
# ═══════════════════════════════════════════════════════════
employee.name # Employee's full name
employee.department_id # Department (for conditional rules)
employee.job_id # Job position
# ═══════════════════════════════════════════════════════════
# COMMON FORMULA PATTERNS
# ═══════════════════════════════════════════════════════════
# Basic hourly calculation
result = worked_days.WORK100.number_of_hours * contract.hourly_wage
# Overtime at 1.5x multiplier
result = worked_days.OVERTIME.number_of_hours * contract.hourly_wage * 1.5
# Percentage of gross (e.g., 6.2% social security)
result = categories.GROSS * 0.062
# Fixed amount with proration for partial month
standard_days = 22
actual_days = worked_days.WORK100.number_of_days
result = 500 * (actual_days / standard_days)
# Conditional allowance based on department
if employee.department_id.name == 'Sales':
result = categories.BASIC * 0.10 # 10% commission base
else:
result = 0
# Progressive tax brackets
gross = categories.GROSS
if gross <= 2000:
result = gross * 0.10
elif gross <= 5000:
result = 200 + (gross - 2000) * 0.15
elif gross <= 10000:
result = 650 + (gross - 5000) * 0.20
else:
result = 1650 + (gross - 10000) * 0.25
# Net salary calculation
result = categories.GROSS - categories.DED
Configuring Rule Parameters
Rule Parameters store configurable values that salary rules can reference. This allows updating rates (tax percentages, allowance amounts) without modifying rule formulas. Navigate to Payroll → Configuration → Rule Parameters.
RULE PARAMETERS CONFIGURATION
═══════════════════════════════════════════════════════════
Parameter: Federal Tax Rate Bracket 1
Code: TAX_RATE_1
Value: 0.10
Description: Tax rate for income $0 - $2,000
Parameter: Federal Tax Rate Bracket 2
Code: TAX_RATE_2
Value: 0.15
Description: Tax rate for income $2,001 - $5,000
Parameter: Federal Tax Bracket 1 Threshold
Code: TAX_THRESH_1
Value: 2000
Description: Upper limit for first tax bracket
Parameter: Social Security Rate
Code: SS_RATE
Value: 0.062
Description: Employee Social Security contribution rate
Parameter: Medicare Rate
Code: MED_RATE
Value: 0.0145
Description: Employee Medicare contribution rate
Parameter: Transport Allowance Amount
Code: TRANS_AMT
Value: 150
Description: Weekly transport allowance
Parameter: Meal Allowance Per Day
Code: MEAL_DAY
Value: 12
Description: Daily meal allowance amount
═══════════════════════════════════════════════════════════
USING PARAMETERS IN SALARY RULES
═══════════════════════════════════════════════════════════
# Reference parameter in Python code
result = categories.GROSS * payslip.rule_parameter('SS_RATE')
# Or for fixed values
result = payslip.rule_parameter('TRANS_AMT')
# Complex example using multiple parameters
gross = categories.GROSS
thresh1 = payslip.rule_parameter('TAX_THRESH_1')
rate1 = payslip.rule_parameter('TAX_RATE_1')
rate2 = payslip.rule_parameter('TAX_RATE_2')
if gross <= thresh1:
result = gross * rate1
else:
result = (thresh1 * rate1) + ((gross - thresh1) * rate2)
Configuring Other Input Types
Other Input Types define additional inputs that can be added to individual payslips for one-time or variable payments. These appear in the "Other Inputs" tab when generating payslips. Navigate to Payroll → Configuration → Other Input Types.
OTHER INPUT TYPES ═══════════════════════════════════════════════════════════ Input Type: Performance Bonus Code: BONUS_PERF Description: Quarterly performance bonus payment Availability: All Structures Input Type: Referral Bonus Code: BONUS_REF Description: Employee referral bonus ($500 per successful hire) Availability: All Structures Input Type: Commission Payment Code: COMMISSION Description: Sales commission for the period Availability: Sales Commission Structure Input Type: Expense Reimbursement Code: EXPENSE_REIMB Description: Approved expense reimbursements Availability: All Structures Input Type: Loan Deduction Code: LOAN_DED Description: Monthly loan repayment deduction Availability: All Structures Input Type: Salary Advance Recovery Code: ADV_RECOVERY Description: Recovery of previous salary advance Availability: All Structures ═══════════════════════════════════════════════════════════ USING OTHER INPUTS IN PAYSLIPS ═══════════════════════════════════════════════════════════ When generating a payslip: 1. Go to "Other Inputs" tab 2. Click "Add a line" 3. Select Input Type (e.g., "Performance Bonus") 4. Enter Amount (e.g., $1,500) 5. Compute Sheet to include in calculation The input is added to the payslip line items based on its category. ═══════════════════════════════════════════════════════════ REFERENCING OTHER INPUTS IN SALARY RULES ═══════════════════════════════════════════════════════════ # Rule to include commission from Other Inputs # Condition: Check if commission input exists # Python Condition: result = inputs.COMMISSION.amount > 0 if 'COMMISSION' in inputs else False # Python Computation: result = inputs.COMMISSION.amount if 'COMMISSION' in inputs else 0
Complete Salary Structure Setup Example
Here's a complete example showing how structure type, structure, and rules work together for a real payroll scenario.
═══════════════════════════════════════════════════════════
STEP 1: CREATE STRUCTURE TYPE
═══════════════════════════════════════════════════════════
Name: Sales Employee
Country: United States
Wage Type: Monthly Fixed Wage
Default Scheduled Pay: Monthly
Default Working Hours: Standard 40 hours/week
═══════════════════════════════════════════════════════════
STEP 2: CREATE SALARY STRUCTURE
═══════════════════════════════════════════════════════════
Name: Sales Representative Compensation
Structure Type: Sales Employee
Country: United States
Scheduled Pay: Monthly
Salary Journal: Payroll Journal
═══════════════════════════════════════════════════════════
STEP 3: CREATE SALARY RULES (Add to Structure)
═══════════════════════════════════════════════════════════
SEQ CODE NAME CATEGORY FORMULA
─── ──── ────────────────────── ───────── ───────────────────────
1 BASIC Base Salary Basic contract.wage
2 COMM Sales Commission Allowance inputs.COMMISSION.amount
(from Other Inputs)
3 QUOTA Quota Achievement Bonus Allowance If commission > target:
contract.wage * 0.05
4 TRANS Transport Allowance Allowance Fixed $400
5 PHONE Phone Allowance Allowance Fixed $75
6 FUEL Fuel Reimbursement Allowance inputs.FUEL_REIMB.amount
100 GROSS Gross Salary Gross BASIC + ALW
110 TAX Federal Tax Deduction Progressive brackets
111 SS Social Security Deduction GROSS × 6.2%
112 MED Medicare Deduction GROSS × 1.45%
115 401K 401k Contribution Deduction GROSS × 5%
200 NET Net Salary Net GROSS - DED
═══════════════════════════════════════════════════════════
STEP 4: CREATE EMPLOYEE CONTRACT
═══════════════════════════════════════════════════════════
Employee: Sarah Johnson
Position: Senior Sales Representative
Department: Sales
Contract Start: January 1, 2026
Salary Structure: Sales Representative Compensation
Monthly Wage: $5,500
═══════════════════════════════════════════════════════════
STEP 5: GENERATE MONTHLY PAYSLIP (January 2026)
═══════════════════════════════════════════════════════════
Other Inputs Added:
• COMMISSION: $2,800 (January sales commission)
• FUEL_REIMB: $125 (mileage reimbursement)
Computed Payslip Lines:
───────────────────────────────────────────────────────────
Base Salary (BASIC): $5,500.00
Sales Commission (COMM): $2,800.00
Quota Achievement Bonus (QUOTA): $275.00
(Commission $2,800 > target $2,000 = bonus)
Transport Allowance (TRANS): $400.00
Phone Allowance (PHONE): $75.00
Fuel Reimbursement (FUEL): $125.00
───────────────────────────────────────────────────────────
GROSS SALARY: $9,175.00
───────────────────────────────────────────────────────────
Federal Tax (TAX): -$1,293.75
Social Security (SS): -$568.85
Medicare (MED): -$133.04
401k Contribution (401K): -$458.75
───────────────────────────────────────────────────────────
TOTAL DEDUCTIONS: -$2,454.39
───────────────────────────────────────────────────────────
NET SALARY: $6,720.61
═══════════════════════════════════════════════════════════
Best Practices
✅ Follow These Guidelines:
- Use meaningful codes: Rule codes like BASIC, OT, TAX are referenced in formulas—make them short, clear, and consistent across structures
- Sequence rules carefully: BASIC (1-10) → Allowances (11-50) → GROSS (100) → Deductions (110-150) → NET (200)—wrong sequences cause calculation errors
- Use Rule Parameters: Store tax rates, allowance amounts as parameters—update once when rates change instead of editing multiple rules
- Test with sample payslips: Before applying structures to all employees, generate test payslips to verify calculations match expected results
- Document complex formulas: Add comments in Python code explaining business logic for future maintenance
- Create separate structures: Different employee types (hourly, salaried, commission) should have separate structures rather than complex conditional rules
- Link accounting properly: Configure debit/credit accounts on rules to ensure automatic journal entries are correct
- Review before validation: Always review computed payslips before validating—validated payslips create accounting entries and are difficult to modify
Common Mistakes to Avoid
🚨 Mistake #1: GROSS Rule Running Before Allowances
GROSS rule has sequence 50, but allowance rules have sequence 60-80 = GROSS doesn't include allowances. Solution: Set GROSS sequence to 100+ (after all contributing rules).
🚨 Mistake #2: Circular Rule References
Rule A references Rule B, and Rule B references Rule A = infinite loop error. Solution: Design rule dependencies as a one-way hierarchy—never mutual references.
🚨 Mistake #3: Missing Work Entry Types
Rule references worked_days.OVERTIME but OVERTIME work entry type doesn't exist = formula returns zero or error. Solution: Create all required work entry types before configuring rules.
🚨 Mistake #4: Hardcoded Values Instead of Parameters
Tax rate embedded directly in rule formula (0.15) = must edit every rule when rate changes. Solution: Use Rule Parameters for all rates and thresholds.
Conclusion
Configuring Salary Structures and Salary Rules in Odoo 18 establishes the foundation for accurate, automated payroll processing. Create Structure Types to classify employees (hourly, salaried, commission), build Salary Structures grouping related rules for each employee category, configure individual Salary Rules with conditions and Python formulas for every payslip component, use Rule Parameters for configurable values like tax rates and allowance amounts, and define Other Input Types for variable payments like bonuses and commissions. Link structures to employee contracts, and the system automatically applies correct calculations when generating payslips—eliminating manual formulas, ensuring consistency across your workforce, enabling easy updates when rates change, and providing complete audit trails of all payroll computations.
🎯 Key Takeaway: Structure Type → Structure → Rules → Contract → Payslip. This hierarchy ensures every employee gets the right calculation logic applied automatically. Configure the structure once, use it for all matching employees, update parameters when rates change—no more spreadsheet payroll nightmares.
