odoo-testing-addons/addons/dine360_kds/models/website_sale_integration.py

100 lines
4.1 KiB
Python

from odoo import models, fields, api, _
import logging
_logger = logging.getLogger(__name__)
class SaleOrder(models.Model):
_inherit = 'sale.order'
def action_confirm(self):
"""
Override to create a POS Order for KDS when a Website Order is confirmed.
"""
res = super(SaleOrder, self).action_confirm()
for order in self:
# Check if it's a website order (usually has website_id)
if order.website_id:
try:
self._create_pos_order_for_kds(order)
except Exception as e:
_logger.error(f"Failed to create POS order for Website Order {order.name}: {str(e)}")
return res
def _create_pos_order_for_kds(self, sale_order):
"""Create a POS Order based on the Sale Order details"""
# Use a savepoint so that if KDS creation fails, the main Sale Order confirmation succeeds
with self.env.cr.savepoint():
PosOrder = self.env['pos.order']
PosSession = self.env['pos.session']
PosConfig = self.env['pos.config']
# 1. Find a suitable POS Config (e.g., 'Website' or first available restaurant)
config = PosConfig.search([('module_pos_restaurant', '=', True), ('active', '=', True)], limit=1)
if not config:
_logger.warning("No active POS Restaurant configuration found. Skipping KDS creation.")
return
# 2. Find or Open a Session
session = PosSession.search([
('config_id', '=', config.id),
('state', '=', 'opened')
], limit=1)
if not session:
_logger.warning(f"No open POS session found for config {config.name}. Cannot send to KDS.")
return
# 3. Create POS Order Lines
lines_data = []
for line in sale_order.order_line:
if not line.product_id:
continue
qty = line.product_uom_qty
if qty <= 0:
continue
# Skip non-kitchen items (delivery charges, shipping, etc.)
if not line.product_id.is_kitchen_item:
continue
lines_data.append((0, 0, {
'product_id': line.product_id.id,
'qty': qty,
'price_unit': line.price_unit,
'price_subtotal': line.price_subtotal,
'price_subtotal_incl': line.price_total,
'full_product_name': line.name,
'tax_ids': [(6, 0, line.tax_id.ids)],
# Key for KDS:
'preparation_status': 'waiting',
'customer_note': 'Web Order',
}))
if not lines_data:
return
# Generate proper POS reference using sequence
pos_reference = session.config_id.sequence_id.next_by_id() if session.config_id.sequence_id else f"Order {sale_order.name}"
# 4. Create POS Order (in Draft/New state to avoid double accounting)
pos_order = PosOrder.create({
'session_id': session.id,
'company_id': sale_order.company_id.id,
'partner_id': sale_order.partner_id.id,
'pricelist_id': sale_order.pricelist_id.id or session.config_id.pricelist_id.id,
'pos_reference': pos_reference,
'lines': lines_data,
'amount_total': sale_order.amount_total,
'amount_tax': sale_order.amount_tax,
'amount_paid': 0.0, # Not processing payment in POS to avoid duplication
'amount_return': 0.0,
'note': f"From Website Order {sale_order.name}",
# 'state': 'draft', # Default is draft
})
# Trigger KDS notification (handled by create method of pos.order.line in dine360_kds)
_logger.info(f"Created POS Order {pos_order.name} from Website Order {sale_order.name} for KDS.")