Feature: Adding Caches and Fallbacks to Live Pricing Requests
This commit is contained in:
@@ -2,10 +2,12 @@
|
||||
|
||||
namespace Modules\Core\Shipping\Filament\Pages;
|
||||
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Get;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Lunar\Shipping\Filament\Resources\ShippingZoneResource\Pages\ManageShippingRates as BaseManageShippingRates;
|
||||
use Lunar\Shipping\Models\ShippingMethod;
|
||||
use Lunar\Shipping\Models\ShippingRate;
|
||||
@@ -17,13 +19,20 @@ use Lunar\Shipping\Models\ShippingRate;
|
||||
* ShippingZoneResource::getPages() — is untouched; the container simply
|
||||
* hands back this subclass whenever the vendor class is resolved.
|
||||
*
|
||||
* Hides the price / price-break fields for a rate whose method has
|
||||
* Relabels the price / price-break fields for a rate whose method has
|
||||
* charge_by = "live" (see ShippingMethodResourceExtension, which adds that
|
||||
* option to methods whose driver supports live pricing) — those fields
|
||||
* would otherwise be dead configuration the driver never reads. Pricing
|
||||
* strategy (cart_total / weight / live) stays entirely on the Shipping
|
||||
* Method, matching Lunar's own existing charge_by convention; nothing new
|
||||
* is stored on the rate itself.
|
||||
* option to methods whose driver supports live pricing) — they stay
|
||||
* visible and editable, but as the fallback price used when the live API
|
||||
* call fails (see AcsRateDriver::resolveLivePrice()), not the primary
|
||||
* price. Pricing strategy (cart_total / weight / live) stays entirely on
|
||||
* the Shipping Method, matching Lunar's own existing charge_by convention;
|
||||
* nothing new is stored on the rate itself.
|
||||
*
|
||||
* Also re-binds the vendor price field's afterStateHydrated(): the vendor
|
||||
* callback reads $record->basePrices->first()->price->decimal with no
|
||||
* null-guard, which crashes on any rate with no basePrices row — routine
|
||||
* for a live rate that has never had a fallback price configured. Same
|
||||
* logic, just null-safe.
|
||||
*/
|
||||
class ManageShippingRates extends BaseManageShippingRates
|
||||
{
|
||||
@@ -32,13 +41,13 @@ class ManageShippingRates extends BaseManageShippingRates
|
||||
$form = parent::form($form);
|
||||
|
||||
return $form->schema(
|
||||
$this->hidePriceFieldsWhenLive($form->getComponents())
|
||||
$this->labelPriceFieldsAsFallbackWhenLive($form->getComponents())
|
||||
);
|
||||
}
|
||||
|
||||
private function hidePriceFieldsWhenLive(array $components): array
|
||||
private function labelPriceFieldsAsFallbackWhenLive(array $components): array
|
||||
{
|
||||
$isNotLive = fn (Get $get) => static::methodChargeBy($get('shipping_method_id')) !== 'live';
|
||||
$isLive = fn (Get $get) => static::methodChargeBy($get('shipping_method_id')) === 'live';
|
||||
|
||||
foreach ($components as $component) {
|
||||
if (! method_exists($component, 'getName')) {
|
||||
@@ -46,11 +55,25 @@ class ManageShippingRates extends BaseManageShippingRates
|
||||
}
|
||||
|
||||
if ($component->getName() === 'price') {
|
||||
$component->visible($isNotLive)->required($isNotLive)->dehydrated(true);
|
||||
$component->required(fn (Get $get) => ! $isLive($get))
|
||||
->helperText(fn (Get $get) => $isLive($get)
|
||||
? 'Used only if the live API call fails.'
|
||||
: null)
|
||||
->afterStateHydrated(static function (TextInput $component, ?Model $record = null): void {
|
||||
if (! $record) {
|
||||
return;
|
||||
}
|
||||
|
||||
$basePrice = $record->basePrices->first();
|
||||
|
||||
$component->state($basePrice?->price->decimal);
|
||||
});
|
||||
}
|
||||
|
||||
if ($component->getName() === 'prices') {
|
||||
$component->visible($isNotLive)->dehydrated(true);
|
||||
$component->helperText(fn (Get $get) => $isLive($get)
|
||||
? 'Used only if the live API call fails.'
|
||||
: null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +91,9 @@ class ManageShippingRates extends BaseManageShippingRates
|
||||
->label(__('lunarpanel.shipping::relationmanagers.shipping_rates.table.price.label'))
|
||||
->formatStateUsing(function ($state, ShippingRate $record) {
|
||||
if (static::methodChargeBy($record->shipping_method_id) === 'live') {
|
||||
return 'Live API pricing';
|
||||
return $state === null
|
||||
? 'Live API pricing, no fallback set'
|
||||
: $state->price->formatted.' (fallback)';
|
||||
}
|
||||
|
||||
return $state?->price->formatted;
|
||||
@@ -80,15 +105,6 @@ class ManageShippingRates extends BaseManageShippingRates
|
||||
);
|
||||
}
|
||||
|
||||
protected static function saveShippingRate(?ShippingRate $shippingRate = null, array $data = []): void
|
||||
{
|
||||
if (static::methodChargeBy($data['shipping_method_id'] ?? $shippingRate?->shipping_method_id) === 'live') {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::saveShippingRate($shippingRate, $data);
|
||||
}
|
||||
|
||||
protected static function methodChargeBy(ShippingMethod|int|string|null $method): ?string
|
||||
{
|
||||
if (blank($method)) {
|
||||
|
||||
Reference in New Issue
Block a user