# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 from odoo import fields, models class FusionBillingCharge(models.Model): """Maps a plan + metric to quota + overage pricing. This is where "5,000,000 included / $0.10 per 1k overage" (NexaMaps) or a NexaCloud CPU-seconds quota lives. Keyed by the shared ``plan_code`` the app references; Odoo owns the money, the app owns feature entitlements. See spec §5.1. """ _name = "fusion.billing.charge" _description = "Fusion Billing — Metered Charge (quota + overage)" _order = "plan_code, name" name = fields.Char(required=True) plan_code = fields.Char( required=True, index=True, help="Shared plan_code the source app references (matches a sale.subscription.plan).", ) plan_id = fields.Many2one( "sale.subscription.plan", help="Optional link to the Odoo recurrence/plan for this charge.", ) metric_id = fields.Many2one( "fusion.billing.metric", required=True, ondelete="restrict", ) product_id = fields.Many2one( "product.product", help="Usage product invoiced for overage.", ) included_quota = fields.Float( default=0.0, help="Units included before overage applies, per period.", ) price_per_unit = fields.Monetary(help="Overage price per unit_batch.") unit_batch = fields.Float( default=1.0, help="Batch size for overage pricing, e.g. 1000 = priced per 1k.", ) charge_model = fields.Selection( [ ("standard", "Standard (per unit)"), ("graduated", "Graduated"), ("package", "Package"), ("volume", "Volume"), ], default="standard", required=True, ) currency_id = fields.Many2one( "res.currency", default=lambda self: self.env.company.currency_id, ) active = fields.Boolean(default=True)