Metadata-Version: 2.1
Name: odoo-addon-delivery_easypost_oca
Version: 17.0.1.0.0.2
Requires-Python: >=3.10
Requires-Dist: easypost==7.15.0
Requires-Dist: odoo>=17.0a,<17.1dev
Summary: OCA Delivery Easypost
Home-page: https://github.com/OCA/delivery-carrier
License: AGPL-3
Author: Binhex, Odoo Community Association (OCA)
Author-email: support@odoo-community.org
Classifier: Programming Language :: Python
Classifier: Framework :: Odoo
Classifier: Framework :: Odoo :: 17.0
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Description-Content-Type: text/x-rst

.. image:: https://odoo-community.org/readme-banner-image
   :target: https://odoo-community.org/get-involved?utm_source=readme
   :alt: Odoo Community Association

=====================
Easypost Shipping OCA
=====================

.. 
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !! This file is generated by oca-gen-addon-readme !!
   !! changes will be overwritten.                   !!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !! source digest: sha256:b5e0177e480b785b9a6a6fb01d331b31520363ba27d5b39509063d1af15d8cde
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
    :target: https://odoo-community.org/page/development-status
    :alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
    :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
    :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fdelivery--carrier-lightgray.png?logo=github
    :target: https://github.com/OCA/delivery-carrier/tree/17.0/delivery_easypost_oca
    :alt: OCA/delivery-carrier
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
    :target: https://translation.odoo-community.org/projects/delivery-carrier-17-0/delivery-carrier-17-0-delivery_easypost_oca
    :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
    :target: https://runboat.odoo-community.org/builds?repo=OCA/delivery-carrier&target_branch=17.0
    :alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module integrates `EasyPost <https://easypost.com>`__ shipping API
with Odoo, providing access to 100+ carriers through a single, unified
interface.

**What is EasyPost?**

EasyPost is a shipping API aggregator that eliminates the need for
separate carrier integrations. Instead of implementing individual APIs
for USPS, UPS, FedEx, DHL, and others, you connect once to EasyPost and
gain access to all supported carriers with pre-negotiated rates.

**Key Features**

- **Automated Rate Calculation**: Get real-time shipping rates from
  multiple carriers and automatically select the lowest rate
- **Label Generation**: Generate and print shipping labels in multiple
  formats (PDF, ZPL, EPL2)
- **Multi-Carrier Support**: Access 100+ carriers including USPS, UPS,
  FedEx, DHL, Canada Post, and regional carriers
- **Shipment Tracking**: Real-time tracking with automatic updates and
  public tracking links
- **Multi-Package Handling**: Support for shipments with multiple
  packages (individual or batch mode)
- **Address Verification**: Automatic address validation to reduce
  delivery errors
- **Multiple Label Formats**: PDF for standard printers, ZPL/EPL2 for
  thermal label printers
- **Test Environment**: Full test mode for development without charges
  or actual shipments
- **Automatic Conversions**: Weight conversion to ounces and currency
  conversion handled automatically

**Benefits of Using EasyPost**

- **Single Integration**: One API connection for all carriers - no need
  to integrate each carrier separately
- **Lowest Rate Selection**: Automatically compares rates from all
  available carriers and selects the cheapest option
- **Pre-Negotiated Rates**: Access to discounted carrier rates through
  EasyPost's volume agreements
- **Reduced Complexity**: Unified API response format regardless of
  carrier
- **Scalability**: Easily add new carriers without code changes
- **Testing Without Risk**: Complete test environment with mock
  shipments

**Technical Architecture**

This module implements a clean, layered architecture:

- **Business Logic Layer** (delivery_carrier.py): Handles Odoo-specific
  logic (orders, pickings, pricing)
- **API Wrapper Layer** (easypost_request.py): Centralizes all EasyPost
  API interactions
- **EasyPost Python SDK** (version 7.15.0): Official EasyPost client
  library
- **Comprehensive Test Suite**: 100% mocked tests with no real API calls
  during testing

**Supported Carriers (via EasyPost)**

USPS, UPS, FedEx, DHL Express, DHL eCommerce, Canada Post, APC Postal,
Asendia, Australia Post, Canpar, Couriers Please, Deutsche Post,
Fastway, Globegistics, Interlink Express, LaserShip, LSO, OnTrac,
Parcelforce, Purolator, Royal Mail, Sendle, StarTrack, and 80+
additional carriers worldwide.

**Use Cases**

- **E-Commerce Stores**: Automatically calculate shipping costs at
  checkout
- **Warehouse Operations**: Generate and print shipping labels for
  outbound orders
- **Multi-Carrier Shipping**: Compare rates across carriers to minimize
  shipping costs
- **International Shipping**: Access to international carriers with
  automatic address verification
- **High-Volume Shipping**: Batch processing for multiple packages in
  single transactions

**Table of contents**

.. contents::
   :local:

Configuration
=============

**Step 1: Configure Delivery Carrier**

