summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2026-02-10 09:18:51 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2026-02-10 09:18:51 +0700
commitb48c7baad0d5d0ae88a7277745938afc89b35991 (patch)
tree0a8edc3099ce23bb3643f33957b11255291ee276
parent6f47933b5ac837af81008a300a0f109c1973d9d4 (diff)
<MIqdad> approval adjust out
-rwxr-xr-xfixco_custom/__manifest__.py1
-rwxr-xr-xfixco_custom/models/__init__.py1
-rw-r--r--fixco_custom/models/stock_inventory.py109
-rw-r--r--fixco_custom/views/stock_inventory.xml33
4 files changed, 144 insertions, 0 deletions
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 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <!-- Form View: Tambahkan field 'number' setelah lokasi -->
+ <record id="view_stock_inventory_form_inherit" model="ir.ui.view">
+ <field name="name">stock.inventory.form.inherit</field>
+ <field name="model">stock.inventory</field>
+ <field name="inherit_id" ref="stock.view_inventory_form"/>
+ <field name="arch" type="xml">
+ <header>
+ <button name="action_approve" string="Approve" type="object"
+ class="btn-primary" attrs="{'invisible': [('adjusment_type', 'not in', ['out'])]}"/>
+ </header>
+ <xpath expr="//field[@name='location_ids']" position="after">
+ <field name="number" readonly="1"/>
+ <field name="adjusment_type" />
+ <field name="approval_state" readonly="1" attrs="{'invisible': [('adjusment_type', 'not in', ['out'])]}"/>
+ </xpath>
+ </field>
+ </record>
+
+ <!-- Tree View: Tambahkan field 'number' setelah tanggal -->
+ <record id="view_stock_inventory_tree_inherit" model="ir.ui.view">
+ <field name="name">stock.inventory.tree.inherit</field>
+ <field name="model">stock.inventory</field>
+ <field name="inherit_id" ref="stock.view_inventory_tree"/>
+ <field name="arch" type="xml">
+ <xpath expr="//field[@name='date']" position="after">
+ <field name="number"/>
+ </xpath>
+ </field>
+ </record>
+
+</odoo>