Files
odoo_source/addons/coupon/models/coupon.py
T
Joseph Caburnay 4d59d3d1f3 [REF][FIX] coupon,sale_coupon: move mail_template_sale_coupon
mail_template_sale_coupon is specific to sale_coupon so we are moving
it back to sale_coupon module. Additionally, we add a way of selecting
a mail template when generating coupons for customers.
2020-11-03 10:48:04 +00:00

117 lines
4.7 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import random
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
class Coupon(models.Model):
_name = 'coupon.coupon'
_description = "Coupon"
_rec_name = 'code'
@api.model
def _generate_code(self):
"""Generate a 20 char long pseudo-random string of digits for barcode
generation.
A decimal serialisation is longer than a hexadecimal one *but* it
generates a more compact barcode (Code128C rather than Code128A).
Generate 8 bytes (64 bits) barcodes as 16 bytes barcodes are not
compatible with all scanners.
"""
return str(random.getrandbits(64))
code = fields.Char(default=_generate_code, required=True, readonly=True)
expiration_date = fields.Date('Expiration Date', compute='_compute_expiration_date')
state = fields.Selection([
('reserved', 'Pending'),
('new', 'Valid'),
('sent', 'Sent'),
('used', 'Used'),
('expired', 'Expired'),
('cancel', 'Cancelled')
], required=True, default='new')
partner_id = fields.Many2one('res.partner', "For Customer")
program_id = fields.Many2one('coupon.program', "Program")
discount_line_product_id = fields.Many2one('product.product', related='program_id.discount_line_product_id', readonly=False,
help='Product used in the sales order to apply the discount.')
_sql_constraints = [
('unique_coupon_code', 'unique(code)', 'The coupon code must be unique!'),
]
@api.depends('create_date', 'program_id.validity_duration')
def _compute_expiration_date(self):
self.expiration_date = 0
for coupon in self.filtered(lambda x: x.program_id.validity_duration > 0):
coupon.expiration_date = (coupon.create_date + relativedelta(days=coupon.program_id.validity_duration)).date()
def _get_default_template(self):
return False
def action_coupon_sent(self):
""" Open a window to compose an email, with the edi invoice template
message loaded by default
"""
self.ensure_one()
default_template = self._get_default_template()
compose_form = self.env.ref('mail.email_compose_message_wizard_form', False)
ctx = dict(
default_model='coupon.coupon',
default_res_id=self.id,
default_use_template=bool(default_template),
default_template_id=default_template and default_template.id,
default_composition_mode='comment',
custom_layout='mail.mail_notification_light',
mark_coupon_as_sent=True,
force_email=True,
)
return {
'name': _('Compose Email'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form.id, 'form')],
'view_id': compose_form.id,
'target': 'new',
'context': ctx,
}
def action_coupon_cancel(self):
self.state = 'cancel'
def cron_expire_coupon(self):
self._cr.execute("""
SELECT C.id FROM COUPON_COUPON as C
INNER JOIN COUPON_PROGRAM as P ON C.program_id = P.id
WHERE C.STATE in ('reserved', 'new', 'sent')
AND P.validity_duration > 0
AND C.create_date + interval '1 day' * P.validity_duration < now()""")
expired_ids = [res[0] for res in self._cr.fetchall()]
self.browse(expired_ids).write({'state': 'expired'})
def _check_coupon_code(self, order_date, partner_id, **kwargs):
""" Check the validity of this single coupon.
:param order_date Date:
:param partner_id int | boolean:
"""
self.ensure_one()
message = {}
if self.state == 'used':
message = {'error': _('This coupon has already been used (%s).') % (self.code)}
elif self.state == 'reserved':
message = {'error': _('This coupon %s exists but the origin sales order is not validated yet.') % (self.code)}
elif self.state == 'cancel':
message = {'error': _('This coupon has been cancelled (%s).') % (self.code)}
elif self.state == 'expired' or (self.expiration_date and self.expiration_date < order_date):
message = {'error': _('This coupon is expired (%s).') % (self.code)}
elif not self.program_id.active:
message = {'error': _('The coupon program for %s is in draft or closed state') % (self.code)}
elif self.partner_id and self.partner_id.id != partner_id:
message = {'error': _('Invalid partner.')}
return message