485 lines
19 KiB
PHP
485 lines
19 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Modules\Shipments;
|
|
|
|
final class DeliveryStatus
|
|
{
|
|
public const UNKNOWN = 'unknown';
|
|
public const CREATED = 'created';
|
|
public const CONFIRMED = 'confirmed';
|
|
public const IN_TRANSIT = 'in_transit';
|
|
public const OUT_FOR_DELIVERY = 'out_for_delivery';
|
|
public const READY_FOR_PICKUP = 'ready_for_pickup';
|
|
public const DELIVERED = 'delivered';
|
|
public const RETURNED = 'returned';
|
|
public const CANCELLED = 'cancelled';
|
|
public const PROBLEM = 'problem';
|
|
|
|
public const TERMINAL_STATUSES = [
|
|
self::DELIVERED,
|
|
self::RETURNED,
|
|
self::CANCELLED,
|
|
];
|
|
|
|
public const LABEL_PL = [
|
|
self::UNKNOWN => 'Nieznany',
|
|
self::CREATED => 'Utworzona',
|
|
self::CONFIRMED => 'Potwierdzona',
|
|
self::IN_TRANSIT => 'W tranzycie',
|
|
self::OUT_FOR_DELIVERY => 'W doręczeniu',
|
|
self::READY_FOR_PICKUP => 'Gotowa do odbioru',
|
|
self::DELIVERED => 'Doręczona',
|
|
self::RETURNED => 'Zwrócona',
|
|
self::CANCELLED => 'Anulowana',
|
|
self::PROBLEM => 'Problem',
|
|
];
|
|
|
|
private const INPOST_MAP = [
|
|
'created' => self::CREATED,
|
|
'offers_prepared' => self::CREATED,
|
|
'offer_selected' => self::CREATED,
|
|
'confirmed' => self::CONFIRMED,
|
|
'dispatched' => self::CONFIRMED,
|
|
'collected' => self::IN_TRANSIT,
|
|
'taken_by_courier' => self::IN_TRANSIT,
|
|
'adopted_at_source_branch' => self::IN_TRANSIT,
|
|
'adopted_at_sorting_center' => self::IN_TRANSIT,
|
|
'sent_from_sorting_center' => self::IN_TRANSIT,
|
|
'adopted_at_target_sorting_center' => self::IN_TRANSIT,
|
|
'sent_from_target_sorting_center' => self::IN_TRANSIT,
|
|
'adopted_at_target_branch' => self::IN_TRANSIT,
|
|
'out_for_delivery' => self::OUT_FOR_DELIVERY,
|
|
'ready_to_pickup' => self::READY_FOR_PICKUP,
|
|
'ready_to_pickup_from_branch' => self::READY_FOR_PICKUP,
|
|
'ready_to_pickup_from_pok' => self::READY_FOR_PICKUP,
|
|
'stack_in_box_machine' => self::READY_FOR_PICKUP,
|
|
'stack_in_customer_service_point' => self::READY_FOR_PICKUP,
|
|
'delivered' => self::DELIVERED,
|
|
'claimed' => self::DELIVERED,
|
|
'returned_to_sender' => self::RETURNED,
|
|
'undelivered' => self::RETURNED,
|
|
'undelivered_wrong_address' => self::RETURNED,
|
|
'undelivered_incomplete_address' => self::RETURNED,
|
|
'undelivered_unknown_recipient' => self::RETURNED,
|
|
'undelivered_cod_cash_receiver' => self::RETURNED,
|
|
'cancelled' => self::CANCELLED,
|
|
'expired' => self::CANCELLED,
|
|
'avizo' => self::PROBLEM,
|
|
'pickup_time_expired' => self::PROBLEM,
|
|
'stack_parcel_pickup_time_expired' => self::PROBLEM,
|
|
'missing' => self::PROBLEM,
|
|
'delay_in_delivery' => self::PROBLEM,
|
|
'oversized' => self::PROBLEM,
|
|
'pickup_reminder_sent' => self::READY_FOR_PICKUP,
|
|
'pickup_reminder_sent_address' => self::READY_FOR_PICKUP,
|
|
'readdressed' => self::IN_TRANSIT,
|
|
'redirect_to_box' => self::IN_TRANSIT,
|
|
];
|
|
|
|
private const INPOST_DESCRIPTIONS = [
|
|
'created' => 'Przesyłka utworzona',
|
|
'offers_prepared' => 'Oferty cenowe przygotowane',
|
|
'offer_selected' => 'Oferta wybrana',
|
|
'confirmed' => 'Przesyłka potwierdzona',
|
|
'dispatched' => 'Przesyłka nadana',
|
|
'collected' => 'Odebrana od nadawcy',
|
|
'taken_by_courier' => 'Odebrana przez kuriera',
|
|
'adopted_at_source_branch' => 'Przyjęta w oddziale źródłowym',
|
|
'adopted_at_sorting_center' => 'Przyjęta w centrum sortowania',
|
|
'sent_from_sorting_center' => 'Wysłana z centrum sortowania',
|
|
'adopted_at_target_sorting_center' => 'Przyjęta w docelowym centrum sortowania',
|
|
'sent_from_target_sorting_center' => 'Wysłana z docelowego centrum sortowania',
|
|
'adopted_at_target_branch' => 'Przyjęta w oddziale docelowym',
|
|
'out_for_delivery' => 'W drodze do odbiorcy',
|
|
'ready_to_pickup' => 'Gotowa do odbioru w paczkomacie',
|
|
'ready_to_pickup_from_branch' => 'Gotowa do odbioru z oddziału',
|
|
'ready_to_pickup_from_pok' => 'Gotowa do odbioru z POK',
|
|
'stack_in_box_machine' => 'Umieszczona w paczkomacie',
|
|
'stack_in_customer_service_point' => 'Umieszczona w punkcie obsługi',
|
|
'delivered' => 'Doręczona',
|
|
'claimed' => 'Odebrana po awizo',
|
|
'returned_to_sender' => 'Zwrócona do nadawcy',
|
|
'undelivered' => 'Niedoręczona',
|
|
'undelivered_wrong_address' => 'Niedoręczona — błędny adres',
|
|
'undelivered_incomplete_address' => 'Niedoręczona — niepełny adres',
|
|
'undelivered_unknown_recipient' => 'Niedoręczona — nieznany odbiorca',
|
|
'undelivered_cod_cash_receiver' => 'Niedoręczona — problem z pobraniem',
|
|
'cancelled' => 'Anulowana',
|
|
'expired' => 'Wygasła',
|
|
'avizo' => 'Awizowana',
|
|
'pickup_time_expired' => 'Czas odbioru upłynął',
|
|
'stack_parcel_pickup_time_expired' => 'Czas odbioru ze stack upłynął',
|
|
'missing' => 'Przesyłka zagubiona',
|
|
'delay_in_delivery' => 'Opóźnienie w dostawie',
|
|
'oversized' => 'Przesyłka ponadgabarytowa',
|
|
'pickup_reminder_sent' => 'Wysłano przypomnienie o odbiorze',
|
|
'pickup_reminder_sent_address' => 'Przypomnienie wysłane na adres',
|
|
'readdressed' => 'Przekierowana na inny adres',
|
|
'redirect_to_box' => 'Przekierowana do paczkomatu',
|
|
];
|
|
|
|
private const APACZKA_MAP = [
|
|
'0' => self::CREATED,
|
|
'1' => self::CONFIRMED,
|
|
'2' => self::IN_TRANSIT,
|
|
'3' => self::IN_TRANSIT,
|
|
'4' => self::OUT_FOR_DELIVERY,
|
|
'5' => self::DELIVERED,
|
|
'6' => self::RETURNED,
|
|
'7' => self::CANCELLED,
|
|
'8' => self::PROBLEM,
|
|
'9' => self::READY_FOR_PICKUP,
|
|
'10' => self::IN_TRANSIT,
|
|
'NEW' => self::CREATED,
|
|
'PENDING' => self::CREATED,
|
|
'CONFIRMED' => self::CONFIRMED,
|
|
'PICKED_UP' => self::IN_TRANSIT,
|
|
'IN_TRANSIT' => self::IN_TRANSIT,
|
|
'OUT_FOR_DELIVERY' => self::OUT_FOR_DELIVERY,
|
|
'DELIVERED' => self::DELIVERED,
|
|
'RETURNED' => self::RETURNED,
|
|
'CANCELLED' => self::CANCELLED,
|
|
'ERROR' => self::PROBLEM,
|
|
'WAITING_FOR_PICKUP' => self::READY_FOR_PICKUP,
|
|
'REDIRECT' => self::IN_TRANSIT,
|
|
];
|
|
|
|
private const APACZKA_DESCRIPTIONS = [
|
|
'0' => 'Oczekuje na przetworzenie',
|
|
'1' => 'Zamówienie potwierdzone',
|
|
'2' => 'Odebrana przez kuriera',
|
|
'3' => 'W transporcie',
|
|
'4' => 'W doręczeniu',
|
|
'5' => 'Doręczona',
|
|
'6' => 'Zwrócona do nadawcy',
|
|
'7' => 'Anulowana',
|
|
'8' => 'Błąd zamówienia',
|
|
'9' => 'Oczekuje na odbiór w punkcie',
|
|
'10' => 'Przekierowana',
|
|
'NEW' => 'Zamówienie utworzone',
|
|
'PENDING' => 'Oczekuje na przetworzenie',
|
|
'CONFIRMED' => 'Zamówienie potwierdzone',
|
|
'PICKED_UP' => 'Odebrana przez kuriera',
|
|
'IN_TRANSIT' => 'W transporcie',
|
|
'OUT_FOR_DELIVERY' => 'W doręczeniu',
|
|
'DELIVERED' => 'Doręczona',
|
|
'RETURNED' => 'Zwrócona do nadawcy',
|
|
'CANCELLED' => 'Anulowana',
|
|
'ERROR' => 'Błąd zamówienia',
|
|
'WAITING_FOR_PICKUP' => 'Oczekuje na odbiór w punkcie',
|
|
'REDIRECT' => 'Przekierowana',
|
|
];
|
|
|
|
private const ALLEGRO_MAP = [
|
|
'NEW' => self::CREATED,
|
|
'READY_TO_SHIP' => self::CONFIRMED,
|
|
'IN_TRANSIT' => self::IN_TRANSIT,
|
|
'DELIVERED' => self::DELIVERED,
|
|
'CANCELLED' => self::CANCELLED,
|
|
'ERROR' => self::PROBLEM,
|
|
'RETURNED' => self::RETURNED,
|
|
];
|
|
|
|
private const ALLEGRO_DESCRIPTIONS = [
|
|
'NEW' => 'Przesyłka utworzona',
|
|
'READY_TO_SHIP' => 'Etykieta wygenerowana, oczekuje na nadanie',
|
|
'IN_TRANSIT' => 'Odebrana przez przewoźnika',
|
|
'DELIVERED' => 'Doręczona',
|
|
'CANCELLED' => 'Anulowana',
|
|
'ERROR' => 'Błąd przetwarzania',
|
|
'RETURNED' => 'Zwrócona do nadawcy',
|
|
];
|
|
|
|
private const ALLEGRO_EDGE_MAP = [
|
|
// Realne slugi z edge API (po slugify opisów)
|
|
'przygotowana_przez_nadawce' => self::CREATED,
|
|
'nadana' => self::CONFIRMED,
|
|
'podjeta_z_maszyny_przez_kuriera' => self::IN_TRANSIT,
|
|
'podjeta_z_punktu_przez_kuriera' => self::IN_TRANSIT,
|
|
'podjeta_z_punktu' => self::IN_TRANSIT,
|
|
'odebrana_przez_kuriera' => self::IN_TRANSIT,
|
|
'przekazal_przesylke_do_magazynu' => self::IN_TRANSIT,
|
|
'przekazana_do_magazynu' => self::IN_TRANSIT,
|
|
'przesylka_wyjechala_w_droge_do_punktu_docelowego' => self::IN_TRANSIT,
|
|
'w_sortowni' => self::IN_TRANSIT,
|
|
'wyjechala_w_droge_do_punktu_docelowego' => self::IN_TRANSIT,
|
|
'wyslana_z_sortowni' => self::IN_TRANSIT,
|
|
'w_doreczeniu' => self::OUT_FOR_DELIVERY,
|
|
'wydana_do_doreczenia' => self::OUT_FOR_DELIVERY,
|
|
'dostarczana' => self::OUT_FOR_DELIVERY,
|
|
'gotowa_do_odbioru' => self::READY_FOR_PICKUP,
|
|
'oczekuje_na_odbior' => self::READY_FOR_PICKUP,
|
|
'przesylka_oczekuje_na_odbior' => self::READY_FOR_PICKUP,
|
|
'dostarczona' => self::DELIVERED,
|
|
'doreczona' => self::DELIVERED,
|
|
'odebrana' => self::DELIVERED,
|
|
'zwrocona' => self::RETURNED,
|
|
'zwrocona_do_nadawcy' => self::RETURNED,
|
|
'anulowana' => self::CANCELLED,
|
|
'odmowa_przyjecia' => self::PROBLEM,
|
|
'uszkodzona' => self::PROBLEM,
|
|
'zagubiona' => self::PROBLEM,
|
|
];
|
|
|
|
private const ALLEGRO_EDGE_DESCRIPTIONS = [
|
|
'przygotowana_przez_nadawce' => 'Przesyłka przygotowana przez nadawcę',
|
|
'nadana' => 'Przesyłka nadana',
|
|
'podjeta_z_maszyny_przez_kuriera' => 'Podjęta z maszyny przez kuriera',
|
|
'podjeta_z_punktu_przez_kuriera' => 'Podjęta z punktu przez kuriera',
|
|
'odebrana_przez_kuriera' => 'Odebrana przez kuriera',
|
|
'przekazana_do_magazynu' => 'Przekazana do magazynu',
|
|
'przesylka_wyjechala_w_droge_do_punktu_docelowego' => 'Wyjechała w drogę do punktu docelowego',
|
|
'w_sortowni' => 'W sortowni',
|
|
'wyjechala_w_droge_do_punktu_docelowego' => 'Wyjechała w drogę do punktu docelowego',
|
|
'wyslana_z_sortowni' => 'Wysłana z sortowni',
|
|
'w_doreczeniu' => 'W doręczeniu',
|
|
'wydana_do_doreczenia' => 'Wydana do doręczenia',
|
|
'dostarczana' => 'Dostarczana',
|
|
'gotowa_do_odbioru' => 'Gotowa do odbioru',
|
|
'oczekuje_na_odbior' => 'Oczekuje na odbiór',
|
|
'przesylka_oczekuje_na_odbior' => 'Oczekuje na odbiór',
|
|
'dostarczona' => 'Dostarczona',
|
|
'doreczona' => 'Doręczona',
|
|
'odebrana' => 'Odebrana',
|
|
'zwrocona' => 'Zwrócona',
|
|
'zwrocona_do_nadawcy' => 'Zwrócona do nadawcy',
|
|
'anulowana' => 'Anulowana',
|
|
'odmowa_przyjecia' => 'Odmowa przyjęcia',
|
|
'uszkodzona' => 'Uszkodzona',
|
|
'zagubiona' => 'Zagubiona',
|
|
];
|
|
|
|
public const ALL_STATUSES = [
|
|
self::UNKNOWN,
|
|
self::CREATED,
|
|
self::CONFIRMED,
|
|
self::IN_TRANSIT,
|
|
self::OUT_FOR_DELIVERY,
|
|
self::READY_FOR_PICKUP,
|
|
self::DELIVERED,
|
|
self::RETURNED,
|
|
self::CANCELLED,
|
|
self::PROBLEM,
|
|
];
|
|
|
|
private const PROVIDER_MAPS = [
|
|
'inpost' => self::INPOST_MAP,
|
|
'apaczka' => self::APACZKA_MAP,
|
|
'allegro_wza' => self::ALLEGRO_MAP,
|
|
'allegro_edge' => self::ALLEGRO_EDGE_MAP,
|
|
];
|
|
|
|
private const PROVIDER_DESCRIPTIONS = [
|
|
'inpost' => self::INPOST_DESCRIPTIONS,
|
|
'apaczka' => self::APACZKA_DESCRIPTIONS,
|
|
'allegro_wza' => self::ALLEGRO_DESCRIPTIONS,
|
|
'allegro_edge' => self::ALLEGRO_EDGE_DESCRIPTIONS,
|
|
];
|
|
|
|
/**
|
|
* @return array<string, array{normalized: string, description: string}>
|
|
*/
|
|
public static function getDefaultMappings(string $provider): array
|
|
{
|
|
$map = self::PROVIDER_MAPS[$provider] ?? [];
|
|
$descriptions = self::PROVIDER_DESCRIPTIONS[$provider] ?? [];
|
|
|
|
$result = [];
|
|
foreach ($map as $rawStatus => $normalized) {
|
|
$result[(string) $rawStatus] = [
|
|
'normalized' => $normalized,
|
|
'description' => (string) ($descriptions[$rawStatus] ?? (string) $rawStatus),
|
|
];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, array{normalized_status: string, description: string}> $overrides keyed by "provider:raw_status"
|
|
*/
|
|
public static function normalizeWithOverrides(string $provider, string $rawStatus, array $overrides): string
|
|
{
|
|
$key = $provider . ':' . $rawStatus;
|
|
if (isset($overrides[$key]) && $overrides[$key]['normalized_status'] !== '') {
|
|
return $overrides[$key]['normalized_status'];
|
|
}
|
|
|
|
return self::normalize($provider, $rawStatus);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, array{normalized_status: string, description: string}> $overrides keyed by "provider:raw_status"
|
|
*/
|
|
public static function descriptionWithOverrides(string $provider, string $rawStatus, array $overrides): string
|
|
{
|
|
$key = $provider . ':' . $rawStatus;
|
|
if (isset($overrides[$key]) && $overrides[$key]['description'] !== '') {
|
|
return $overrides[$key]['description'];
|
|
}
|
|
|
|
return self::description($provider, $rawStatus);
|
|
}
|
|
|
|
public static function normalize(string $provider, string $rawStatus): string
|
|
{
|
|
$map = match ($provider) {
|
|
'inpost' => self::INPOST_MAP,
|
|
'apaczka' => self::APACZKA_MAP,
|
|
'allegro_wza' => self::ALLEGRO_MAP,
|
|
'allegro_edge' => self::ALLEGRO_EDGE_MAP,
|
|
default => [],
|
|
};
|
|
|
|
return $map[$rawStatus] ?? self::UNKNOWN;
|
|
}
|
|
|
|
public static function description(string $provider, string $rawStatus): string
|
|
{
|
|
$map = match ($provider) {
|
|
'inpost' => self::INPOST_DESCRIPTIONS,
|
|
'apaczka' => self::APACZKA_DESCRIPTIONS,
|
|
'allegro_wza' => self::ALLEGRO_DESCRIPTIONS,
|
|
'allegro_edge' => self::ALLEGRO_EDGE_DESCRIPTIONS,
|
|
default => [],
|
|
};
|
|
|
|
return $map[$rawStatus] ?? $rawStatus;
|
|
}
|
|
|
|
public static function label(string $status): string
|
|
{
|
|
return self::LABEL_PL[$status] ?? 'Nieznany';
|
|
}
|
|
|
|
public static function isTerminal(string $status): bool
|
|
{
|
|
return in_array($status, self::TERMINAL_STATUSES, true);
|
|
}
|
|
|
|
public static function slugifyAllegroDescription(string $description): string
|
|
{
|
|
$text = trim($description);
|
|
if ($text === '') {
|
|
return 'unknown';
|
|
}
|
|
|
|
// Usuń typowe prefiksy
|
|
$text = preg_replace('/^Przesy[łl]ka zosta[łl]a\s+/ui', '', $text);
|
|
$text = preg_replace('/^Kurier\s+/ui', '', $text);
|
|
$text = preg_replace('/^Paczka zosta[łl]a\s+/ui', '', $text);
|
|
|
|
// Polskie znaki na ASCII
|
|
$polish = ['ą','ć','ę','ł','ń','ó','ś','ź','ż','Ą','Ć','Ę','Ł','Ń','Ó','Ś','Ź','Ż'];
|
|
$ascii = ['a','c','e','l','n','o','s','z','z','A','C','E','L','N','O','S','Z','Z'];
|
|
$text = str_replace($polish, $ascii, $text);
|
|
|
|
// Lowercase, zamień nie-alfanumeryczne na podkreślenia
|
|
$text = strtolower($text);
|
|
$text = preg_replace('/[^a-z0-9]+/', '_', $text);
|
|
$text = trim($text, '_');
|
|
|
|
return $text !== '' ? $text : 'unknown';
|
|
}
|
|
|
|
/**
|
|
* Keyword-based fallback for unknown Allegro edge descriptions.
|
|
* Used when slugified description is not in ALLEGRO_EDGE_MAP.
|
|
*/
|
|
public static function guessStatusFromDescription(string $description): string
|
|
{
|
|
$lower = mb_strtolower($description, 'UTF-8');
|
|
|
|
if (str_contains($lower, 'doręczon') || str_contains($lower, 'dostarczono') || str_contains($lower, 'odebrana przez odbiorc')) {
|
|
return self::DELIVERED;
|
|
}
|
|
if (str_contains($lower, 'zwrócon') || str_contains($lower, 'zwrocona')) {
|
|
return self::RETURNED;
|
|
}
|
|
if (str_contains($lower, 'anulowan')) {
|
|
return self::CANCELLED;
|
|
}
|
|
if (str_contains($lower, 'doręczeni') || str_contains($lower, 'doreczenia') || str_contains($lower, 'wydana do')) {
|
|
return self::OUT_FOR_DELIVERY;
|
|
}
|
|
if (str_contains($lower, 'sortowni') || str_contains($lower, 'magazyn') || str_contains($lower, 'w drodze') || str_contains($lower, 'tranzyt') || str_contains($lower, 'kurier') || str_contains($lower, 'podjęta') || str_contains($lower, 'podjeta') || str_contains($lower, 'wyjechał') || str_contains($lower, 'wyjechala')) {
|
|
return self::IN_TRANSIT;
|
|
}
|
|
if (str_contains($lower, 'oczekuje na odb') || str_contains($lower, 'gotowa do odb') || (str_contains($lower, 'odbiór') && !str_contains($lower, 'w drodze'))) {
|
|
return self::READY_FOR_PICKUP;
|
|
}
|
|
if (str_contains($lower, 'nadana') || str_contains($lower, 'nadano')) {
|
|
return self::CONFIRMED;
|
|
}
|
|
if (str_contains($lower, 'przygotowan') || str_contains($lower, 'utworzon')) {
|
|
return self::CREATED;
|
|
}
|
|
if (str_contains($lower, 'uszkodzon') || str_contains($lower, 'problem') || str_contains($lower, 'zagubion')) {
|
|
return self::PROBLEM;
|
|
}
|
|
|
|
return self::UNKNOWN;
|
|
}
|
|
|
|
public static function trackingUrl(string $provider, string $trackingNumber, string $carrierId = ''): ?string
|
|
{
|
|
$number = trim($trackingNumber);
|
|
if ($number === '') {
|
|
return null;
|
|
}
|
|
|
|
$encoded = rawurlencode($number);
|
|
|
|
if ($provider === 'inpost') {
|
|
return 'https://inpost.pl/sledzenie-przesylek?number=' . $encoded;
|
|
}
|
|
|
|
if ($carrierId !== '') {
|
|
$url = self::matchCarrierByName($encoded, strtolower(trim($carrierId)));
|
|
if ($url !== null) {
|
|
return $url;
|
|
}
|
|
}
|
|
|
|
if ($provider === 'allegro_wza') {
|
|
return 'https://allegro.pl/allegrodelivery/sledzenie-paczki?numer=' . $encoded;
|
|
}
|
|
|
|
return 'https://www.google.com/search?q=' . $encoded . '+sledzenie+przesylki';
|
|
}
|
|
|
|
private static function matchCarrierByName(string $encoded, string $carrier): ?string
|
|
{
|
|
if (str_contains($carrier, 'dpd')) {
|
|
return 'https://tracktrace.dpd.com.pl/parcelDetails?p1=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'dhl')) {
|
|
return 'https://www.dhl.com/pl-pl/home/sledzenie-przesylki.html?tracking-id=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'inpost') || str_contains($carrier, 'paczkomat')) {
|
|
return 'https://inpost.pl/sledzenie-przesylek?number=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'orlen') || str_contains($carrier, 'ruch')) {
|
|
return 'https://www.orlenpaczka.pl/sledz-paczke/?numer=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'poczta') || str_contains($carrier, 'pocztex')) {
|
|
return 'https://emonitoring.poczta-polska.pl/?numer=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'ups')) {
|
|
return 'https://www.ups.com/track?tracknum=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'fedex')) {
|
|
return 'https://www.fedex.com/fedextrack/?trknbr=' . $encoded;
|
|
}
|
|
if (str_contains($carrier, 'gls')) {
|
|
return 'https://gls-group.com/PL/pl/sledzenie-paczek?match=' . $encoded;
|
|
}
|
|
if ($carrier === 'allegro') {
|
|
return 'https://allegro.pl/allegrodelivery/sledzenie-paczki?numer=' . $encoded;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|