configure Odoo container names and implement custom checkout UI with fulfillment selection and field validation

This commit is contained in:
Alaguraj0361 2026-04-08 12:59:32 +05:30
parent 132727a5bf
commit 3408b893cb
2 changed files with 79 additions and 28 deletions

View File

@ -288,12 +288,24 @@
if (data.result && data.result.success) { if (data.result && data.result.success) {
msgDiv.className = 'alert alert-success my-3 animated fadeIn'; msgDiv.className = 'alert alert-success my-3 animated fadeIn';
msgDiv.style.display = ''; msgDiv.style.display = '';
msgDiv.innerHTML = `<strong>✓ Delivery Available!</strong>Uber Delivery Fee: $${data.result.fee} (Distance Based)`; msgDiv.innerHTML = `<div class="d-flex align-items-center">
<i class="fa fa-check-circle me-3" style="font-size: 24px;"></i>
<div>
<strong>✓ Delivery Available!</strong><br/>
Uber Delivery Fee: $${data.result.fee} (Distance Based)
</div>
</div>`;
if (submitBtn) submitBtn.disabled = false; if (submitBtn) submitBtn.disabled = false;
} else { } else {
msgDiv.className = 'alert alert-danger my-3 animated fadeIn'; msgDiv.className = 'alert alert-danger my-3 animated fadeIn';
msgDiv.style.display = ''; msgDiv.style.display = '';
msgDiv.innerHTML = `<strong>✕ Delivery Unavailable</strong>${data.result?.error || "Distance too far for Uber Direct."}`; msgDiv.innerHTML = `<div class="d-flex align-items-center">
<i class="fa fa-exclamation-triangle me-3" style="font-size: 24px;"></i>
<div>
<strong>✕ Uber Direct: Invalid Operation</strong><br/>
${data.result?.error || "This specific address is outside the Uber delivery radius."}
</div>
</div>`;
if (submitBtn) submitBtn.disabled = true; if (submitBtn) submitBtn.disabled = true;
} }
}).catch(err => { }).catch(err => {
@ -334,28 +346,14 @@
} }
}); });
// 2. Find and remove the Shipping section AND its address cards // 2. Find and remove the Shipping section
const allHeaders = [...document.querySelectorAll('h2, h3, h4, h5')]; const allHeaders = [...document.querySelectorAll('h2, h3, h4, h5')];
const shippingHeader = allHeaders.find(h => h.textContent.trim().toLowerCase() === 'shipping'); const shippingHeader = allHeaders.find(h => h.textContent.trim().toLowerCase() === 'shipping');
if (shippingHeader) { if (shippingHeader) {
// Find the container for shipping addresses (usually follows the header or is in a sibling div)
shippingHeader.style.display = 'none'; shippingHeader.style.display = 'none';
shippingHeader.classList.add('d-none'); if (shippingHeader.nextElementSibling) shippingHeader.nextElementSibling.style.display = 'none';
// Often Odoo 17 puts addresses in a 'row' following the header
let nextEl = shippingHeader.nextElementSibling;
if (nextEl) {
nextEl.style.display = 'none';
nextEl.classList.add('d-none');
}
// If they are side-by-side in columns, hide the shipping column
const shippingCol = shippingHeader.closest('.col-lg-6'); const shippingCol = shippingHeader.closest('.col-lg-6');
if (shippingCol) { if (shippingCol) shippingCol.style.display = 'none';
shippingCol.style.display = 'none';
shippingCol.classList.add('d-none');
}
} }
// 3. Force Billing section to be full width // 3. Force Billing section to be full width
@ -370,17 +368,56 @@
} }
} }
// 4. Hide secondary 'Shipping' add address buttons // 4. CHECK UBER FOR SELECTED CARD
document.querySelectorAll('a[href*="/shop/address"]').forEach(btn => { const billingGrid = document.querySelector('#address_selection');
if (btn.textContent.toLowerCase().includes('shipping')) { if (billingGrid) {
const card = btn.closest('.col-lg-6') || btn.closest('.card') || btn.parentElement; let msgBox = document.getElementById('uber_checkout_msg');
card.style.display = 'none'; if (!msgBox) {
msgBox = document.createElement('div');
msgBox.id = 'uber_checkout_msg';
billingGrid.parentNode.insertBefore(msgBox, billingGrid);
} }
});
function verifySelectedAddress() {
// Find selected address card info
const selectedCard = document.querySelector('input[name="partner_id"]:checked')?.closest('.card');
if (!selectedCard) return;
const addressText = selectedCard.querySelector('address')?.innerText || "";
const parts = addressText.split('\n').map(p => p.trim());
// Crude parsing
const street = parts[1] || "";
const cityZip = parts[2] || "";
msgBox.className = 'alert alert-info my-3';
msgBox.innerHTML = "Verifying Uber coverage for this address...";
fetch('/shop/uber/quote', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ params: { address_data: {
street: street,
zip: cityZip.split(' ').pop(),
city: cityZip.split(' ')[0],
} } })
}).then(r => r.json()).then(data => {
if (data.result &amp;&amp; data.result.success) {
msgBox.className = 'alert alert-success my-3';
msgBox.innerHTML = `<strong>✓ Uber Delivery Available!</strong> Fee: $${data.result.fee}`;
document.querySelector('button[type="submit"]')?.removeAttribute('disabled');
} else {
msgBox.className = 'alert alert-danger my-3';
msgBox.innerHTML = `<strong>✕ Uber Direct: Invalid Operation</strong><br/>${data.result?.error || "Outside delivery radius."}`;
document.querySelector('button[type="submit"]')?.setAttribute('disabled', 'disabled');
}
});
}
document.querySelectorAll('input[name="partner_id"]').forEach(i => i.addEventListener('change', verifySelectedAddress));
verifySelectedAddress();
}
} }
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', applyCheckoutFixes); else applyCheckoutFixes(); if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', applyCheckoutFixes); else applyCheckoutFixes();
// Handle dynamic Odoo updates
document.addEventListener('website_sale_ready', applyCheckoutFixes); document.addEventListener('website_sale_ready', applyCheckoutFixes);
})(); })();
</script> </script>

View File

@ -174,10 +174,24 @@ class UberConfig(models.Model):
if response.status_code != 200: if response.status_code != 200:
# Log detailed error for debugging # Log detailed error for debugging
_logger.error("Uber Quote Error: %s - %s", response.status_code, response.text) _logger.error("Uber Quote Error: %s - %s", response.status_code, response.text)
data = {}
try:
data = response.json()
except:
pass
# Construct descriptive error message
msg = data.get('message', 'Uber API Error')
if data.get('errors'):
details = " ".join([e.get('message', '') for e in data['errors']])
if details:
msg = f"{msg} {details}"
return { return {
'success': False, 'success': False,
'error': response.json().get('message', 'Uber API Error'), 'error': msg,
'code': response.json().get('code', 'unknown') 'code': data.get('code', 'unknown'),
'raw_error': data
} }
data = response.json() data = response.json()