test drive

This commit is contained in:
2025-04-21 10:39:02 +05:00
parent 885dc939c6
commit 016ffd7614
10 changed files with 158 additions and 36 deletions

View File

@@ -268,3 +268,21 @@ function dbTypeToPhp(string $type): string
default => 'string', default => 'string',
}; };
} }
/**
* Cached value
*
* @param string $name
* @param mixed $value
* @param int $seconds
*/
function cached(string $name, mixed $value, int $seconds = 60): mixed
{
return cache()->has($name)
? cache($name)
: cache()->remember(
key: $name,
ttl: $seconds,
callback: fn () => is_callable($value) ? call_user_func($value) : $value
);
}

View File

@@ -10,6 +10,41 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
/**
* @property int $id
* @property null|string $unique_id
* @property int $card_state_id
* @property int $card_type_id
* @property string $region
* @property int $branch_id
* @property string $customer_name
* @property string $customer_surname
* @property null|string $customer_patronic_name
* @property null|string $born_at
* @property null|string $old_surname
* @property string $citizenship
* @property string $passport_serie
* @property string $passport_id
* @property string $passport_given_at
* @property string $passport_given_by
* @property string $born_place
* @property null|string $job_location
* @property null|string $passport_address
* @property null|string $real_address
* @property null|string $phone
* @property null|string $phone_additional
* @property null|string $status
* @property string $passport_one
* @property string $passport_two
* @property string $passport_three
* @property string $passport_four
* @property null|string $notes
* @property int $user_id
* @property null|\Illuminate\Support\Carbon $created_at
* @property null|\Illuminate\Support\Carbon $updated_at
* @property null|\Illuminate\Support\Carbon $deleted_at
* @property bool $paid
*/
class CardOrder extends Model class CardOrder extends Model
{ {
use HasFactory; use HasFactory;

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Modules\CardOrder\Nova\Actions;
use App\Nova\Resources\Order\Card\CardOrder;
use App\Repos\Order\OrderRepo;
use App\Repos\Payment\OnlinePaymentRepo;
use Closure;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Actions\ActionResponse;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;
class RetryNovaCardOrderPayment extends Action
{
use InteractsWithQueue, Queueable;
/**
* Name.
*/
public function name(): string
{
return __('Retry payment');
}
/**
* Permissions
*/
public static function permissions(CardOrder $resource): Closure
{
return fn () => ! $resource->paid && $resource->status === OrderRepo::PENDING;
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<array-key, \Illuminate\Database\Eloquent\Model> $models
* @return mixed
*/
public function handle(ActionFields $fields, Collection $models): mixed
{
$resource = $models->first();
$payment = (new OnlinePaymentRepo)->payCardOrder($resource);
return $payment['status'] === 'success'
? ActionResponse::openInNewTab($payment['url'])
: ActionResponse::danger('Тöleg sistemada registrasiýa bolmady!');
}
/**
* Get the fields available on the action.
*
* @return array<int, \Laravel\Nova\Fields\Field>
*/
public function fields(NovaRequest $request): array
{
return [];
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace App\Nova\Guard;
use Closure;
use Illuminate\Http\Request;
class NovaGuard
{
/**
* Admin user
*/
public static function isAdmin(): Closure
{
return fn (Request $request): bool => $request->user()->isAdmin();
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Nova\Resources\Order\Card;
use App\Models\Branch\Branch; use App\Models\Branch\Branch;
use App\Models\Order\Card\CardOrder as CardOrderModel; use App\Models\Order\Card\CardOrder as CardOrderModel;
use App\Modules\CardOrder\Nova\Actions\RetryNovaCardOrderPayment;
use App\Nova\Filters\RegionFilter; use App\Nova\Filters\RegionFilter;
use App\Nova\Filters\StatusFilter; use App\Nova\Filters\StatusFilter;
use App\Nova\Forms\NovaForm; use App\Nova\Forms\NovaForm;
@@ -23,10 +24,7 @@ use App\Rules\DowranAgaAllowed;
use App\Rules\OnlyLetters; use App\Rules\OnlyLetters;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Gate;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Date; use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Hidden; use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\ID; use Laravel\Nova\Fields\ID;
@@ -40,6 +38,9 @@ use Laravel\Nova\URL;
use Nurmuhammet\NovaCustomHtml\NovaCustomHtml; use Nurmuhammet\NovaCustomHtml\NovaCustomHtml;
use Nurmuhammet\NovaInputmask\NovaInputmask; use Nurmuhammet\NovaInputmask\NovaInputmask;
/**
* @mixin CardOrderModel
*/
class CardOrder extends Resource class CardOrder extends Resource
{ {
/** /**
@@ -117,17 +118,18 @@ class CardOrder extends Resource
*/ */
public static function indexQuery(NovaRequest $request, mixed $query): Builder public static function indexQuery(NovaRequest $request, mixed $query): Builder
{ {
/** @var \App\Models\User */
$user = $request->user(); $user = $request->user();
if ($user->isAdmin()) { if ($user->isAdmin()) {
return $query; return $query;
} }
if ($user->isOperator()) { if ($user->isOperator() && count($user->branches()->pluck('branches.id')) < 1) {
return $query->whereIn('branch_id', $user->branches()->pluck('branches.id')); return $query->whereIn('branch_id', $user->branches()->pluck('branches.id'));
} }
return $query->where('user_id', $request->user()->id); return $query->where('user_id', $user->id);
} }
/** /**
@@ -155,20 +157,6 @@ class CardOrder extends Resource
: sprintf('resources/%s/%s', static::uriKey(), $resource->getKey()); : sprintf('resources/%s/%s', static::uriKey(), $resource->getKey());
} }
/**
* Return the location to redirect the user after update.
*
* @param \Laravel\Nova\Resource $resource
*/
// public static function redirectAfterUpdate(NovaRequest $request, $resource): URL|string
// {
// $payment = (new OnlinePaymentRepo())->payCardOrder($resource);
// return $payment['status'] === 'success'
// ? URL::remote($payment['url'])
// : sprintf('resources/%s/%s', static::uriKey(), $resource->getKey());
// }
/** /**
* Get the fields for index. * Get the fields for index.
* *
@@ -389,19 +377,10 @@ class CardOrder extends Resource
public function actions(NovaRequest $request): array public function actions(NovaRequest $request): array
{ {
return [ return [
Action::using('Tölegi täzeden geçir', function (ActionFields $fields, Collection $models) { RetryNovaCardOrderPayment::make()
$resource = $models->first(); ->icon('credit-card')
$payment = (new OnlinePaymentRepo)->payCardOrder($resource);
return $payment['status'] === 'success'
? URL::remote($payment['url'])
: sprintf('resources/%s/%s', static::uriKey(), $resource->getKey());
})->icon('credit-card')
->sole() ->sole()
->canSee(function ($request) { ->canSee(RetryNovaCardOrderPayment::permissions($this)),
return $request->user()->isAdmin();
}),
]; ];
} }
} }

View File

@@ -54,7 +54,7 @@ class User extends Resource
* @var array<int, string> * @var array<int, string>
*/ */
public static $search = [ public static $search = [
'id', 'name', 'email', 'phone', 'id', 'name', 'email', 'phone', 'username',
]; ];
/** /**

View File

@@ -14,6 +14,10 @@ class CardStateRepo
*/ */
public static function values(): Collection|array public static function values(): Collection|array
{ {
return CardState::where('active', true)->pluck('name', 'id'); return cached(
'card-states',
fn () => CardState::where('active', true)->pluck('name', 'id'),
60 * 60
);
} }
} }

View File

@@ -14,6 +14,10 @@ class CardTypeRepo
*/ */
public static function values(): Collection|array public static function values(): Collection|array
{ {
return CardType::where('active', true)->pluck('name', 'id'); return cached(
'card-types',
fn () => CardType::where('active', true)->pluck('name', 'id'),
60 * 60
);
} }
} }

View File

@@ -333,5 +333,6 @@
"Loan order required docs": "Karz gerekli resminamalary", "Loan order required docs": "Karz gerekli resminamalary",
"Required docs": "Gerekli resminamalar", "Required docs": "Gerekli resminamalar",
"Payment items": "Тöleg taryhy", "Payment items": "Тöleg taryhy",
"This month": "Şul aý" "This month": "Şul aý",
"Retry payment": "Tölegi täzeden geçir"
} }

View File

@@ -7,7 +7,7 @@ parameters:
- app/ - app/
# Level 9 is the highest level # Level 9 is the highest level
level: 7 level: 6
# ignoreErrors: # ignoreErrors:
# - '#PHPDoc tag @var#' # - '#PHPDoc tag @var#'