mirror of
https://github.com/bringout/oca-ocb-accounting.git
synced 2026-04-25 04:02:01 +02:00
19.0 vanilla
This commit is contained in:
parent
ba20ce7443
commit
768b70e05e
2357 changed files with 1057103 additions and 712486 deletions
|
|
@ -1,8 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.tools.float_utils import float_is_zero
|
||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||
from odoo.tools.misc import groupby
|
||||
|
||||
|
||||
|
|
@ -10,13 +8,32 @@ class StockQuant(models.Model):
|
|||
_inherit = 'stock.quant'
|
||||
|
||||
value = fields.Monetary('Value', compute='_compute_value', groups='stock.group_stock_manager')
|
||||
currency_id = fields.Many2one('res.currency', compute='_compute_value', groups='stock.group_stock_manager')
|
||||
currency_id = fields.Many2one('res.currency', related='company_id.currency_id', groups='stock.group_stock_manager')
|
||||
accounting_date = fields.Date(
|
||||
'Accounting Date',
|
||||
help="Date at which the accounting entries will be created"
|
||||
" in case of automated inventory valuation."
|
||||
" If empty, the inventory date will be used.")
|
||||
cost_method = fields.Selection(related="product_categ_id.property_cost_method")
|
||||
cost_method = fields.Selection(
|
||||
string="Cost Method",
|
||||
selection=[
|
||||
('standard', "Standard Price"),
|
||||
('fifo', "First In First Out (FIFO)"),
|
||||
('average', "Average Cost (AVCO)"),
|
||||
],
|
||||
compute='_compute_cost_method',
|
||||
)
|
||||
|
||||
@api.depends_context('company')
|
||||
@api.depends('product_categ_id.property_cost_method')
|
||||
def _compute_cost_method(self):
|
||||
for quant in self:
|
||||
quant.cost_method = (
|
||||
quant.product_categ_id.with_company(
|
||||
quant.company_id
|
||||
).property_cost_method
|
||||
or (quant.company_id or self.env.company).cost_method
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _should_exclude_for_valuation(self):
|
||||
|
|
@ -29,52 +46,58 @@ class StockQuant(models.Model):
|
|||
|
||||
@api.depends('company_id', 'location_id', 'owner_id', 'product_id', 'quantity')
|
||||
def _compute_value(self):
|
||||
""" (Product.value_svl / Product.quantity_svl) * quant.quantity, i.e. average unit cost * on hand qty
|
||||
"""
|
||||
self.fetch(['company_id', 'location_id', 'owner_id', 'product_id', 'quantity', 'lot_id'])
|
||||
self.value = 0
|
||||
for quant in self:
|
||||
quant.currency_id = quant.company_id.currency_id
|
||||
if not quant.location_id or not quant.product_id or\
|
||||
not quant.location_id._should_be_valued() or\
|
||||
quant._should_exclude_for_valuation() or\
|
||||
float_is_zero(quant.quantity, precision_rounding=quant.product_id.uom_id.rounding):
|
||||
quant.value = 0
|
||||
quant.product_id.uom_id.is_zero(quant.quantity):
|
||||
continue
|
||||
quantity = quant.product_id.with_company(quant.company_id).quantity_svl
|
||||
if float_is_zero(quantity, precision_rounding=quant.product_id.uom_id.rounding):
|
||||
quant.value = 0.0
|
||||
if quant.product_id.lot_valuated:
|
||||
quantity = quant.lot_id.with_company(quant.company_id).product_qty
|
||||
value = quant.lot_id.with_company(quant.company_id).total_value
|
||||
else:
|
||||
quantity = quant.product_id.with_company(quant.company_id).qty_available
|
||||
value = quant.product_id.with_company(quant.company_id).total_value
|
||||
if quant.product_id.uom_id.is_zero(quantity):
|
||||
continue
|
||||
quant.value = quant.quantity * quant.product_id.with_company(quant.company_id).value_svl / quantity
|
||||
quant.value = quant.quantity * value / quantity
|
||||
|
||||
@api.model
|
||||
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
|
||||
""" This override is done in order for the grouped list view to display the total value of
|
||||
the quants inside a location. This doesn't work out of the box because `value` is a computed
|
||||
field.
|
||||
"""
|
||||
if 'value' not in fields:
|
||||
return super(StockQuant, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
||||
res = super(StockQuant, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
||||
for group in res:
|
||||
if group.get('__domain'):
|
||||
quants = self.search(group['__domain'])
|
||||
group['value'] = sum(quant.value for quant in quants)
|
||||
return res
|
||||
def _read_group_select(self, aggregate_spec, query):
|
||||
# flag value as aggregatable, and manually sum the values from the
|
||||
# records in the group
|
||||
if aggregate_spec in ('value:sum', 'value:sum_currency'):
|
||||
return super()._read_group_select('id:recordset', query)
|
||||
return super()._read_group_select(aggregate_spec, query)
|
||||
|
||||
def _apply_inventory(self):
|
||||
def _read_group_postprocess_aggregate(self, aggregate_spec, raw_values):
|
||||
if aggregate_spec in ('value:sum', 'value:sum_currency'):
|
||||
column = super()._read_group_postprocess_aggregate('id:recordset', raw_values)
|
||||
return (sum(records.mapped('value')) for records in column)
|
||||
return super()._read_group_postprocess_aggregate(aggregate_spec, raw_values)
|
||||
|
||||
def _apply_inventory(self, date=None):
|
||||
for accounting_date, inventory_ids in groupby(self, key=lambda q: q.accounting_date):
|
||||
inventories = self.env['stock.quant'].concat(*inventory_ids)
|
||||
if accounting_date:
|
||||
super(StockQuant, inventories.with_context(force_period_date=accounting_date))._apply_inventory()
|
||||
super(StockQuant, inventories.with_context(force_period_date=accounting_date))._apply_inventory(date)
|
||||
inventories.accounting_date = False
|
||||
else:
|
||||
super(StockQuant, inventories)._apply_inventory()
|
||||
super(StockQuant, inventories)._apply_inventory(date)
|
||||
|
||||
def _get_inventory_move_values(self, qty, location_id, location_dest_id, out=False):
|
||||
res_move = super()._get_inventory_move_values(qty, location_id, location_dest_id, out)
|
||||
def _get_inventory_move_values(self, qty, location_id, location_dest_id, package_id=False, package_dest_id=False):
|
||||
res_move = super()._get_inventory_move_values(qty, location_id, location_dest_id, package_id, package_dest_id)
|
||||
if not self.env.context.get('inventory_name'):
|
||||
force_period_date = self.env.context.get('force_period_date', False)
|
||||
if force_period_date:
|
||||
res_move['name'] += _(' [Accounted on %s]', force_period_date)
|
||||
if self.product_uom_id.is_zero(qty):
|
||||
name = _('Product Quantity Confirmed')
|
||||
else:
|
||||
name = _('Product Quantity Updated')
|
||||
if self.env.uid and self.env.uid != SUPERUSER_ID:
|
||||
name += f' ({self.env.user.display_name})'
|
||||
res_move['inventory_name'] = name + _(' [Accounted on %s]', force_period_date)
|
||||
return res_move
|
||||
|
||||
@api.model
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue