summaryrefslogtreecommitdiff
path: root/addons/lunch/models/lunch_alert.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/lunch/models/lunch_alert.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/lunch/models/lunch_alert.py')
-rw-r--r--addons/lunch/models/lunch_alert.py119
1 files changed, 119 insertions, 0 deletions
diff --git a/addons/lunch/models/lunch_alert.py b/addons/lunch/models/lunch_alert.py
new file mode 100644
index 00000000..9110f792
--- /dev/null
+++ b/addons/lunch/models/lunch_alert.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+import pytz
+
+from odoo import api, fields, models
+from odoo.osv import expression
+
+from .lunch_supplier import float_to_time
+from datetime import datetime, timedelta
+
+from odoo.addons.base.models.res_partner import _tz_get
+
+WEEKDAY_TO_NAME = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
+
+class LunchAlert(models.Model):
+ """ Alerts to display during a lunch order. An alert can be specific to a
+ given day, weekly or daily. The alert is displayed from start to end hour. """
+ _name = 'lunch.alert'
+ _description = 'Lunch Alert'
+ _order = 'write_date desc, id'
+
+ name = fields.Char('Alert Name', required=True, translate=True)
+ message = fields.Html('Message', required=True, translate=True)
+
+ mode = fields.Selection([
+ ('alert', 'Alert in app'),
+ ('chat', 'Chat notification')], string='Display', default='alert')
+ recipients = fields.Selection([
+ ('everyone', 'Everyone'),
+ ('last_week', 'Employee who ordered last week'),
+ ('last_month', 'Employee who ordered last month'),
+ ('last_year', 'Employee who ordered last year')], string='Recipients', default='everyone')
+ notification_time = fields.Float(default=10.0, string='Notification Time')
+ notification_moment = fields.Selection([
+ ('am', 'AM'),
+ ('pm', 'PM')], default='am', required=True)
+ tz = fields.Selection(_tz_get, string='Timezone', required=True, default=lambda self: self.env.user.tz or 'UTC')
+
+ until = fields.Date('Show Until')
+ recurrency_monday = fields.Boolean('Monday', default=True)
+ recurrency_tuesday = fields.Boolean('Tuesday', default=True)
+ recurrency_wednesday = fields.Boolean('Wednesday', default=True)
+ recurrency_thursday = fields.Boolean('Thursday', default=True)
+ recurrency_friday = fields.Boolean('Friday', default=True)
+ recurrency_saturday = fields.Boolean('Saturday', default=True)
+ recurrency_sunday = fields.Boolean('Sunday', default=True)
+
+ available_today = fields.Boolean('Is Displayed Today',
+ compute='_compute_available_today', search='_search_available_today')
+
+ active = fields.Boolean('Active', default=True)
+
+ location_ids = fields.Many2many('lunch.location', string='Location')
+
+ _sql_constraints = [
+ ('notification_time_range',
+ 'CHECK(notification_time >= 0 and notification_time <= 12)',
+ 'Notification time must be between 0 and 12')
+ ]
+
+ @api.depends('recurrency_monday', 'recurrency_tuesday', 'recurrency_wednesday',
+ 'recurrency_thursday', 'recurrency_friday', 'recurrency_saturday',
+ 'recurrency_sunday')
+ def _compute_available_today(self):
+ today = fields.Date.context_today(self)
+ fieldname = 'recurrency_%s' % (WEEKDAY_TO_NAME[today.weekday()])
+
+ for alert in self:
+ alert.available_today = alert.until > today if alert.until else True and alert[fieldname]
+
+ def _search_available_today(self, operator, value):
+ if (not operator in ['=', '!=']) or (not value in [True, False]):
+ return []
+
+ searching_for_true = (operator == '=' and value) or (operator == '!=' and not value)
+ today = fields.Date.context_today(self)
+ fieldname = 'recurrency_%s' % (WEEKDAY_TO_NAME[today.weekday()])
+
+ return expression.AND([
+ [(fieldname, operator, value)],
+ expression.OR([
+ [('until', '=', False)],
+ [('until', '>' if searching_for_true else '<', today)],
+ ])
+ ])
+
+ def _notify_chat(self):
+ records = self.search([('mode', '=', 'chat'), ('active', '=', True)])
+
+ today = fields.Date.today()
+ now = fields.Datetime.now()
+
+ for alert in records:
+ notification_to = now.astimezone(pytz.timezone(alert.tz)).replace(second=0, microsecond=0, tzinfo=None)
+ notification_from = notification_to - timedelta(minutes=5)
+ send_at = datetime.combine(fields.Date.today(),
+ float_to_time(alert.notification_time, alert.notification_moment))
+
+ if alert.available_today and send_at > notification_from and send_at <= notification_to:
+ order_domain = [('state', '!=', 'cancelled')]
+
+ if alert.location_ids.ids:
+ order_domain = expression.AND([order_domain, [('user_id.last_lunch_location_id', 'in', alert.location_ids.ids)]])
+
+ if alert.recipients != 'everyone':
+ weeks = 1
+
+ if alert.recipients == 'last_month':
+ weeks = 4
+ else: # last_year
+ weeks = 52
+
+ delta = timedelta(weeks=weeks)
+ order_domain = expression.AND([order_domain, [('date', '>=', today - delta)]])
+
+ orders = self.env['lunch.order'].search(order_domain).mapped('user_id')
+ partner_ids = [user.partner_id.id for user in orders]
+ if partner_ids:
+ self.env['mail.thread'].message_notify(body=alert.message, partner_ids=partner_ids)