ifnex/04_Laravel/app/Http/Controllers/Api/TrackController.php
Kazem Alghasi b35e933475 Phase 3.5 — Core Features Complete:
 Multi-Package Support (3.5.1)
- Add shipment_packages migration and ShipmentPackage model
- Add packages() relation to Shipment model
- Update CustomerOrderController to accept packages[] array
- Auto-calculate volumetric weight from dimensions (L*W*H/5000)
- Repeater UI for adding/removing packages
- Real-time summary of total weights

 Invoice Form for PARCEL (3.5.2)
- New step in order form (only for PARCEL type)
- Customs items: description, HS Code, quantity, unit price (USD)
- Auto-calculate total per item and invoice total
- Maximum 9 items
- 5-step order form structure

 PDF Redesign (3.5.4)
- Install picqer/php-barcode-generator
- Redesign AWB with barcode, From/To, Value, Service, Type
- Redesign Invoice with 9-row table, legal declaration
- Redesign Label to A5 landscape with large barcode
- DOC/PARCEL condition (only PARCEL has invoice)
- Barcode as base64 embed

 Technical Fixes (3.5.5)
- Add Enum casts to Shipment model (status, direction, type)
- Fix deselectAfterCompletion -> deselectRecordsAfterCompletion
- Migration for shipment_items (row_number, unit_price)
- Migration to make name nullable
- Fix Enum method names (DocNormal/DocEconomy)

 Tracking Test (3.5.6)
- Update TrackController with status_label
- Redesign tracking page with beautiful timeline
- Status box with colored badge
- Timeline with date, description, location, source
- Carrier mappings section

Documentation:
- Update README, Laravel_README, Roadmap, Checklist
- Add IFNEX_Meeting_Summary.md for client presentation
- Update IFNEX_I18N_Strategy.md (moved to deploy phase)

Phase 3.5 — 90% complete (i18n moved to deploy phase)"
2026-08-29 08:35:34 +03:30

75 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Shipment;
use Illuminate\Http\JsonResponse;
/**
* API ترکینگ مرسولات — فاز ۰
*
* GET /api/v1/track/{awb_no}
*
* خروجی: تایم‌لاین کامل رویدادهای ترکینگ + اطلاعات پایه مرسوله + نگاشت‌های شرکت حمل
*/
class TrackController extends Controller
{
/**
* دریافت تایم‌لاین ترکینگ یک مرسوله
*/
public function show(string $awb_no): JsonResponse
{
$shipment = Shipment::where('awb_no', $awb_no)
->with([
'fromCountry:id,name,iso_code',
'toCountry:id,name,iso_code',
'carrierMappings:id,shipment_id,carrier_code,carrier_tracking_number,booking_number,direction,delivery_status,notes',
'trackingEvents' => fn ($query) => $query->orderBy('event_date', 'desc')->orderBy('event_time', 'desc'),
])
->first();
if (!$shipment) {
return response()->json([
'success' => false,
'message' => 'مرسوله‌ای با این کد یافت نشد',
'awb_no' => $awb_no,
], 404);
}
return response()->json([
'success' => true,
'data' => [
'shipment' => [
'awb_no' => $shipment->awb_no,
'direction' => $shipment->direction?->value,
'type' => $shipment->type?->value,
'status' => $shipment->status?->value,
'status_label' => $shipment->status?->label(),
'from_country' => $shipment->fromCountry?->name,
'to_country' => $shipment->toCountry?->name,
'sender_name' => $shipment->sender_name,
'receiver_name' => $shipment->receiver_name,
'weight' => $shipment->weight,
'created_at' => $shipment->created_at?->toIso8601String(),
],
'carrier_mappings' => $shipment->carrierMappings->map(fn ($mapping) => [
'carrier_code' => $mapping->carrier_code,
'carrier_tracking_number' => $mapping->carrier_tracking_number,
'booking_number' => $mapping->booking_number,
'delivery_status' => $mapping->delivery_status,
'notes' => $mapping->notes,
]),
'tracking_events' => $shipment->trackingEvents->map(fn ($event) => [
'date' => $event->event_date?->toDateString(),
'time' => $event->event_time ? ($event->event_time instanceof \Carbon\Carbon ? $event->event_time->format('H:i') : $event->event_time) : null,
'location' => $event->location,
'description' => $event->event_description,
'status' => $event->delivery_status,
'source' => $event->source,
]),
],
]);
}
}