# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) from odoo import models, fields, api class FusionApiAccess(models.Model): _name = 'fusion.api.access' _description = 'API Access Rule' _order = 'consumer_id, provider_id' _rec_name = 'display_name' consumer_id = fields.Many2one( 'fusion.api.consumer', required=True, ondelete='cascade', ) provider_id = fields.Many2one( 'fusion.api.provider', required=True, ondelete='cascade', ) is_enabled = fields.Boolean(default=True, string='Enabled', tracking=True) monthly_budget_usd = fields.Float( string='Monthly Budget (USD)', help='Maximum monthly spend. 0 = unlimited.', ) daily_budget_usd = fields.Float( string='Daily Budget (USD)', help='Maximum daily spend. 0 = unlimited.', ) max_rpm = fields.Integer( string='Max Requests/Min', help='Maximum requests per minute. 0 = unlimited.', ) max_rpd = fields.Integer( string='Max Requests/Day', help='Maximum requests per day. 0 = unlimited.', ) current_month_cost = fields.Float( compute='_compute_current_usage', string='Month Spend', ) current_day_cost = fields.Float( compute='_compute_current_usage', string='Today Spend', ) current_day_requests = fields.Integer( compute='_compute_current_usage', string='Today Requests', ) budget_usage_pct = fields.Float( compute='_compute_current_usage', string='Budget Used %', ) is_budget_exceeded = fields.Boolean(compute='_compute_current_usage') display_name = fields.Char(compute='_compute_display_name', store=True) company_id = fields.Many2one('res.company', default=lambda self: self.env.company) _sql_constraints = [ ('consumer_provider_uniq', 'unique(consumer_id, provider_id, company_id)', 'Only one access rule per consumer-provider pair per company.'), ] @api.depends('consumer_id.name', 'provider_id.name') def _compute_display_name(self): for rec in self: consumer = rec.consumer_id.name or '' provider = rec.provider_id.name or '' rec.display_name = f"{consumer} / {provider}" def _compute_current_usage(self): today = fields.Date.today() month_start = today.replace(day=1) for rec in self: month_usages = self.env['fusion.api.usage'].sudo().search([ ('consumer_id', '=', rec.consumer_id.id), ('provider_id', '=', rec.provider_id.id), ('create_date', '>=', fields.Datetime.to_string(month_start)), ('status', '=', 'success'), ]) day_usages = month_usages.filtered( lambda u: u.create_date.date() == today ) rec.current_month_cost = sum(u.estimated_cost_usd for u in month_usages) rec.current_day_cost = sum(u.estimated_cost_usd for u in day_usages) rec.current_day_requests = len(day_usages) if rec.monthly_budget_usd > 0: rec.budget_usage_pct = ( rec.current_month_cost / rec.monthly_budget_usd ) * 100 rec.is_budget_exceeded = ( rec.current_month_cost >= rec.monthly_budget_usd ) else: rec.budget_usage_pct = 0.0 rec.is_budget_exceeded = False