136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""One-off rate-quote sweep across every FedEx service code.
|
|
|
|
Loops the full carrier selection (~38 services) against two routes —
|
|
CA domestic (matching SO-30045) and CA → US — to figure out which
|
|
services are valid for the shipping lanes EN Technologies actually
|
|
uses. Prints a CSV-ish matrix to stdout so the report can be pasted
|
|
straight into chat.
|
|
|
|
Run with:
|
|
odoo shell -c /etc/odoo/odoo.conf -d admin --no-http < this_file
|
|
"""
|
|
from types import SimpleNamespace
|
|
|
|
from odoo.addons.fusion_shipping.api.fedex_rest.request import (
|
|
FedexRequest as FedexRestRequest,
|
|
)
|
|
|
|
CARRIER_ID = 17 # FedEx REST carrier on entech
|
|
WEIGHT_LB = 5.0
|
|
DIMS = {'length': 12, 'width': 10, 'height': 6}
|
|
|
|
carrier = env['delivery.carrier'].browse(CARRIER_ID)
|
|
assert carrier.exists(), 'FedEx carrier id=17 not found on this DB.'
|
|
|
|
service_codes = [code for code, _label in carrier._fields[
|
|
'fedex_rest_service_type'
|
|
].selection]
|
|
|
|
# CA Toronto sender (from company address)
|
|
sender = SimpleNamespace(
|
|
street='36 Taber Road', street2=False,
|
|
city='Toronto', zip='M9W3A8',
|
|
state_id=env['res.country.state'].search(
|
|
[('code', '=', 'ON'), ('country_id.code', '=', 'CA')], limit=1,
|
|
),
|
|
country_id=env['res.country'].search([('code', '=', 'CA')], limit=1),
|
|
name='ENTECH', phone='4167492400', email='ship@entech.test',
|
|
commercial_partner_id=None, parent_id=None, vat=False,
|
|
is_company=True,
|
|
)
|
|
|
|
# Route A — CA domestic (Niagara Falls, ON)
|
|
ca_recipient = env['res.partner'].search([
|
|
('city', 'ilike', 'Niagara Falls'), ('country_id.code', '=', 'CA'),
|
|
], limit=1)
|
|
assert ca_recipient.exists(), 'No CA partner found for the domestic route.'
|
|
|
|
# Route B — CA → US (a real US partner with a complete address)
|
|
us_recipient = env['res.partner'].search([
|
|
('country_id.code', '=', 'US'), ('city', '!=', False),
|
|
('zip', '!=', False), ('state_id', '!=', False),
|
|
], limit=1)
|
|
if not us_recipient:
|
|
# Fabricate one in memory (we won't write to DB).
|
|
us_recipient = env['res.partner'].new({
|
|
'name': 'Test US Customer',
|
|
'street': '1 World Trade Center',
|
|
'city': 'New York',
|
|
'zip': '10007',
|
|
'state_id': env['res.country.state'].search(
|
|
[('code', '=', 'NY'), ('country_id.code', '=', 'US')], limit=1,
|
|
).id,
|
|
'country_id': env['res.country'].search(
|
|
[('code', '=', 'US')], limit=1,
|
|
).id,
|
|
'phone': '2125551212',
|
|
'email': 'us@test.com',
|
|
})
|
|
|
|
# Sender partner — use the company partner for proper address resolution.
|
|
sender_partner = env.company.partner_id
|
|
|
|
|
|
def quote(service_code, recipient):
|
|
srm = FedexRestRequest(carrier)
|
|
srm.service_type = service_code
|
|
pkg = SimpleNamespace(
|
|
weight=WEIGHT_LB,
|
|
dimension=DIMS,
|
|
packaging_type='YOUR_PACKAGING',
|
|
total_cost=0, commodities=[], currency_id=env.ref('base.CAD'),
|
|
)
|
|
try:
|
|
res = srm._get_shipping_price(
|
|
ship_from=sender_partner,
|
|
ship_to=recipient,
|
|
packages=[pkg],
|
|
currency='CAD',
|
|
)
|
|
return {
|
|
'ok': True,
|
|
'price': res.get('price'),
|
|
'currency': res.get('currency'),
|
|
'service_name': res.get('service_name', '').strip(),
|
|
'delivery': (res.get('delivery_timestamp') or '')[:16].replace(
|
|
'T', ' ',
|
|
),
|
|
'transit': res.get('transit_time', ''),
|
|
'error': '',
|
|
}
|
|
except Exception as exc:
|
|
msg = str(exc).replace('\n', ' ').strip()
|
|
# Trim Odoo's "Error from FedEx: " prefix if present.
|
|
return {
|
|
'ok': False, 'price': 0, 'currency': '',
|
|
'service_name': '', 'delivery': '', 'transit': '',
|
|
'error': msg[:140],
|
|
}
|
|
|
|
|
|
def emit_row(route, code, label, result):
|
|
print('|{route}|{code}|{label}|{ok}|{price}|{cur}|{eta}|{transit}|{err}|'.format(
|
|
route=route,
|
|
code=code,
|
|
label=label[:50],
|
|
ok='OK' if result['ok'] else 'FAIL',
|
|
price=('%.2f' % result['price']) if result['ok'] else '',
|
|
cur=result['currency'],
|
|
eta=result['delivery'],
|
|
transit=result['transit'],
|
|
err=result['error'],
|
|
))
|
|
|
|
|
|
print('|Route|ServiceCode|Label|Status|Price|Cur|DeliveryETA|Transit|Error|')
|
|
print('|---|---|---|---|---|---|---|---|---|')
|
|
|
|
label_map = dict(carrier._fields['fedex_rest_service_type'].selection)
|
|
for code in service_codes:
|
|
label = label_map.get(code, code)
|
|
emit_row('CA->CA', code, label, quote(code, ca_recipient))
|
|
emit_row('CA->US', code, label, quote(code, us_recipient))
|
|
|
|
print('DONE')
|