odoo 18
This commit is contained in:
118
custom_addons/kosbar_erp_ext/references/custom-product-code.md
Normal file
118
custom_addons/kosbar_erp_ext/references/custom-product-code.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Custom Product Code & Item Code Automation
|
||||
|
||||
## Overview
|
||||
Odoo 17/19 Community tidak punya field `code` standar untuk product category. Untuk kebutuhan stock keeping unit (SKU) yang unik, kita buat field `item_code` yang di‑generate otomatis dari:
|
||||
|
||||
```
|
||||
item_code = parent_category_code (2 digit) + category_code (2 digit) + product_id (4 digit) + name_slug (lowercase, no space)
|
||||
```
|
||||
|
||||
Contoh:
|
||||
- Kategori anak: id=06, parent=01 → prefix = `0106`
|
||||
- Produk: id=3, nama="Backup BRT 30 x 36 x 1,25 mm"
|
||||
- Hasil: `01060003backupbrt30x36x1,25mm`
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### 1. Extend `product.category` → field `code`
|
||||
```python
|
||||
class ProductCategory(models.Model):
|
||||
_inherit = 'product.category'
|
||||
code = fields.Char(string='Category Code', compute='_compute_code', store=True, size=4)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
records = super().create(vals_list)
|
||||
for r in records:
|
||||
r.code = f'{r.id:02d}'
|
||||
return records
|
||||
```
|
||||
|
||||
### 2. Extend `product.template` → field `item_code`
|
||||
Field `item_code`:
|
||||
- **Stored** (`store=True`) — dipakai untuk pencarian & unique index.
|
||||
- **Read‑only di view** — tidak boleh ditulis manual.
|
||||
- **On‑change preview** → tampilkan prefix kategori saat buat produk baru.
|
||||
|
||||
```python
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
item_code = fields.Char(string='Item Code', store=True, readonly=False)
|
||||
|
||||
_sql_constraints = [
|
||||
('item_code_unique', 'UNIQUE(item_code)', 'Item Code harus unik.'),
|
||||
]
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
records = super().create(vals_list)
|
||||
for r in records:
|
||||
r.item_code = r._full_item_code(r)
|
||||
return records
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if 'name' in vals or 'categ_id' in vals:
|
||||
for r in self:
|
||||
r.item_code = r._full_item_code(r)
|
||||
return res
|
||||
```
|
||||
|
||||
### 3. Extend `product.product` (varian)
|
||||
Untuk produk ber‑varian, `item_code` diturunkan via related field ke template:
|
||||
|
||||
```python
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = 'product.product'
|
||||
|
||||
item_code = fields.Char(
|
||||
string='Item Code',
|
||||
related='product_tmpl_id.item_code',
|
||||
store=True,
|
||||
readonly=True,
|
||||
)
|
||||
```
|
||||
|
||||
### 4. XML View — field read‑only
|
||||
```xml
|
||||
<!-- product_template_form_view inheritance -->
|
||||
<field name="default_code" position="after">
|
||||
<field name="item_code" readonly="1" placeholder="Terisi otomatis"/>
|
||||
</field>
|
||||
```
|
||||
|
||||
### 5. PostgreSQL — Unique Index (optional, backup)
|
||||
Constraint `__sql_constraints` sudah menambah unique index via Odoo ORM. Untuk kecepatan lebih cepat di PostgreSQL level, dapat manual:
|
||||
|
||||
```sql
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS product_template_item_code_uniq
|
||||
ON product_template (item_code) WHERE item_code IS NOT NULL;
|
||||
```
|
||||
|
||||
### 6. Migration — isi data existing
|
||||
```python
|
||||
env.cr.execute("""
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS product_template_item_code_uniq
|
||||
ON product_template (item_code) WHERE item_code IS NOT NULL
|
||||
""")
|
||||
|
||||
cats = env['product.category'].search([])
|
||||
for c in cats:
|
||||
if not c.code:
|
||||
c.code = f'{c.id:02d}'
|
||||
|
||||
prods = env['product.template'].search([])
|
||||
for p in prods:
|
||||
p.item_code = p._full_item_code(p)
|
||||
```
|
||||
|
||||
## Pitfalls
|
||||
- `@api.depends('id')` **not allowed** di Odoo 19. Namun `id` tersedia di `create()` setelah super() selesai.
|
||||
- Field `code` di kategori **harus `size` ditentukan** ( Odoo 17+ lint error tanpa `size`)
|
||||
- Product dengan `categ_id = False` → gunakan fallback `00`.
|
||||
- **Item Code read‑only di view**: bila pakai `store=True`, field tetap dapat ditulis via ORM (API). Untuk mencegah manual edit, gunakan `readonly=True` + `@api.constrains` untuk validasi.
|
||||
|
||||
## References
|
||||
- `models/product_template.py` — contoh implementasi lengkap (sudah ada di addon `kosbar_erp_ext`)
|
||||
- `views/product_views.xml` — XML view inheritance
|
||||
Reference in New Issue
Block a user