133 lines
6.8 KiB
Python

from odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
class Dine360OnlineOrders(http.Controller):
@http.route('/shop/update_service_mode', type='json', auth="public", website=True)
def update_service_mode(self, service_mode, **post):
order = request.website.sale_get_order()
if order and service_mode in ['pickup', 'delivery', 'dine_in']:
order.sudo().write({
'fulfilment_type': service_mode,
'order_source': 'online'
})
return True
class Dine360WebsiteSaleOnline(WebsiteSale):
@http.route(['/shop/cart'], type='http', auth="public", website=True, sitemap=False)
def cart(self, **post):
"""When user visits cart, remove any delivery fee so cart shows ONLY food items subtotal and tax"""
request.session.pop('address_confirmed_for_order', None)
order = request.website.sale_get_order()
if order and order.state == 'draft':
delivery_lines = order.order_line.filtered(lambda l: l.is_delivery)
if delivery_lines:
delivery_lines.sudo().unlink()
order.sudo().write({
'carrier_id': False,
'uber_delivery_fee': 0.0
})
return super(Dine360WebsiteSaleOnline, self).cart(**post)
@http.route(['/shop/cart/update_json'], type='json', auth="public", methods=['POST'], website=True, csrf=False)
def cart_update_json(self, *args, **kwargs):
"""Ensure delivery fee is not shown when modifying cart quantities"""
res = super(Dine360WebsiteSaleOnline, self).cart_update_json(*args, **kwargs)
order = request.website.sale_get_order()
if order and order.state == 'draft':
delivery_lines = order.order_line.filtered(lambda l: l.is_delivery)
if delivery_lines:
delivery_lines.sudo().unlink()
order.sudo().write({
'carrier_id': False,
'uber_delivery_fee': 0.0
})
return res
@http.route(['/shop/checkout'], type='http', auth="public", website=True, sitemap=False)
def checkout(self, **post):
"""Enforce redirect to address & fulfillment selection page every single time from cart"""
order = request.website.sale_get_order()
if not order or order.state != 'draft':
return request.redirect('/shop')
if not order.order_line:
return request.redirect('/shop/cart')
# If user has already selected & submitted the address in this flow, proceed to standard checkout/payment
if post.get('express') or request.session.get('address_confirmed_for_order') == order.id:
return super(Dine360WebsiteSaleOnline, self).checkout(**post)
# Otherwise, always direct to the unified delivery/pickup address page
partner_id = order.partner_id.id if order.partner_id else 0
return request.redirect(f'/shop/address?mode=billing&partner_id={partner_id}')
@http.route(['/shop/address'], type='http', methods=['GET', 'POST'], auth="public", website=True, sitemap=False)
def address(self, **post):
"""Process address form submission, record fulfillment type, and mark address as confirmed"""
order = request.website.sale_get_order()
if post.get('submitted'):
if order:
request.session['address_confirmed_for_order'] = order.id
fulfilment_type = post.get('fulfilment_type', 'delivery')
order.sudo().write({
'fulfilment_type': fulfilment_type,
'order_source': 'online'
})
# For store pickup orders, auto-populate dummy fields so Odoo's backend validation succeeds
if post.get('fulfilment_type') == 'pickup':
if not post.get('street'): post['street'] = 'Store Pickup'
if not post.get('city'): post['city'] = 'Local'
if not post.get('zip'): post['zip'] = '00000'
if not post.get('country_id'):
country = request.env['res.country'].sudo().search([], limit=1)
post['country_id'] = str(country.id) if country else ''
for k, v in post.items():
if k in ['street', 'city', 'zip', 'country_id']:
if hasattr(request.params, 'update'):
try:
request.params[k] = v
except TypeError:
pass
return super(Dine360WebsiteSaleOnline, self).address(**post)
@http.route(['/shop/payment'], type='http', auth="public", website=True, sitemap=False)
def shop_payment(self, **post):
"""Ensure customer came from address selection, and bypass missing delivery carrier validation"""
order = request.website.sale_get_order()
if not order or order.state != 'draft' or not order.order_line:
return request.redirect('/shop/cart')
# If user directly visits /shop/payment without passing the address & fulfillment page, redirect them
if request.session.get('address_confirmed_for_order') != order.id:
partner_id = order.partner_id.id if order.partner_id else 0
return request.redirect(f'/shop/address?mode=billing&partner_id={partner_id}')
# For delivery orders, ensure the delivery line is active and reflects the stored fee
if order.fulfilment_type == 'delivery':
delivery_line = order.order_line.filtered(lambda l: l.is_delivery)
fee = getattr(order, 'uber_delivery_fee', 0.0)
if not delivery_line and fee > 0 and hasattr(order, '_add_uber_delivery_fee'):
order.sudo()._add_uber_delivery_fee(fee)
elif order.fulfilment_type in ['pickup', 'dine_in']:
# Ensure no leftover delivery line for pickup
order.order_line.filtered(lambda l: l.is_delivery).sudo().unlink()
return super(Dine360WebsiteSaleOnline, self).shop_payment(**post)
@http.route('/shop/payment/transaction/<int:order_id>', type='json', auth="public", website=True)
def shop_payment_transaction(self, order_id, access_token=None, **kwargs):
"""Preserve delivery fee during payment transaction initiation"""
order = request.env['sale.order'].sudo().browse(order_id)
if order and order.fulfilment_type == 'delivery':
delivery_line = order.order_line.filtered(lambda l: l.is_delivery)
fee = getattr(order, 'uber_delivery_fee', 0.0)
if not delivery_line and fee > 0 and hasattr(order, '_add_uber_delivery_fee'):
order._add_uber_delivery_fee(fee)
return super(Dine360WebsiteSaleOnline, self).shop_payment_transaction(order_id, access_token=access_token, **kwargs)