# Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models class ResPartner(models.Model): _inherit = 'res.partner' membership_level_id = fields.Many2one( 'loyalty.program', string='Membership Level', help='Specific multi-level membership assigned to this customer.' ) @api.model def _load_pos_data_fields(self, config_id): fields_list = super()._load_pos_data_fields(config_id) # Add custom field for customer membership level fields_list.append('membership_level_id') return fields_list def write(self, vals): """ When a partner's membership level changes, transfer points, history, and archive their loyalty cards from the OLD level's program. """ if 'membership_level_id' in vals: new_level_id = vals['membership_level_id'] for partner in self: old_level_id = partner.membership_level_id.id if partner.membership_level_id else False # Only act when the level is actually changing to a different value if old_level_id and old_level_id != new_level_id: old_cards = self.env['loyalty.card'].sudo().search([ ('partner_id', '=', partner.id), ('program_id', '=', old_level_id), ('active', '=', True), ]) if old_cards and new_level_id: new_card = self.env['loyalty.card'].sudo().search([ ('partner_id', '=', partner.id), ('program_id', '=', new_level_id), ], limit=1) if not new_card: new_card = self.env['loyalty.card'].sudo().create({ 'partner_id': partner.id, 'program_id': new_level_id, 'points': 0, }) # 1. Transfer points for old_card in old_cards: pts = old_card.points if abs(pts) > 0.0001: new_card.points += pts old_card.points = 0.0 # 2. Transfer loyalty history (point transactions) old_histories = self.env['loyalty.history'].sudo().search([ ('card_id', 'in', old_cards.ids) ]) if old_histories: old_histories.write({'card_id': new_card.id}) # 3. Transfer POS order line references old_pos_lines = self.env['pos.order.line'].sudo().search([ ('coupon_id', 'in', old_cards.ids) ]) if old_pos_lines: old_pos_lines.write({'coupon_id': new_card.id}) # 4. Transfer Sales order line references old_sale_lines = self.env['sale.order.line'].sudo().search([ ('coupon_id', 'in', old_cards.ids) ]) if old_sale_lines: old_sale_lines.write({'coupon_id': new_card.id}) # Archive old-level cards if old_cards: old_cards.write({'active': False, 'points': 0.0}) return super().write(vals)