--- name: odoo-module-creator description: Creates complete Odoo 16.0 modules with proper structure, manifests, models, views, and security. This skill should be used when the user requests creation of a new Odoo module, such as "Create a new module for inventory tracking" or "I need a new POS customization module" or "Generate module structure for vendor management". --- # Odoo Module Creator ## Overview This skill enables creation of complete, production-ready Odoo 16.0 Enterprise modules with proper directory structure, manifest files, models, views, security configurations, and documentation. It follows OCA guidelines and Siafa project standards. ## Module Creation Workflow ### Step 1: Gather Module Requirements Ask clarifying questions to collect essential information: 1. **Module technical name** (snake_case format, e.g., `stock_batch_tracking`, `pos_custom_receipt`) 2. **Module display name** (human-readable, e.g., "Stock Batch Tracking", "POS Custom Receipt") 3. **Module purpose** (1-2 sentence description of functionality) 4. **Module category** (select from: Sales, Inventory, Accounting, Point of Sale, Human Resources, Manufacturing, Purchases, Warehouse, Website, etc.) 5. **Dependencies** (base modules required, e.g., `stock`, `account`, `point_of_sale`) 6. **Module type** (see Module Types section below) 7. **Target addon directory** (e.g., `addons-stock`, `addons-pos`, `addons-account`) ### Step 2: Determine Module Type Identify which type of module to create based on the purpose: **A. Simple Model Module** - CRUD operations for a new business entity - Creates new models with fields and views - Example: Customer feedback tracking, equipment registry **B. Extension Module** - Extends existing Odoo models - Inherits and adds fields/methods to existing models - Example: Add serial number tracking to stock.picking **C. POS Customization** - Point of Sale enhancements - Extends POS models, screens, or receipts - Example: Custom receipt format, loyalty points integration **D. Stock/Inventory Enhancement** - Warehouse and inventory features - Stock valuation, warehouse operations, batch tracking - Example: Inter-warehouse transit, GRN-invoice linking **E. Accounting Customization** - Financial module extensions - Account moves, vendor bills, analytic accounting - Example: Multi-dimensional analytics, custom invoicing **F. Report Module** - Custom reports (PDF, Excel) - QWeb templates, data aggregation, export functionality - Example: Sales analysis, inventory valuation reports **G. Integration Module** - External API/service connectors - REST API clients, webhooks, data synchronization - Example: Beatroute connector, payment gateway integration **H. Widget/UI Customization** - Frontend enhancements - JavaScript widgets, custom views, web controllers - Example: Kanban view customizations, dashboard widgets ### Step 3: Generate Module Structure Create the complete directory structure with all required files: ``` module_name/ ├── __init__.py ├── __manifest__.py ├── models/ │ ├── __init__.py │ └── [model_files].py ├── views/ │ ├── [model]_views.xml │ └── menu_views.xml ├── security/ │ ├── security_groups.xml (if needed) │ └── ir.model.access.csv ├── data/ (optional) │ └── data.xml ├── wizards/ (if needed) │ ├── __init__.py │ └── [wizard_name].py ├── report/ (if reports needed) │ ├── __init__.py │ ├── [report_name].py │ └── templates/ │ └── [report_template].xml ├── static/ │ ├── description/ │ │ ├── icon.png │ │ └── index.html │ └── src/ (for JS/CSS if needed) │ ├── js/ │ └── css/ └── tests/ (recommended) ├── __init__.py └── test_[module].py ``` ### Step 4: Generate __manifest__.py Create manifest with standard metadata: ```python { 'name': '[Module Display Name]', 'version': '16.0.1.0.0', 'category': '[Category]', 'summary': '[Brief one-line description]', 'description': """ [Detailed multi-line description of module functionality] Key Features: - Feature 1 - Feature 2 - Feature 3 """, 'author': 'Jamshid K', 'website': 'https://siafadates.com', 'license': 'LGPL-3', 'depends': [ 'base', # Additional dependencies ], 'data': [ 'security/security_groups.xml', # Load first 'security/ir.model.access.csv', 'views/[model]_views.xml', 'views/menu_views.xml', 'data/data.xml', # If needed 'report/templates/[report].xml', # If needed ], 'assets': { # If JS/CSS needed 'web.assets_backend': [ 'module_name/static/src/js/*.js', 'module_name/static/src/css/*.css', ], }, 'demo': [], # Demo data if applicable 'installable': True, 'auto_install': False, 'application': False, # True for standalone apps } ``` ### Step 5: Generate Model Files Create model files following Odoo ORM best practices: ```python from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError import logging _logger = logging.getLogger(__name__) class ModelName(models.Model): """Description of the model.""" _name = 'module.model' _description = 'Model Description' _inherit = ['mail.thread', 'mail.activity.mixin'] # If needed _order = 'create_date desc' # Fields name = fields.Char( string='Name', required=True, index=True, tracking=True, help='Primary identifier for this record' ) active = fields.Boolean( string='Active', default=True, help='If unchecked, this record will be hidden' ) state = fields.Selection([ ('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled'), ], string='Status', default='draft', required=True, tracking=True) company_id = fields.Many2one( 'res.company', string='Company', required=True, default=lambda self: self.env.company ) # Relational fields partner_id = fields.Many2one('res.partner', string='Partner') line_ids = fields.One2many('module.model.line', 'parent_id', string='Lines') # Computed fields total_amount = fields.Float( string='Total Amount', compute='_compute_total_amount', store=True ) # Constraints _sql_constraints = [ ('name_unique', 'UNIQUE(name, company_id)', 'Name must be unique per company!'), ] @api.depends('line_ids', 'line_ids.amount') def _compute_total_amount(self): """Compute total amount from lines.""" for record in self: record.total_amount = sum(record.line_ids.mapped('amount')) @api.onchange('partner_id') def _onchange_partner_id(self): """Update fields when partner changes.""" if self.partner_id: # Logic here pass @api.constrains('total_amount') def _check_total_amount(self): """Validate total amount is positive.""" for record in self: if record.total_amount < 0: raise ValidationError('Total amount must be positive!') def action_confirm(self): """Confirm the record.""" self.ensure_one() if self.state != 'draft': raise UserError('Only draft records can be confirmed!') self.write({'state': 'confirmed'}) _logger.info('Record %s confirmed by user %s', self.name, self.env.user.name) ``` ### Step 6: Generate View Files Create XML view definitions: ```xml module.model.tree module.model module.model.form module.model

