Feature: Wire up carrier-agnostic shipping admin UI

Registers ShippingServiceProvider (carrier config, driver/fulfillment bindings, Rates page override) and wires the shipping admin surface into CorePlugin: dynamic carrier dropdown on Shipping Method create/edit, a "Create Shipment" order action resolved generically by carrier, and a Pickup Manifests page for carriers that support manifest batching.
This commit is contained in:
2026-07-19 00:52:01 +03:00
parent 37c2e1194c
commit 4acabe4185
8 changed files with 452 additions and 2 deletions
@@ -0,0 +1,83 @@
<?php
namespace Modules\Core\Shipping\Extensions;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\Concerns\HasChildComponents;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Lunar\Admin\Support\Extending\ResourceExtension;
use Lunar\Shipping\Facades\Shipping;
class ShippingMethodResourceExtension extends ResourceExtension
{
public function extendForm(Form $form): Form
{
return $form->schema(
$this->replaceDriverField($form->getComponents())
);
}
public function extendTable(Table $table): Table
{
return $table->columns(
array_map(function ($column) {
if (method_exists($column, 'getName') && $column->getName() === 'driver') {
return $this->driverColumn();
}
return $column;
}, $table->getColumns())
);
}
private function driverColumn(): TextColumn
{
return TextColumn::make('driver')
->label('Type')
->formatStateUsing(fn ($state) => $this->driverLabel($state));
}
private function driverLabel(string $key): string
{
$driver = collect(Shipping::getSupportedDrivers())->get($key);
return $driver?->name() ?? $key;
}
/**
* Recursively walk the form tree and replace the hardcoded driver
* Select (nested inside Section > Group) with one listing every
* registered driver, built-in or custom.
*
* @param array<Component> $components
* @return array<Component>
*/
private function replaceDriverField(array $components): array
{
return array_map(function (Component $component) {
if (method_exists($component, 'getName') && $component->getName() === 'driver') {
return $this->driverSelect();
}
if (in_array(HasChildComponents::class, class_uses_recursive($component), true)) {
$component->schema(
$this->replaceDriverField($component->getChildComponents())
);
}
return $component;
}, $components);
}
private function driverSelect(): Select
{
return Select::make('driver')
->label('Type')
->options(fn () => collect(Shipping::getSupportedDrivers())
->mapWithKeys(fn ($driver, $key) => [$key => $driver->name()]))
->default('flat-rate');
}
}