from odoo import models, fields, api, _ import logging _logger = logging.getLogger(__name__) class PosOrder(models.Model): _inherit = 'pos.order' is_online_order = fields.Boolean( string='Online Order', default=False, help='Indicates this order came from the website shop' ) online_order_status = fields.Selection([ ('pending', 'Pending'), ('confirmed', 'Confirmed'), ('rejected', 'Rejected'), ], string='Online Order Status', default='pending') sale_order_id = fields.Many2one( 'sale.order', string='Source Sale Order', help='The website sale order that generated this POS order' ) online_customer_name = fields.Char( string='Online Customer', compute='_compute_online_customer_name', store=True ) online_order_date = fields.Datetime( string='Online Order Date', default=fields.Datetime.now ) # Note: order_source and fulfilment_type fields are defined in dine360_order_channels # dine360_online_orders just uses these fields @api.depends('partner_id', 'partner_id.name') def _compute_online_customer_name(self): for order in self: order.online_customer_name = order.partner_id.name or 'Guest' def action_confirm_online_order(self): """Cashier confirms the online order → sends to KDS""" self.ensure_one() self.write({'online_order_status': 'confirmed'}) # Set all order lines to 'waiting' so KDS picks them up for line in self.lines: if line.product_id.is_kitchen_item and line.product_id.type != 'service': line.write({ 'preparation_status': 'waiting', }) # Notify KDS self.lines.filtered( lambda l: l.product_id.is_kitchen_item and l.product_id.type != 'service' )._notify_kds() # Notify POS that order was confirmed if self.config_id: channel = "online_orders_%s" % self.config_id.id self.env['bus.bus']._sendone(channel, 'online_order_confirmed', { 'order_id': self.id, 'order_name': self.pos_reference or self.name, }) _logger.info("Online order %s confirmed and sent to KDS", self.name) return True def action_reject_online_order(self): """Cashier rejects the online order""" self.ensure_one() self.write({'online_order_status': 'rejected'}) # Notify POS if self.config_id: channel = "online_orders_%s" % self.config_id.id self.env['bus.bus']._sendone(channel, 'online_order_rejected', { 'order_id': self.id, 'order_name': self.pos_reference or self.name, }) _logger.info("Online order %s rejected", self.name) return True @api.model_create_multi def create(self, vals_list): for vals in vals_list: if 'session_id' in vals: session = self.env['pos.session'].browse(vals['session_id']) if session.config_id.is_kiosk: vals['order_source'] = 'kiosk' vals['fulfilment_type'] = session.config_id.kiosk_service_mode or 'pickup' return super().create(vals_list) @api.model def get_online_orders(self, config_id): """Fetch pending online orders for a specific POS config""" domain = [ ('is_online_order', '=', True), ('online_order_status', '=', 'pending'), ('config_id', '=', config_id), ] orders = self.search(domain, order='online_order_date desc') result = [] for order in orders: lines = [] for line in order.lines: lines.append({ 'id': line.id, 'product_name': line.full_product_name or line.product_id.name, 'qty': line.qty, 'price_unit': line.price_unit, 'price_subtotal_incl': line.price_subtotal_incl, 'customer_note': line.customer_note or '', 'is_kitchen_item': line.product_id.is_kitchen_item, }) result.append({ 'id': order.id, 'name': order.pos_reference or order.name, 'partner_name': order.partner_id.name or 'Guest', 'partner_phone': order.partner_id.phone or order.partner_id.mobile or '', 'amount_total': order.amount_total, 'date_order': order.date_order.isoformat() if order.date_order else '', 'sale_order_name': order.sale_order_id.name if order.sale_order_id else '', 'service_mode': order.fulfilment_type, 'order_source': order.order_source, 'note': order.note or '', 'lines': lines, }) return result