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'), ], 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.env.user.id not in [10, 14, 20, 21, 15]: raise UserError("Hanya User tertentu yang dapat melakukan Adjust-In/Out") return super(StockInventory, self).action_start() @api.model def create(self, vals): """Pastikan nomor hanya dibuat saat penyimpanan.""" if vals.get('adjusment_type') == 'in': vals['approval_state'] = False elif vals.get('adjusment_type') == 'out': vals['approval_state'] = 'logistic' if 'adjusment_type' in vals and not vals.get('number'): vals['number'] = False order = super(StockInventory, self).create(vals) if order.adjusment_type: self._assign_number(order) return order def action_validate(self): if self.adjusment_type == 'out': if self.approval_state != 'approved': if self.approval_state == 'logistic': if not self.env.user.id in [10, 14, 20, 21]: raise UserError("Adjustment Out harus diapprove oleh Logistic") self.approval_state = 'accounting' return True elif self.approval_state == 'accounting': if not self.env.user.id in [13, 24, 2]: raise UserError("Adjustment Out harus diapprove oleh Accounting") self.approval_state = 'approved' return super(StockInventory, self).action_validate() else: raise UserError("Adjustment Out harus melalui approval terlebih dahulu.") return super(StockInventory, self).action_validate() 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: if record.adjusment_type == 'in': record.approval_state = False elif record.adjusment_type == 'out' and record.approval_state == False: record.approval_state = 'logistic' 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)