"""MV of per-asset book value snapshot. Refresh via cron or model._refresh().""" import logging import os from odoo import api, fields, models _logger = logging.getLogger(__name__) class FusionAssetBookValuesMV(models.Model): _name = "fusion.asset.book.values.mv" _description = "MV of asset book value snapshot" _auto = False _table = "fusion_asset_book_values_mv" _order = "book_value desc" asset_id = fields.Many2one('fusion.asset', readonly=True) company_id = fields.Many2one('res.company', readonly=True) category_id = fields.Many2one('fusion.asset.category', readonly=True) state = fields.Char(readonly=True) cost = fields.Float(readonly=True) salvage_value = fields.Float(readonly=True) total_depreciated = fields.Float(readonly=True) book_value = fields.Float(readonly=True) posted_periods = fields.Integer(readonly=True) pending_periods = fields.Integer(readonly=True) acquisition_date = fields.Date(readonly=True) in_service_date = fields.Date(readonly=True) def init(self): sql_path = os.path.join( os.path.dirname(__file__), '..', 'data', 'sql', 'create_mv_asset_book_values.sql', ) with open(sql_path, 'r') as f: self.env.cr.execute(f.read()) _logger.info("fusion_asset_book_values_mv: created/verified MV") @api.model def _refresh(self, *, concurrently=True): # CONCURRENTLY requires a unique index (we have one) and that the MV # has been populated at least once. Wrap the concurrent attempt in a # savepoint so a failure (e.g. first-ever refresh before the MV is # populated) does NOT poison the surrounding transaction; we then # fall back to a plain REFRESH. if concurrently: try: with self.env.cr.savepoint(): self.env.cr.execute( "REFRESH MATERIALIZED VIEW CONCURRENTLY " "fusion_asset_book_values_mv" ) return except Exception as e: # noqa: BLE001 _logger.warning("Concurrent MV refresh failed (%s); fallback", e) self.env.cr.execute( "REFRESH MATERIALIZED VIEW fusion_asset_book_values_mv" )