Odoo Development

🇹🇭 ภาษาไทย

คู่มือสำหรับ developer ที่ต้องการพัฒนา module บน Odoo หรือ integrate ระบบผ่าน API — ครอบคลุมตั้งแต่ installation, สถาปัตยกรรมเทคนิค, การสร้าง custom module จนถึง deployment บน production

โครงสร้างเทคนิค (Tech Stack)

Layerเทคโนโลยี
BackendPython, PostgreSQL, XML
FrontendQWeb (HTML/XML template engine), JavaScript
ORMObject-Relational Mapping — จัดการ database ผ่าน Python class
FrameworkOdoo Framework (models, views, controllers)

Odoo Editions

Editionลักษณะ
CommunityFree, open-source
EnterprisePaid, มี features เพิ่มเติม + support

ติดตั้ง Odoo บน Ubuntu (7 ขั้นตอน)

Step 1 — System Update

sudo apt update && sudo apt upgrade -y

Step 2 — Install Required Packages

sudo apt install git python3-pip build-essential wget python3-dev python3-venv \
python3-wheel libxslt-dev libzip-dev libldap2-dev libsasl2-dev python3-setuptools \
node-less libjpeg-dev libpq-dev gcc g++ -y

Step 3 — PostgreSQL

sudo apt install postgresql -y
sudo -u postgres createuser --createdb --username postgres --no-createrole --no-superuser odoo15

Step 4 — Wkhtmltopdf (สำหรับ PDF reports)

sudo apt install xfonts-75dpi xfonts-base -y
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.bionic_amd64.deb
sudo apt install ./wkhtmltox_0.12.6-1.bionic_amd64.deb

Step 5 — Download Odoo Source

git clone https://github.com/odoo/odoo --depth 1 --branch 15.0 --single-branch odoo15
cd odoo15

Step 6 — Python Virtual Environment

python3 -m venv odoo-venv
source odoo-venv/bin/activate
pip3 install wheel
pip3 install -r requirements.txt

Step 7 — Run Odoo Server

./odoo-bin -d odoo15 -i base --addons-path=addons --db-filter=odoo15

Odoo Module Development

โครงสร้าง Module

ไฟล์ / โฟลเดอร์หน้าที่
__manifest__.pymodule metadata
models/Python models (database tables)
views/XML views (form, tree, kanban)
security/ir.model.access.csvaccess control rules
data/XML data files (default data, cron jobs)

1. Model (Python)

from odoo import models, fields
 
class Student(models.Model):
    _name = 'student.student'
    _description = 'Student'
 
    name  = fields.Char(string='Student Name', required=True)
    age   = fields.Integer(string='Age')
    class_id = fields.Many2one('student.class', string='Class')  # Many2one

Field Types หลัก: Char, Integer, Float, Boolean, Date, Datetime, Many2one, One2many, Many2many

2. View (XML)

Form View:

<record id="view_student_form" model="ir.ui.view">
  <field name="name">student.form</field>
  <field name="model">student.student</field>
  <field name="arch" type="xml">
    <form string="Student">
      <sheet><group>
        <field name="name"/>
        <field name="age"/>
      </group></sheet>
    </form>
  </field>
</record>

Tree (List) View:

<record id="view_student_tree" model="ir.ui.view">
  <field name="arch" type="xml">
    <tree string="Students">
      <field name="name"/><field name="age"/>
    </tree>
  </field>
</record>

3. Menu Items (XML)

<menuitem id="menu_student_root" name="Student Management"/>
<menuitem id="menu_student" name="Students"
          parent="menu_student_root" action="action_student"/>

4. Security — ir.model.access.csv

id,name,model_id :id,group_id :id,perm_read,perm_write,perm_create,perm_unlink
access_student,access.student,model_student_student,base.group_user,1,1,1,1
คอลัมน์ความหมาย
model_id :idmodel ที่ rule นี้ใช้กับ
group_id :iduser group (เช่น base.group_user = Employees)
perm_read/write/create/unlink1=อนุญาต, 0=ไม่อนุญาต

Advanced Development

Relationships

