configure Odoo container names and implement custom checkout UI with fulfillment selection and field validation
This commit is contained in:
parent
132727a5bf
commit
3408b893cb
@ -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 && 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>
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user