---
name: evolution_dispatch_contact_source
description: "Dispatch record carries its own contact (contact_name/phone/email); delivery docket must use it, not the site/entity primary contact"
metadata: 
  node_type: memory
  type: project
  originSessionId: 70fadcf9-d002-4fe1-8d96-48c6f4bc9cd8
---

A `dispatch` row stores its OWN selected contact in `dispatch.contact_name` / `dispatch.phone` / `dispatch.email` / `dispatch.contactid` — set via the "Contact" picker in `dispatchedit.inc` (JS maps the chosen contact's mobile→phone field, email→email field). This is the source of truth for who the docket goes to.

**Bug (fixed 2026-07-17):** the Delivery Docket in `print.php` built its "Site Contact:" row (`$dispContact`, inside `@dispatchShippingAddress;`) from the SITE's default addressbook contact (`addressbookmeta … WHERE src='site' AND srcid=$vars['site']`) — showing the entity's general primary contact instead of the dispatch-selected one.

**Fix:** static method `dispatch::buildContact($dispatch, $siteContact)` in `library/dispatch.php` — prefers the dispatch's own contact (rendered as stored to match portal), falls back to the legacy site contact only when none chosen. `print.php` includes `library/dispatch.php` and also exposes a new `@dispatchContact;` template token.

Note: docket templates are per-customer uploads (`uploads` table, not in repo). If a customer's docket still shows the wrong person, their template's contact field must point at `@dispatchContact;` (or the now-fixed "Site Contact:" row) instead of `@customer;`.
