add uber.config model for Uber Direct integration and delivery settings
This commit is contained in:
parent
a209e448a0
commit
940a3f7a58
@ -110,10 +110,8 @@ class UberConfig(models.Model):
|
||||
return "https://api.uber.com/v1"
|
||||
|
||||
def _get_token_url(self):
|
||||
"""Return OAuth token URL based on environment"""
|
||||
"""Return OAuth token URL (login.uber.com supports both Sandbox and Production)"""
|
||||
self.ensure_one()
|
||||
if self.environment == 'sandbox':
|
||||
return "https://sandbox-login.uber.com/oauth/v2/token"
|
||||
return "https://login.uber.com/oauth/v2/token"
|
||||
|
||||
def _get_access_token(self):
|
||||
@ -170,31 +168,63 @@ class UberConfig(models.Model):
|
||||
self.ensure_one()
|
||||
current_scope = (self.scope or '').strip()
|
||||
if not current_scope or current_scope != 'eats.deliveries':
|
||||
# Default to required delivery scope
|
||||
self.write({'scope': 'eats.deliveries'})
|
||||
|
||||
try:
|
||||
token = self._get_access_token()
|
||||
message = "Connection Successful! Token retrieved successfully using scope 'eats.deliveries'. Uber Direct delivery quotes and couriers are ready."
|
||||
msg_type = "success"
|
||||
return self._return_notification(message, msg_type)
|
||||
message = "Connection Successful! Token retrieved successfully using scope 'eats.deliveries'. Uber Direct live delivery quotes and couriers are fully active."
|
||||
return self._return_notification(message, "success")
|
||||
except UserError as e:
|
||||
err_str = str(e)
|
||||
client_id = (self.client_id or '').strip()
|
||||
client_secret = (self.client_secret or '').strip()
|
||||
|
||||
# Diagnostic 1: Check if credentials work on Production login vs Sandbox login
|
||||
org_token = None
|
||||
detected_env = None
|
||||
for env_name, token_url in [
|
||||
('production', 'https://login.uber.com/oauth/v2/token'),
|
||||
('sandbox', 'https://sandbox-login.uber.com/oauth/v2/token')
|
||||
]:
|
||||
try:
|
||||
r = requests.post(token_url, data={
|
||||
'client_id': client_id,
|
||||
'client_secret': client_secret,
|
||||
'grant_type': 'client_credentials',
|
||||
'scope': 'direct.organizations'
|
||||
}, timeout=10)
|
||||
if r.status_code == 200:
|
||||
detected_env = env_name
|
||||
org_token = r.json().get('access_token')
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if detected_env:
|
||||
env_mismatch_note = ""
|
||||
if self.environment != detected_env:
|
||||
env_mismatch_note = f"\n\nNote: Your credentials matched the {detected_env.upper()} environment, but Odoo is currently set to '{self.environment.capitalize()}'. Change Environment to '{detected_env.capitalize()}'."
|
||||
|
||||
message = (
|
||||
f"Credentials Authenticated Successfully!\n\n"
|
||||
f"Your Client ID and Secret are valid and connected to your Uber Direct organization (scope: 'direct.organizations').{env_mismatch_note}\n\n"
|
||||
f"To enable 'eats.deliveries' (Courier Dispatch & Live Quotes):\n"
|
||||
f"1. For Sandbox Testing: In direct.uber.com, click 'Switch to testing' (top right of Developer page), then copy the testing Client ID & Secret into Odoo and set Environment to 'Sandbox / Testing'.\n"
|
||||
f"2. For Live Production: In direct.uber.com, click 'Set up' under Billing (left menu) to add a payment card/method and add your store address under Locations. Uber activates 'eats.deliveries' once billing is attached."
|
||||
)
|
||||
return self._return_notification(message, "warning")
|
||||
|
||||
if "invalid_scope" in err_str.lower() or "scope" in err_str.lower():
|
||||
message = (
|
||||
"Uber Direct Permission Required: Your Uber Client ID requires the 'eats.deliveries' scope.\n\n"
|
||||
"How to resolve:\n"
|
||||
"1. Go to https://developer.uber.com and log in.\n"
|
||||
"2. Check that your app was created with the 'Uber Direct' / 'Deliveries' API Suite (not 'Others').\n"
|
||||
"3. If created as 'Others', click 'Create Application' and choose 'Uber Direct' / 'Deliveries'.\n"
|
||||
"4. Under 'Access Token' / 'Products', ensure 'eats.deliveries' is active."
|
||||
"1. For Sandbox: In direct.uber.com, click 'Switch to testing' to use testing credentials.\n"
|
||||
"2. For Production: Set up Billing and Location in direct.uber.com to activate live courier dispatch.\n"
|
||||
"3. Ensure Environment in Odoo matches (Sandbox vs Production)."
|
||||
)
|
||||
msg_type = "warning"
|
||||
else:
|
||||
message = f"Connection Failed: {err_str}"
|
||||
msg_type = "danger"
|
||||
return self._return_notification(message, "warning")
|
||||
|
||||
return self._return_notification(message, msg_type)
|
||||
return self._return_notification(f"Connection Failed: {err_str}", "danger")
|
||||
|
||||
def _auth_with_scope(self, scope_to_test):
|
||||
"""Helper to test a specific scope without saving"""
|
||||
@ -460,11 +490,33 @@ class UberConfig(models.Model):
|
||||
'raw_error': data
|
||||
}
|
||||
|
||||
# 2. Out of range / undeliverable error from Uber (Live coverage check)
|
||||
if any(x in code.lower() or x in msg.lower() for x in ['out_of_range', 'out of range', 'outside', 'undeliverable', 'address_undeliverable', 'coverage', 'unserviceable']):
|
||||
# 2. Tax form / Billing profile required
|
||||
if 'tax_form' in msg.lower() or 'customer_blocked' in code.lower():
|
||||
tax_err = _(
|
||||
"Uber Direct Account Setup Notice: Please complete your tax/billing details at "
|
||||
"https://direct.uber.com/accounts/%s/billing to enable live deliveries."
|
||||
) % (customer_id or '')
|
||||
if pricing_source == 'uber_fallback' and dropoff_data:
|
||||
dist_result = self.calculate_distance_quote(dropoff_data, company)
|
||||
dist_result['warning'] = tax_err
|
||||
return dist_result
|
||||
return {
|
||||
'success': False,
|
||||
'error': _("Uber Direct: This address is outside Uber's delivery coverage area. Please choose Store Pickup."),
|
||||
'error': tax_err,
|
||||
'code': code,
|
||||
'raw_error': data
|
||||
}
|
||||
|
||||
# 3. Out of range / undeliverable error from Uber (Live coverage check)
|
||||
if any(x in code.lower() or x in msg.lower() for x in ['out_of_range', 'out of range', 'outside', 'undeliverable', 'address_undeliverable', 'coverage', 'unserviceable']):
|
||||
details = data.get('metadata', {}).get('details') if isinstance(data.get('metadata'), dict) else ''
|
||||
if details:
|
||||
coverage_err = _("Uber Direct: %s Please select an address closer to the restaurant or choose Store Pickup.") % details
|
||||
else:
|
||||
coverage_err = _("Uber Direct: This address is outside Uber's delivery coverage area. Please choose Store Pickup.")
|
||||
return {
|
||||
'success': False,
|
||||
'error': coverage_err,
|
||||
'code': code,
|
||||
'raw_error': data
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user