103 lines
4.7 KiB
PHP
103 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Modules\Core\Providers;
|
|
|
|
use Illuminate\Console\Scheduling\Schedule as ConsoleSchedule;
|
|
use Illuminate\Support\ServiceProvider;
|
|
use Livewire\Livewire;
|
|
use Livewire\Mechanisms\ComponentRegistry;
|
|
use Lunar\Models\Order;
|
|
use Lunar\Shipping\Facades\Shipping;
|
|
use Lunar\Shipping\Filament\Resources\ShippingZoneResource\Pages\ManageShippingRates as VendorManageShippingRates;
|
|
use Lunar\Shipping\Models\ShippingMethod;
|
|
use Modules\Core\Shipping\Carriers\Acs\AcsClient;
|
|
use Modules\Core\Shipping\Carriers\Acs\AcsFulfillmentService;
|
|
use Modules\Core\Shipping\Carriers\Acs\AcsRateDriver;
|
|
use Modules\Core\Shipping\Carriers\Acs\Jobs\WarmAcsAreaCacheJob;
|
|
use Modules\Core\Shipping\Carriers\BoxNow\BoxNowClient;
|
|
use Modules\Core\Shipping\Carriers\BoxNow\BoxNowFulfillmentService;
|
|
use Modules\Core\Shipping\Carriers\BoxNow\BoxNowRateDriver;
|
|
use Modules\Core\Shipping\Contracts\CarrierFulfillmentInterface;
|
|
use Modules\Core\Shipping\Filament\Pages\ManageShippingRates;
|
|
use Modules\Core\Shipping\Jobs\PollShipmentTrackingJob;
|
|
use Modules\Core\Shipping\Models\Shipment;
|
|
|
|
class ShippingServiceProvider extends ServiceProvider
|
|
{
|
|
public function register(): void
|
|
{
|
|
$this->mergeConfigFrom(__DIR__ . '/../../config/shippingCarriers/acs.php', 'acs');
|
|
$this->mergeConfigFrom(__DIR__ . '/../../config/shippingCarriers/boxnow.php', 'boxnow');
|
|
|
|
$this->app->singleton(AcsClient::class, fn () => new AcsClient(config('acs')));
|
|
$this->app->singleton(BoxNowClient::class, fn () => new BoxNowClient(config('boxnow')));
|
|
|
|
$this->app->bind(CarrierFulfillmentInterface::class, function ($app, array $params) {
|
|
return match ($params['carrier'] ?? null) {
|
|
'acs' => $app->make(AcsFulfillmentService::class),
|
|
'box-now' => $app->make(BoxNowFulfillmentService::class),
|
|
default => null,
|
|
};
|
|
});
|
|
|
|
// The vendor Rates page has no extension hook, so we swap it for
|
|
// our subclass everywhere. Route::get($path, VendorClass::class)
|
|
// instantiates the vendor class directly via the container for the
|
|
// initial full-page load (bypassing Livewire's component registry
|
|
// entirely), so this container bind is required in addition to the
|
|
// Livewire::component() re-registration below — the bind covers
|
|
// first load, the Livewire registration covers every AJAX
|
|
// round-trip (form submits, table interactions) afterwards.
|
|
$this->app->bind(VendorManageShippingRates::class, ManageShippingRates::class);
|
|
}
|
|
|
|
public function boot(): void
|
|
{
|
|
$this->publishes([
|
|
__DIR__ . '/../../config/shippingCarriers/acs.php' => config_path('shippingCarriers/acs.php'),
|
|
__DIR__ . '/../../config/shippingCarriers/boxnow.php' => config_path('shippingCarriers/boxnow.php'),
|
|
], 'core-config');
|
|
|
|
Order::resolveRelationUsing('shipments', function ($order) {
|
|
return $order->hasMany(Shipment::class);
|
|
});
|
|
|
|
// Deferred: the Shipping facade resolves a binding registered in
|
|
// lunarphp/table-rate-shipping's own ShippingServiceProvider::boot(),
|
|
// and provider boot order between packages isn't guaranteed.
|
|
$this->app->booted(function () {
|
|
Shipping::extend('acs', fn ($app) => $app->make(AcsRateDriver::class));
|
|
Shipping::extend('box-now', fn ($app) => $app->make(BoxNowRateDriver::class));
|
|
|
|
$this->app->make(ConsoleSchedule::class)
|
|
->job(new WarmAcsAreaCacheJob)
|
|
->dailyAt('06:00')
|
|
->when(fn () => ShippingMethod::where('driver', 'acs')->exists());
|
|
|
|
$this->app->make(ConsoleSchedule::class)
|
|
->job(new PollShipmentTrackingJob)
|
|
->everyThirtyMinutes();
|
|
|
|
$this->overrideRatesPageLivewireComponent();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The vendor Rates page has no extension hook, so we swap it for our
|
|
* subclass (see Shipping/Filament/Pages/ManageShippingRates). Filament
|
|
* already registered the vendor class as a Livewire component under a
|
|
* name derived from its class string (see
|
|
* Panel::registerLivewireComponents()); Livewire's own registry is a
|
|
* simple last-write-wins name => class map, so re-registering the same
|
|
* derived name against our subclass here overrides it — keeping the
|
|
* route, sub-navigation, and every Livewire round-trip (including form
|
|
* submissions) pointed at one consistent component identity.
|
|
*/
|
|
private function overrideRatesPageLivewireComponent(): void
|
|
{
|
|
$name = $this->app->make(ComponentRegistry::class)->getName(VendorManageShippingRates::class);
|
|
|
|
Livewire::component($name, ManageShippingRates::class);
|
|
}
|
|
}
|