pos_loyalty_multi_level/models/res_partner.py

81 lines
3.4 KiB
Python

# 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),
])
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
# 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})
return super().write(vals)