Skip to content

Development Workflow Guide

Complete guide for developing, testing, and deploying changes to the Odoo 15 system.

Repository Setup

Single Company Setup

# You already have this - just use it directly
cd /path/to/odoo15-production
git remote -v  # Check your remote

Multi-Company / SaaS Setup

# Create a template repo, then clone for each client
git clone git@github.com:yourorg/odoo15-production.git client-abc
cd client-abc
# Customize .env for this client

Git Branching Strategy

main (production)
  ├── develop (staging/test)
  │     │
  │     ├── feature/new-sms-template
  │     ├── feature/inventory-report
  │     └── bugfix/signature-upload
  └── hotfix/critical-fix (emergency only)

Branch Types

Branch Purpose Merges To
main Production code -
develop Integration testing main
feature/* New features develop
bugfix/* Bug fixes develop
hotfix/* Emergency production fixes main and develop

Daily Workflow

Starting New Work

# 1. Always start from develop
git checkout develop
git pull origin develop

# 2. Create feature branch
git checkout -b feature/add-customer-field

# 3. Make your changes
# ... edit files ...

# 4. Test locally
docker compose restart odoo
# Test in browser at localhost:8016

# 5. Commit changes
git add .
git commit -m "feat(signature): Add customer phone field to FSM order"

# 6. Push branch
git push origin feature/add-customer-field

Merging Changes

# Option A: Pull Request (recommended for teams)
# Create PR on GitHub, get review, merge via web UI

# Option B: Local merge (solo developer)
git checkout develop
git merge feature/add-customer-field
git push origin develop

# When ready for production
git checkout main
git merge develop
git push origin main

Module Development

Creating a New Module

# 1. Create module structure
mkdir -p extra-addons/odoo/my_new_module/{models,views,security}

# 2. Create manifest
cat > extra-addons/odoo/my_new_module/__manifest__.py << 'EOF'
{
    'name': 'My New Module',
    'version': '15.0.1.0.0',
    'category': 'Sales',
    'summary': 'Description here',
    'description': """
My New Module
=============
Detailed description of what this module does.
    """,
    'author': 'Your Company',
    'depends': ['base', 'sale'],
    'data': [
        'security/ir.model.access.csv',
        'views/my_views.xml',
    ],
    'installable': True,
    'auto_install': False,
    'license': 'LGPL-3',
}
EOF

# 3. Create __init__.py files
echo "from . import models" > extra-addons/odoo/my_new_module/__init__.py
echo "from . import my_model" > extra-addons/odoo/my_new_module/models/__init__.py

# 4. Create model
cat > extra-addons/odoo/my_new_module/models/my_model.py << 'EOF'
from odoo import models, fields, api

class MyModel(models.Model):
    _name = 'my.model'
    _description = 'My Model'

    name = fields.Char('Name', required=True)
    description = fields.Text('Description')
EOF

# 5. Create security file
cat > extra-addons/odoo/my_new_module/security/ir.model.access.csv << 'EOF'
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_my_model,my.model,model_my_model,base.group_user,1,1,1,1
EOF

# 6. Restart Odoo to detect new module
docker compose restart odoo

# 7. Install module
docker compose exec odoo odoo -i my_new_module --stop-after-init -d odoo_test

Editing Existing Modules

# 1. Create branch
git checkout -b bugfix/fix-sms-sending

# 2. Edit files
nano extra-addons/odoo/justcall_sms/models/justcall_sms.py

# 3. Bump version in manifest
nano extra-addons/odoo/justcall_sms/__manifest__.py
# Change version: '15.0.2.0.0' -> '15.0.2.0.1'

# 4. Update module in Odoo
docker compose exec odoo odoo -u justcall_sms --stop-after-init -d odoo_test

# 5. Test your changes
docker compose restart odoo

# 6. Commit
git add .
git commit -m "fix(justcall): Fix SMS sending for international numbers"

Module Commands Reference

# Install module
docker compose exec odoo odoo -i MODULE_NAME --stop-after-init -d DATABASE

# Update module
docker compose exec odoo odoo -u MODULE_NAME --stop-after-init -d DATABASE

# Update multiple modules
docker compose exec odoo odoo -u module1,module2,module3 --stop-after-init -d DATABASE

# Update ALL modules (slow, use sparingly)
docker compose exec odoo odoo -u all --stop-after-init -d DATABASE

# Install with dependencies
docker compose exec odoo odoo -i base,sale,MODULE_NAME --stop-after-init -d DATABASE

Documentation Updates

When to Update Docs

Change Type Documentation Action
New module created Create docs/content/modules/new-module.md
New feature added Update relevant module doc
API endpoint added Update docs/content/api/openapi.md
Config option added Update docs/content/getting-started/configuration.md
New script created Update docs/content/operations/

How to Update Documentation

# 1. Edit markdown files
nano docs/content/modules/justcall-sms.md

# 2. If adding new page, update navigation
nano docs/mkdocs.yml
# Add your page to the nav: section

# 3. Rebuild docs container
docker compose build docs

# 4. Restart docs service
docker compose up -d docs

# 5. Verify in browser
# Open http://localhost:8080

# 6. Check for warnings in build output
docker compose logs docs | grep -i warning

# 7. Commit documentation with code
git add docs/
git commit -m "docs(justcall): Add new template configuration section"

Documentation Structure

docs/content/
├── index.md                 # Homepage
├── getting-started/         # Installation & setup
│   ├── installation.md
│   ├── configuration.md
│   └── quickstart.md
├── modules/                 # Module documentation
│   ├── justcall-sms.md
│   ├── service-signature.md
│   └── ...
├── pwa/                     # PWA documentation
├── api/                     # API reference
├── operations/              # DevOps guides
└── development/             # Developer guides (you are here)

Complete Development Cycle Example

Scenario: Add a "Technician Notes" field to FSM orders

# === STEP 1: Create Branch ===
git checkout develop
git pull origin develop
git checkout -b feature/fsm-technician-notes

# === STEP 2: Edit Model ===
nano extra-addons/odoo/jdx_field_service_automation/models/fsm_order.py

Add the field:

technician_notes = fields.Text('Technician Notes', help='Internal notes for technician')

# === STEP 3: Edit View ===
nano extra-addons/odoo/jdx_field_service_automation/views/fsm_order_extended.xml

Add to form view:

<field name="technician_notes" placeholder="Notes for technician..."/>

# === STEP 4: Update Module Version ===
nano extra-addons/odoo/jdx_field_service_automation/__manifest__.py
# Change: 'version': '15.0.0.1',  (increment last number)

# === STEP 5: Update Module in Odoo ===
docker compose exec odoo odoo -u jdx_field_service_automation --stop-after-init -d odoo_test
docker compose restart odoo

# === STEP 6: Test in Browser ===
# Open http://localhost:8016
# Navigate to Field Service > Orders
# Verify new field appears

# === STEP 7: Update Documentation ===
nano docs/content/modules/fsm-extensions.md
# Add section about new field

# === STEP 8: Rebuild Docs ===
docker compose build docs
docker compose up -d docs

# === STEP 9: Commit Everything ===
git add .
git commit -m "feat(fsm): Add technician notes field to FSM orders

- Added technician_notes text field to fsm.order model
- Added field to form view
- Updated documentation"

# === STEP 10: Push & Merge ===
git push origin feature/fsm-technician-notes
git checkout develop
git merge feature/fsm-technician-notes
git push origin develop

Deployment Scripts

Two scripts simplify the deployment process:

Script Location Purpose
local_deploy.sh Your dev machine Commit and push to GitHub
production_deploy.sh Production server Pull, build, update, restart

Quick Usage

# === ON YOUR LOCAL MACHINE ===
./local_deploy.sh "feat(justcall): Add MMS support"

# === ON PRODUCTION SERVER ===
./production_deploy.sh update

Common Commands

# Local deployment
./local_deploy.sh "your commit message"

# Production - quick update (most common)
./production_deploy.sh update

# Production - update specific module
./production_deploy.sh update-module justcall_sms

# Production - rebuild containers
./production_deploy.sh rebuild-all
./production_deploy.sh rebuild-pwa
./production_deploy.sh rebuild-docs

# Production - service management
./production_deploy.sh status
./production_deploy.sh logs odoo
./production_deploy.sh restart

For complete command reference, see Deployment Scripts Reference.

Production Deployment (Manual Method)

If you prefer manual deployment without scripts:

# On production server
ssh user@production-server
cd /opt/odoo15-production

# 1. Backup first!
./scripts/backup.sh full

# 2. Pull latest code
git checkout main
git pull origin main

# 3. Rebuild containers if Dockerfile changed
docker compose build

# 4. Update Odoo modules
docker compose exec odoo odoo -u all --stop-after-init -d odoo_production

# 5. Restart all services
docker compose down
docker compose up -d

# 6. Verify deployment
./scripts/health-check.sh

# 7. Check logs for errors
docker compose logs --tail=50 odoo

Hotfix Deployment (Emergency)

# 1. Create hotfix branch from main
git checkout main
git checkout -b hotfix/critical-fix

# 2. Make fix
# ... edit files ...

# 3. Commit
git commit -m "hotfix: Fix critical issue"

# 4. Merge to main immediately
git checkout main
git merge hotfix/critical-fix
git push origin main

# 5. Deploy to production
# (follow standard deployment steps)

# 6. Also merge to develop
git checkout develop
git merge hotfix/critical-fix
git push origin develop

Quick Reference Commands

Daily Operations

docker compose ps                    # Check container status
docker compose logs -f odoo          # Watch Odoo logs (Ctrl+C to exit)
docker compose logs -f --tail=100    # Last 100 lines, follow
docker compose restart odoo          # Restart Odoo
docker compose restart pwa           # Restart PWA
docker compose up -d                 # Start all services
docker compose down                  # Stop all services

Module Management

# Install module
docker compose exec odoo odoo -i MODULE --stop-after-init -d DATABASE

# Update module
docker compose exec odoo odoo -u MODULE --stop-after-init -d DATABASE

# Update all modules
docker compose exec odoo odoo -u all --stop-after-init -d DATABASE

# List installed modules
docker compose exec db psql -U odoo -d odoo_test -c "SELECT name, state FROM ir_module_module WHERE state='installed' ORDER BY name;"

Backup & Restore

./scripts/backup.sh full             # Full backup (DB + filestore)
./scripts/backup.sh db               # Database only
./scripts/restore.sh backup.sql.gz   # Restore database
./scripts/health-check.sh            # Check all services

Git Commands

git status                           # Check uncommitted changes
git diff                             # See what changed
git log --oneline -10                # Last 10 commits
git branch -a                        # List all branches
git stash                            # Temporarily save changes
git stash pop                        # Restore stashed changes

Documentation

docker compose build docs            # Rebuild docs
docker compose up -d docs            # Restart docs
docker compose logs docs             # Check for build errors

Commit Message Format

Use conventional commits format:

type(scope): description

[optional body]

[optional footer]

Types

Type Description
feat New feature
fix Bug fix
docs Documentation only
style Formatting, no code change
refactor Code restructuring
test Adding tests
chore Maintenance tasks

Examples

feat(justcall): Add MMS support for outgoing messages
fix(signature): Fix S3 upload timeout for large files
docs(api): Update authentication examples
refactor(pwa): Simplify job list rendering

Best Practices Checklist

Practice Description
Never commit to main directly Always use feature branches
Test before merging Run on test environment first
Update docs with code Same commit for code + docs
Bump version numbers Update __manifest__.py version
Write clear commit messages type(scope): description format
Backup before major changes ./scripts/backup.sh full
Check build warnings Review docker compose build output
Review your diff git diff before committing
Keep branches short-lived Merge within 1-2 days
Delete merged branches git branch -d feature/done

Troubleshooting

Module Won't Install

# Check Odoo logs
docker compose logs odoo | tail -50

# Common fixes:
# 1. Missing dependency - install required module first
# 2. Syntax error - check Python files
# 3. XML error - validate XML files

Changes Not Appearing

# 1. Did you update the module?
docker compose exec odoo odoo -u MODULE --stop-after-init -d DATABASE

# 2. Did you restart Odoo?
docker compose restart odoo

# 3. Clear browser cache
# Ctrl+Shift+R or Cmd+Shift+R

Database Connection Error

# Check database is running
docker compose ps db

# Check connection
docker compose exec db pg_isready -U odoo

# View database logs
docker compose logs db