709 lines
32 KiB
PHP
709 lines
32 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Exceptions\ExternalApiException;
|
|
use App\Exceptions\LabelPrintException;
|
|
use App\Exceptions\ShipmentException;
|
|
use App\Jobs\ReprintLabelsJob;
|
|
use App\Models\ActionLog;
|
|
use App\Models\Carrier;
|
|
use App\Models\CarrierExtraFeeTypes;
|
|
use App\Models\CarrierMaster;
|
|
use App\Models\Label;
|
|
use App\Models\ShipmentErrorLog;
|
|
use App\Models\ShipmentProcessedBaseFee;
|
|
use App\Models\ShipmentProcessedExtraFee;
|
|
use App\Models\ShipmentRequest;
|
|
use App\Models\ShipmentRequestBatch;
|
|
use App\Models\ShipmentRequestBatchItem;
|
|
use App\Models\ShipmentRequestInvoice;
|
|
use App\Models\ShipmentRequestItem;
|
|
use App\Models\ShipmentStatus;
|
|
use App\Models\ShipmentStatusHistory;
|
|
use App\Models\UserDetails;
|
|
use App\Rules\Base64Pdf;
|
|
use App\Services\CallbackService;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
use Illuminate\Http\Request;
|
|
use App\Models\Shipment;
|
|
use App\Factories\CarrierServiceFactory;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Inertia\Inertia;
|
|
|
|
class LabelController extends Controller
|
|
{
|
|
|
|
|
|
protected CallbackService $callbackService;
|
|
|
|
public function __construct(CallbackService $callbackService)
|
|
{
|
|
$this->callbackService = $callbackService;
|
|
}
|
|
|
|
private $validateArray = [
|
|
'shipments' => 'required|array|min:1',
|
|
'shipments.*.shipmentReference' => 'required|string|max:255',
|
|
'shipments.*.note' => 'nullable|string|max:1000',
|
|
'shipments.*.delivery_address' => 'required|array',
|
|
'shipments.*.delivery_address.name' => 'required|string|max:255',
|
|
'shipments.*.delivery_address.companyName' => 'nullable|string|max:255',
|
|
'shipments.*.delivery_address.streetName' => 'required|string|max:255',
|
|
'shipments.*.delivery_address.streetNumber' => 'required|string|max:10',
|
|
'shipments.*.delivery_address.city' => 'required|string|max:255',
|
|
'shipments.*.delivery_address.zip' => 'required|string|max:20',
|
|
'shipments.*.delivery_address.stateISO' => 'nullable|string|max:10',
|
|
'shipments.*.delivery_address.countryISO' => 'required|string|max:3',
|
|
'shipments.*.pickupPointCode' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointName' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointAddress.streetName' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointAddress.streetNumber' => 'nullable|string|max:10',
|
|
'shipments.*.pickupPointAddress.addressLine2' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointAddress.city' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointAddress.zip' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointAddress.stateISO' => 'nullable|string|max:255',
|
|
'shipments.*.pickupPointAddress.countryISO' => 'nullable|string|max:255',
|
|
'shipments.*.postnummer' => 'nullable|string|max:255',
|
|
'shipments.*.contactEmail' => 'nullable|email|max:255',
|
|
'shipments.*.contactTelephone' => 'nullable|string|max:20',
|
|
'shipments.*.codValue' => 'nullable|numeric',
|
|
'shipments.*.codVariableSymbol' => 'nullable|string|max:8',
|
|
'shipments.*.shipmentValue' => 'required|numeric',
|
|
'shipments.*.currency' => 'required|string|max:3',
|
|
'shipments.*.weight' => 'required|numeric',
|
|
'shipments.*.items' => 'required|array|min:1',
|
|
'shipments.*.items.*.name' => 'required|string|max:255',
|
|
'shipments.*.items.*.item_note' => 'nullable|string',
|
|
'shipments.*.items.*.HSCode' => 'nullable|string|max:255',
|
|
'shipments.*.items.*.model_number' => 'nullable|string|max:255',
|
|
'shipments.*.items.*.price' => 'required|numeric',
|
|
'shipments.*.items.*.quantity' => 'required|integer',
|
|
'shipments.*.items.*.originCountry' => 'required|string|max:3',
|
|
'shipments.*.items.*.weight' => 'required|numeric',
|
|
'shipments.*.items.*.item_id_internal_warehouse' => 'nullable|numeric',
|
|
'shipments.*.items.*.item_id_external' => 'nullable|numeric',
|
|
'shipments.*.carrier_id' => 'required|string|max:255',
|
|
'shipments.*.allegro_carrier_id' => 'nullable|string|max:255',
|
|
'shipments.*.packageType' => 'required|in:ENVELOPE,PACKAGE',
|
|
'shipments.*.sendAgainFlag' => 'nullable|boolean',
|
|
'shipments.*.allegroSmart' => 'nullable|boolean',
|
|
'shipments.*.parcelSize' => 'required|array',
|
|
'shipments.*.parcelSize.width' => 'required|string|max:255',
|
|
'shipments.*.parcelSize.length' => 'required|string|max:255',
|
|
'shipments.*.parcelSize.height' => 'required|string|max:255',
|
|
'shipments.*.invoice_data' => 'nullable|array',
|
|
'shipments.*.invoice_data.invoiceNumber' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.date' => 'nullable|string',
|
|
'shipments.*.invoice_data.currency' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.address.name' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.address.companyName' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.address.companyVatNumber' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.address.streetName' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.address.streetNumber' => 'nullable|string|max:10',
|
|
'shipments.*.invoice_data.address.city' => 'nullable|string|max:255',
|
|
'shipments.*.invoice_data.address.zip' => 'nullable|string|max:20',
|
|
'shipments.*.invoice_data.address.stateISO' => 'nullable|string|max:10',
|
|
'shipments.*.invoice_data.address.countryISO' => 'nullable|string|max:3'
|
|
|
|
];
|
|
|
|
//TODO: custom validation
|
|
// 1. UPS pickup data required for APP only users
|
|
// 2. UPS invoice pdf required for UPS nonEU
|
|
/**
|
|
* @throws LabelPrintException
|
|
* @throws ExternalApiException
|
|
*/
|
|
public function createLabels(Request $request)
|
|
{
|
|
// Validate the request for an array of shipments
|
|
$base64PdfRule = new Base64Pdf();
|
|
$this->validateArray['shipments.*.invoice_data.invoice_file'] = ['nullable', $base64PdfRule];
|
|
|
|
$validator = Validator::make($request->all(), $this->validateArray);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
// Proceed with the validated data
|
|
$validatedData = $validator->validated();
|
|
|
|
$labels = [];
|
|
foreach ($validatedData['shipments'] as $shipmentData) {
|
|
|
|
|
|
// Create shipment request
|
|
$shipment_request = ShipmentRequest::create([
|
|
'shipment_reference' => $shipmentData['shipmentReference'],
|
|
'user_id' => $request->user()->id,
|
|
'note' => $shipmentData['note'] ?? null,
|
|
'delivery_address_name' => $shipmentData['delivery_address']['name'],
|
|
'delivery_address_company_name' => $shipmentData['delivery_address']['companyName'] ?? null,
|
|
'delivery_address_street_name' => $shipmentData['delivery_address']['streetName'],
|
|
'delivery_address_street_number' => $shipmentData['delivery_address']['streetNumber'],
|
|
'delivery_address_address_line_2' => $shipmentData['delivery_address']['addressLine2'] ?? null,
|
|
'delivery_address_city' => $shipmentData['delivery_address']['city'],
|
|
'delivery_address_zip' => $shipmentData['delivery_address']['zip'],
|
|
'delivery_address_state_iso' => $shipmentData['delivery_address']['stateISO'] ?? null,
|
|
'delivery_address_country_iso' => $shipmentData['delivery_address']['countryISO'],
|
|
'pickup_point_code' => $shipmentData['pickupPointCode'] ?? null,
|
|
'pickup_point_address_street_name' => $shipmentData['pickupPointAddress']['streetName'] ?? null,
|
|
'pickup_point_address_street_number' => $shipmentData['pickupPointAddress']['streetNumber'] ?? null,
|
|
'pickup_point_address_city' => $shipmentData['pickupPointAddress']['city'] ?? null,
|
|
'pickup_point_address_zip' => $shipmentData['pickupPointAddress']['zip'] ?? null,
|
|
'pickup_point_address_state_iso' => $shipmentData['pickupPointAddress']['stateISO'] ?? null,
|
|
'pickup_point_address_country_iso' => $shipmentData['pickupPointAddress']['countryISO'] ?? null,
|
|
'contact_email' => $shipmentData['contactEmail'] ?? null,
|
|
'contact_telephone' => $shipmentData['contactTelephone'] ?? null,
|
|
'cod_value' => $shipmentData['codValue'] ?? null,
|
|
'cod_variable_symbol' => $shipmentData['codVariableSymbol'] ?? null,
|
|
'shipment_value' => $shipmentData['shipmentValue'],
|
|
'currency' => $shipmentData['currency'],
|
|
'weight' => $shipmentData['weight'],
|
|
'width' => $shipmentData['parcelSize']['width'],
|
|
'length' => $shipmentData['parcelSize']['length'],
|
|
'height' => $shipmentData['parcelSize']['height'],
|
|
'carrier_id' => $shipmentData['carrier_id'],
|
|
'allegro_carrier_id' => $shipmentData['allegro_carrier_id'] ?? null,
|
|
'package_type' => $shipmentData['packageType'],
|
|
'send_again_flag' => $shipmentData['sendAgainFlag'] ?? false,
|
|
'allegro_smart' => $shipmentData['allegroSmart'] ?? false,
|
|
'postnummer' => $shipmentData['postnummer'] ?? null,
|
|
]);
|
|
|
|
// Create shipment items
|
|
foreach ($shipmentData['items'] as $itemData) {
|
|
ShipmentRequestItem::create([
|
|
'shipment_request_id' => $shipment_request->id,
|
|
'name' => $itemData['name'],
|
|
'item_note' => $itemData['item_note'] ?? null,
|
|
'model_number' => $itemData['model_number'] ?? null,
|
|
'HSCode' => $itemData['HSCode'] ?? null,
|
|
'price' => $itemData['price'],
|
|
'quantity' => $itemData['quantity'],
|
|
'originCountry' => $itemData['originCountry'],
|
|
'weight' => $itemData['weight'],
|
|
'item_id_internal_warehouse' => $itemData['item_id_internal_warehouse'] ?? null,
|
|
'item_id_external' => $itemData['item_id_external'] ?? null,
|
|
]);
|
|
}
|
|
if (!empty($shipmentData['invoice_data'])) {
|
|
ShipmentRequestInvoice::create([
|
|
'shipment_request_id' => $shipment_request->id,
|
|
'invoice_number' => $shipmentData['invoice_data']['invoiceNumber'],
|
|
'invoice_date' => $shipmentData['invoice_data']['date'],
|
|
'invoice_currency' => $shipmentData['invoice_data']['currency'],
|
|
'invoice_address_name' => $shipmentData['invoice_data']['address']['name'],
|
|
'invoice_address_company_name' => $shipmentData['invoice_data']['address']['companyName'] ?? null,
|
|
'invoice_address_company_vat_number' => $shipmentData['invoice_data']['address']['companyVatNumber'] ?? null,
|
|
'invoice_address_street_name' => $shipmentData['invoice_data']['address']['streetName'],
|
|
'invoice_address_street_number' => $shipmentData['invoice_data']['address']['streetNumber'],
|
|
'invoice_address_city' => $shipmentData['invoice_data']['address']['city'],
|
|
'invoice_address_zip' => $shipmentData['invoice_data']['address']['zip'],
|
|
'invoice_address_state_iso' => $shipmentData['invoice_data']['address']['stateISO'] ?? null,
|
|
'invoice_address_country_iso' => $shipmentData['invoice_data']['address']['countryISO'],
|
|
'invoice_raw_data' => $shipmentData['invoice_data']['invoice_file'],
|
|
]);
|
|
}
|
|
|
|
// Instantiate the correct carrier service dynamically for each shipment
|
|
$carrierService = CarrierServiceFactory::create($shipment_request->carrier);
|
|
|
|
try {
|
|
$label = $carrierService->genShipLabel($shipment_request);
|
|
if ($label) {
|
|
$labels[] = $label;
|
|
}
|
|
} catch (ExternalApiException|LabelPrintException|ShipmentException|GuzzleException|\Exception $e) {
|
|
$errors[] = [
|
|
'shipmentReference' => $shipmentData['shipmentReference'],
|
|
'error' => $e->getMessage(),
|
|
];
|
|
|
|
ShipmentErrorLog::create(
|
|
array(
|
|
"shipment_request_id" => $shipment_request->id,
|
|
"error_message" => $e->getMessage()
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!empty($errors)) {
|
|
return response()->json(['errors' => $errors], 400);
|
|
}
|
|
|
|
// Placeholder function to merge labels into a file
|
|
$file = $this->mergeLabelsIntoFile($labels);
|
|
|
|
// return response()->json(['file' => $file], 201);
|
|
return response($file, 200)
|
|
->header('Content-Type', 'application/pdf')
|
|
->header('Content-Disposition', 'attachment; filename="labels.pdf"');
|
|
|
|
}
|
|
|
|
|
|
public function processShipmentsByCarrier(Request $request)
|
|
{
|
|
|
|
Log::channel('expedice')->info('function processShipmentsByCarrier initiated by ' . $request->user()->name, [
|
|
'carrier' => $request->get('carrier')
|
|
]);
|
|
|
|
$carrierIds = Carrier::where('carrier_shortname', $request->get('carrier')['shortname'])
|
|
->pluck('id')
|
|
->toArray();
|
|
|
|
$shipmentRequests = ShipmentRequest::whereIn('carrier_id', $carrierIds)
|
|
->whereDoesntHave('shipment')
|
|
->whereDoesntHave('batch')
|
|
->get();
|
|
|
|
$batch = ShipmentRequestBatch::create([
|
|
'user_id' => $request->user()->id,
|
|
'carrier_master_id' => CarrierMaster::where('shortname', $request->get('carrier')['shortname'])->first()->id,
|
|
]);
|
|
|
|
|
|
foreach ($shipmentRequests as $shipment_request) {
|
|
|
|
|
|
// Instantiate the correct carrier service dynamically for each shipment
|
|
$carrierService = CarrierServiceFactory::create($shipment_request->carrier);
|
|
ShipmentRequestBatchItem::create([
|
|
'shipment_request_batch_id' => $batch->id,
|
|
'shipment_request_id' => $shipment_request->id,
|
|
]);
|
|
try {
|
|
$label = $carrierService->genShipLabel($shipment_request);
|
|
|
|
if ($label) {
|
|
$labels[] = $label;
|
|
}
|
|
} catch (ExternalApiException|LabelPrintException|ShipmentException|GuzzleException|\Exception $e) {
|
|
$errors[] = [
|
|
'shipmentReference' => $shipment_request->shipment_reference,
|
|
'error' => $e->getMessage(),
|
|
];
|
|
|
|
ShipmentErrorLog::create(
|
|
array(
|
|
"shipment_request_id" => $shipment_request->id,
|
|
"error_message" => $e->getMessage()
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
try {
|
|
|
|
|
|
if (empty($labels)) {
|
|
return response()->json(['errors' => $errors], 400);
|
|
}
|
|
|
|
// Placeholder function to merge labels into a file
|
|
$file = $this->mergeLabelsIntoFile($labels);
|
|
|
|
// return response()->json(['file' => $file], 201);
|
|
return response($file, 200)
|
|
->header('Content-Type', 'application/pdf')
|
|
->header('Content-Disposition', 'attachment; filename="labels.pdf"');
|
|
|
|
} catch (\Exception $e) {
|
|
$errors[] = [
|
|
'shipmentReference' => 0,
|
|
'error' => $e->getMessage(),
|
|
];
|
|
return response()->json(['errors' => $errors], 400);
|
|
}
|
|
|
|
}
|
|
|
|
public function validateAndStoreShipment(Request $request)
|
|
{
|
|
|
|
$euCountries = [
|
|
'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE',
|
|
'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK'
|
|
];
|
|
|
|
$base64PdfRule = new Base64Pdf();
|
|
|
|
|
|
foreach ($request->input('shipments', []) as $index => $shipment) {
|
|
$carrierId = $shipment['carrier_id'] ?? null;
|
|
$countryISO = $shipment['delivery_address']['countryISO'] ?? null;
|
|
|
|
if (in_array($carrierId, [12, 14, 29, 40968, 40969]) && !in_array($countryISO, $euCountries)) {
|
|
$this->validateArray['shipments.*.invoice_data.invoice_file'] = ['required', $base64PdfRule];
|
|
$this->validateArray["shipments.*.invoice_data"] = 'required|array';
|
|
$this->validateArray["shipments.*.invoice_data.invoiceNumber"] = 'required|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.date"] = 'required|string';
|
|
$this->validateArray["shipments.*.invoice_data.currency"] = 'required|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.address.name"] = 'required|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.address.companyName"] = 'nullable|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.address.companyVatNumber"] = 'nullable|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.address.streetName"] = 'required|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.address.streetNumber"] = 'required|string|max:10';
|
|
$this->validateArray["shipments.*.invoice_data.address.city"] = 'required|string|max:255';
|
|
$this->validateArray["shipments.*.invoice_data.address.zip"] = 'required|string|max:20';
|
|
$this->validateArray["shipments.*.invoice_data.address.stateISO"] = 'nullable|string|max:10';
|
|
$this->validateArray["shipments.*.invoice_data.address.countryISO"] = 'required|string|max:3';
|
|
}
|
|
}
|
|
$validator = Validator::make($request->all(), $this->validateArray);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
$validatedData = $validator->validated();
|
|
|
|
$return_array = [];
|
|
$status_code = 200;
|
|
|
|
|
|
foreach ($validatedData['shipments'] as $shipmentData) {
|
|
|
|
try {
|
|
|
|
DB::transaction(function () use ($shipmentData, $request, &$return_array) {
|
|
|
|
|
|
// Create shipment request
|
|
$shipment_request = ShipmentRequest::create([
|
|
'shipment_reference' => $shipmentData['shipmentReference'],
|
|
'user_id' => $request->user()->id,
|
|
'note' => $shipmentData['note'] ?? null,
|
|
'delivery_address_name' => $shipmentData['delivery_address']['name'],
|
|
'delivery_address_company_name' => $shipmentData['delivery_address']['companyName'] ?? null,
|
|
'delivery_address_street_name' => $shipmentData['delivery_address']['streetName'],
|
|
'delivery_address_street_number' => $shipmentData['delivery_address']['streetNumber'],
|
|
'delivery_address_address_line_2' => $shipmentData['delivery_address']['addressLine2'] ?? null,
|
|
'delivery_address_city' => $shipmentData['delivery_address']['city'],
|
|
'delivery_address_zip' => $shipmentData['delivery_address']['zip'],
|
|
'delivery_address_state_iso' => $shipmentData['delivery_address']['stateISO'] ?? null,
|
|
'delivery_address_country_iso' => $shipmentData['delivery_address']['countryISO'],
|
|
'pickup_point_code' => $shipmentData['pickupPointCode'] ?? null,
|
|
'pickup_point_address_street_name' => $shipmentData['pickupPointAddress']['streetName'] ?? null,
|
|
'pickup_point_address_street_number' => $shipmentData['pickupPointAddress']['streetNumber'] ?? null,
|
|
'pickup_point_address_city' => $shipmentData['pickupPointAddress']['city'] ?? null,
|
|
'pickup_point_address_zip' => $shipmentData['pickupPointAddress']['zip'] ?? null,
|
|
'pickup_point_address_state_iso' => $shipmentData['pickupPointAddress']['stateISO'] ?? null,
|
|
'pickup_point_address_country_iso' => $shipmentData['pickupPointAddress']['countryISO'] ?? null,
|
|
'contact_email' => $shipmentData['contactEmail'] ?? null,
|
|
'contact_telephone' => $shipmentData['contactTelephone'] ?? null,
|
|
'cod_value' => $shipmentData['codValue'] ?? null,
|
|
'cod_variable_symbol' => $shipmentData['codVariableSymbol'] ?? null,
|
|
'shipment_value' => $shipmentData['shipmentValue'],
|
|
'currency' => $shipmentData['currency'],
|
|
'weight' => $shipmentData['weight'],
|
|
'width' => $shipmentData['parcelSize']['width'],
|
|
'length' => $shipmentData['parcelSize']['length'],
|
|
'height' => $shipmentData['parcelSize']['height'],
|
|
'carrier_id' => $shipmentData['carrier_id'],
|
|
'allegro_carrier_id' => $shipmentData['allegro_carrier_id'] ?? null,
|
|
'package_type' => $shipmentData['packageType'],
|
|
'send_again_flag' => $shipmentData['sendAgainFlag'] ?? false,
|
|
'allegro_smart' => $shipmentData['allegroSmart'] ?? false,
|
|
'postnummer' => $shipmentData['postnummer'] ?? null,
|
|
]);
|
|
|
|
ShipmentStatusHistory::create(
|
|
array(
|
|
'shipment_request_id' => $shipment_request->id,
|
|
'shipment_status_id' => ShipmentStatus::STATUS_CREATED,
|
|
)
|
|
);
|
|
|
|
// Create shipment items
|
|
foreach ($shipmentData['items'] as $itemData) {
|
|
ShipmentRequestItem::create([
|
|
'shipment_request_id' => $shipment_request->id,
|
|
'name' => $itemData['name'],
|
|
'item_note' => $itemData['item_note'] ?? null,
|
|
'model_number' => $itemData['model_number'] ?? null,
|
|
'HSCode' => $itemData['HSCode'] ?? null,
|
|
'price' => $itemData['price'],
|
|
'quantity' => $itemData['quantity'],
|
|
'originCountry' => $itemData['originCountry'],
|
|
'weight' => $itemData['weight'],
|
|
'item_id_internal_warehouse' => $itemData['item_id_internal_warehouse'] ?? null,
|
|
'item_id_external' => $itemData['item_id_external'] ?? null,
|
|
]);
|
|
}
|
|
|
|
if (!empty($shipmentData['invoice_data'])) {
|
|
ShipmentRequestInvoice::create([
|
|
'shipment_request_id' => $shipment_request->id,
|
|
'invoice_number' => $shipmentData['invoice_data']['invoiceNumber'],
|
|
'invoice_date' => $shipmentData['invoice_data']['date'],
|
|
'invoice_currency' => $shipmentData['invoice_data']['currency'],
|
|
'invoice_address_name' => $shipmentData['invoice_data']['address']['name'],
|
|
'invoice_address_company_name' => $shipmentData['invoice_data']['address']['companyName'] ?? null,
|
|
'invoice_address_company_vat_number' => $shipmentData['invoice_data']['address']['companyVatNumber'] ?? null,
|
|
'invoice_address_street_name' => $shipmentData['invoice_data']['address']['streetName'],
|
|
'invoice_address_street_number' => $shipmentData['invoice_data']['address']['streetNumber'],
|
|
'invoice_address_city' => $shipmentData['invoice_data']['address']['city'],
|
|
'invoice_address_zip' => $shipmentData['invoice_data']['address']['zip'],
|
|
'invoice_address_state_iso' => $shipmentData['invoice_data']['address']['stateISO'] ?? null,
|
|
'invoice_address_country_iso' => $shipmentData['invoice_data']['address']['countryISO'],
|
|
'invoice_raw_data' => $shipmentData['invoice_data']['invoice_file'],
|
|
]);
|
|
}
|
|
|
|
$return_array[$shipmentData['shipmentReference']] = "Shipment stored sucessfully. Ready for dispatch.";
|
|
|
|
// if ($shipment_request->user->details->apiCallbackURL && $shipment_request->user->details->callbacks_enabled) {
|
|
// $this->callbackService->sendCallback($shipment_request->user->details->apiCallbackURL, [
|
|
// 'endpoint' => 'storeShipment',
|
|
// 'result' => 'true',
|
|
// 'shipment_reference' => $shipmentData['shipmentReference'],
|
|
// 'additionalInfo' => null
|
|
// ]);
|
|
// }
|
|
|
|
});
|
|
} catch (ExternalApiException|LabelPrintException|ShipmentException|GuzzleException|\Exception $e) {
|
|
|
|
$return_array[$shipmentData['shipmentReference']] = $e->getMessage();
|
|
$status_code = 400;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
return response()->json(['response' => $return_array], $status_code);
|
|
|
|
|
|
}
|
|
|
|
|
|
protected function addStickerToLabel(Label $label)
|
|
{
|
|
try {
|
|
$stickerPdfData = ExpediceStickersController::getStickerForLabel($label->shipment->shipmentRequest);
|
|
$mainPdfData = $label->label_data;
|
|
|
|
$client = new Client();
|
|
|
|
$response = $client->post('http://pdf_manager:5000/combine-pdfs', [
|
|
'multipart' => [
|
|
[
|
|
'name' => 'main_pdf',
|
|
'contents' => $mainPdfData,
|
|
'filename' => 'main.pdf'
|
|
],
|
|
[
|
|
'name' => 'sticker_pdf',
|
|
'contents' => $stickerPdfData,
|
|
'filename' => 'sticker.pdf'
|
|
],
|
|
[
|
|
'name' => 'resize',
|
|
'contents' => in_array($label->shipment->shipmentRequest->carrier->carrierMaster->shortname, ["ups"]) ? 'true' : 'true'
|
|
]
|
|
]
|
|
]);
|
|
|
|
return $response->getBody();
|
|
}
|
|
catch (\Exception $e) {
|
|
throw $e;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Placeholder function to merge labels into a file
|
|
protected function mergeLabelsIntoFile(array $labels)
|
|
{
|
|
|
|
$timestamp = uniqid() . "_" . now()->timestamp;
|
|
|
|
$outputFilePath = storage_path("app/label_result_" . $timestamp . ".pdf");
|
|
$cmd_string = "gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -dAutoRotatePages=/None -dFIXEDMEDIA -dPDFFitPage -sPAPERSIZE=a4 -sOutputFile=$outputFilePath";
|
|
$pdf_files = [];
|
|
|
|
foreach ($labels as $label) {
|
|
|
|
$timestamp = uniqid() . "_" . now()->timestamp;
|
|
|
|
// Log::info($label->shipment->shipmentRequest->id . " - starting sticker to label");
|
|
|
|
$label_data_final = $this->addStickerToLabel($label);
|
|
if (is_null($label_data_final)) {
|
|
$label_data_final = $label->label_data;
|
|
}
|
|
|
|
// Log::info($label->shipment->shipmentRequest->id . " - done sticker");
|
|
|
|
$filename = 'labels-' . $timestamp . '.pdf';
|
|
Storage::disk('local')->put($filename, $label_data_final);
|
|
|
|
$pdf_files[] = Storage::disk('local')->path($filename);
|
|
|
|
// Log::info($label->shipment->shipmentRequest->id . " - pdf metadata get done");
|
|
|
|
ShipmentStatusHistory::create(
|
|
array(
|
|
'shipment_request_id' => $label->shipment->shipmentRequest->id,
|
|
'shipment_status_id' => ShipmentStatus::STATUS_LABEL_CREATED,
|
|
)
|
|
);
|
|
|
|
// Log::info($label->shipment->shipmentRequest->id . " - status created");
|
|
|
|
}
|
|
|
|
foreach ($pdf_files as $file) {
|
|
if (!is_null($file)) {
|
|
$cmd_string .= " " . $file;
|
|
}
|
|
}
|
|
Log::info($cmd_string);
|
|
|
|
// Execute the Ghostscript command to merge PDFs
|
|
exec($cmd_string);
|
|
|
|
// Log::info("command gs done");
|
|
// Delete temporary PDF files after merging
|
|
foreach ($pdf_files as $file) {
|
|
if (file_exists($file)) {
|
|
// unlink($file);
|
|
}
|
|
}
|
|
|
|
// Log::info("tmp files deleted");
|
|
|
|
$ret_file = file_get_contents($outputFilePath);
|
|
if (file_exists($outputFilePath)) {
|
|
unlink($outputFilePath);
|
|
}
|
|
// Log::info("output final deleted");
|
|
return $ret_file;
|
|
}
|
|
|
|
public function labelsList(Request $request)
|
|
{
|
|
$shipments = ShipmentRequest::with(['carrier'])
|
|
->whereDoesntHave('shipment')
|
|
->get();
|
|
|
|
$groupedShipments = $shipments->groupBy('carrier.carrier_shortname')
|
|
->sortByDesc(function ($group) {
|
|
return $group->count();
|
|
});
|
|
|
|
|
|
$result = $groupedShipments->map(function ($items, $key) {
|
|
$carrier = $items->first()->carrier;
|
|
return [
|
|
'carrier_name' => $carrier->carrier_name,
|
|
'img' => $carrier->img,
|
|
'carrier_shortname' => $carrier->carrier_shortname,
|
|
'package_count' => $items->count(),
|
|
];
|
|
})->values();
|
|
|
|
|
|
// Check if the request is an Inertia request
|
|
if ($request->header('X-Inertia')) {
|
|
return Inertia::render('Expedice', [
|
|
'carriers' => $result,
|
|
]);
|
|
}
|
|
|
|
// For API requests, return a JSON response
|
|
return response()->json($result);
|
|
}
|
|
|
|
|
|
public function reprintLabels(Request $request)
|
|
{
|
|
|
|
$userId = $request->user()->id;
|
|
|
|
// broadcast(new LabelsProcessed($userId, [
|
|
// 'errors' => "test test", // Pass all collected errors
|
|
// 'error_code' => 400,
|
|
// ]));
|
|
|
|
// Dispatch the job
|
|
ReprintLabelsJob::dispatch(
|
|
$request->get('shipmentIds'),
|
|
$request->get('batchIds'),
|
|
$request->get('send_again', false),
|
|
$userId
|
|
);
|
|
|
|
return response()->json(['message' => 'Label creation queued successfully. Please wait....']);
|
|
|
|
}
|
|
|
|
public function processViaDifferentCarrier(Request $request)
|
|
{
|
|
|
|
try {
|
|
|
|
|
|
Log::channel('expedice')->info('function processViaDifferentCarrier initiated by ' . $request->user()->name, [
|
|
'shipment_request_ids' => $request->get('shipmentIds'),
|
|
'carrier_id' => $request->get('carrierId')
|
|
]);
|
|
|
|
$shipment_request = ShipmentRequest::whereIn('id', $request->get('shipmentIds'))->first();
|
|
|
|
$carrier = Carrier::where('id', $request->get('carrierId'))->first();
|
|
|
|
$batch = ShipmentRequestBatch::create([
|
|
'user_id' => $request->user()->id,
|
|
'carrier_master_id' => $carrier->carrier_master_id,
|
|
]);
|
|
|
|
|
|
$shipment_request->pickup_point_code = null;
|
|
$shipment_request->carrier_id = $carrier->id;
|
|
|
|
// Save the changes to the database
|
|
$shipment_request->save();
|
|
|
|
// Instantiate the correct carrier service dynamically for each shipment
|
|
$carrierService = CarrierServiceFactory::create($carrier);
|
|
|
|
if (isset($shipment_request->shipment)) {
|
|
$res = $carrierService->cancelShipment($shipment_request->shipment);
|
|
}
|
|
|
|
ReprintLabelsJob::dispatch(
|
|
$request->get('shipmentIds'),
|
|
null,
|
|
false,
|
|
$request->user()->id
|
|
);
|
|
|
|
return response()->json(['message' => 'Label creation queued successfully. Please wait....']);
|
|
}
|
|
catch (\Exception $e) {
|
|
return response()->json(['error' => $e->getMessage()]);
|
|
}
|
|
|
|
}
|
|
|
|
}
|