commit f2490ffcb86274d1a83d9d1abf9e5134cd321d17 Author: Suherdy Yacob Date: Tue Dec 23 15:00:00 2025 +0700 first commit diff --git a/__init__.py b/__init__.py new file mode 100755 index 0000000..0650744 --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/__manifest__.py b/__manifest__.py new file mode 100755 index 0000000..93ed414 --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Warehouse Stock Value Revaluation", + 'summary': """ + Inventory Cost Revaluation, Stock Revaluation for Accurate Accounting + """, + 'description': """ + Inventory Revaluation Odoo App provides a solution for businesses to reassess and recalculate the value of their stock. + It allows creating backdate inventory adjustment and revaluation. + """, + 'author': "Antigravity", + 'website': "https://www.mapan.co.id", + 'category': 'Inventory/Inventory', + 'version': '17.0.1.0.0', + 'depends': ['stock_account'], + 'data': [ + 'security/ir.model.access.csv', + 'views/stock_inventory_revaluation_views.xml', + ], + 'license': 'LGPL-3', + 'installable': True, + 'application': True, +} diff --git a/__pycache__/__init__.cpython-312.pyc b/__pycache__/__init__.cpython-312.pyc new file mode 100755 index 0000000..047cde5 Binary files /dev/null and b/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__init__.py b/models/__init__.py new file mode 100755 index 0000000..64e8444 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1 @@ +from . import stock_inventory_revaluation diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc new file mode 100755 index 0000000..a48fff3 Binary files /dev/null and b/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__pycache__/stock_inventory_revaluation.cpython-312.pyc b/models/__pycache__/stock_inventory_revaluation.cpython-312.pyc new file mode 100755 index 0000000..51027a6 Binary files /dev/null and b/models/__pycache__/stock_inventory_revaluation.cpython-312.pyc differ diff --git a/models/stock_inventory_revaluation.py b/models/stock_inventory_revaluation.py new file mode 100755 index 0000000..32be72a --- /dev/null +++ b/models/stock_inventory_revaluation.py @@ -0,0 +1,145 @@ +from odoo import models, fields, api, _ +from odoo.exceptions import UserError +from odoo.tools import float_compare, float_is_zero + +class StockInventoryRevaluation(models.Model): + _name = 'stock.inventory.revaluation' + _description = 'Stock Inventory Revaluation' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='Reference', required=True, copy=False, readonly=True, default=lambda self: _('New')) + date = fields.Datetime(string='Date', required=True, default=fields.Datetime.now) + product_id = fields.Many2one('product.product', string='Product', required=True, domain=[('type', '=', 'product')]) + account_journal_id = fields.Many2one('account.journal', string='Journal', required=True) + account_id = fields.Many2one('account.account', string='Account', help="Counterpart account for the revaluation") + + current_value = fields.Float(string='Current Value', compute='_compute_current_value', store=True) + quantity = fields.Float(string='Quantity', compute='_compute_current_value', store=True) + + extra_cost = fields.Float(string='Extra Cost', help="Amount to add to the stock value") + + state = fields.Selection([ + ('draft', 'Draft'), + ('done', 'Done'), + ('cancel', 'Cancelled') + ], string='Status', default='draft', tracking=True) + + company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company) + + @api.depends('product_id', 'date') + def _compute_current_value(self): + for record in self: + if record.product_id and record.date: + # Calculate quantity and value at the specific date + layers = self.env['stock.valuation.layer'].search([ + ('product_id', '=', record.product_id.id), + ('create_date', '<=', record.date), + ('company_id', '=', record.company_id.id) + ]) + record.quantity = sum(layers.mapped('quantity')) + record.current_value = sum(layers.mapped('value')) + elif record.product_id: + record.quantity = record.product_id.quantity_svl + record.current_value = record.product_id.value_svl + else: + record.quantity = 0.0 + record.current_value = 0.0 + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + if vals.get('name', _('New')) == _('New'): + vals['name'] = self.env['ir.sequence'].next_by_code('stock.inventory.revaluation') or _('New') + return super().create(vals_list) + + def action_validate(self): + self.ensure_one() + if float_is_zero(self.extra_cost, precision_rounding=self.currency_id.rounding): + raise UserError(_("The Extra Cost cannot be zero.")) + + # Create Accounting Entry + move_vals = self._prepare_account_move_vals() + move = self.env['account.move'].create(move_vals) + move.action_post() + + # Create Stock Valuation Layer + self._create_valuation_layer(move) + + self.state = 'done' + + def _prepare_account_move_vals(self): + self.ensure_one() + debit_account_id = self.product_id.categ_id.property_stock_valuation_account_id.id + + # Auto-detect counterpart account if not set + credit_account_id = self.account_id.id + if not credit_account_id: + if self.extra_cost > 0: + credit_account_id = self.product_id.categ_id.property_stock_account_input_categ_id.id + else: + credit_account_id = self.product_id.categ_id.property_stock_account_output_categ_id.id + + if not debit_account_id: + raise UserError(_("Please define the Stock Valuation Account for product category: %s") % self.product_id.categ_id.name) + if not credit_account_id: + raise UserError(_("Please define the Stock Input/Output Account for product category: %s, or select an Account manually.") % self.product_id.categ_id.name) + + amount = self.extra_cost + name = _('%s - Revaluation') % self.name + + # If amount is negative, swap accounts/logic or just let debits be negative? + # Usually easier to swap or just have positive/negative balance. + # Standard: Debit Stock, Credit Counterpart for increase. + + lines = [ + (0, 0, { + 'name': name, + 'account_id': debit_account_id, + 'debit': amount if amount > 0 else 0, + 'credit': -amount if amount < 0 else 0, + 'product_id': self.product_id.id, + }), + (0, 0, { + 'name': name, + 'account_id': credit_account_id, + 'debit': -amount if amount < 0 else 0, + 'credit': amount if amount > 0 else 0, + }), + ] + + return { + 'ref': self.name, + 'date': self.date.date(), # BACKDATE HERE + 'journal_id': self.account_journal_id.id, + 'line_ids': lines, + 'move_type': 'entry', + } + + def _create_valuation_layer(self, move): + self.ensure_one() + layer_vals = { + 'product_id': self.product_id.id, + 'value': self.extra_cost, + 'unit_cost': 0, # Not adjusting unit cost directly, just total value + 'quantity': 0, + 'remaining_qty': 0, + 'description': _('Revaluation: %s') % self.name, + 'account_move_id': move.id, + 'company_id': self.company_id.id, + # We try to force the date if the model allows it, but stock.valuation.layer usually takes create_date. + # However, for reporting, Odoo joins with account_move. + } + # Note: stock.valuation.layer 'create_date' is automatic. + # But we can try to override it or rely on the account move date for reports. + # Standard Odoo valuation reports often rely on the move date. + + layer = self.env['stock.valuation.layer'].create(layer_vals) + + # Force backdate the validation layer's create_date to match the revaluation date + # This is critical for "Inventory Valuation at Date" reports. + self.env.cr.execute('UPDATE stock_valuation_layer SET create_date = %s WHERE id = %s', (self.date, layer.id)) + + + @property + def currency_id(self): + return self.company_id.currency_id diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv new file mode 100755 index 0000000..303ef83 --- /dev/null +++ b/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_stock_inventory_revaluation,stock.inventory.revaluation,model_stock_inventory_revaluation,base.group_user,1,1,1,1 diff --git a/views/stock_inventory_revaluation_views.xml b/views/stock_inventory_revaluation_views.xml new file mode 100755 index 0000000..951511e --- /dev/null +++ b/views/stock_inventory_revaluation_views.xml @@ -0,0 +1,93 @@ + + + + + + Stock Revaluation + stock.inventory.revaluation + REV/ + 5 + + + + + + stock.inventory.revaluation.form + stock.inventory.revaluation + +
+
+
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ + + + stock.inventory.revaluation.tree + stock.inventory.revaluation + + + + + + + + + + + + + + Inventory Revaluation + stock.inventory.revaluation + tree,form + +

+ Create a new Inventory Revaluation +

+
+
+ + + +
+