Extend the shipment database schema to support additional tracking fields, state information, and financial data. This update also transitions shipment documentation from RTL/Persian to LTR/English layouts and integrates barcode generation for AWB and labels. - feat(db): add migration for missing shipment fields (state, cod_amount, declared_value, etc.) - feat(shipment): update Shipment model with new casts and helper methods - feat(ui): refactor Filament resource to use ShipmentStatus enum and add new input fields - feat(pdf): implement barcode generation using picqer/php-barcode-generator - feat(pdf): redesign AWB, Invoice, and Label templates for LTR/English support - refactor(enum): simplify ShipmentStatus enum and update labels/colors - chore(deps): add picqer/php-barcode-generator dependency
98 lines
3.3 KiB
PHP
98 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Shipment;
|
|
use Dompdf\Dompdf;
|
|
use Dompdf\Options;
|
|
use Illuminate\Support\Collection;
|
|
use Picqer\Barcode\BarcodeGeneratorHTML;
|
|
|
|
class PdfService
|
|
{
|
|
public function awb(Shipment $shipment): string
|
|
{
|
|
$shipment->loadMissing(['fromCountry', 'toCountry', 'items']);
|
|
|
|
$data = [
|
|
'shipment' => $shipment,
|
|
'shipper' => $this->formatAddress($shipment, 'sender'),
|
|
'receiver' => $this->formatAddress($shipment, 'receiver'),
|
|
'items' => $shipment->items ?? collect(),
|
|
'barcode' => $this->generateBarcode($shipment->awb_no),
|
|
];
|
|
|
|
return $this->generatePdf(view('pdfs.awb', $data)->render(), 'A4', 'portrait');
|
|
}
|
|
|
|
public function invoice(Shipment $shipment): string
|
|
{
|
|
$shipment->loadMissing(['fromCountry', 'toCountry', 'items']);
|
|
|
|
$data = [
|
|
'shipment' => $shipment,
|
|
'shipper' => $this->formatAddress($shipment, 'sender'),
|
|
'receiver' => $this->formatAddress($shipment, 'receiver'),
|
|
'items' => $shipment->isParcel() ? ($shipment->items ?? collect()) : collect(),
|
|
'invoice_total_usd' => $shipment->invoice_total_usd,
|
|
'barcode' => $this->generateBarcode($shipment->awb_no),
|
|
];
|
|
|
|
return $this->generatePdf(view('pdfs.invoice', $data)->render(), 'A4', 'portrait');
|
|
}
|
|
|
|
public function label(Shipment $shipment): string
|
|
{
|
|
$shipment->loadMissing(['fromCountry', 'toCountry']);
|
|
|
|
$data = [
|
|
'shipment' => $shipment,
|
|
'shipper' => $this->formatAddress($shipment, 'sender'),
|
|
'receiver' => $this->formatAddress($shipment, 'receiver'),
|
|
'barcode' => $this->generateBarcode($shipment->awb_no),
|
|
];
|
|
|
|
return $this->generatePdf(view('pdfs.label', $data)->render(), 'A4', 'portrait');
|
|
}
|
|
|
|
private function generatePdf(string $html, string $paper, string $orientation): string
|
|
{
|
|
$options = new Options();
|
|
$options->set('isHtml5ParserEnabled', true);
|
|
$options->set('isRemoteEnabled', true);
|
|
$options->set('defaultFont', 'DejaVu Sans');
|
|
|
|
$dompdf = new Dompdf($options);
|
|
$dompdf->loadHtml($html);
|
|
$dompdf->setPaper($paper, $orientation);
|
|
$dompdf->render();
|
|
|
|
return $dompdf->output();
|
|
}
|
|
|
|
private function formatAddress(Shipment $shipment, string $prefix): Collection
|
|
{
|
|
return collect([
|
|
'name' => $shipment->{"{$prefix}_name"},
|
|
'company' => $shipment->{"{$prefix}_company"},
|
|
'phone' => $shipment->{"{$prefix}_phone"},
|
|
'email' => $shipment->{"{$prefix}_email"},
|
|
'address' => $shipment->{"{$prefix}_address"},
|
|
'city' => $shipment->{"{$prefix}_city"},
|
|
'state' => $shipment->{"{$prefix}_state"},
|
|
'zip' => $shipment->{"{$prefix}_zip"},
|
|
'id_number' => $shipment->{"{$prefix}_id_number"},
|
|
]);
|
|
}
|
|
|
|
private function generateBarcode(string $code): string
|
|
{
|
|
try {
|
|
$generator = new BarcodeGeneratorHTML();
|
|
return $generator->getBarcode($code, $generator::TYPE_CODE_128, 2, 60);
|
|
} catch (\Throwable $e) {
|
|
return '<div style="color:#999;font-size:10px;">Barcode unavailable</div>';
|
|
}
|
|
}
|
|
}
|