from odoo import models, api, fields from odoo.exceptions import UserError from datetime import datetime import logging _logger = logging.getLogger(__name__) class StockInventory(models.Model): _inherit = ['stock.inventory'] _order = 'id desc' _rec_name = 'number' number = fields.Char(string='Document No', index=True, copy=False, readonly=True) adjusment_type = fields.Selection([ ('in', 'Adjusment In'), ('out', 'Adjusment Out'), ], string='Adjusments Type', required=True) approval_state = fields.Selection([ ('logistic', 'Logistic'), ('accounting', 'Accounting'), ('approved', 'Approved'), ], default='logistic', tracking=True) def _generate_number_stock_inventory(self): """Men-generate nomor untuk semua stock inventory yang belum memiliki number.""" stock_records = self.env['stock.inventory'].search([('number', '=', False)], order='id asc') for record in stock_records: self._assign_number(record) _logger.info('Generate Number Done') def _assign_number(self, record): """Menentukan nomor berdasarkan kategori Adjust-In atau Adjust-Out.""" name_upper = record.name.upper() if record.name else "" if self.adjusment_type == 'out': last_number = self._get_last_sequence("ADJUST/OUT/") record.number = f"ADJUST/OUT/{last_number}" elif self.adjusment_type == 'in': last_number = self._get_last_sequence("ADJUST/IN/") record.number = f"ADJUST/IN/{last_number}" else: record.number = "UNKNOWN" # Jika tidak termasuk kategori def _get_last_sequence(self, prefix): """Mengambil nomor terakhir berdasarkan prefix (ADJUST/OUT/ atau ADJUST/IN/) dengan format 00001, 00002, dst.""" last_record = self.env['stock.inventory'].search( [("number", "like", f"{prefix}%")], order="number desc", limit=1 ) if last_record and last_record.number: try: last_number = int(last_record.number.split("/")[-1]) # Ambil angka terakhir return str(last_number + 1).zfill(5) # Format jadi 00001, 00002, dst. except ValueError: return "00001" # Jika format tidak valid, mulai dari 00001 return "00001" # Jika belum ada data, mulai dari 00001 def action_start(self): if self.approval_state != 'approved' and self.adjusment_type == 'out': raise UserError('Harus melalui proses approval') if self.adjusment_type == 'in': if self.env.user.id not in [10, 14, 20, 21]: raise UserError("Hanya User tertentu yang dapat melakukan Adjust-In") return super(StockInventory, self).action_start() @api.model def create(self, vals): """Pastikan nomor hanya dibuat saat penyimpanan.""" if 'adjusment_type' in vals and not vals.get('number'): vals['number'] = False # Jangan buat number otomatis dulu order = super(StockInventory, self).create(vals) if order.adjusment_type: self._assign_number(order) # Generate number setelah save return order def action_approve(self): if self.adjusment_type == 'out': for rec in self: if rec.approval_state == 'logistic': if not rec.env.user.id in [10, 14, 20, 21]: raise UserError("Harus diapprove logistic") rec.approval_state = 'accounting' elif rec.approval_state == 'accounting': if not rec.env.user.id in [13, 24, 2]: raise UserError("Harus diapprove accounting") rec.approval_state = 'approved' else: raise UserError("Sudah Approved") def write(self, vals): """Jika adjusment_type diubah, generate ulang nomor.""" res = super(StockInventory, self).write(vals) if 'adjusment_type' in vals: for record in self: self._assign_number(record) return res def copy(self, default=None): """Saat duplikasi, adjusment_type dikosongkan dan number tidak ikut terduplikasi.""" default = dict(default or {}, adjusment_type=False, number=False) return super(StockInventory, self).copy(default=default)