forked from Mapan/odoo17e
110 lines
4.3 KiB
Python
110 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import re
|
|
|
|
from odoo import api, fields, models
|
|
from odoo.exceptions import UserError
|
|
from odoo.osv.expression import expression
|
|
|
|
|
|
class StockReport(models.Model):
|
|
_inherit = 'stock.report'
|
|
|
|
valuation = fields.Float("Valuation of Inventory using a Domain", readonly=True, store=False,
|
|
help="Note that you can only access this value in the read_group, only the sum operator is supported")
|
|
stock_value = fields.Float("Total Valuation of Inventory", readonly=True, store=False,
|
|
help="Note that you can only access this value in the read_group, only the sum operator is supported and only date_done is used from the domain")
|
|
|
|
@api.model
|
|
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
|
|
"""
|
|
This is a hack made in order to improve performance as adding
|
|
inventory valuation on the report itself would be too costly.
|
|
|
|
Basically when asked to return the valuation, it will run a smaller
|
|
SQL query that will calculate the inventory valuation on the given
|
|
domain.
|
|
|
|
Only the SUM operator is supported for valuation.
|
|
|
|
We can also get the stock_value of the inventory at a specific date
|
|
(default is today).
|
|
|
|
The same applies to this stock_value field, it only supports the sum operator
|
|
and does not support the group by.
|
|
|
|
NB: This should probably be implemented in a read instead of read_group since
|
|
we don't support grouping
|
|
|
|
NB: We might be able to avoid doing this hack by optimizing the query used to
|
|
generate the report (= TODO: see nse)
|
|
"""
|
|
stock_value = next((field for field in fields if re.search(r'\bstock_value\b', field)), False)
|
|
valuation = next((field for field in fields if re.search(r'\bvaluation\b', field)), False)
|
|
|
|
if stock_value:
|
|
fields.remove(stock_value)
|
|
|
|
if valuation:
|
|
fields.remove(valuation)
|
|
|
|
if stock_value or valuation:
|
|
if groupby:
|
|
raise UserError("valuation and stock_value don't support grouping")
|
|
|
|
if any(field.split(':')[1].split('(')[0] != 'sum' for field in [stock_value, valuation] if field):
|
|
raise UserError("read_group only support operator sum for valuation and stock_value")
|
|
|
|
res = []
|
|
if fields:
|
|
res = super(StockReport, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
|
|
|
|
if not res and (stock_value or valuation):
|
|
res = [{}]
|
|
|
|
if stock_value:
|
|
products = self.env['product.product'].with_context(active_test=False)
|
|
# Split the recordset for faster computing.
|
|
value = sum(
|
|
product.value_svl
|
|
for products_split in self.env.cr.split_for_in_conditions(
|
|
products.search([("product_tmpl_id.type", "=", "product")]).ids
|
|
)
|
|
for product in products.browse(products_split)
|
|
)
|
|
|
|
res[0].update({
|
|
'__count': 1,
|
|
stock_value.split(':')[0]: value,
|
|
})
|
|
|
|
if valuation:
|
|
query = """
|
|
SELECT
|
|
SUM(move_valuation.valuation) as valuation
|
|
FROM (
|
|
SELECT
|
|
sum(svl.value) AS valuation
|
|
FROM
|
|
stock_move move
|
|
INNER JOIN stock_valuation_layer AS svl ON svl.stock_move_id = move.id
|
|
WHERE
|
|
move.id IN (
|
|
SELECT "stock_report".id FROM %s WHERE %s)
|
|
GROUP BY
|
|
move.id
|
|
) as move_valuation
|
|
"""
|
|
|
|
subdomain = domain + [('company_id', '=', self.env.company.id)]
|
|
subtables, subwhere, subparams = expression(subdomain, self).query.get_sql()
|
|
|
|
self.env.cr.execute(query % (subtables, subwhere), subparams)
|
|
res[0].update({
|
|
'__count': 1,
|
|
valuation.split(':')[0]: self.env.cr.fetchall()[0][0],
|
|
})
|
|
|
|
return res
|