integrate Uber Direct delivery services into POS orders and add a channel management UI panel.

This commit is contained in:
Alaguraj0361 2026-04-02 22:27:48 +05:30
parent dae5dc5220
commit 2318ea10e8
3 changed files with 65 additions and 30 deletions

View File

@ -38,12 +38,17 @@ export class ChannelPanel extends Component {
this.state = useState({ this.state = useState({
showDelivery: false, showDelivery: false,
showDetails: false, // For manual fields toggle
searchQuery: '', searchQuery: '',
searchResults: [], searchResults: [],
searching: false, searching: false,
}); });
} }
toggleDetails() {
this.state.showDetails = !this.state.showDetails;
}
get currentOrder() { get currentOrder() {
return this.pos.get_order(); return this.pos.get_order();
} }

View File

@ -59,20 +59,28 @@
</div> </div>
<!-- Delivery Address Section --> <!-- Delivery Address Section -->
<div t-if="isDelivery" class="delivery-panel p-2 rounded mt-1"> <div t-if="isDelivery" class="delivery-panel p-2 rounded mt-1 shadow-sm">
<div class="fw-bold small mb-2">🚚 Delivery Address</div> <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"> <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..." placeholder="🔍 Search saved address..."
t-att-value="state.searchQuery" t-att-value="state.searchQuery"
t-on-input="onAddressSearch"/> t-on-input="onAddressSearch"/>
<div t-if="state.searching" class="text-muted small ps-1">Searching...</div> <div t-if="state.searching" class="text-muted small ps-1">Searching...</div>
<div t-if="state.searchResults.length > 0" <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"> <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)"> t-on-click="() => this.onSelectPartner(partner)">
<span class="fw-bold" t-esc="partner.name"/> <span class="fw-bold" t-esc="partner.name"/>
<span class="text-muted"> <span class="text-muted">
@ -83,7 +91,8 @@
</div> </div>
</div> </div>
<!-- Manual fields --> <!-- 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" <input type="text" class="form-control form-control-sm mb-1"
placeholder="Street" placeholder="Street"
t-att-value="currentOrder.delivery_street" t-att-value="currentOrder.delivery_street"
@ -108,6 +117,14 @@
t-on-change="(ev) => this.onDeliveryFieldChange('notes', ev)"/> t-on-change="(ev) => this.onDeliveryFieldChange('notes', ev)"/>
</div> </div>
<!-- Quick Info when hidden -->
<div t-if="!state.showDetails &amp;&amp; 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>
</div>
</div> </div>
</t> </t>
</t> </t>

View File

@ -158,8 +158,21 @@ class PosOrder(models.Model):
order._add_uber_delivery_fee(delivery_fee) order._add_uber_delivery_fee(delivery_fee)
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
error_msg = f"Uber API Error {e.response.status_code}: {e.response.text}" # Try to parse the error message if it's JSON
raise UserError(_(error_msg)) 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: except Exception as e:
raise UserError(_("Failed to request delivery: %s") % str(e)) raise UserError(_("Failed to request delivery: %s") % str(e))