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) {
msgDiv.className = 'alert alert-success my-3 animated fadeIn';
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;
} else {
msgDiv.className = 'alert alert-danger my-3 animated fadeIn';
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;
}
}).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 shippingHeader = allHeaders.find(h => h.textContent.trim().toLowerCase() === 'shipping');
if (shippingHeader) {
// Find the container for shipping addresses (usually follows the header or is in a sibling div)
shippingHeader.style.display = 'none';
shippingHeader.classList.add('d-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
if (shippingHeader.nextElementSibling) shippingHeader.nextElementSibling.style.display = 'none';
const shippingCol = shippingHeader.closest('.col-lg-6');
if (shippingCol) {
shippingCol.style.display = 'none';
shippingCol.classList.add('d-none');
}
if (shippingCol) shippingCol.style.display = 'none';
}
// 3. Force Billing section to be full width
@ -370,17 +368,56 @@
}
}
// 4. Hide secondary 'Shipping' add address buttons
document.querySelectorAll('a[href*="/shop/address"]').forEach(btn => {
if (btn.textContent.toLowerCase().includes('shipping')) {
const card = btn.closest('.col-lg-6') || btn.closest('.card') || btn.parentElement;
card.style.display = 'none';
// 4. CHECK UBER FOR SELECTED CARD
const billingGrid = document.querySelector('#address_selection');
if (billingGrid) {
let msgBox = document.getElementById('uber_checkout_msg');
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();
// Handle dynamic Odoo updates
document.addEventListener('website_sale_ready', applyCheckoutFixes);
})();
</script>

View File

@ -174,10 +174,24 @@ class UberConfig(models.Model):
if response.status_code != 200:
# Log detailed error for debugging
_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 {
'success': False,
'error': response.json().get('message', 'Uber API Error'),
'code': response.json().get('code', 'unknown')
'error': msg,
'code': data.get('code', 'unknown'),
'raw_error': data
}
data = response.json()