1. Go to **Inventory → Configuration → Delivery Methods**
2. Create a new delivery method or edit an existing one
3. Set **Provider** to **Easypost OCA**
4. In the **Easypost Configuration** tab, configure the following
   fields:

   - **Easypost Test API Key**: Your test API key from EasyPost
     dashboard (for development and testing)
   - **Easypost Production API Key**: Your production API key (for live
     shipments)
   - **Label Format**: Choose the label format according to your
     printer:

     - **PDF** (default): Standard format, works with all printers
     - **ZPL**: For Zebra thermal printers (direct thermal printing)
     - **EPL2**: For legacy Eltron/Zebra thermal printers

   - **Delivery Multiple Packages**: Select the shipping strategy for
     orders with multiple packages:

     - **Shipments** (default): Create individual shipment for each
       package, charged separately
     - **Batch**: Create batch shipment with all packages in a single
       transaction

5. Configure **Pricing** tab as needed (fixed price, percentage, or
   formula-based)
6. Enable the **Test Environment** checkbox during development to use
   test API key
7. **Save** the delivery method

**Step 2: Configure Product Packaging (Optional)**

For accurate shipping calculations using carrier-specific package types:

1. Go to **Inventory → Configuration → Product Packagings**
2. Create or edit a product packaging
3. Set **Carrier** to **Easypost OCA**
4. Configure package dimensions: **Length**, **Width**, **Height** (in
   inches)
5. Set **Shipper Package Code** for carrier-specific packaging (e.g.,
   "Parcel", "FedExBox", "FlatRateEnvelope")
6. Set **Carrier Prefix** to filter by specific carrier if needed (e.g.,
   "USPS", "FedEx")
7. **Save** the packaging

**Step 3: Configure Warehouse Address**

Ensure your warehouse has a complete address that will be used as the
shipper address:

1. Go to **Inventory → Configuration → Warehouses**
2. Edit your warehouse
3. Set complete **Address** with all required fields:

   - Street address
   - City
   - State/Province
   - ZIP/Postal code
   - Country

4. Verify the address is accurate - this will be the "Ship From" address
   on all labels

**Step 4: Enable API Logging (Optional)**

For debugging API interactions and troubleshooting issues:

1. Edit the delivery carrier configured in Step 1
2. Go to the **Advanced Options** tab
3. Enable **Log XML** checkbox
4. Check API request/response logs at **Settings → Technical → Logging**

**Important Configuration Notes**

- **Test vs Production Mode**: Toggle the **Test Environment** checkbox
  to switch between test and production API keys. Always test thoroughly
  in test mode before going live.
- **Weight Units**: The module automatically converts product weights to
  ounces (EasyPost requirement). Ensure all products have weight
  configured.
- **Currency Conversion**: EasyPost returns rates in USD. The module
  automatically converts to the order's currency using Odoo's currency
  rates.
- **USPS/UPS End Shipper**: These carriers require an end shipper ID for
  certain services. The module automatically creates and manages this -
  no manual configuration needed.
- **API Keys Security**: Keep your production API key secure. Never
  commit API keys to version control or share them publicly.
- **Rate Caching**: EasyPost rates are calculated in real-time. Rates
  shown at quotation time may differ slightly at shipping time if time
  has passed.

Usage
=====

**Workflow 1: Calculate Shipping Rates on Sale Order**

1. Create a new **Sale Order**: Go to **Sales → Orders → Quotations →
   Create**
2. Add products to the order (ensure products have weight configured)
3. Set the **Customer** with a complete shipping address
4. Click the **Add Shipping** button
5. In the **Add a shipping method** wizard:

   - Select your **Easypost OCA** delivery method from the list
   - Click **Get Rate** button

6. The system will:

   - Query EasyPost API with order details (weight, origin/destination
     addresses)
   - Automatically select the lowest rate from all available carriers
   - Add a shipping line to the order with the carrier name (e.g.,
     "Easypost - USPS Priority")

7. The **Sale Order** now shows:

   - Shipping line with carrier name and calculated price
   - Stored data: shipment_id, rate_id, carrier_name (for later shipment
     creation)

8. Confirm the order when ready to proceed

**Workflow 2: Generate Shipping Labels (Single Package)**

1. After confirming the sale order, a **Delivery Order** is
   automatically created
2. Go to **Inventory → Delivery Orders** and open the delivery order
3. Click **Check Availability** to reserve stock
4. Set the **Done** quantities for each product line
5. Click **Validate** button - the system will automatically:

   - Create an EasyPost shipment using the stored rate (or calculate a
     new rate if expired)
   - Purchase the shipment (charges your EasyPost account)
   - Download the shipping label in your configured format
     (PDF/ZPL/EPL2)
   - Attach the label to the picking in the **Chatter** messages
   - Set the tracking number on the delivery order

6. Find the shipping label in the **Chatter** section at the bottom
7. Click the attachment to download and print the label
8. Attach the printed label to your package and ship

**Workflow 3: Multi-Package Shipments**

If your delivery order contains multiple packages:

1. In the delivery order, after setting **Done** quantities

2. Use the **Put in Pack** button to create packages:

   - Select products for the first package
   - Click **Put in Pack** - creates Package 1
   - Repeat for additional packages

