from dateutil.relativedelta import relativedelta from odoo import api, fields, models MEMBER_ID_SEQUENCE_CODE = 'community.membership.member_id' DEFAULT_MEMBER_ID_FORMAT = 'MEM-{year}-{seq}' class ResPartner(models.Model): _inherit = 'res.partner' membership_member_id = fields.Char( string='Member ID', copy=False, index=True, readonly=True, ) membership_tier_id = fields.Many2one('community.membership.tier', string='Membership Tier') membership_state = fields.Selection( [ ('none', 'Not a Member'), ('invoiced', 'Invoiced'), ('active', 'Active'), ('renewal_due', 'Renewal Due'), ('expired', 'Expired'), ], default='none', copy=False, tracking=True, ) membership_start = fields.Date(copy=False) membership_expiry = fields.Date(copy=False) family_head_id = fields.Many2one( 'res.partner', string='Family Head', domain=[('membership_tier_id', '!=', False)], help="If this member belongs to a family membership, the primary member it is grouped under.", ) is_volunteer = fields.Boolean(string='Volunteer') volunteer_hours = fields.Float(string='Volunteer Hours') def action_activate_membership(self): """Transition to 'active', generating a member ID and expiry if needed.""" today = fields.Date.context_today(self) for partner in self: if not partner.membership_tier_id: continue vals = {'membership_state': 'active'} if not partner.membership_member_id: vals['membership_member_id'] = partner._generate_member_id() if not partner.membership_start: vals['membership_start'] = today duration_days = partner.membership_tier_id.duration_days() if duration_days: vals['membership_expiry'] = today + relativedelta(days=duration_days) partner.write(vals) return True def _generate_member_id(self): self.ensure_one() get_param = self.env['ir.config_parameter'].sudo().get_param member_id_format = get_param('community_membership.member_id_format', DEFAULT_MEMBER_ID_FORMAT) seq_number = self.env['ir.sequence'].next_by_code(MEMBER_ID_SEQUENCE_CODE) or '1' year = fields.Date.context_today(self).year return ( member_id_format .replace('{year}', str(year)) .replace('{seq}', seq_number) )