ประเภทความหมายตัวอย่าง
Many2onerecord นี้ → 1 record อื่นStudent → Class
One2many1 record → หลาย recordClass → Students
Many2manyหลาย → หลายStudent ↔ Subjects

Computed Fields

from odoo import api
 
average_grade = fields.Float(compute='_compute_average_grade', store=True)
 
@api.depends('subject_ids.grade')
def _compute_average_grade(self):
    for record in self:
        grades = [s.grade for s in record.subject_ids]
        record.average_grade = sum(grades) / len(grades) if grades else 0
  • store=True → บันทึกลง DB (searchable/sortable)
  • store=False (default) → คำนวณตอน display เท่านั้น

Scheduled Actions (ir.cron)

Python method:

def send_daily_student_report(self):
    students = self.search([])
    for student in students:
        _logger.info(f'Student: {student.name}')

XML config:

<record id="ir_cron_student_report" model="ir.cron">
  <field name="name">Daily Student Report</field>
  <field name="model_id" ref="model_student_student"/>
  <field name="state">code</field>
  <field name="code">model.send_daily_student_report()</field>
  <field name="interval_number">1</field>
  <field name="interval_type">days</field>
  <field name="numbercall">-1</field>  <!-- -1 = unlimited -->
  <field name="active">True</field>
</record>

จัดการผ่าน UI: Settings → Technical → Automation → Scheduled Actions


API Integration

XML-RPC (Python)

import xmlrpc.client
 
url = 'http://localhost:8069'
db = 'odoo15'
uid = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common') \
         .authenticate(db, 'admin', 'admin', {})
 
models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object')
 
# Create a record
models.execute_kw(db, uid, 'admin', 'student.student', 'create',
                  [{'name': 'Ali', 'age': 18}])

REST API (http.Controller)

from odoo import http
from odoo.http import request
 
class StudentAPI(http.Controller):
    @http.route('/api/students', auth='public', type='json', methods=['GET'])
    def get_students(self):
        students = request.env['student.student'].sudo().search([])
        return [{'id': s.id, 'name': s.name, 'age': s.age} for s in students]

Mobile (React Native / Flutter)

// React Native + Axios
axios.get('http://localhost:8069/api/students')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

Deployment & Security

งานวิธี
Reverse ProxyNginx
SSLLet’s Encrypt (Certbot)
Database Backupodoo-bin backup + cron
Password PolicySet strong admin password + restrict portal


🇬🇧 English

Developer guide for building Odoo custom modules and integrating via API — covers installation, architecture, module development pattern, and production deployment.

Tech Stack

LayerTechnology
BackendPython, PostgreSQL, XML
FrontendQWeb (HTML/XML template engine), JavaScript
ORMObject-Relational Mapping — database management via Python classes

Ubuntu Installation (7 Steps)

  1. System update (apt update && upgrade)
  2. Required packages (git, python3-dev, libldap2-dev, node-less, etc.)
  3. PostgreSQL — create DB user for Odoo
  4. Wkhtmltopdf — PDF report generation
  5. Clone Odoo source from GitHub
  6. Python virtual environment + pip install -r requirements.txt
  7. Run: ./odoo-bin -d <db> -i base --addons-path=addons

Module Development Pattern

4-file minimum for a working module:

FilePurpose
models/model.pyPython class → database table
views/view.xmlXML form/tree views
security/ir.model.access.csvCRUD permission rules per group
__manifest__.pyModule metadata

Key Concepts

Relationships:

  • Many2one — many records → one parent (FK)
  • One2many — inverse of Many2one
  • Many2many — many-to-many junction table

Computed Fields: @api.depends('field') decorator; store=True persists to DB

Scheduled Actions: ir.cron records; configure via Settings → Technical → Automation → Scheduled Actions; numbercall=-1 for unlimited runs

API Access

MethodEndpointUse Case
XML-RPC/xmlrpc/2/common + /xmlrpc/2/objectServer-to-server integration
REST APICustom @http.route controllersMobile apps, third-party
MobileAxios/Fetch via REST endpointsReact Native / Flutter

Deployment

  • Nginx reverse proxy in front of Odoo
  • Let’s Encrypt for SSL/TLS
  • Database backups via odoo-bin backup command
  • Production: disable --dev mode, set db_password, restrict admin access