135 lines
4.9 KiB
Python
135 lines
4.9 KiB
Python
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
|