# ngauge-delivery-upn

UPN (United Pallet Network) delivery integration for NGauge / Yii2.

Provides a full Yii2 module for creating and managing pallet consignments through the UPN External Links SOAP API.

---

## Features

- SOAP-based integration with the UPN External Links API
- Submit pallet consignments (`AddConsignment_V4`)
- Delete unprocessed consignments (`DeleteImportedCon`)
- Retrieve PDF pallet labels as Base64 string (`PalletLabels_V2_asString`)
- Get postcode service restrictions (`GetPostcodeRestrictions`)
- Tracking and POD data (`GetPODAndTrackingByDepot_V2`)
- Collection status checking (`Collection_GetStatus`)
- Run and delivery time lookup (`CON_GetRunAndDelTime_V2`)
- Delivery signature and photo retrieval
- Bootstrap 4 admin UI for configuration and consignment creation
- Async dispatch via Yii2 queue
- Settings stored (encrypted) in `params-local.php`

---

## Requirements

- PHP 8.0+
- `ext-soap` PHP extension
- Yii2 ~2.0
- yii2-bootstrap4 ^2.0

---

## Installation

```bash
composer require portalpeople/ngauge-delivery-upn
```

Add to `backend/config/params-local.php`:

```php
'plugins' => [
    'upn' => [
        'enabled'    => true,
        'apiUrl'     => 'https://services.upn.co.uk:20675/ExternalLinks',
        'depot'      => 123,        // Your UPN depot number
        'customerId' => 10016,      // Your depot's unique customer ID
        'username'   => 'youruser',
        'password'   => \backend\components\Security::encryptSensitiveData('your-password'),
        'debug'      => false,
    ],
],
```

The depot number, customer ID, username and password are provided by your contracted UPN haulier. Contact [it@u-p-n.co.uk](mailto:it@u-p-n.co.uk) if unsure.

---

## API Authentication

UPN uses **per-call** authentication. The depot number, username and password are passed as parameters to every SOAP function call. There is no token or session to manage.

---

## Module Endpoints

| URL | Action |
|-----|--------|
| `/upn/config` | Configuration settings |
| `/upn/consignment/create` | Create a pallet consignment |
| `/upn/consignment/delete` | Delete an unprocessed consignment (POST) |
| `/upn/consignment/tracking` | Get POD and tracking data for depot |
| `/upn/consignment/collection-status` | Get collection status (POST, barcodes[]) |
| `/upn/consignment/services?postcode=…` | Postcode service restrictions |
| `/upn/consignment/label-pdf?conBarcode=…` | PDF pallet labels (Base64) |
| `/upn/consignment/delivery-time?barcodes[]=…` | Run and delivery time |
| `/upn/config/status` | Module status (JSON) |

---

## Service Codes

### Main Service
| Code | Description |
|------|-------------|
| 1 | Priority – Next day delivery |
| 2 | Standard – 2 working days (up to 5 for Scotland) |
| 3 | International |
| 4 | Pallet Return |

### Additional (Premium) Service
| Code | Description |
|------|-------------|
| 0 | None |
| 5 | Before 10am |
| 6 | AM / Before 12pm |
| 7 | Timed |
| 8 | Saturday Before 10am |
| 9 | Saturday AM |
| 10 | Saturday Timed |
| 13 | Out of Hours |
| 25 | Restricted Access |

### Extra Service
| Code | Description |
|------|-------------|
| 0 | None |
| 11 | Book In (contact delivery point to arrange) |
| 12 | Booked (specific day) |

---

## Pallet Types & Sizes

### Pallet Type
| Code | Description |
|------|-------------|
| 1 | Full Pallet |
| 2 | Euro Pallet |
| 3 | Half Pallet |
| 4 | Quarter Pallet |
| 5 | Micro Pallet |
| 6 | Quarter+ Pallet |

### Pallet Size
| Code | Description |
|------|-------------|
| 1 | Normal (up to 1.2m) |
| 2 | Oversize (up to 1.5m) |
| 3 | OOG2 (up to 2.0m) |
| 4 | OOG3 (up to 3.0m) |

---

## Notes

- PDF labels from `PalletLabels_V2_asString` are returned as Base64-encoded strings. Decode with `base64_decode()` and stream as `application/pdf`.
- Tracking data from `GetPODAndTrackingByDepot_V2` is **incremental** — it returns only data logged since the function was last called.
- Consignments can only be deleted before UPN processes them. Once on the network they cannot be cancelled via the API.
- For Timed (7) or Booked (12) services, a `DeliveryDateTime` must be provided in the consignment data.
- Use `GetPostcodeRestrictions` to determine which services and pallet types are available for a given postcode district before presenting options to the user.
