summaryrefslogtreecommitdiff
path: root/addons/coupon/models/coupon.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/coupon/models/coupon.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/coupon/models/coupon.py')
-rw-r--r--addons/coupon/models/coupon.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/addons/coupon/models/coupon.py b/addons/coupon/models/coupon.py
new file mode 100644
index 00000000..5f023906
--- /dev/null
+++ b/addons/coupon/models/coupon.py
@@ -0,0 +1,92 @@
+# -*- 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 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('coupon.mail_template_sale_coupon', False)
+ 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(template),
+ default_template_id=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'})