import re from odoo import models, fields, api from odoo.exceptions import ValidationError class ProductTemplate(models.Model): _inherit = 'product.template' item_code = fields.Char( string='Item Code', store=True, readonly=False, # biar view bisa pakai; kita atur readonly di XML help='Kombinasi: parent_kode + kategori_kode + id(+4 digit) + nama_tanpa_spasi(lower). ' 'Read-only, dipakai sbg stock keeping unit code.', ) @api.onchange('categ_id') def _onchange_categ_preview(self): """Saat create belum simpan id -> tampilkan pratinjau gabungan kode kategori.""" if self.categ_id and not self.env.context.get('default_product_tmpl_id') \ and not self.id and not self.item_code: cat = self.categ_id if cat and not cat.code: cat.code = f'{cat.id:02d}' parent = cat.parent_id.code if cat.parent_id else '' own = cat.code or '' self.item_code = f'{parent}{own}' @api.constrains('item_code') def _check_item_code_unique(self): for rec in self: if not rec.item_code: continue dup = self.search([('item_code', '=', rec.item_code), ('id', '!=', rec.id)], limit=1) if dup: raise ValidationError( f'Item Code "{rec.item_code}" sudah dipakai oleh produk lain ' f'({dup.name}). Item Code harus unik.' ) def _category_prefix(self, cat): """Return gabungan kode kategori (parent+own), 4 digit atau 00.""" if not cat: return '00' if not cat.code: cat.code = f'{cat.id:02d}' parent_code = cat.parent_id.code if cat.parent_id else '' own_code = cat.code or '' return f'{parent_code}{own_code}' def _name_slug(self, name): slug = (name or '').lower().replace(',', '.') return re.sub(r'\s+', '', slug) def _full_item_code(self, obj): """Compute full item_code: prefix kategori + id:04d + name_slug.""" prefix = self._category_prefix(obj.categ_id) oid = obj.id or 0 return f'{prefix}{oid:04d}{self._name_slug(obj.name)}' @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