3. Click **Validate** - behavior depends on your carrier configuration:

   **Shipments Mode** (default):

   - Creates individual EasyPost shipment for each package
   - Each package gets its own tracking number
   - Each package is charged separately
   - System generates a single merged PDF/ZPL with all labels in
     sequence

   **Batch Mode**:

   - Creates a batch shipment containing all packages
   - Packages are purchased together in a single transaction
   - May provide better rates for bulk shipping
   - Single merged label file with all package labels

4. All tracking numbers are displayed in the delivery order
   (comma-separated)

5. The merged label file contains all package labels - print and attach
   to corresponding packages

**Workflow 4: Track Shipments**

After shipment creation:

1. Open the **Delivery Order**
2. Click the **Tracking** button/link in the form
3. Opens the EasyPost tracking page in a new browser tab
4. View real-time shipment status, location history, and delivery
   confirmation

**Using Product Packaging for Accurate Rates**

To use carrier-specific package types (flat rate boxes, envelopes,
etc.):

1. In the delivery order, after using **Put in Pack**
2. Edit the created **Package** record
3. Set the **Packaging** field to a product packaging configured for
   EasyPost (see CONFIGURE.rst)
4. The packaging dimensions and shipper package code are sent to
   EasyPost
5. Results in more accurate rates and ensures carrier compatibility

**Label Format Guide**

Choose the appropriate label format for your printing setup:

- **PDF Format**:

  - Works with all standard printers
  - Can preview in browser before printing
  - Best for offices with regular laser/inkjet printers
  - Label size: typically 8.5"x11" or 4"x6"

- **ZPL Format**:

  - For Zebra thermal label printers
  - Direct thermal printing (no ink/toner required)
  - Common in warehouses and shipping departments
  - Requires ZPL-compatible thermal printer

- **EPL2 Format**:

  - For legacy Eltron and older Zebra thermal printers
  - Use only if your printer doesn't support ZPL
  - Less common in modern shipping operations

**Important Usage Notes**

- **Product Weight Required**: All products in the order must have
  weight configured. Orders without weight cannot calculate shipping
  rates.
- **Complete Addresses Required**: Both warehouse address (ship from)
  and customer address (ship to) must be complete with street, city,
  state/province, ZIP, and country.
- **Test Mode Shipments**: Shipments created in test mode (with test API
  key) are not actually shipped. They are mock shipments for testing
  purposes and no charges apply.
- **Cannot Cancel Shipments**: EasyPost shipments cannot be cancelled
  through Odoo. Some carriers allow refunds within 24 hours - use the
  EasyPost dashboard for refund requests.
- **Rate Expiration**: Shipping rates may change between quotation and
  shipment if significant time has passed. The system will automatically
  recalculate rates at shipping time if the stored rate has expired.
- **Multiple Carriers**: EasyPost automatically compares rates from
  multiple carriers (USPS, UPS, FedEx, etc.) and selects the lowest
  rate. You can see the selected carrier name in the shipping line
  (e.g., "Easypost - USPS Priority").
- **Tracking Updates**: Tracking information is available immediately
  after shipment creation. Real tracking events (scans, delivery) appear
  as the carrier processes the shipment.

Known issues / Roadmap
======================

**Planned Future Enhancements**

The following features are being considered for future releases:

- **Carrier Service Selection**: Allow users to manually select specific
  carrier/service combinations instead of automatic lowest rate
  selection
- **Custom Carrier Accounts**: Support for connecting specific carrier
  accounts configured in EasyPost dashboard for using negotiated rates
- **Shipment Cancellation**: Implement shipment cancellation and refund
  workflow for eligible shipments within the refund window
- **Insurance Options**: Add configuration for shipment insurance with
  automatic insurance purchase based on order value
- **International Customs Forms**: Generate and attach customs forms
  automatically for international shipments
- **Return Labels**: Generate return shipping labels with reverse
  addresses for customer returns and RMA workflows
- **Advanced Batch Operations**: Enhanced batch management including
  void batch, rebuy batch, and USPS scan forms generation
- **Rate Shopping Interface**: Display all available rates to users in a
  comparison view for manual carrier selection
- **Delivery Preferences**: Support for signature confirmation, delivery
  confirmation, adult signature, and other service options
- **Webhook Integration**: Real-time tracking updates via EasyPost
  webhooks instead of polling
- **Performance Optimization**: Implement rate caching and bulk
  operations for high-volume shipping scenarios
- **Smart Box Selection**: Automatic package size recommendation based
  on product dimensions and weight
- **Shipping Rules Engine**: Configurable rules for automatic carrier
  selection based on destination, weight, or value thresholds
- **Carbon Offset Integration**: Support for EasyPost's carbon offset
  program with reporting

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/delivery-carrier/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/delivery-carrier/issues/new?body=module:%20delivery_easypost_oca%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Binhex

Contributors
------------

- `Binhex <https://www.binhex.cloud>`__:

  - Antonio Ruban <<a.ruban@binhex.cloud>>
  - Christian Ramos

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
   :alt: Odoo Community Association
   :target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/delivery-carrier <https://github.com/OCA/delivery-carrier/tree/17.0/delivery_easypost_oca>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
