DPD/BRT Integration - Phase 1 Completion
β What Has Been Implementedβ
1. Core API Client (DpdApi.php)β
Location: src/CoreBundle/Api/DpdApi.php
Features:
- β REST API client for DPD/BRT shipment API
- β Create shipment with label generation (PDF)
- β Confirm shipment (for explicit confirmation mode)
- β Delete shipment
- β Calculate routing
- β Get tracking information by parcel ID
- β Error handling with detailed logging
- β Comprehensive PHPDoc comments
Key Methods:
// Create shipment and get PDF labels
$response = $dpdApi->createShipment($createData, true);
// Get tracking info
$tracking = $dpdApi->getTrackingByParcelId($parcelId);
// Get tracking URL for customers
$url = $dpdApi->getTrackingUrl($parcelId);
// Extract labels from response
$labels = $dpdApi->extractLabels($response);
2. Business Logic Service (DpdService.php)β
Location: src/CoreBundle/Services/DpdService.php
Features:
- β Create shipments for sale products
- β
Save PDF labels to disk (
/web/pdf_dpd/) - β
Update SaleProduct with generic fields (Geodis pattern):
carrier= 'DPD'tracking_id= parcel IDshipment_infos= JSON responseexpedition_ticket_files= PDF pathstrack_links= tracking URLs
- β
Use
ShipmentTrackingSynchronizerfor consistency - β Event dispatching (SaleProductsShippedEvent, etc.)
- β Comprehensive error handling
- β Tracking synchronization support
Key Method:
$dpdService = $container->get('CoreBundle\Services\DpdService');
$dpdService->createSaleProductShipment(
$saleProductIds, // Array of SaleProduct IDs
$userId, // User creating shipment
false, // Log changes
true // Send notifications
);
3. Service Registrationβ
Location: src/CoreBundle/Resources/config/services.yml
Added:
parameters:
mz.dpd.api.class: CoreBundle\Api\DpdApi
mz.dpd.service.class: CoreBundle\Services\DpdService
services:
mz.dpd.api:
class: "%mz.dpd.api.class%"
arguments:
- "@logger"
- "%dpd.api_url%"
- "%dpd.user_id%"
- "%dpd.password%"
tags:
- { name: monolog.logger, channel: logidav_dpd }
CoreBundle\Services\DpdService:
class: "%mz.dpd.service.class%"
autowire: true
lazy: true
4. Configuration Parametersβ
Location: app/config/parameters.yml.dist
Added:
dpd:
api_url: 'https://api.brt.it'
user_id: 'YOUR_DPD_USER_ID'
password: 'YOUR_DPD_PASSWORD'
customer_code: 123456 # Your BRT customer code
departure_depot: 123 # Your departure depot code
operating_mode: 'auto' # 'auto' or 'explicit'
π§ Setup Instructionsβ
Step 1: Copy Configurationβ
Copy parameters.yml.dist to parameters.yml (if not already done):
cp app/config/parameters.yml.dist app/config/parameters.yml
Step 2: Configure DPD Credentialsβ
Edit app/config/parameters.yml and update the DPD section with your credentials:
dpd:
api_url: 'https://api.brt.it' # Production URL
user_id: 'your_actual_user_id'
password: 'your_actual_password'
customer_code: 456789 # Your actual customer code
departure_depot: 123 # Your actual depot code
operating_mode: 'auto'
Step 3: Create PDF Directoryβ
Create the directory for storing DPD labels:
mkdir -p web/pdf_dpd
chmod 755 web/pdf_dpd
Step 4: Clear Symfony Cacheβ
php bin/console cache:clear
π§ͺ Testingβ
Test 1: Verify Service Registrationβ
php bin/console debug:container mz.dpd.api
php bin/console debug:container CoreBundle\Services\DpdService
Expected output: Service definitions should be displayed.
Test 2: Test API Connection (Create Test Script)β
Create scripts/test_dpd_api.php:
<?php
require __DIR__ . '/../vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;
$kernel = new AppKernel('dev', true);
$kernel->boot();
$container = $kernel->getContainer();
/** @var \CoreBundle\Api\DpdApi $dpdApi */
$dpdApi = $container->get('mz.dpd.api');
// Test tracking (use a real parcel ID if you have one)
try {
$parcelId = 'TEST123456789012'; // Replace with real parcel ID
$tracking = $dpdApi->getTrackingByParcelId($parcelId);
print_r($tracking);
echo "β
API Connection successful!\n";
} catch (\Exception $e) {
echo "β API Error: " . $e->getMessage() . "\n";
}
Run:
php scripts/test_dpd_api.php
Test 3: Test Shipment Creation (Manual Test)β
// Get service
$dpdService = $container->get('CoreBundle\Services\DpdService');
// Create shipment for a sale product
$saleProductIds = [123]; // Replace with actual SaleProduct ID
$userId = 1; // Your user ID
$result = $dpdService->createSaleProductShipment(
$saleProductIds,
$userId,
false,
false // Don't send notifications during testing
);
if ($result) {
echo "β
Shipment created successfully!\n";
} else {
echo "β Shipment creation failed\n";
}
π Data Flowβ
User Action (Phase 2)
β
DpdService::createSaleProductShipment()
β
DpdApi::createShipment() β DPD REST API
β
Response with parcelID + PDF label (base64)
β
Save PDF to /web/pdf_dpd/
β
Update SaleProduct:
- carrier = 'DPD'
- tracking_id = parcelID
- shipment_infos = JSON response
- expedition_ticket_files = ['/pdf_dpd/xxx.pdf']
- track_links = ['https://www.brt.it/tracking?parcelID=xxx']
β
ShipmentTrackingSynchronizer::sync()
β
Dispatch Events:
- SaleProductsShippedEvent
- SaleProductsAfterTicketPrintedEvent
π Loggingβ
All DPD operations are logged to the logidav_dpd channel.
Check logs:
tail -f var/logs/dev.log | grep DPD
π API Response Examplesβ
Create Shipment Responseβ
{
"createResponse": {
"executionMessage": {
"code": 0,
"severity": "INFO",
"message": "Success"
},
"parcelNumberFrom": "1234567",
"parcelNumberTo": "1234567",
"arrivalDepot": "123",
"deliveryZone": "01",
"labels": {
"label": [{
"parcelID": "ABC123DEF456789012",
"stream": "JVBERi0xLjQKJeLj...", // base64 PDF
"trackingByParcelID": "ABC123DEF456"
}]
}
}
}
Tracking Responseβ
{
"ttParcelIdResponse": {
"executionMessage": {
"code": 0,
"severity": "INFO"
},
"esito": 0,
"bolla": {
"dati_spedizione": {
"spedizione_id": "1234567890"
},
"dati_consegna": {
"data_consegna_merce": "2025-10-24",
"firmatario_consegna": "John Doe"
}
},
"lista_eventi": [{
"data": "2025-10-23",
"ora": "14:30",
"descrizione": "Pacco ricevuto"
}]
}
}
π¨ Error Codesβ
Common DPD API error codes:
-1: Generic error-3: Database connection problems-5: Invalid parameter-10: Shipment number required-11: Shipment not found-21: Customer code required-22: Non-unique reference-30: Parcel ID required
β Phase 1 Checklistβ
- Create
DpdApi.phpwith REST client - Create
DpdService.phpwith business logic - Register services in
services.yml - Add parameters to
parameters.yml.dist - Use generic SaleProduct fields (no new DB columns)
- Implement PDF label saving
- Add comprehensive error handling
- Add logging support
- Follow Geodis pattern for consistency
π Next Steps (Phase 2)β
- Create
DpdController.phpfor/dpd/dashboard - Update
processingNotPrinted.html.twigto add "Send to DPD" action - Create dashboard views
- Add JavaScript handlers
- Test end-to-end workflow
π Referencesβ
- API Documentation:
BrtRestApi-EN/RestShipmentProd.en/Index.html - Swagger Specs:
BrtRestApi-EN/RestShipmentProd.en/SwaggerViewerShipment.jsonBrtRestApi-EN/RestShipmentProd.en/SwaggerViewerTracking.json
- Support: cedvas@brt.it
π― Success Criteriaβ
Phase 1 is complete when:
- β Services are registered and accessible
- β DPD API can be called successfully
- β Shipments can be created programmatically
- β PDF labels are saved correctly
- β SaleProduct entities are updated with shipment data
- β Tracking synchronization works
- β Events are dispatched correctly