Feature: Order Updates, Events, Order Flows, Shipment And COD support

This commit is contained in:
2026-09-14 00:03:06 +03:00
parent 78bbd8390a
commit 44c6b7defd
73 changed files with 2854 additions and 464 deletions
@@ -14,6 +14,7 @@ use Modules\Core\Shipping\DTOs\ManifestResult;
use Modules\Core\Shipping\DTOs\ShipmentRequest;
use Modules\Core\Shipping\DTOs\TrackingCheckpoint;
use Modules\Core\Shipping\Enums\TrackingStatus;
use Modules\Core\Shipping\Models\Manifest;
use Modules\Core\Shipping\Models\Shipment;
class AcsFulfillmentService implements CarrierFulfillmentInterface, SupportsManifestBatching, SupportsTracking
@@ -88,7 +89,7 @@ class AcsFulfillmentService implements CarrierFulfillmentInterface, SupportsMani
public function cancelShipment(Shipment $shipment): void
{
if ($shipment->manifest_reference) {
if ($shipment->manifest_id) {
throw new RuntimeException('Cannot cancel a shipment already included in an issued manifest.');
}
@@ -103,7 +104,7 @@ class AcsFulfillmentService implements CarrierFulfillmentInterface, SupportsMani
{
return Shipment::query()
->where('carrier', 'acs')
->whereNull('manifest_reference')
->whereNull('manifest_id')
->whereNull('cancelled_at')
->get();
}
@@ -123,11 +124,18 @@ class AcsFulfillmentService implements CarrierFulfillmentInterface, SupportsMani
$pickupListNo = (string) $response->valueOutput['PickupList_No'];
$manifest = Manifest::create([
'carrier' => 'acs',
'reference' => $pickupListNo,
'shipment_count' => $shipments->count(),
'issued_at' => now(),
]);
$shipments->each(fn (Shipment $shipment) => $shipment->update([
'manifest_reference' => $pickupListNo,
'manifest_id' => $manifest->id,
]));
return ManifestResult::success($pickupListNo, $shipments);
return ManifestResult::success($manifest, $shipments);
}
public function trackShipment(Shipment $shipment): Collection
@@ -176,6 +184,11 @@ class AcsFulfillmentService implements CarrierFulfillmentInterface, SupportsMani
{
$action = strtolower($action);
// TODO: no live ACS payload sample yet showing a distinct
// collection checkpoint separate from transit ("arrival"/
// "departure" already map to InTransit) — add a str_contains()
// arm mapping to TrackingStatus::CollectedFromSender here once
// one is confirmed.
return match (true) {
str_contains($action, 'delivery to consignee') => TrackingStatus::Delivered,
str_contains($action, 'on delivery') => TrackingStatus::OutForDelivery,