forked from alaguraj/odoo-testing-addons
integrate Uber Direct delivery services into POS orders and add a channel management UI panel.
This commit is contained in:
parent
dae5dc5220
commit
2318ea10e8
@ -38,12 +38,17 @@ export class ChannelPanel extends Component {
|
||||
|
||||
this.state = useState({
|
||||
showDelivery: false,
|
||||
showDetails: false, // For manual fields toggle
|
||||
searchQuery: '',
|
||||
searchResults: [],
|
||||
searching: false,
|
||||
});
|
||||
}
|
||||
|
||||
toggleDetails() {
|
||||
this.state.showDetails = !this.state.showDetails;
|
||||
}
|
||||
|
||||
get currentOrder() {
|
||||
return this.pos.get_order();
|
||||
}
|
||||
|
||||
@ -59,20 +59,28 @@
|
||||
</div>
|
||||
|
||||
<!-- Delivery Address Section -->
|
||||
<div t-if="isDelivery" class="delivery-panel p-2 rounded mt-1">
|
||||
<div class="fw-bold small mb-2">🚚 Delivery Address</div>
|
||||
<div t-if="isDelivery" class="delivery-panel p-2 rounded mt-1 shadow-sm">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<div class="fw-bold small text-muted"><i class="fa fa-map-marker text-danger"/> Delivery Address</div>
|
||||
<button class="btn btn-sm btn-link text-primary p-0 text-decoration-none shadow-none fw-bold"
|
||||
style="font-size: 10px"
|
||||
t-on-click="toggleDetails">
|
||||
<t t-if="state.showDetails"><i class="fa fa-caret-up"/> HIDE FIELDS</t>
|
||||
<t t-else=""><i class="fa fa-caret-down"/> EDIT MANUAL</t>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Partner search -->
|
||||
<!-- Partner search (always visible under Delivery) -->
|
||||
<div class="position-relative mb-2">
|
||||
<input type="text" class="form-control form-control-sm"
|
||||
<input type="text" class="form-control form-control-sm border-primary"
|
||||
placeholder="🔍 Search saved address..."
|
||||
t-att-value="state.searchQuery"
|
||||
t-on-input="onAddressSearch"/>
|
||||
<div t-if="state.searching" class="text-muted small ps-1">Searching...</div>
|
||||
<div t-if="state.searchResults.length > 0"
|
||||
class="address-dropdown position-absolute bg-white border rounded shadow-sm w-100">
|
||||
class="address-dropdown position-absolute bg-white border rounded shadow w-100 mt-1">
|
||||
<t t-foreach="state.searchResults" t-as="partner" t-key="partner.id">
|
||||
<div class="address-result p-2 border-bottom small"
|
||||
<div class="address-result p-2 border-bottom small list-group-item-action"
|
||||
t-on-click="() => this.onSelectPartner(partner)">
|
||||
<span class="fw-bold" t-esc="partner.name"/> —
|
||||
<span class="text-muted">
|
||||
@ -83,29 +91,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Manual fields -->
|
||||
<input type="text" class="form-control form-control-sm mb-1"
|
||||
placeholder="Street"
|
||||
t-att-value="currentOrder.delivery_street"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('street', ev)"/>
|
||||
<div class="d-flex gap-1 mb-1">
|
||||
<input type="text" class="form-control form-control-sm"
|
||||
placeholder="City"
|
||||
t-att-value="currentOrder.delivery_city"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('city', ev)"/>
|
||||
<input type="text" class="form-control form-control-sm"
|
||||
placeholder="Zip" style="max-width:90px"
|
||||
t-att-value="currentOrder.delivery_zip"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('zip', ev)"/>
|
||||
<!-- Manual fields (hidden by default) -->
|
||||
<div t-if="state.showDetails" class="manual-address-fields mt-2 p-2 border-top bg-white rounded">
|
||||
<input type="text" class="form-control form-control-sm mb-1"
|
||||
placeholder="Street"
|
||||
t-att-value="currentOrder.delivery_street"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('street', ev)"/>
|
||||
<div class="d-flex gap-1 mb-1">
|
||||
<input type="text" class="form-control form-control-sm"
|
||||
placeholder="City"
|
||||
t-att-value="currentOrder.delivery_city"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('city', ev)"/>
|
||||
<input type="text" class="form-control form-control-sm"
|
||||
placeholder="Zip" style="max-width:90px"
|
||||
t-att-value="currentOrder.delivery_zip"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('zip', ev)"/>
|
||||
</div>
|
||||
<input type="tel" class="form-control form-control-sm mb-1"
|
||||
placeholder="Phone"
|
||||
t-att-value="currentOrder.delivery_phone"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('phone', ev)"/>
|
||||
<textarea class="form-control form-control-sm" rows="2"
|
||||
placeholder="Delivery notes (gate code, floor...)"
|
||||
t-att-value="currentOrder.delivery_notes"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('notes', ev)"/>
|
||||
</div>
|
||||
|
||||
<!-- Quick Info when hidden -->
|
||||
<div t-if="!state.showDetails && currentOrder.delivery_street" class="small mt-1 text-muted fst-italic">
|
||||
<i class="fa fa-info-circle"/>
|
||||
<t t-esc="currentOrder.delivery_street"/>,
|
||||
<t t-esc="currentOrder.delivery_city"/>
|
||||
</div>
|
||||
<input type="tel" class="form-control form-control-sm mb-1"
|
||||
placeholder="Phone"
|
||||
t-att-value="currentOrder.delivery_phone"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('phone', ev)"/>
|
||||
<textarea class="form-control form-control-sm" rows="2"
|
||||
placeholder="Delivery notes (gate code, floor...)"
|
||||
t-att-value="currentOrder.delivery_notes"
|
||||
t-on-change="(ev) => this.onDeliveryFieldChange('notes', ev)"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -158,8 +158,21 @@ class PosOrder(models.Model):
|
||||
order._add_uber_delivery_fee(delivery_fee)
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
error_msg = f"Uber API Error {e.response.status_code}: {e.response.text}"
|
||||
raise UserError(_(error_msg))
|
||||
# Try to parse the error message if it's JSON
|
||||
try:
|
||||
err_data = e.response.json()
|
||||
err_code = err_data.get('code', 'unknown_error')
|
||||
err_msg = err_data.get('message', 'An error occurred with Uber API.')
|
||||
|
||||
if err_code == 'address_undeliverable':
|
||||
# Special handling for radius errors (most common issue)
|
||||
details = err_data.get('metadata', {}).get('details', '')
|
||||
raise UserError(_("Address Undeliverable: The drop-off location is outside Uber's delivery radius. \n\nDetails: %s") % details)
|
||||
|
||||
raise UserError(_("Uber API Error (%s): %s") % (err_code, err_msg))
|
||||
except (ValueError, AttributeError):
|
||||
# Fallback to default error text if not JSON
|
||||
raise UserError(_("Uber API Error %s: %s") % (e.response.status_code, e.response.text))
|
||||
except Exception as e:
|
||||
raise UserError(_("Failed to request delivery: %s") % str(e))
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user