109 lines
4.5 KiB
Python
109 lines
4.5 KiB
Python
from odoo import models, fields, api, _
|
|
from odoo.exceptions import ValidationError
|
|
from datetime import timedelta
|
|
import pytz
|
|
|
|
class RestaurantReservation(models.Model):
|
|
_name = 'restaurant.reservation'
|
|
_description = 'Restaurant Table Reservation'
|
|
_order = 'start_time desc'
|
|
|
|
name = fields.Char(string='Reservation Reference', required=True, copy=False, readonly=True, default=lambda self: _('New'))
|
|
customer_name = fields.Char(string='Customer Name', required=True)
|
|
phone = fields.Char(string='Phone Number', required=True)
|
|
email = fields.Char(string='Email')
|
|
num_people = fields.Integer(string='Number of People', default=1)
|
|
|
|
floor_id = fields.Many2one('restaurant.floor', string='Floor', required=True)
|
|
table_id = fields.Many2one('restaurant.table', string='Table', required=True)
|
|
|
|
start_time = fields.Datetime(string='Start Time', required=True)
|
|
end_time = fields.Datetime(string='End Time', required=True)
|
|
|
|
whatsapp_url = fields.Char(compute='_compute_whatsapp_url')
|
|
|
|
def _compute_whatsapp_url(self):
|
|
for rec in self:
|
|
if rec.phone and rec.customer_name and rec.start_time:
|
|
msg = f"Hello {rec.customer_name}, your reservation {rec.name or ''} for {rec.start_time.strftime('%I:%M %p')} is confirmed!"
|
|
rec.whatsapp_url = f"https://wa.me/{rec.phone}?text={msg.replace(' ', '%20')}"
|
|
else:
|
|
rec.whatsapp_url = False
|
|
|
|
state = fields.Selection([
|
|
('draft', 'Draft'),
|
|
('confirmed', 'Confirmed'),
|
|
('completed', 'Completed'),
|
|
('cancelled', 'Cancelled')
|
|
], string='Status', default='draft', tracking=True)
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
if vals.get('name', _('New')) == _('New'):
|
|
vals['name'] = self.env['ir.sequence'].next_by_code('restaurant.reservation') or _('New')
|
|
return super(RestaurantReservation, self).create(vals)
|
|
|
|
@api.constrains('table_id', 'start_time', 'end_time', 'state')
|
|
def _check_overlap(self):
|
|
for rec in self:
|
|
if rec.state in ['confirmed', 'completed']:
|
|
overlap = self.search([
|
|
('id', '!=', rec.id),
|
|
('table_id', '=', rec.table_id.id),
|
|
('state', '=', 'confirmed'),
|
|
('start_time', '<', rec.end_time),
|
|
('end_time', '>', rec.start_time),
|
|
])
|
|
if overlap:
|
|
raise ValidationError(_('This table is already reserved for the selected time slot.'))
|
|
|
|
@api.constrains('start_time', 'end_time')
|
|
def _check_opening_hours(self):
|
|
restaurant_tz = pytz.timezone('America/Toronto')
|
|
for rec in self:
|
|
local_start = pytz.utc.localize(rec.start_time).astimezone(restaurant_tz)
|
|
local_end = pytz.utc.localize(rec.end_time).astimezone(restaurant_tz)
|
|
|
|
day = local_start.weekday() # 0=Mon, 6=Sun
|
|
time_start = local_start.hour + local_start.minute / 60.0
|
|
time_end = local_end.hour + local_end.minute / 60.0
|
|
|
|
if day in [6, 0, 1, 2, 3]: # Sun-Thu
|
|
if time_start < 12.0 or time_end > 21.0:
|
|
raise ValidationError(_('Reservations for Sunday - Thursday must be between 12:00 PM and 9:00 PM (Local Time).'))
|
|
else: # Fri-Sat
|
|
if time_start < 12.0 or time_end > 23.0:
|
|
raise ValidationError(_('Reservations for Friday & Saturday must be between 12:00 PM and 11:00 PM (Local Time).'))
|
|
|
|
@api.onchange('start_time')
|
|
def _onchange_start_time(self):
|
|
if self.start_time:
|
|
self.end_time = self.start_time + timedelta(hours=1)
|
|
|
|
def action_confirm(self):
|
|
self.write({'state': 'confirmed'})
|
|
self._send_confirmation_notification()
|
|
|
|
def action_complete(self):
|
|
self.write({'state': 'completed'})
|
|
|
|
def action_cancel(self):
|
|
self.write({'state': 'cancelled'})
|
|
|
|
def _send_confirmation_notification(self):
|
|
""" Placeholder for WhatsApp/SMS logic """
|
|
for rec in self:
|
|
# Logic for WhatsApp/SMS can be added here
|
|
# e.g., self.env['sms.api']._send_sms(rec.phone, "Your table is confirmed!")
|
|
pass
|
|
|
|
@api.model
|
|
def _auto_complete_reservations(self):
|
|
""" Scheduled action to mark past reservations as completed """
|
|
now = fields.Datetime.now()
|
|
past_reservations = self.search([
|
|
('state', '=', 'confirmed'),
|
|
('end_time', '<', now)
|
|
])
|
|
past_reservations.write({'state': 'completed'})
|