From b48c7baad0d5d0ae88a7277745938afc89b35991 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Tue, 10 Feb 2026 09:18:51 +0700 Subject: approval adjust out --- fixco_custom/__manifest__.py | 1 + fixco_custom/models/__init__.py | 1 + fixco_custom/models/stock_inventory.py | 109 +++++++++++++++++++++++++++++++++ fixco_custom/views/stock_inventory.xml | 33 ++++++++++ 4 files changed, 144 insertions(+) create mode 100644 fixco_custom/models/stock_inventory.py create mode 100644 fixco_custom/views/stock_inventory.xml diff --git a/fixco_custom/__manifest__.py b/fixco_custom/__manifest__.py index 9d781c0..83caa93 100755 --- a/fixco_custom/__manifest__.py +++ b/fixco_custom/__manifest__.py @@ -55,6 +55,7 @@ 'views/purchase_order_line_wizard.xml', 'views/account_payment.xml', 'views/account_move_line.xml', + 'views/stock_inventory.xml', ], 'demo': [], 'css': [], diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py index 94954eb..31b5794 100755 --- a/fixco_custom/models/__init__.py +++ b/fixco_custom/models/__init__.py @@ -42,3 +42,4 @@ from . import purchase_order_multi_bills from . import account_payment from . import stock_location from . import account_asset +from . import stock_inventory \ No newline at end of file diff --git a/fixco_custom/models/stock_inventory.py b/fixco_custom/models/stock_inventory.py new file mode 100644 index 0000000..96ac045 --- /dev/null +++ b/fixco_custom/models/stock_inventory.py @@ -0,0 +1,109 @@ +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([ + ('draft', 'Draft'), + ('logistic', 'Logistic'), + ('accounting', 'Accounting'), + ('approved', 'Approved'), + ], default='draft', 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 self.approval_state in [False, '', 'draft']: + self.approval_state = 'logistic' + elif self.approval_state == 'logistic': + if not rec.env.user.id in [10, 14, 20, 21]: + raise UserError("Harus diapprove logistic") + self.approval_state = 'accounting' + elif self.approval_state == 'accounting': + if not rec.env.user.id in [13, 24, 2]: + raise UserError("Harus diapprove accounting") + self.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) diff --git a/fixco_custom/views/stock_inventory.xml b/fixco_custom/views/stock_inventory.xml new file mode 100644 index 0000000..df74783 --- /dev/null +++ b/fixco_custom/views/stock_inventory.xml @@ -0,0 +1,33 @@ + + + + + stock.inventory.form.inherit + stock.inventory + + +
+
+ + + + + +
+
+ + + + stock.inventory.tree.inherit + stock.inventory + + + + + + + + +
-- cgit v1.2.3