from odoo import models, fields, api
import logging
from markupsafe import Markup
_logger = logging.getLogger(__name__)
class KpiPeriodLine(models.Model):
_name = 'kpi.period.line'
_description = 'KPI Period Line (Worksheet)'
_order = 'sequence, id'
line_id = fields.Many2one('kpi.kpi.line', string='KPI Line', required=True, ondelete='cascade')
name = fields.Char(string='Period', required=True)
sequence = fields.Integer(string='Sequence', default=10)
date_start = fields.Date(string='Start Date')
date_end = fields.Date(string='End Date')
realization = fields.Float(string='Realization', digits=(16, 2))
target = fields.Float(string='Target (Period)', digits=(16, 2))
state = fields.Selection([
('draft', 'Open'),
('closed', 'Closed'),
], string='Status', default='draft')
def write(self, vals):
# Track changes for visualization in chatter of the parent KPI
tracked_fields = {'realization', 'target', 'state'}
fields_to_check = tracked_fields.intersection(vals.keys())
if fields_to_check:
# Store old values to compare
old_values = {rec.id: {f: rec[f] for f in fields_to_check} for rec in self}
# Perform write
result = super(KpiPeriodLine, self).write(vals)
# Check and log
for rec in self:
for field in fields_to_check:
old_val = old_values[rec.id].get(field)
new_val = vals.get(field)
# Handle comparisons safely
changed = False
if self._fields[field].type == 'float':
if float(old_val or 0.0) != float(new_val or 0.0):
changed = True
else:
if old_val != new_val:
changed = True
if changed:
parent_kpi = rec.line_id.kpi_id
if parent_kpi:
field_label = self._fields[field].string
# Format values for display (mapped selection, etc) not fully implemented here but using raw strings for now is usually fine for floats/simple selects
# For State showing label would be better but raw value is understandable for "draft/closed"
body = Markup("KPI Line %s - Period %s updated %s: %s → %s") % (
rec.line_id.name,
rec.name,
field_label,
old_val,
new_val
)
parent_kpi.message_post(body=body)
return result
return super(KpiPeriodLine, self).write(vals)