Özel Odoo Modülleri Nasıl Oluşturulur: OWL, ORM ve Kalıtım için Geliştirici Kılavuzu
Odoo'nun 82 resmi modülü ve 40.000'den fazla topluluk modülü tam olarak iş gereksinimlerinizi karşılamadığında, özel modül geliştirme boşluğu doldurur. Bu kılavuz, modül yapısı, OWL ön uç çerçevesi, ORM kalıpları, miras mekanizmaları ve OCA (Odoo Topluluk Birliği) yönergeleriyle uyumlu en iyi uygulamalar dahil olmak üzere 2026'da Odoo modülleri oluşturmanın temellerini kapsar.
Özel Odoo Modülü Nedir?
Özel Odoo modülü, Python arka uç mantığı, XML görünüm tanımları, JavaScript ön uç bileşenleri ve Odoo'nun işlevselliğini genişleten güvenlik kurallarından oluşan bağımsız bir pakettir. Modüller tamamen yeni özellikler ekleyebilir, mevcut davranışı değiştirebilir veya Odoo'yu harici sistemlerle entegre edebilir. Odoo'nun her bir parçası, mimariyi doğası gereği genişletilebilir kılan bir modüldür.
Modül Dizin Yapısı
İyi organize edilmiş bir modül şu standart yapıyı takip eder:
my_custom_module/
├── __init__.py # Python package init
├── __manifest__.py # Module metadata and dependencies
├── models/
│ ├── __init__.py
│ └── my_model.py # Business logic and data models
├── views/
│ ├── my_model_views.xml # Form, tree, and kanban views
│ └── menu.xml # Menu items and actions
├── security/
│ ├── ir.model.access.csv # Access control list
│ └── security.xml # Record rules and groups
├── data/
│ └── data.xml # Default data records
├── static/
│ └── src/
│ ├── js/ # OWL components
│ ├── css/ # Stylesheets
│ └── xml/ # QWeb templates
├── wizard/ # Transient models for wizards
├── reports/ # QWeb report templates
└── tests/ # Unit tests
Manifest Dosyası
__manifest__.py dosyası modülünüzün kimliğini tanımlar:
{
'name': 'My Custom Module',
'version': '18.0.1.0.0',
'category': 'Custom',
'summary': 'Short description of what the module does',
'description': """
Long description with details about
features and configuration.
""",
'author': 'ECOSIRE',
'website': 'https://ecosire.com',
'license': 'LGPL-3',
'depends': ['base', 'sale', 'stock'],
'data': [
'security/ir.model.access.csv',
'views/my_model_views.xml',
'views/menu.xml',
'data/data.xml',
],
'assets': {
'web.assets_backend': [
'my_custom_module/static/src/js/**/*',
'my_custom_module/static/src/css/**/*',
'my_custom_module/static/src/xml/**/*',
],
},
'installable': True,
'application': False,
'auto_install': False,
}
Sürüm kuralı: {odoo_version}.{major}.{minor}.{patch} (ör. 18.0.1.0.0).
ORM ile çalışma
Odoo'nun Nesne-İlişkisel Haritalaması (ORM), tüm arka uç geliştirmelerinin temelidir. Modeller veritabanı tablolarıyla eşleşir ve ORM, CRUD işlemlerini, hesaplanan alanları, kısıtlamaları ve iş akışı yönetimini sağlar.
Model Tanımlama
from odoo import models, fields, api
class ProjectTask(models.Model):
_name = 'my_module.task'
_description = 'Project Task'
_order = 'priority desc, create_date desc'
name = fields.Char(string='Task Name', required=True)
description = fields.Html(string='Description')
state = fields.Selection([
('draft', 'Draft'),
('in_progress', 'In Progress'),
('done', 'Done'),
('cancelled', 'Cancelled'),
], default='draft', tracking=True)
assigned_to = fields.Many2one('res.users', string='Assigned To')
deadline = fields.Date(string='Deadline')
priority = fields.Selection([
('0', 'Normal'),
('1', 'Important'),
('2', 'Urgent'),
], default='0')
tag_ids = fields.Many2many('my_module.tag', string='Tags')
progress = fields.Float(compute='_compute_progress', store=True)
Alan Türleri Referansı
| Alan Türü | Python Türü | Kullanım Örneği | |---|---|---| | Karakter | dizi | Kısa metin (isim, referans) | | Metin | dizi | Uzun düz metin | | HTML | dizi | Zengin metin içeriği | | Tamsayı | int | Tam sayılar | | Şamandıra | şamandıra | Ondalık sayılar | | Boolean | bool | Doğru/Yanlış işaretleri | | Tarih | tarih | Saat olmadan tarih | | Tarihsaat | tarihsaat | Tarih ve saat | | Seçim | dizi | Açılır seçenekler | | Çok2bir | int | Bir kayda bağlantı | | Bir2çok | liste | Many2one'un Tersi | | Çok2çok | liste | Birden çok kayda bağlantı | | İkili | bayt | Dosya ekleri |
Hesaplanan Alanlar ve Kısıtlamalar
@api.depends('subtask_ids.state')
def _compute_progress(self):
for task in self:
total = len(task.subtask_ids)
done = len(task.subtask_ids.filtered(
lambda t: t.state == 'done'
))
task.progress = (done / total * 100) if total else 0
@api.constrains('deadline')
def _check_deadline(self):
for task in self:
if task.deadline and task.deadline < fields.Date.today():
raise ValidationError(
"Deadline cannot be in the past."
)
Kalıtım Mekanizmaları
Odoo, her biri farklı bir amaca hizmet eden üç tür miras sağlar:
1. Sınıf Mirası (Uzantı)
Alanlar ekleyerek veya yöntemleri geçersiz kılarak mevcut bir modeli genişletin. Bu en yaygın kalıptır.
class SaleOrderExtend(models.Model):
_inherit = 'sale.order'
custom_reference = fields.Char(string='Custom Ref')
approved_by = fields.Many2one('res.users')
def action_confirm(self):
# Add custom logic before standard confirmation
for order in self:
if order.amount_total > 10000 and not order.approved_by:
raise UserError("Orders over $10,000 require approval.")
return super().action_confirm()
2. Prototip Mirası
Mevcut bir modelden tüm alanları ve yöntemleri kopyalayan yeni bir model oluşturun.
class CustomPartner(models.Model):
_name = 'my_module.partner'
_inherit = 'res.partner' # Copies structure
_description = 'Custom Partner'
3. Yetki Devri
Many2one bağlantısı aracılığıyla mevcut bir modele yetki veren yeni bir model oluşturun. Ana modelin alanları alt modelde şeffaf bir şekilde görünür.
class LibraryMember(models.Model):
_name = 'library.member'
_inherits = {'res.partner': 'partner_id'}
partner_id = fields.Many2one('res.partner', required=True,
ondelete='cascade')
membership_date = fields.Date()
member_number = fields.Char()
OWL Çerçevesi (Ön Uç)
Odoo 18, ön uç çerçevesi olarak OWL'yi (Odoo Web Kütüphanesi) kullanır. OWL, React veya Vue'ya benzer, ancak Odoo'nun ihtiyaçları için özel olarak tasarlanmış bileşen tabanlı bir çerçevedir.
Temel OWL Bileşeni
/** @odoo-module */
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
class TaskDashboard extends Component {
static template = "my_module.TaskDashboard";
setup() {
this.state = useState({
tasks: [],
filter: 'all',
});
this.loadTasks();
}
async loadTasks() {
this.state.tasks = await this.env.services.orm.searchRead(
"my_module.task",
[["state", "!=", "cancelled"]],
["name", "state", "assigned_to", "deadline"]
);
}
get filteredTasks() {
if (this.state.filter === 'all') return this.state.tasks;
return this.state.tasks.filter(
t => t.state === this.state.filter
);
}
}
QWeb Şablonu (XML)
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="my_module.TaskDashboard">
<div class="o_task_dashboard">
<div class="task-filters">
<button t-on-click="() => state.filter = 'all'">All</button>
<button t-on-click="() => state.filter = 'in_progress'">
In Progress
</button>
</div>
<div class="task-list">
<t t-foreach="filteredTasks" t-as="task" t-key="task.id">
<div class="task-card">
<span t-esc="task.name"/>
</div>
</t>
</div>
</div>
</t>
</templates>
Güvenlik Yapılandırması
Her modelin açık erişim kurallarına ihtiyacı vardır. Bunlar olmadan hiçbir kullanıcı modelin verilerine erişemez.
Erişim Kontrol Listesi (ir.model.access.csv)
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_task_user,task.user,model_my_module_task,base.group_user,1,1,1,0
access_task_manager,task.manager,model_my_module_task,my_module.group_manager,1,1,1,1
Kayıt Kuralları (security.xml)
<record id="task_own_rule" model="ir.rule">
<field name="name">Own Tasks Only</field>
<field name="model_id" ref="model_my_module_task"/>
<field name="domain_force">
[('assigned_to', '=', user.id)]
</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>
Modülünüzü Test Etme
Odoo, Odoo'ya özgü test sınıflarıyla unittest çerçevesini kullanan Python birim testlerini destekler:
from odoo.tests.common import TransactionCase
class TestTask(TransactionCase):
def setUp(self):
super().setUp()
self.task = self.env['my_module.task'].create({
'name': 'Test Task',
'state': 'draft',
})
def test_task_creation(self):
self.assertEqual(self.task.state, 'draft')
self.assertEqual(self.task.progress, 0)
def test_deadline_constraint(self):
with self.assertRaises(ValidationError):
self.task.write({
'deadline': fields.Date.subtract(
fields.Date.today(), days=1
),
})
Testleri şununla çalıştırın: odoo-bin -d test_db --test-enable -i my_custom_module --stop-after-init
Sıkça Sorulan Sorular
S: Özel bir Odoo modülü oluşturmak ne kadar sürer? Basit modüller (yeni alanlar, temel görünümler) 1-3 gün sürer. Orta düzey modüller (yeni modeller, iş akışları, raporlar) 1-3 hafta sürer. Karmaşık modüller (çok modelli sistemler, harici entegrasyonlar, özel OWL bileşenleri) 4-12 hafta sürer. Özel modüllere ihtiyaç duyan ancak şirket içi Odoo geliştiricileri bulunmayan işletmeler için ekibimizden deneyimli bir Odoo geliştiricisini işe alın.
S: Temel Odoo kodunu değiştirmeli miyim yoksa ayrı bir modül oluşturmalı mıyım? Her zaman ayrı bir modül oluşturun. Çekirdek kodu değiştirmek, yükseltilebilirliği bozar ve sürüm güncellemeleri sırasında birleştirme çakışmalarına neden olur. Özel modülünüzdeki mevcut modelleri ve görünümleri genişletmek için devralmayı kullanın.
S: OCA yönergeleri nelerdir? Odoo Topluluk Birliği (OCA), adlandırma kuralları, belge gereksinimleri, test kapsamı beklentileri ve kod stili kuralları dahil olmak üzere modül kalitesine yönelik kodlama standartları yayınlar. OCA kurallarına uymak, modülünüzün bakımının yapılabilir olmasını ve daha geniş topluluk ekosistemiyle uyumlu olmasını sağlar.
Profesyonel Yardım Alma
Özel Odoo modülleri oluşturmak Python, JavaScript, PostgreSQL ve Odoo'nun çerçeve kurallarında uzmanlık gerektirir. İster basit bir saha uzantısına ister karmaşık çok modüllü bir sisteme ihtiyacınız olsun, ECOSIRE'ın Odoo özelleştirme hizmetleri OCA standartlarına göre oluşturulmuş üretime hazır modüller sunar.
Özel modül gereksinimlerinizi görüşmek ve bir geliştirme tahmini almak için Bize ulaşın.
Yazan
ECOSIRE Research and Development Team
ECOSIRE'da kurumsal düzeyde dijital ürünler geliştiriyor. Odoo entegrasyonları, e-ticaret otomasyonu ve yapay zeka destekli iş çözümleri hakkında içgörüler paylaşıyor.
İlgili Makaleler
Amazon.de Odoo Entegrasyonu: Odoo ERP ile Almanya'nın En Büyük Pazarında Satış Yapmak
Amazon.de'yi Alman pazarı için Odoo ERP ile entegre etme. FBA Almanya, Pan-Avrupa sipariş karşılama, Almanya KDV'si, VerpackG uyumluluğu ve uzlaşma mutabakatını kapsar.
Odoo ile Alman e-Ticaret Pazarına Giriş: Uluslararası Satıcılar için Adım Adım Kılavuz
Alman e-Ticaret pazarına giren uluslararası satıcılar için eksiksiz kılavuz. Alman tüketicilere satış yapmak için pazar analizini, yasal gereklilikleri, KDV kaydını, pazar yeri seçimini ve Odoo ERP kurulumunu kapsar.
Odoo ile Alman e-Ticaret İadelerini Yönetmek: Yüksek Getirili Piyasalara Yönelik Stratejiler
Odoo ERP kullanarak Almanya'nın yüksek e-Ticaret getiri oranlarıyla nasıl başa çıkılır? Zalando, Otto, Amazon.de ve Kaufland için iade işleme iş akışlarını, neden kodu analizlerini, yeniden stoklama otomasyonunu ve pazara özel politikaları kapsar.