From 5f34bf941938c9bd3763dd7151489a1b6282fa0b Mon Sep 17 00:00:00 2001 From: Alaguraj0361 Date: Sat, 11 Apr 2026 12:45:24 +0530 Subject: [PATCH] implement website order to POS integration with cashier confirmation for KDS dispatch and update docker configuration --- .../models/website_sale_integration.py | 5 ++- .../dine360_online_orders/models/pos_order.py | 37 ++++++++++++++----- .../models/sale_order.py | 27 +++++++++++--- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/addons/dine360_kds/models/website_sale_integration.py b/addons/dine360_kds/models/website_sale_integration.py index d0c0f91..da29b71 100644 --- a/addons/dine360_kds/models/website_sale_integration.py +++ b/addons/dine360_kds/models/website_sale_integration.py @@ -56,8 +56,9 @@ class SaleOrder(models.Model): if qty <= 0: continue - # Skip non-kitchen items (delivery charges, shipping, etc.) - if not line.product_id.is_kitchen_item or line.product_id.type == 'service': + # Skip non-kitchen items, but allow delivery lines for accurate total matching + is_delivery_line = getattr(line, 'is_delivery', False) + if not is_delivery_line and (not line.product_id.is_kitchen_item or line.product_id.type == 'service'): continue lines_data.append((0, 0, { diff --git a/addons/dine360_online_orders/models/pos_order.py b/addons/dine360_online_orders/models/pos_order.py index 7fa6131..1fffd6f 100644 --- a/addons/dine360_online_orders/models/pos_order.py +++ b/addons/dine360_online_orders/models/pos_order.py @@ -45,8 +45,12 @@ class PosOrder(models.Model): self.ensure_one() 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': + # If it's an online order with an online payment option or Stripe txn, mark as paid in POS to avoid confusion + has_paid_transaction = False + if self.sale_order_id: + has_paid_transaction = any(t.state in ['authorized', 'done'] for t in self.sale_order_id.transaction_ids) + + if self.is_online_order and self.sale_order_id and (self.sale_order_id.payment_option == 'online_gateway' or has_paid_transaction): # 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) @@ -56,18 +60,31 @@ class PosOrder(models.Model): 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, + # Use add_payment if it exists, otherwise manual creation + payment_data = { + 'amount': self.amount_total, 'payment_date': fields.Datetime.now(), 'payment_method_id': payment_method.id, 'pos_order_id': self.id, - }) + } + if hasattr(self, 'add_payment'): + self.add_payment(payment_data) + else: + self.env['pos.payment'].create(payment_data) - # Update order state if fully paid - if self.amount_total <= self.amount_paid: - # Process the order as paid - self.action_pos_order_paid() + # Force recomputation of amount_paid + self.env.flush_all() + self.invalidate_recordset(['payment_ids', 'amount_paid']) + + # Instead of relying strictly on action_pos_order_paid which throws UserError on cache lag, + # we force the state logic directly if we just paid the exact full amount. + self.write({'state': 'paid'}) + try: + self._create_order_picking() + except AttributeError: + _logger.warning("No _create_order_picking method found on POS order") + except Exception as e: + _logger.error("Error creating picking for online POS order: %s", str(e)) else: _logger.warning("Could not find a suitable POS Payment Method for online order %s", self.name) diff --git a/addons/dine360_online_orders/models/sale_order.py b/addons/dine360_online_orders/models/sale_order.py index 0534074..6e54dc7 100644 --- a/addons/dine360_online_orders/models/sale_order.py +++ b/addons/dine360_online_orders/models/sale_order.py @@ -125,19 +125,34 @@ class SaleOrderOnline(models.Model): # Link back to sale order 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: + # Check if paid via gateway (custom field) or standard Odoo transaction (Stripe, etc.) + has_paid_transaction = any(t.state in ['authorized', 'done'] for t in sale_order.transaction_ids) + if (sale_order.payment_option == 'online_gateway' or has_paid_transaction) 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({ + payment_data = { '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() + } + if hasattr(pos_order, 'add_payment'): + pos_order.add_payment(payment_data) + else: + pos_order.env['pos.payment'].create(payment_data) + + pos_order.env.flush_all() + pos_order.invalidate_recordset(['payment_ids', 'amount_paid']) + + # Process as paid so the state changes and payment button disappears safely + pos_order.write({'state': 'paid'}) + try: + pos_order._create_order_picking() + except AttributeError: + _logger.warning("No _create_order_picking method found on POS order") + except Exception as e: + _logger.error("Error creating picking for online POS order: %s", str(e)) # Set all lines to a "hold" state - they will go to KDS only when cashier confirms for line in pos_order.lines: