100 lines
4.1 KiB
Python
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.")
|