feat: implement online order management system for POS and Sale orders with KDS integration
This commit is contained in:
parent
375101a50f
commit
85873ae560
@ -41,10 +41,36 @@ class PosOrder(models.Model):
|
|||||||
order.online_customer_name = order.partner_id.name or 'Guest'
|
order.online_customer_name = order.partner_id.name or 'Guest'
|
||||||
|
|
||||||
def action_confirm_online_order(self):
|
def action_confirm_online_order(self):
|
||||||
"""Cashier confirms the online order → sends to KDS"""
|
"""Cashier confirms the online order → sends to KDS and marks as paid if already paid online"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
self.write({'online_order_status': 'confirmed'})
|
self.write({'online_order_status': 'confirmed'})
|
||||||
|
|
||||||
|
# If it's an online order with an online payment option, mark as paid in POS to avoid confusion
|
||||||
|
if self.is_online_order and self.sale_order_id and self.sale_order_id.payment_option == 'online_gateway':
|
||||||
|
# Check if it needs payment (not yet paid in POS)
|
||||||
|
if self.state == 'draft' and self.amount_total > 0 and self.amount_paid < self.amount_total:
|
||||||
|
# Find a suitable payment method (Online Payment or Stripe)
|
||||||
|
# We prioritize methods linked to the current POS config
|
||||||
|
payment_method = self._get_online_payment_method()
|
||||||
|
|
||||||
|
if payment_method:
|
||||||
|
_logger.info("Automatically adding online payment from Stripe gateway for order %s using method %s", self.name, payment_method.name)
|
||||||
|
|
||||||
|
# Create pos.payment record
|
||||||
|
self.env['pos.payment'].create({
|
||||||
|
'amount': self.amount_total - self.amount_paid,
|
||||||
|
'payment_date': fields.Datetime.now(),
|
||||||
|
'payment_method_id': payment_method.id,
|
||||||
|
'pos_order_id': self.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
# Update order state if fully paid
|
||||||
|
if self.amount_total <= self.amount_paid:
|
||||||
|
# Process the order as paid
|
||||||
|
self.action_pos_order_paid()
|
||||||
|
else:
|
||||||
|
_logger.warning("Could not find a suitable POS Payment Method for online order %s", self.name)
|
||||||
|
|
||||||
# Set all order lines to 'waiting' so KDS picks them up
|
# Set all order lines to 'waiting' so KDS picks them up
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
if line.product_id.is_kitchen_item and line.product_id.type != 'service':
|
if line.product_id.is_kitchen_item and line.product_id.type != 'service':
|
||||||
@ -94,6 +120,34 @@ class PosOrder(models.Model):
|
|||||||
vals['fulfilment_type'] = session.config_id.kiosk_service_mode or 'pickup'
|
vals['fulfilment_type'] = session.config_id.kiosk_service_mode or 'pickup'
|
||||||
return super().create(vals_list)
|
return super().create(vals_list)
|
||||||
|
|
||||||
|
def _get_online_payment_method(self):
|
||||||
|
"""Find a suitable POS payment method for online/stripe payments"""
|
||||||
|
# 1. Look for methods in the current config first
|
||||||
|
if self.config_id:
|
||||||
|
for method in self.config_id.payment_method_ids:
|
||||||
|
if 'online' in method.name.lower() or 'stripe' in method.name.lower():
|
||||||
|
return method
|
||||||
|
|
||||||
|
# Fallback to any non-cash method in config
|
||||||
|
for method in self.config_id.payment_method_ids:
|
||||||
|
if not method.is_cash_count:
|
||||||
|
return method
|
||||||
|
|
||||||
|
# 2. Global search if config search fails
|
||||||
|
method = self.env['pos.payment.method'].search([
|
||||||
|
('name', 'ilike', 'Online'),
|
||||||
|
], limit=1)
|
||||||
|
if not method:
|
||||||
|
method = self.env['pos.payment.method'].search([
|
||||||
|
('name', 'ilike', 'Stripe'),
|
||||||
|
], limit=1)
|
||||||
|
if not method:
|
||||||
|
method = self.env['pos.payment.method'].search([
|
||||||
|
('is_cash_count', '=', False)
|
||||||
|
], limit=1)
|
||||||
|
|
||||||
|
return method
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def get_online_orders(self, config_id):
|
def get_online_orders(self, config_id):
|
||||||
"""Fetch pending online orders for a specific POS config"""
|
"""Fetch pending online orders for a specific POS config"""
|
||||||
|
|||||||
@ -91,6 +91,20 @@ class SaleOrderOnline(models.Model):
|
|||||||
# Link back to sale order
|
# Link back to sale order
|
||||||
sale_order.write({'pos_order_id': pos_order.id})
|
sale_order.write({'pos_order_id': pos_order.id})
|
||||||
|
|
||||||
|
# If paid online via gateway, record payment in POS immediately
|
||||||
|
if sale_order.payment_option == 'online_gateway' and sale_order.amount_total > 0:
|
||||||
|
payment_method = pos_order._get_online_payment_method()
|
||||||
|
if payment_method:
|
||||||
|
_logger.info("Recording online payment for POS order %s from Sale Order %s", pos_order.name, sale_order.name)
|
||||||
|
pos_order.env['pos.payment'].create({
|
||||||
|
'amount': sale_order.amount_total,
|
||||||
|
'payment_date': fields.Datetime.now(),
|
||||||
|
'payment_method_id': payment_method.id,
|
||||||
|
'pos_order_id': pos_order.id,
|
||||||
|
})
|
||||||
|
# Process as paid so the state changes and payment button disappears
|
||||||
|
pos_order.action_pos_order_paid()
|
||||||
|
|
||||||
# Set all lines to a "hold" state - they will go to KDS only when cashier confirms
|
# Set all lines to a "hold" state - they will go to KDS only when cashier confirms
|
||||||
for line in pos_order.lines:
|
for line in pos_order.lines:
|
||||||
if line.product_id.is_kitchen_item:
|
if line.product_id.is_kitchen_item:
|
||||||
|
|||||||
12
scratch/list_payment_methods.py
Normal file
12
scratch/list_payment_methods.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from odoo import api, SUPERUSER_ID
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
def list_payment_methods():
|
||||||
|
env = api.Environment(request.cr, SUPERUSER_ID, {})
|
||||||
|
methods = env['pos.payment.method'].search([])
|
||||||
|
print("POS Payment Methods:")
|
||||||
|
for m in methods:
|
||||||
|
print(f"ID: {m.id}, Name: {m.name}, Is Cash: {m.is_cash_count}, Journal: {m.journal_id.name if m.journal_id else 'None'}")
|
||||||
|
|
||||||
|
# This is just a draft, I can't run it easily without request context.
|
||||||
|
# I'll use a better approach: search in code if there's any reference to a specific payment method name.
|
||||||
Loading…
x
Reference in New Issue
Block a user