summaryrefslogtreecommitdiff
path: root/addons/coupon/models/coupon.py
diff options
context:
space:
mode:
authorJoseph Caburnay <jcb@odoo.com>2019-10-10 11:45:35 +0000
committerPierre Masereel <pim@odoo.com>2020-05-08 14:27:29 +0000
commitafad149eb8a542b39e9508a458d7aeb43aeb60ed (patch)
tree80b405cfb2d6050e848120a071ce2ed22c712932 /addons/coupon/models/coupon.py
parentef05ca2812c3407dddd20921604661726c859d74 (diff)
[REF] *_sale_coupon: create coupon module
This refactoring extracts parts of `sale_coupon` module to create a more generic module called `coupon`. This new module can be extended in different sales modules to implement functionalities specific to modules that extend it.
Diffstat (limited to 'addons/coupon/models/coupon.py')
-rw-r--r--addons/coupon/models/coupon.py57
1 files changed, 10 insertions, 47 deletions
diff --git a/addons/coupon/models/coupon.py b/addons/coupon/models/coupon.py
index 2dbc15a6ecf..5f023906f4b 100644
--- a/addons/coupon/models/coupon.py
+++ b/addons/coupon/models/coupon.py
@@ -6,9 +6,9 @@ from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
-class SaleCoupon(models.Model):
- _name = 'sale.coupon'
- _description = "Sales Coupon"
+class Coupon(models.Model):
+ _name = 'coupon.coupon'
+ _description = "Coupon"
_rec_name = 'code'
@api.model
@@ -19,7 +19,7 @@ class SaleCoupon(models.Model):
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
+ Generate 8 bytes (64 bits) barcodes as 16 bytes barcodes are not
compatible with all scanners.
"""
return str(random.getrandbits(64))
@@ -35,11 +35,7 @@ class SaleCoupon(models.Model):
('cancel', 'Cancelled')
], required=True, default='new')
partner_id = fields.Many2one('res.partner', "For Customer")
- program_id = fields.Many2one('sale.coupon.program', "Program")
- order_id = fields.Many2one('sale.order', 'Order Reference', readonly=True,
- help="The sales order from which coupon is generated")
- sales_order_id = fields.Many2one('sale.order', 'Used in', readonly=True,
- help="The sales order on which the coupon is applied")
+ 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.')
@@ -47,54 +43,21 @@ class SaleCoupon(models.Model):
('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 _check_coupon_code(self, order):
- message = {}
- applicable_programs = order._get_applicable_programs()
- 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_order.date()):
- message = {'error': _('This coupon is expired (%s).') % (self.code)}
- # Minimum requirement should not be checked if the coupon got generated by a promotion program (the requirement should have only be checked to generate the coupon)
- elif self.program_id.program_type == 'coupon_program' and not self.program_id._filter_on_mimimum_amount(order):
- message = {'error': _('A minimum of %s %s should be purchased to get the reward') % (self.program_id.rule_minimum_amount, self.program_id.currency_id.name)}
- 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 != order.partner_id:
- message = {'error': _('Invalid partner.')}
- elif self.program_id in order.applied_coupon_ids.mapped('program_id'):
- message = {'error': _('A Coupon is already applied for the same reward')}
- elif self.program_id._is_global_discount_program() and order._is_global_discount_already_applied():
- message = {'error': _('Global discounts are not cumulable.')}
- elif self.program_id.reward_type == 'product' and not order._is_reward_in_order_lines(self.program_id):
- message = {'error': _('The reward products should be in the sales order lines to apply the discount.')}
- elif not self.program_id._is_valid_partner(order.partner_id):
- message = {'error': _("The customer doesn't have access to this reward.")}
- # Product requirement should not be checked if the coupon got generated by a promotion program (the requirement should have only be checked to generate the coupon)
- elif self.program_id.program_type == 'coupon_program' and not self.program_id._filter_programs_on_products(order):
- message = {'error': _("You don't have the required product quantities on your sales order. All the products should be recorded on the sales order. (Example: You need to have 3 T-shirts on your sales order if the promotion is 'Buy 2, Get 1 Free').")}
- else:
- if self.program_id not in applicable_programs and self.program_id.promo_applicability == 'on_current_order':
- message = {'error': _('At least one of the required conditions is not met to get the reward!')}
- return message
-
def action_coupon_sent(self):
""" Open a window to compose an email, with the edi invoice template
message loaded by default
"""
self.ensure_one()
- template = self.env.ref('sale_coupon.mail_template_sale_coupon', False)
+ template = self.env.ref('coupon.mail_template_sale_coupon', False)
compose_form = self.env.ref('mail.email_compose_message_wizard_form', False)
ctx = dict(
- default_model='sale.coupon',
+ default_model='coupon.coupon',
default_res_id=self.id,
default_use_template=bool(template),
default_template_id=template.id,
@@ -119,8 +82,8 @@ class SaleCoupon(models.Model):
def cron_expire_coupon(self):
self._cr.execute("""
- SELECT C.id FROM SALE_COUPON as C
- INNER JOIN SALE_COUPON_PROGRAM as P ON C.program_id = P.id
+ 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()""")