Feature: Adding Caches and Fallbacks to Live Pricing Requests

This commit is contained in:
2026-08-29 10:31:58 +03:00
parent 6671c5e9d1
commit f85fb51ecd
5 changed files with 182 additions and 44 deletions
+35 -23
View File
@@ -8,12 +8,14 @@ use Lunar\Shipping\DataTransferObjects\ShippingOptionRequest;
use Lunar\Shipping\Interfaces\ShippingRateInterface;
use Lunar\Shipping\Models\ShippingRate;
use Modules\Core\Shipping\Carriers\Acs\Exceptions\AcsApiException;
use Modules\Core\Shipping\Concerns\CachesLivePricing;
use Modules\Core\Shipping\Concerns\ResolvesFixedPricing;
use Modules\Core\Shipping\Contracts\SupportsLivePricing;
class AcsRateDriver implements ShippingRateInterface, SupportsLivePricing
{
use ResolvesFixedPricing;
use CachesLivePricing;
public ShippingRate $shippingRate;
@@ -51,35 +53,45 @@ class AcsRateDriver implements ShippingRateInterface, SupportsLivePricing
return $this->resolveLivePrice($shippingRate, $shippingMethod, $cart, $postcode);
}
/**
* Wrapped in CachesLivePricing's cache so a live-pricing outage within
* the cache window still serves the last successful quote instead of
* immediately falling back. A cold cache during an outage falls back
* to the rate's own configured static price (resolveFixedPrice()) —
* see ManageShippingRates, which now allows a static price to be
* configured on a "live" rate specifically for this fallback.
*/
private function resolveLivePrice(ShippingRate $shippingRate, $shippingMethod, $cart, string $postcode): ?ShippingOption
{
try {
$destination = $this->areaResolver->resolve($postcode);
return $this->cached($shippingRate, $cart, function () use ($shippingRate, $shippingMethod, $cart, $postcode) {
try {
$destination = $this->areaResolver->resolve($postcode);
$response = $this->client->call('ACS_Price_Calculation', [
'Billing_Code' => config('acs.billing_code'),
'Acs_Station_Destination' => $destination->stationId,
'Weight' => $this->totalWeightInKg($cart),
'Pickup_Date' => now()->toDateString(),
'Charge_Type' => 2,
])->throwIfError();
} catch (AcsApiException $e) {
report($e);
$response = $this->client->call('ACS_Price_Calculation', [
'Billing_Code' => config('acs.billing_code'),
'Acs_Station_Destination' => $destination->stationId,
'Weight' => $this->totalWeightInKg($cart),
'Pickup_Date' => now()->toDateString(),
'Charge_Type' => 2,
])->throwIfError();
} catch (AcsApiException $e) {
report($e);
return null;
}
return $this->resolveFixedPrice($shippingRate, $shippingMethod, $cart);
}
$amount = (int) round(($response->valueOutput['Total_Ammount'] ?? 0) * 100);
$amount = (int) round(($response->valueOutput['Total_Ammount'] ?? 0) * 100);
return new ShippingOption(
name: $shippingMethod->name ?: $this->name(),
description: $shippingMethod->description ?: $this->description(),
identifier: $shippingRate->getIdentifier(),
price: new Price($amount, $cart->currency, 1),
taxClass: $shippingRate->getTaxClass(),
taxReference: $shippingRate->getTaxReference(),
meta: ['acs_station_destination' => $destination->stationId],
);
return new ShippingOption(
name: $shippingMethod->name ?: $this->name(),
description: $shippingMethod->description ?: $this->description(),
identifier: $shippingRate->getIdentifier(),
price: new Price($amount, $cart->currency, 1),
taxClass: $shippingRate->getTaxClass(),
taxReference: $shippingRate->getTaxReference(),
meta: ['acs_station_destination' => $destination->stationId],
);
});
}
public function on(ShippingRate $shippingRate): self