from odoo import api, fields, models PERIOD_DURATION_DAYS = { 'annual': 365, 'monthly': 30, 'one_time': None, # never expires } class CommunityMembershipTier(models.Model): _name = 'community.membership.tier' _description = 'Membership Tier' _order = 'sequence, id' name = fields.Char(required=True, translate=True) code = fields.Char(required=True, help="Short internal code, e.g. 'IND', 'FAM'.") price = fields.Monetary(currency_field='currency_id', required=True) currency_id = fields.Many2one( 'res.currency', required=True, default=lambda self: self.env.company.currency_id, ) period = fields.Selection( [ ('annual', 'Annual'), ('one_time', 'One-time (lifetime)'), ('monthly', 'Monthly'), ], default='annual', required=True, ) member_state_logic = fields.Text( string='State Notes', help="Free-text notes for admins on any special membership-state handling " "this tier needs (e.g. lifetime tiers never move to 'expired').", ) sequence = fields.Integer(default=10) product_id = fields.Many2one( 'product.product', string='Membership Product', readonly=True, copy=False, help="Auto-created service product used to invoice this tier's dues.", ) active = fields.Boolean(default=True) _code_uniq = models.Constraint( 'unique(code)', 'A membership tier with this code already exists.', ) @api.model_create_multi def create(self, vals_list): tiers = super().create(vals_list) for tier in tiers: if not tier.product_id: tier.product_id = tier._create_membership_product() return tiers def write(self, vals): res = super().write(vals) if 'price' in vals or 'name' in vals: for tier in self: if tier.product_id: tier.product_id.write(tier._membership_product_values()) return res def _membership_product_values(self): self.ensure_one() return { 'name': self.name, 'list_price': self.price, 'type': 'service', 'sale_ok': True, 'purchase_ok': False, 'invoice_policy': 'order', } def _create_membership_product(self): self.ensure_one() product = self.env['product.product'].create(self._membership_product_values()) return product def duration_days(self): self.ensure_one() return PERIOD_DURATION_DAYS.get(self.period)