# Sites Module

**Folder:** `CRUD/site/` · **Main table:** `site_address` · **Reached from:** navbar → Sites

Site addresses are the delivery locations machines get hired to. Every hire on the Hire List points at a site, and sites are linked to a customer. Sites store full address, contact, coordinates (for the live map and lorry-run planning) and an active/archived flag.

> This document is the **template** for how every module is documented: one section per page, in the order a user meets them, with AJAX/helper endpoints listed at the end.

---

## All Sites — `site_index_server.php`

![All Sites](../screenshots/sites__all_sites.png)

The site list. A server-side DataTable (data loads page-by-page from `site_address_data_server_side.php`, so it stays fast even with 1,400+ sites).

**What you can do here:**
- Search by site name, customer, or postcode.
- See at a glance whether a site is **Active** or **Inactive** (badge column).
- Row actions: view, edit, archive/reactivate, delete.

## Create Site — `site_create.php`

![Create Site](../screenshots/sites__create_site.png)

Add a new site. Renders the form on GET; inserts into `site_address` on POST.

**Fields:** site name (required — the only hard validation), customer (dropdown backed by the `customers` table; select2 searchable), address lines 1–3, town, county, postcode, contact + contact number (from `contact_list`), active flag, latitude/longitude.

**Behaviour worth knowing:**
- Entering a postcode can auto-fill lat/long via the **geocode** helper (Google Maps Geocoding API, see `geocode_postcode.php` below). Coordinates drive the Live Locations map.
- The customer dropdown stores both the customer id (`site_customer_id`) and a snapshot of the name (`site_customer`) on the row.
- `site_create_modal.php` is the same form packaged as a modal so other pages (e.g. creating a hire) can add a site without leaving the page; `site_create_json.php` is its AJAX submit endpoint.

## View Site — `site_read.php` / `site_read_hl.php`

Read-only view of one site (`?id=<id_site_address>`). Two variants exist:
- `site_read.php` — opened from the site list; back-links return to the list.
- `site_read_hl.php` — the same view opened **from the Hire List**; redirects/back-links return to the hire list instead.

## Edit Site — `site_update.php`

Edit an existing site (`?id=...`). Same fields as create; updates the row on POST. `site_update_json.php` is the AJAX version used when editing inline from other pages.

## Archive / Reactivate — `site_actions/`

Sites are normally **archived, not deleted**, so history stays intact:
- `site_actions/site_archive.php` — AJAX POST; sets `site_active = 'N'`.
- `site_actions/site_reactivate.php` — AJAX POST; sets `site_active = 'Y'`.
- `site_actions/site_clear_site_move.php` — clears a pending site-move flag from a site.

## Delete Site — `site_delete.php`

Hard delete. GET shows a confirmation page; POST removes the row from `site_address` and returns to the list. Use archive instead unless the site was created in error.

---

## AJAX / helper endpoints (not user-facing)

| File | Method | Purpose |
|---|---|---|
| `site_address_data_server_side.php` | GET | DataTables server-side data source for the site list |
| `site_create_json.php` | POST | Create a site from the modal; returns JSON |
| `site_update_json.php` | POST | Update a site inline; returns JSON |
| `geocode_postcode.php` | GET `?postcode=` | Looks up lat/lng for a postcode via Google Maps API; returns JSON |
| `site_actions/site_archive.php` | POST | Archive (deactivate) a site |
| `site_actions/site_reactivate.php` | POST | Reactivate a site |
| `site_actions/site_clear_site_move.php` | POST | Clear site-move flag |

## Database

Main table **`site_address`** (see [database-schema.md](../database-schema.md#site_address) for full columns). Key relationships:
- `site_customer_id` → `customers.id_customer`
- `site_contact_id` → `contact_list`
- Referenced by `hire_list` (each hire's delivery site) and `hire_site_map`
- `site_lat` / `site_long` feed the Live Locations map (`CRUD/maps/live_locations.php`)
