Skip to content

purolator: make tracking status description-aware for Undeliverable/Other scans#971

Open
HansDaigle wants to merge 5564 commits intokarrioapi:mainfrom
HansDaigle:fix/purolator-tracking-status-mapping
Open

purolator: make tracking status description-aware for Undeliverable/Other scans#971
HansDaigle wants to merge 5564 commits intokarrioapi:mainfrom
HansDaigle:fix/purolator-tracking-status-mapping

Conversation

@HansDaigle
Copy link
Contributor

@HansDaigle HansDaigle commented Feb 20, 2026

Summary

Purolator tracking status mapping is currently derived only from ScanType (for example, all Undeliverable scans are mapped to one status). In production payloads, the same ScanType can represent materially different outcomes based on the description (pickup-ready, return-to-sender, delayed, etc.).

This PR makes Purolator tracking status mapping description-aware while keeping a safe default for unknown descriptions.

Why this needs an update

  • ScanType alone is too coarse for Purolator tracking semantics.
  • The same ScanType appears with different descriptions that should map to different normalized statuses.
  • Without description-aware mapping, downstream systems lose important state transitions (for example ready_for_pickup vs return_to_sender vs delivery_delayed).
  • Purolator requests can be configured with language=fr; status mapping must therefore tolerate French descriptions too.

Real-life validation dataset

This mapping was derived and validated against real historical Purolator tracking data from production logs:

  • 147,766 Purolator tracking events
  • 18,718 distinct tracking numbers
  • 141 distinct description variants

Changes

  • modules/connectors/purolator/karrio/providers/purolator/units.py
    • adds map_tracking_status(event_code, event_description)
    • adds normalized description mapping table for Other, OnDelivery, Delivery, ProofOfPickUp, Undeliverable
    • adds keyword fallback rules for unseen Undeliverable wording variants
    • adds accent-insensitive normalization and French keyword handling for language=fr responses
    • expands TrackingStatus enum values used by this mapper
  • modules/connectors/purolator/karrio/providers/purolator/tracking.py
    • uses description-aware mapper for shipment-level and event-level status
    • adds null-safe scan/depot handling
  • modules/connectors/purolator/tests/purolator/test_tracking.py
    • adds new tests for description overrides and undeliverable keyword fallbacks
    • adds test coverage for French descriptions
    • updates fixture expectation to include event-level status now emitted by mapper

Tests

Executed:

cd modules/connectors/purolator
source /Users/hansdaigle/git/karrio-upstream/.venv/karrio/bin/activate
python -m unittest discover -f tests -v

Result: 25 passed

Ansh-Dev-Nagar and others added 30 commits January 20, 2026 19:28
danh91 and others added 22 commits February 14, 2026 06:30
Fix Cache.get() writing None to system cache instead of actual value
when syncing from shallow cache. Reduce DHL Parcel DE buffer_minutes
from 30 to 5 to prevent tokens from being considered immediately
expired when expires_in <= 1800s.
- Fix periodic_data_archiving running every minute by setting crontab to daily at midnight
- Always include feature flags in CONSTANCE_CONFIG with False default when module absent
- Replace naive datetime.now() with timezone.now() for Fee record queries
- Fix health status API double-slash URL causing 404
- Add keyword search field to tracing records filter
fix: resolve OSS admin bugs and developer tools issues
@vercel
Copy link

vercel bot commented Feb 20, 2026

@HansDaigle is attempting to deploy a commit to the karrio Team on Vercel.

A member of the Team first needs to authorize it.

@HansDaigle
Copy link
Contributor Author

Implementation note: Purolator can emit the same ScanType with different Description values that imply different outcomes. This PR intentionally maps by ScanType + Description (with keyword fallback) so these cases do not collapse into a single status.

@HansDaigle
Copy link
Contributor Author

Follow-up: added French-description handling as well (accent-insensitive normalization + FR fallback keywords for Undeliverable), since Purolator settings support language=fr. Added dedicated test coverage in modules/connectors/purolator/tests/purolator/test_tracking.py.

@danh91
Copy link
Member

danh91 commented Mar 1, 2026

Merged into patch-2026.1.16 release branch.

@danh91 danh91 closed this Mar 1, 2026
@danh91 danh91 reopened this Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants