pos_loyalty_subscription/models/pos_order.py
2026-06-04 12:01:05 +07:00

82 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.tools import float_compare
from datetime import datetime, time
import pytz
class PosOrder(models.Model):
_inherit = 'pos.order'
def validate_coupon_programs(self, point_changes, new_codes):
point_changes_int = {int(k): v for k, v in point_changes.items()}
subscription_cards = self.env['loyalty.card'].browse(point_changes_int.keys()).exists().filtered(
lambda c: c.program_id.program_type == 'subscription'
)
# Validate dates and limits for subscription cards
for card in subscription_cards:
today = fields.Date.today()
if card.subscription_start_date and today < card.subscription_start_date:
return {
'successful': False,
'payload': {
'message': _('The subscription for %s is not active yet (Starts on %s).', card.partner_id.name, card.subscription_start_date),
}
}
if card.subscription_end_date and today > card.subscription_end_date:
return {
'successful': False,
'payload': {
'message': _('The subscription for %s has expired (Expired on %s).', card.partner_id.name, card.subscription_end_date),
}
}
# Check usage limit today in user local timezone
user_tz = pytz.timezone(self.env.user.tz or 'UTC')
now_utc = fields.Datetime.now()
now_local = pytz.utc.localize(now_utc).astimezone(user_tz)
midnight_local = now_local.replace(hour=0, minute=0, second=0, microsecond=0)
start_date = midnight_local.astimezone(pytz.utc).replace(tzinfo=None)
history_count = self.env['loyalty.history'].sudo().search_count([
('card_id', '=', card.id),
('create_date', '>=', start_date),
('used', '>', 0),
])
if history_count >= 1:
return {
'successful': False,
'payload': {
'message': _('Customer %s has already claimed their subscription free product today.', card.partner_id.name),
}
}
# Bypass the points validation by temporarily mocking subscription cards points to a high value.
original_points = {card: card.points for card in subscription_cards}
for card in subscription_cards:
card.points = 9999.0
try:
res = super().validate_coupon_programs(point_changes, new_codes)
finally:
for card, points in original_points.items():
card.points = points
return res
def confirm_coupon_programs(self, coupon_data):
# Run super to process normal workflow
res = super().confirm_coupon_programs(coupon_data)
# After points calculations/deductions are processed, reset the points back to 0.0 for subscription cards
coupon_data_int = {int(k): v for k, v in coupon_data.items()}
for card_id in coupon_data_int.keys():
card = self.env['loyalty.card'].browse(card_id).exists()
if card and card.program_id.program_type == 'subscription':
card.points = 0.0
return res