module.model.search module.model Model Name module.model tree,form {}

Create your first record!

Click the create button to add a new record.

``` ### Step 7: Generate Security Files Create security groups (if needed): ```xml Module Category 100 User Manager ``` Create access rights CSV: ```csv id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_model_user,module.model.user,model_module_model,group_user,1,1,1,0 access_model_manager,module.model.manager,model_module_model,group_manager,1,1,1,1 ``` ### Step 8: Generate Tests (Recommended) **Use the `odoo-test-creator` skill** to create comprehensive test suites for the module. The odoo-test-creator skill provides: - Test templates for different module types (basic models, constraints, inheritance) - Best practices specific to Siafa project standards - Solutions to common testing pitfalls (database constraints, HTML fields, permissions) - Proper import patterns and setUp methods To create tests with the odoo-test-creator skill, simply invoke: ``` Use the odoo-test-creator skill to create tests for [module_name] ``` The skill will: 1. Analyze the module structure to determine what needs testing 2. Select appropriate test templates based on module type 3. Generate comprehensive test methods for CRUD operations, constraints, computed fields, and business logic 4. Handle database constraints properly (using existing records vs. creating with .sudo()) 5. Apply Siafa-specific patterns and best practices **Quick Test Example** (if not using the skill): ```python from odoo.tests.common import TransactionCase from odoo.exceptions import UserError class TestModel(TransactionCase): """Test cases for module.model""" def setUp(self): """Set up test data""" super().setUp() self.Model = self.env['module.model'] # Use existing records when possible self.partner = self.env['res.partner'].search([], limit=1) if not self.partner: self.skipTest("No partner available for testing") def test_01_create_model(self): """Test creating a model record""" record = self.Model.create({ 'name': 'Test Record', 'partner_id': self.partner.id, }) self.assertTrue(record) self.assertEqual(record.state, 'draft') def test_02_constraint_validation(self): """Test constraint validation""" record = self.Model.create({ 'name': 'Test Record', 'partner_id': self.partner.id, }) with self.assertRaises(UserError) as context: record.write({'invalid_field': 'invalid_value'}) self.assertIn('expected error', str(context.exception)) ``` **Important:** For production modules, always use the `odoo-test-creator` skill to ensure comprehensive test coverage and proper handling of Siafa-specific constraints. ## Code Standards and Best Practices Follow these standards when generating module code: 1. **Naming Conventions** - Module name: `snake_case` (e.g., `stock_batch_tracking`) - Model name: `module.model` (e.g., `stock.batch.tracking`) - Fields: `snake_case` (e.g., `batch_number`, `expiry_date`) - Methods: `snake_case` with verb prefix (e.g., `action_confirm`, `_compute_total`) - XML IDs: `view_model_type` (e.g., `view_batch_tracking_form`) 2. **Import Order** ```python # Standard library import logging from datetime import datetime # Odoo imports from odoo import models, fields, api, _ from odoo.exceptions import UserError, ValidationError from odoo.tools import float_compare, float_is_zero ``` 3. **Field Attributes** - Always provide `string` parameter - Add `help` text for complex fields - Use `tracking=True` for important fields - Set `index=True` for searchable fields - Include `company_id` for multi-company support 4. **Method Decorators** - Use `@api.depends()` for computed fields - Use `@api.onchange()` for onchange methods - Use `@api.constrains()` for validation - Use `@api.model` for class-level methods 5. **Error Handling** - Use `UserError` for user-facing errors - Use `ValidationError` for constraint violations - Always log important actions with `_logger` 6. **Security** - Always create access rights CSV - Use security groups for sensitive operations - Add record rules if row-level security needed - Test with different user permissions ## Module Type Templates Reference the `assets/templates/` directory for complete templates by module type: - `simple_model/` - Basic CRUD module - `extension/` - Inheriting existing models - `pos_custom/` - POS customizations - `stock_enhancement/` - Inventory features - `report_module/` - Custom reports ## Resources ### assets/templates/ Contains complete module templates for different module types. Use these as starting points and customize based on specific requirements. ### assets/icon.png Default module icon. Replace with custom icon if needed (PNG, 128x128px recommended). ### assets/index.html Module description HTML template for the Apps menu.