102 lines
3.1 KiB
PHP
102 lines
3.1 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace Modules\Core\Shipping\Extensions;
|
||
|
|
|
||
|
|
use Filament\Actions;
|
||
|
|
use Filament\Forms;
|
||
|
|
use Filament\Notifications\Notification;
|
||
|
|
use Lunar\Admin\Support\Extending\ViewPageExtension;
|
||
|
|
use Lunar\Models\Order;
|
||
|
|
use Lunar\Shipping\Models\ShippingMethod;
|
||
|
|
use Modules\Core\Shipping\Contracts\CarrierFulfillmentInterface;
|
||
|
|
|
||
|
|
class OrderViewExtension extends ViewPageExtension
|
||
|
|
{
|
||
|
|
public function headerActions(array $actions): array
|
||
|
|
{
|
||
|
|
$actions[] = $this->createShipmentAction();
|
||
|
|
|
||
|
|
return $actions;
|
||
|
|
}
|
||
|
|
|
||
|
|
private function createShipmentAction(): Actions\Action
|
||
|
|
{
|
||
|
|
return Actions\Action::make('create_shipment')
|
||
|
|
->label('Create Shipment')
|
||
|
|
->icon('heroicon-o-truck')
|
||
|
|
->modalSubmitActionLabel('Create Shipment')
|
||
|
|
->form([
|
||
|
|
Forms\Components\Toggle::make('confirm')
|
||
|
|
->label('Confirm')
|
||
|
|
->helperText('This will create a real shipment with the carrier.')
|
||
|
|
->rules([
|
||
|
|
function () {
|
||
|
|
return function (string $attribute, $value, \Closure $fail) {
|
||
|
|
if ($value !== true) {
|
||
|
|
$fail('Please confirm before creating the shipment.');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
},
|
||
|
|
]),
|
||
|
|
])
|
||
|
|
->action(function (Order $record, Actions\Action $action) {
|
||
|
|
$service = $this->resolveFulfillmentService($record);
|
||
|
|
|
||
|
|
if (! $service) {
|
||
|
|
Notification::make()
|
||
|
|
->title('No carrier fulfillment integration is configured for this order.')
|
||
|
|
->danger()
|
||
|
|
->send();
|
||
|
|
|
||
|
|
$action->halt();
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$service->createShipment($record);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
report($e);
|
||
|
|
|
||
|
|
Notification::make()
|
||
|
|
->title('Failed to create shipment: '.$e->getMessage())
|
||
|
|
->danger()
|
||
|
|
->send();
|
||
|
|
|
||
|
|
$action->halt();
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Notification::make()
|
||
|
|
->title('Shipment created.')
|
||
|
|
->success()
|
||
|
|
->send();
|
||
|
|
})
|
||
|
|
->visible(fn (Order $record) => $record->shipments()->exists() === false
|
||
|
|
&& $this->resolveFulfillmentService($record) !== null);
|
||
|
|
}
|
||
|
|
|
||
|
|
private function resolveCarrier(Order $record): ?string
|
||
|
|
{
|
||
|
|
$code = $record->shippingAddress?->shipping_option;
|
||
|
|
|
||
|
|
if (! $code) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ShippingMethod::where('code', $code)->value('driver');
|
||
|
|
}
|
||
|
|
|
||
|
|
private function resolveFulfillmentService(Order $record): ?CarrierFulfillmentInterface
|
||
|
|
{
|
||
|
|
$carrier = $this->resolveCarrier($record);
|
||
|
|
|
||
|
|
if (! $carrier) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return app(CarrierFulfillmentInterface::class, ['carrier' => $carrier]);
|
||
|
|
}
|
||
|
|
}
|