Compare commits
94 Commits
8c33cc6645
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5bc322170 | ||
|
|
749208ac97 | ||
|
|
1870583441 | ||
|
|
76c05ebe7c | ||
|
|
515731003c | ||
|
|
a9c7ec6b80 | ||
|
|
4038d47582 | ||
|
|
326987d6de | ||
|
|
f433fc3e41 | ||
|
|
5361c00e7b | ||
|
|
5e37bd1a76 | ||
|
|
5a53b90272 | ||
|
|
59548a486f | ||
|
|
c0bfe974ad | ||
|
|
895c5f6226 | ||
|
|
88d84ac457 | ||
|
|
94ad59ce24 | ||
|
|
b1630ea623 | ||
|
|
6a700fbd4b | ||
|
|
8e548126b2 | ||
|
|
2ec9b28a60 | ||
|
|
4fc242bc7d | ||
|
|
6df3a27383 | ||
|
|
7111b1db09 | ||
|
|
c4ee279d91 | ||
|
|
14c4ea5791 | ||
|
|
01a0aa8ca1 | ||
|
|
97fea41b62 | ||
|
|
5568d32a31 | ||
| 4e78ff77cc | |||
| 4c0917e6ba | |||
| c56e3383d1 | |||
| 967501d58f | |||
| 88fdc3aa7f | |||
| 183916a62a | |||
| a9490e132d | |||
| 438e5a3f43 | |||
| cbd469c97f | |||
| bc45f2756e | |||
| 73448548e7 | |||
| f0e9767e78 | |||
| 0e39450849 | |||
| 4c83d41eb0 | |||
| bccf52a8fb | |||
| 6e03c4d218 | |||
| 53f8c893ca | |||
| 52d070f4e5 | |||
| 209f3899b5 | |||
| 58d6ef0a9a | |||
| 1a0756fdca | |||
| f506972c91 | |||
| 19abe08a90 | |||
| 6428c9e20c | |||
| 9d66f21854 | |||
| da5bb6e99b | |||
| 680d5d4130 | |||
| f73a510984 | |||
| 4b7c3da3d4 | |||
| b0877399eb | |||
| 3b5b7f10c4 | |||
| 45e95725cd | |||
| a98a41efab | |||
| 3911e8e21a | |||
| dc871f36d4 | |||
| 2dd06d0e4f | |||
| a9e5f7ece8 | |||
| 7e7d583973 | |||
| ba6d703893 | |||
| 2bb9ec2ae2 | |||
| 1d67616cdb | |||
| 5a37d56cfb | |||
| c1b3a58c3a | |||
| c94ac5d12d | |||
| c24f7cbac6 | |||
| 8637c22ed7 | |||
| 2659aae278 | |||
| 038b5ea2fb | |||
| 54e11dcbb4 | |||
| 3ea35f6bca | |||
| b67fd61bf8 | |||
| 816a6c2f60 | |||
| 294ec0144d | |||
| c2e9198dbc | |||
| 074fe44ab3 | |||
| 31ab39b21c | |||
| 7bdd5243bd | |||
| 0da1efe5c3 | |||
| 8c24f00382 | |||
| 60f7efd6ba | |||
| c16bb98ed3 | |||
| 0779e4b9f6 | |||
| 9be16228f7 | |||
| 84f551ddc6 | |||
| 96415c2bc1 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,9 +11,9 @@
|
||||
/.phpunit.cache
|
||||
/.vscode
|
||||
/.zed
|
||||
/database/data/
|
||||
/auth.json
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
|
||||
@@ -23,7 +23,7 @@ class CreateCardOrder extends CreateRecord
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
$defaultUrl = $this->getResource()::getUrl('index');
|
||||
$defaultUrl = string($this->getResource()::getUrl('index'));
|
||||
|
||||
/** @var \App\Modules\CardOrder\Models\CardOrder */
|
||||
$record = $this->record;
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Cards\CardOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\Cards\CardOrders\CardOrderResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListCardOrders extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListCardOrders extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,20 @@ class CardOrdersTable
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('unique_id')
|
||||
->label(__('ID'))
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('status')
|
||||
->label(__('Status'))
|
||||
->color(OrderStatusRepository::statusColorMatching())
|
||||
->formatStateUsing(fn (string $state) => OrderStatusRepository::statusFormatted($state))
|
||||
->badge()
|
||||
->sortable()
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('cardState.name')
|
||||
->label(__('Reason'))
|
||||
->searchable(),
|
||||
@@ -69,14 +78,6 @@ class CardOrdersTable
|
||||
->label(__('Phone'))
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('status')
|
||||
->label(__('Status'))
|
||||
->color(OrderStatusRepository::statusColorMatching())
|
||||
->formatStateUsing(fn (string $state) => OrderStatusRepository::statusFormatted($state))
|
||||
->badge()
|
||||
->sortable()
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('updated_at')
|
||||
->label(__('Updated At'))
|
||||
->dateTime()
|
||||
|
||||
@@ -5,15 +5,23 @@ namespace App\Filament\Clusters\Cards\Cards\Pages;
|
||||
use App\Filament\Clusters\Cards\Cards\CardResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ManageRecords;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ManageCards extends ManageRecords
|
||||
{
|
||||
protected static string $resource = CardResource::class;
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return __('My cards');
|
||||
}
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
CreateAction::make()
|
||||
->label(__('Add card'))
|
||||
->createAnother(false),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class CardsCluster extends Cluster
|
||||
{
|
||||
protected static ?int $navigationSort = 1;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCreditCard;
|
||||
|
||||
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Cards\Resources\CardPinOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\Cards\Resources\CardPinOrders\CardPinOrderResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListCardPinOrders extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListCardPinOrders extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class CardPinOrdersTable
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID'),
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Loans\LoanOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\Loans\LoanOrders\LoanOrderResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListLoanOrders extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListLoanOrders extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class LoanOrdersTable
|
||||
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -9,6 +9,8 @@ use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class LoansCluster extends Cluster
|
||||
{
|
||||
protected static ?int $navigationSort = 2;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedBanknotes;
|
||||
|
||||
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Loans\Resources\LoanOrderMobiles\Pages;
|
||||
|
||||
use App\Filament\Clusters\Loans\Resources\LoanOrderMobiles\LoanOrderMobileResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListLoanOrderMobiles extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListLoanOrderMobiles extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class LoanOrderMobilesTable
|
||||
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Loans\Resources\LoanPaidOffLetters\Pages;
|
||||
|
||||
use App\Filament\Clusters\Loans\Resources\LoanPaidOffLetters\LoanPaidOffLetterResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListLoanPaidOffLetters extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListLoanPaidOffLetters extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class LoanPaidOffLettersTable
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments;
|
||||
|
||||
use BackedEnum;
|
||||
use Filament\Clusters\Cluster;
|
||||
use Filament\Pages\Enums\SubNavigationPosition;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class OnlinePaymentsCluster extends Cluster
|
||||
{
|
||||
protected static ?int $navigationSort = 5;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedServerStack;
|
||||
|
||||
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Online payments');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments;
|
||||
|
||||
use App\Filament\Clusters\OnlinePayments\OnlinePaymentsCluster;
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Pages\EditOnlinePayment;
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Pages\ListOnlinePayments;
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Schemas\OnlinePaymentForm;
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Tables\OnlinePaymentsTable;
|
||||
use App\Modules\OnlinePayment\Models\OnlinePayment;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class OnlinePaymentResource extends Resource
|
||||
{
|
||||
protected static ?string $model = OnlinePayment::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
protected static ?string $cluster = OnlinePaymentsCluster::class;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'orderId';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return OnlinePaymentForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return OnlinePaymentsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListOnlinePayments::route('/'),
|
||||
'edit' => EditOnlinePayment::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Pages;
|
||||
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\OnlinePaymentResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateOnlinePayment extends CreateRecord
|
||||
{
|
||||
protected static string $resource = OnlinePaymentResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Pages;
|
||||
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\OnlinePaymentResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditOnlinePayment extends EditRecord
|
||||
{
|
||||
protected static string $resource = OnlinePaymentResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Pages;
|
||||
|
||||
use App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\OnlinePaymentResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListOnlinePayments extends ListRecords
|
||||
{
|
||||
protected static string $resource = OnlinePaymentResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Schemas;
|
||||
|
||||
use App\Modules\OnlinePayment\Repositories\OnlinePaymentRepository;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Components\Fieldset;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class OnlinePaymentForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make()
|
||||
->columnSpanFull()
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
'xl' => 3,
|
||||
])
|
||||
->schema([
|
||||
// Payment Information
|
||||
Fieldset::make(__('Payment Information'))
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('amount')
|
||||
->label(__('Amount'))
|
||||
->required()
|
||||
->numeric()
|
||||
->suffix('TMT')
|
||||
->rules(['required', 'numeric', 'min:0']),
|
||||
|
||||
TextInput::make('description')
|
||||
->label(__('Description'))
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('orderNumber')
|
||||
->label(__('Order Number'))
|
||||
->maxLength(255)
|
||||
->helperText(__('Leave empty to auto-generate')),
|
||||
|
||||
Select::make('paymentStatus')
|
||||
->label(__('Payment Status'))
|
||||
->options(OnlinePaymentRepository::statusValues())
|
||||
->default(OnlinePaymentRepository::PENDING)
|
||||
->required(),
|
||||
]),
|
||||
|
||||
// Card Information
|
||||
Fieldset::make(__('Card Information'))
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('cardholderName')
|
||||
->label(__('Cardholder Name'))
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('pan')
|
||||
->label(__('Card Number (PAN)'))
|
||||
->maxLength(255)
|
||||
->mask('9999 9999 9999 9999')
|
||||
->placeholder('1234 5678 9012 3456'),
|
||||
|
||||
TextInput::make('expiration')
|
||||
->label(__('Expiration Date'))
|
||||
->mask('99/99')
|
||||
->placeholder('MM/YY'),
|
||||
|
||||
TextInput::make('approvalCode')
|
||||
->label(__('Approval Code'))
|
||||
->maxLength(255),
|
||||
]),
|
||||
|
||||
// Additional Information
|
||||
Fieldset::make(__('Additional Information'))
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('booking_number')
|
||||
->label(__('Booking Number'))
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('depositedAmount')
|
||||
->label(__('Deposited Amount'))
|
||||
->numeric()
|
||||
->suffix('TMT'),
|
||||
|
||||
TextInput::make('refunded_amount')
|
||||
->label(__('Refunded Amount'))
|
||||
->numeric()
|
||||
->suffix('TMT'),
|
||||
|
||||
TextInput::make('username')
|
||||
->label(__('Username'))
|
||||
->maxLength(255)
|
||||
->helperText(__('Payment provider username')),
|
||||
]),
|
||||
|
||||
// URLs
|
||||
Fieldset::make(__('URLs'))
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('formUrl')
|
||||
->label(__('Form URL'))
|
||||
->url()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('successUrl')
|
||||
->label(__('Success URL'))
|
||||
->url()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('errorUrl')
|
||||
->label(__('Error URL'))
|
||||
->url()
|
||||
->maxLength(255),
|
||||
]),
|
||||
|
||||
// API Information
|
||||
Fieldset::make(__('API Information'))
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('api_client')
|
||||
->label(__('API Client'))
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('callbackStatus')
|
||||
->label(__('Callback Status'))
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('orderId')
|
||||
->label(__('Order ID'))
|
||||
->maxLength(255)
|
||||
->helperText(__('External order identifier')),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\OnlinePayments\Resources\OnlinePayments\Tables;
|
||||
|
||||
use App\Modules\OnlinePayment\Repositories\OnlinePaymentRepository;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class OnlinePaymentsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->defaultSort('created_at', direction: 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label(__('ID'))
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('orderNumber')
|
||||
->label(__('Order Number'))
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('amount')
|
||||
->label(__('Amount'))
|
||||
->money('TMT')
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('description')
|
||||
->label(__('Description'))
|
||||
->limit(50),
|
||||
|
||||
TextColumn::make('paymentStatus')
|
||||
->label(__('Payment Status'))
|
||||
->badge()
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
OnlinePaymentRepository::PAID => 'success',
|
||||
OnlinePaymentRepository::FAILED => 'danger',
|
||||
default => 'warning',
|
||||
})
|
||||
->formatStateUsing(fn (string $state): string => OnlinePaymentRepository::statusValues()[$state] ?? $state)
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('cardholderName')
|
||||
->label(__('Cardholder Name'))
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('pan')
|
||||
->label(__('Card Number'))
|
||||
->formatStateUsing(fn (string $state): string => $state ? '**** **** **** '.substr($state, -4) : '-')
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('orderId')
|
||||
->label(__('Order ID'))
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('username')
|
||||
->label(__('Username'))
|
||||
->searchable()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
|
||||
TextColumn::make('created_at')
|
||||
->label(__('Created At'))
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(),
|
||||
|
||||
TextColumn::make('updated_at')
|
||||
->label(__('Updated At'))
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\CurrencyRates;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\Pages\CreateCurrencyRate;
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\Pages\EditCurrencyRate;
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\Pages\ListCurrencyRates;
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\Schemas\CurrencyRateForm;
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\Tables\CurrencyRatesTable;
|
||||
use App\Filament\Clusters\Settings\SettingsCluster;
|
||||
use App\Modules\CurrencyRate\Models\CurrencyRate;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class CurrencyRateResource extends Resource
|
||||
{
|
||||
protected static ?string $model = CurrencyRate::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCurrencyDollar;
|
||||
|
||||
protected static ?string $cluster = SettingsCluster::class;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Currencies');
|
||||
}
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('Currency rate');
|
||||
}
|
||||
|
||||
public static function getPluralModelLabel(): string
|
||||
{
|
||||
return __('Currency rates');
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return CurrencyRateForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return CurrencyRatesTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListCurrencyRates::route('/'),
|
||||
'create' => CreateCurrencyRate::route('/create'),
|
||||
'edit' => EditCurrencyRate::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\CurrencyRates\Pages;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\CurrencyRateResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateCurrencyRate extends CreateRecord
|
||||
{
|
||||
protected static string $resource = CurrencyRateResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\CurrencyRates\Pages;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\CurrencyRateResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditCurrencyRate extends EditRecord
|
||||
{
|
||||
protected static string $resource = CurrencyRateResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\CurrencyRates\Pages;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\CurrencyRates\CurrencyRateResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListCurrencyRates extends ListRecords
|
||||
{
|
||||
protected static string $resource = CurrencyRateResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\CurrencyRates\Schemas;
|
||||
|
||||
use App\Modules\CurrencyRate\Models\CurrencyRate;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class CurrencyRateForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('currency_from')
|
||||
->label(__('Currency from'))
|
||||
->native(false)
|
||||
->searchable()
|
||||
->options(CurrencyRate::currencies())
|
||||
->rules('required')
|
||||
->belowLabel('1 möçberi'),
|
||||
|
||||
Select::make('currency_to')
|
||||
->label(__('Currency to'))
|
||||
->native(false)
|
||||
->searchable()
|
||||
->options(CurrencyRate::currencies())
|
||||
->rules('required')
|
||||
->belowLabel('1 möçberi'),
|
||||
|
||||
TextInput::make('value')
|
||||
->label(__('Currency value'))
|
||||
->required()
|
||||
->numeric()
|
||||
->belowLabel('Bitin däl sanlary "." bilen ýazmaly'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\CurrencyRates\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class CurrencyRatesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('currency_from')
|
||||
->label(__('Currency from'))
|
||||
->searchable(),
|
||||
TextColumn::make('currency_to')
|
||||
->label(__('Currency to'))
|
||||
->searchable(),
|
||||
TextColumn::make('value')
|
||||
->label(__('Currency value'))
|
||||
->searchable(),
|
||||
TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Pages;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\VisaMasterSettingsResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateVisaMasterSettings extends CreateRecord
|
||||
{
|
||||
protected static string $resource = VisaMasterSettingsResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Pages;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\VisaMasterSettingsResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditVisaMasterSettings extends EditRecord
|
||||
{
|
||||
protected static string $resource = VisaMasterSettingsResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Pages;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\VisaMasterSettingsResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListVisaMasterSettings extends ListRecords
|
||||
{
|
||||
protected static string $resource = VisaMasterSettingsResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Schemas;
|
||||
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterSettings;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class VisaMasterSettingsForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('name')
|
||||
->label(__('Type'))
|
||||
->options(VisaMasterSettings::types())
|
||||
->native(false)
|
||||
->required(),
|
||||
|
||||
TextInput::make('display_name')
|
||||
->label(__('Name'))
|
||||
->required()
|
||||
->string()
|
||||
->maxLength(255)
|
||||
->readonly(! user()->isMe()),
|
||||
|
||||
RichEditor::make('value')
|
||||
->label(__('Content'))
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class VisaMasterSettingsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->searchable(),
|
||||
TextColumn::make('display_name')
|
||||
->searchable(),
|
||||
TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\Settings\Resources\VisaMasterSettings;
|
||||
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Pages\CreateVisaMasterSettings;
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Pages\EditVisaMasterSettings;
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Pages\ListVisaMasterSettings;
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Schemas\VisaMasterSettingsForm;
|
||||
use App\Filament\Clusters\Settings\Resources\VisaMasterSettings\Tables\VisaMasterSettingsTable;
|
||||
use App\Filament\Clusters\Settings\SettingsCluster;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterSettings;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class VisaMasterSettingsResource extends Resource
|
||||
{
|
||||
protected static ?string $model = VisaMasterSettings::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedDocumentText;
|
||||
|
||||
protected static ?string $cluster = SettingsCluster::class;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'display_name';
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Currencies');
|
||||
}
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('Warning text');
|
||||
}
|
||||
|
||||
public static function getPluralModelLabel(): string
|
||||
{
|
||||
return __('Warning text');
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return VisaMasterSettingsForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return VisaMasterSettingsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListVisaMasterSettings::route('/'),
|
||||
'create' => CreateVisaMasterSettings::route('/create'),
|
||||
'edit' => EditVisaMasterSettings::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class SettingsCluster extends Cluster
|
||||
{
|
||||
protected static ?int $navigationSort = 100;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCog8Tooth;
|
||||
|
||||
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::End;
|
||||
|
||||
@@ -9,6 +9,8 @@ use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class UsersCluster extends Cluster
|
||||
{
|
||||
protected static ?int $navigationSort = 6;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedUsers;
|
||||
|
||||
protected static string|BackedEnum|null $activeNavigationIcon = Heroicon::Users;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\VisaMasterPaymentOrderResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateVisaMasterPaymentOrder extends CreateRecord
|
||||
{
|
||||
protected static string $resource = VisaMasterPaymentOrderResource::class;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\VisaMasterPaymentOrderResource;
|
||||
use App\Modules\VisaMasterPaymentOrder\Filament\Actions\PayVisaMasterPaymentAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class EditVisaMasterPaymentOrder extends EditRecord
|
||||
{
|
||||
protected static string $resource = VisaMasterPaymentOrderResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
PayVisaMasterPaymentAction::make(),
|
||||
DeleteAction::make(),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return __('Order details');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\VisaMasterPaymentOrderResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListVisaMasterPaymentOrders extends ListRecords
|
||||
{
|
||||
protected static string $resource = VisaMasterPaymentOrderResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Schemas\VisaMasterPaymentOrderInfolist;
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\VisaMasterPaymentOrderResource;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
|
||||
class ViewVisaMasterPaymentOrder extends ViewRecord
|
||||
{
|
||||
protected static string $resource = VisaMasterPaymentOrderResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
EditAction::make()
|
||||
->icon(Heroicon::OutlinedPencil),
|
||||
];
|
||||
}
|
||||
|
||||
public function infolist(Schema $schema): Schema
|
||||
{
|
||||
return VisaMasterPaymentOrderInfolist::configure($schema);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Schemas;
|
||||
|
||||
use App\Modules\FilamentPermission\Repositories\FilamentPermissionRepository;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use App\Modules\PhoneNumberVerification\Rules\PhoneNumberVerificationRule;
|
||||
use App\Modules\Region\Repositories\RegionRepository;
|
||||
use App\Modules\TurkmenPassport\Repositories\TurkmenPassportRepository;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Components\Fieldset;
|
||||
use Filament\Schemas\Components\FusedGroup;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Wizard;
|
||||
use Filament\Schemas\Components\Wizard\Step;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use RalphJSmit\Filament\Upload\Filament\Forms\Components\AdvancedFileUpload;
|
||||
|
||||
class VisaMasterPaymentOrderForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Hidden::make('user_id')->default(Auth::id()),
|
||||
|
||||
Section::make()
|
||||
->columnSpan(4)
|
||||
->columns(4)
|
||||
->disabled(fn (string $context): bool => FilamentPermissionRepository::forClients())
|
||||
->components([
|
||||
Select::make('status')
|
||||
->label(__('Status'))
|
||||
->options(OrderStatusRepository::statusValues())
|
||||
->default(OrderStatusRepository::defaultStatus())
|
||||
->native(false)
|
||||
->columnSpan(2),
|
||||
|
||||
Toggle::make('paid')
|
||||
->label(sprintf('%s (%s)', __('Paid'), __('This month')))
|
||||
->inline(false)
|
||||
->disabled(true)
|
||||
->onIcon(Heroicon::CheckCircle)
|
||||
->offIcon(Heroicon::XCircle)
|
||||
->onColor('success')
|
||||
->offColor('danger'),
|
||||
|
||||
RichEditor::make('notes')
|
||||
->label(__('Bellik'))
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
|
||||
Wizard::make([
|
||||
Step::make(__('Order type and bank'))
|
||||
->schema([
|
||||
Fieldset::make(__('Order type'))
|
||||
->schema([
|
||||
Select::make('type')
|
||||
->label(__('Type'))
|
||||
->options(VisaMasterPaymentOrder::applicationTypes())
|
||||
->native(false)
|
||||
->required(),
|
||||
]),
|
||||
|
||||
Fieldset::make(__('Location'))
|
||||
->schema([
|
||||
Select::make('region')
|
||||
->label(__('Region'))
|
||||
->options(RegionRepository::values())
|
||||
->live()
|
||||
->afterStateUpdated(fn (callable $set) => $set('branch_id', null))
|
||||
->required(),
|
||||
|
||||
Select::make('branch_id')
|
||||
->label(__('Branch'))
|
||||
->relationship('branch', 'name', function ($query, callable $get) {
|
||||
$query->orderByTranslation('name');
|
||||
|
||||
$region = $get('region');
|
||||
if ($region) {
|
||||
$query->where('region', $region);
|
||||
}
|
||||
})
|
||||
->required(),
|
||||
]),
|
||||
]),
|
||||
Step::make(__('Payment sender data'))
|
||||
->columns(8)
|
||||
->schema([
|
||||
TextInput::make('sender_full_name')
|
||||
->label(__('Name, Surname, Patronic name'))
|
||||
->columnSpan(4)
|
||||
->default(user()->fullName())
|
||||
->required(),
|
||||
|
||||
FusedGroup::make([
|
||||
Select::make('sender_passport_serie')
|
||||
->label(__('Passport serie'))
|
||||
->options(TurkmenPassportRepository::values())
|
||||
->native(false)
|
||||
->required()
|
||||
->columnSpan(1)
|
||||
->default(user()->getOption('passport_serie')),
|
||||
|
||||
TextInput::make('sender_passport_number')
|
||||
->label(__('Passport number'))
|
||||
->required()
|
||||
->columnSpan(1)
|
||||
->mask('999999')
|
||||
->default(user()->getOption('passport_id')),
|
||||
])
|
||||
->columnSpan(2)
|
||||
->label(__('Passport serie and number'))
|
||||
->columns(2),
|
||||
|
||||
TextInput::make('phone')
|
||||
->label(__('Phone'))
|
||||
->required()
|
||||
->mask('99 99 99 99')
|
||||
->prefix('+993')
|
||||
->rules([
|
||||
new PhoneNumberVerificationRule,
|
||||
])
|
||||
->columnSpan(2)
|
||||
->default(user()->phone),
|
||||
|
||||
TextInput::make('sender_deposit_account')
|
||||
->label(__('Deposit account'))
|
||||
->columnSpan(4)
|
||||
->required(),
|
||||
|
||||
TextInput::make('address')
|
||||
->label(__('Address'))
|
||||
->columnSpan(4)
|
||||
->required(),
|
||||
|
||||
Section::make(__('Files'))
|
||||
->description('PNG, JPEG, PDF')
|
||||
->columnSpanFull()
|
||||
->columns(2)
|
||||
->schema([
|
||||
AdvancedFileUpload::make('sender_passport_local')
|
||||
->spatieMediaLibrary(collection: 'sender_passport_local')
|
||||
->multiple(),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('sender_passport_international')
|
||||
->collection('sender_passport_international')
|
||||
->label(__('Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin pasportynyň asyl görnüşi we göçürmesi')),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('sender_travel_stamp_on_passport')
|
||||
->collection('sender_travel_stamp_on_passport')
|
||||
->label(__('Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin pasportyndaky daşary döwletine gidendigi we daşary döwlete barandygy baradaky (ştampyň) bellenen sahypasynyň göçürmesi'))
|
||||
->required(),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('sender_proof_of_kinship')
|
||||
->collection('sender_proof_of_kinship')
|
||||
->label(__('Ugradyjynyň we kabul edijiniň (talybyň) özara garyndaşlyk derejesini tassyklaýjy resminamalarynyň göçürmesi')),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('sender_passport_local_old')
|
||||
->collection('sender_passport_local_old')
|
||||
->label(__('Ugradyjy we kabul ediji (talyp) 2015-nji ýyldan soňra Türkmenistanyň raýatynyň pasportyny ikinji gezek alan bolsa, onda birinji gezek alan pasportynyň seriýasy baradaky maglumat')),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('sender_passport_local_old_replacement')
|
||||
->collection('sender_passport_local_old_replacement')
|
||||
->label(__('Ugradyjy we kabul ediji (talyp) 2015-nji ýyldan soňra Türkmenistanyň raýatynyň pasportyny ikinji gezek alandan soňra birinji gezek alan pasportynyň seriýasy baradaky maglumaty bilmeýän ,bolsa onda polisiýanyň degişli edaralaryndan birinji alan pasportynyň seriýasy baradaky güwänamasy')),
|
||||
]),
|
||||
]),
|
||||
|
||||
Step::make(__('Payee information'))
|
||||
->columns(8)
|
||||
->schema([
|
||||
TextInput::make('reciever_full_name')
|
||||
->label(__('Name, Surname, Patronic name'))
|
||||
->columnSpan(5)
|
||||
->required(),
|
||||
|
||||
FusedGroup::make([
|
||||
Select::make('reciever_passport_serie')
|
||||
->label(__('Passport serie'))
|
||||
->options(TurkmenPassportRepository::values())
|
||||
->native(false)
|
||||
->required()
|
||||
->columnSpan(1),
|
||||
|
||||
TextInput::make('reciever_passport_number')
|
||||
->label(__('Passport number'))
|
||||
->required()
|
||||
->columnSpan(1)
|
||||
->mask('999999'),
|
||||
])
|
||||
->columnSpan(3)
|
||||
->label(__('Passport serie and number'))
|
||||
->columns(2),
|
||||
|
||||
Section::make(__('Files'))
|
||||
->description('PNG, JPEG, PDF')
|
||||
->columnSpanFull()
|
||||
->columns(2)
|
||||
->schema([
|
||||
SpatieMediaLibraryFileUpload::make('receiver_requisite')
|
||||
->collection('receiver_requisite')
|
||||
->label(__('Talyba degişli walýuta "VISA" kartyň rekwizitleri'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1)
|
||||
->required(),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_document_stating_he_is_studying')
|
||||
->collection('receiver_document_stating_he_is_studying')
|
||||
->label(__('Talybyň daşary ýurt döwletiniň ýokary okuw mekdebinde okaýandygy baradaky güwänamasy'))
|
||||
->maxSize(4096)
|
||||
->openable()
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_ticket')
|
||||
->collection('receiver_ticket')
|
||||
->label(__('Talybyň bilediniň göçürmesi'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_passport_local')
|
||||
->collection('receiver_passport_local')
|
||||
->label(__('Talyba degişli Türkmenistanyň raýatynyň (içki milli) pasportynyň asyl görnüşi we göçürmesi'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_passport_international')
|
||||
->collection('receiver_passport_international')
|
||||
->label(__('Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin (zagran) pasportynyň göçürmesi'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_visa')
|
||||
->collection('receiver_visa')
|
||||
->label(__('Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin pasportyndaky daşary ýurtda galyp okap bilýändigi baradaky berlen möhleti hereket edýän rugsatnamasynyň (wizasynyň) bellenen sahypasynyň göçürmesi'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_travel_stamp_on_passport')
|
||||
->collection('receiver_travel_stamp_on_passport')
|
||||
->label(__('Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin pasportyndaky Türkmenistandan çykandygy we daşary ýurt döwletine girendigi baradaky ştamplaryň (seneli ştampyň) bellenen sahypasynyň göçürmesi'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('receiver_document_stating_he_is_studying_2')
|
||||
->collection('receiver_document_stating_he_is_studying_2')
|
||||
->label(__('Talybyň daşary ýurt döwletiniň ýokary okuw mekdebinde okaýandygy baradaky güwänamasyndaky maglumatyň doly takyk däl ýagdaýynda takyk däl maglumatyň sebäpleri baradaky daşary ýurt döwletiniň ýokary okuw mekdebinden haty'))
|
||||
->maxSize(4096)
|
||||
->columnSpan(1),
|
||||
]),
|
||||
]),
|
||||
|
||||
])->columnSpanFull()->skippable(fn (string $context) => $context === 'edit'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Schemas;
|
||||
|
||||
use App\Filament\Infolists\Components\SpatieMediaLibraryFileEntry;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use App\Modules\Region\Repositories\RegionRepository;
|
||||
use App\Modules\TurkmenPassport\Repositories\TurkmenPassportRepository;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Schemas\Components\Fieldset;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Tabs;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class VisaMasterPaymentOrderInfolist
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make()
|
||||
->columnSpanFull()
|
||||
->columns(4)
|
||||
->components([
|
||||
TextEntry::make('unique_id')
|
||||
->label(__('Order ID'))
|
||||
->columnSpan(1)
|
||||
->extraAttributes(['style' => 'text-transform:uppercase;font-size:1.5em;font-weight:bold;']),
|
||||
|
||||
TextEntry::make('type')
|
||||
->label(__('Payment type'))
|
||||
->extraAttributes(['style' => 'text-transform:uppercase;font-size:1.5em;font-weight:bold;']),
|
||||
|
||||
TextEntry::make('status')
|
||||
->label(__('Status'))
|
||||
->formatStateUsing(fn (string $state) => OrderStatusRepository::statusFormatted($state))
|
||||
->extraAttributes(['style' => 'text-transform:uppercase;font-size:1.2em;font-weight:bold;'])
|
||||
->color(OrderStatusRepository::statusColorMatching()),
|
||||
|
||||
IconEntry::make('paid')
|
||||
->label(sprintf('%s (%s)', __('Paid'), __('This month')))
|
||||
->boolean()
|
||||
->trueIcon(Heroicon::CheckCircle)
|
||||
->falseIcon(Heroicon::XCircle)
|
||||
->trueColor('success')
|
||||
->falseColor('danger'),
|
||||
|
||||
Fieldset::make(__('Location'))
|
||||
->schema([
|
||||
TextEntry::make('region')
|
||||
->label(__('Region'))
|
||||
->formatStateUsing(fn (string $state): string => RegionRepository::label($state)),
|
||||
|
||||
TextEntry::make('branch.name')
|
||||
->label(__('Branch'))
|
||||
->placeholder('-'),
|
||||
])
|
||||
->columnSpan(2),
|
||||
|
||||
TextEntry::make('notes')
|
||||
->label(__('Bellik'))
|
||||
->html()
|
||||
->visible(fn (VisaMasterPaymentOrder $record): bool => ! is_null($record->notes) && $record->notes != '' && $record->notes != '<p></p>' && Str::length($record->notes) > 7)
|
||||
->columnSpan(2)
|
||||
->placeholder('-'),
|
||||
]),
|
||||
|
||||
Tabs::make('Order Information')
|
||||
->tabs([
|
||||
Tab::make(__('Payment sender data'))
|
||||
->columns(8)
|
||||
->schema([
|
||||
Fieldset::make(__('Data'))
|
||||
->columnSpan(8)
|
||||
->columns(8)
|
||||
->schema([
|
||||
TextEntry::make('sender_full_name')
|
||||
->label(__('Name, Surname, Patronic name'))
|
||||
->columnSpan(4)
|
||||
->placeholder('-'),
|
||||
|
||||
TextEntry::make('sender_passport')
|
||||
->label(__('Passport serie and number'))
|
||||
->formatStateUsing(function ($record) {
|
||||
$serie = TurkmenPassportRepository::values()[$record->sender_passport_serie] ?? $record->sender_passport_serie;
|
||||
|
||||
return $serie.' '.$record->sender_passport_number;
|
||||
})
|
||||
->columnSpan(2)
|
||||
->placeholder('-'),
|
||||
|
||||
TextEntry::make('phone')
|
||||
->label(__('Phone'))
|
||||
->formatStateUsing(fn ($state) => '+993 '.$state)
|
||||
->columnSpan(2)
|
||||
->placeholder('-'),
|
||||
|
||||
TextEntry::make('sender_deposit_account')
|
||||
->label(__('Deposit account'))
|
||||
->columnSpan(4)
|
||||
->placeholder('-'),
|
||||
|
||||
TextEntry::make('address')
|
||||
->label(__('Address'))
|
||||
->columnSpan(4)
|
||||
->placeholder('-'),
|
||||
]),
|
||||
|
||||
Section::make(__('Files'))
|
||||
->description('PNG, JPEG, PDF')
|
||||
->columnSpanFull()
|
||||
->columns(2)
|
||||
->schema([
|
||||
SpatieMediaLibraryFileEntry::make('sender_passport_local')
|
||||
->collection('sender_passport_local')
|
||||
->label(__('Ugradyja degişli Türkmenistanyň raýatynyň (içki milli) pasportynyň asyl görnüşi we göçürmesi')),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('sender_passport_international')
|
||||
->collection('sender_passport_international')
|
||||
->label(__('Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin pasportynyň asyl görnüşi we göçürmesi')),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('sender_travel_stamp_on_passport')
|
||||
->collection('sender_travel_stamp_on_passport')
|
||||
->label(__('Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin pasportyndaky daşary döwletine gidendigi we daşary döwlete barandygy baradaky (ştampyň) bellenen sahypasynyň göçürmesi')),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('sender_proof_of_kinship')
|
||||
->collection('sender_proof_of_kinship')
|
||||
->label(__('Ugradyjynyň we kabul edijiniň (talybyň) özara garyndaşlyk derejesini tassyklaýjy resminamalarynyň göçürmesi')),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('sender_passport_local_old')
|
||||
->collection('sender_passport_local_old')
|
||||
->label(__('Ugradyjy we kabul ediji (talyp) 2015-nji ýyldan soňra Türkmenistanyň raýatynyň pasportyny ikinji gezek alan bolsa, onda birinji gezek alan pasportynyň seriýasy baradaky maglumat')),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('sender_passport_local_old_replacement')
|
||||
->collection('sender_passport_local_old_replacement')
|
||||
->label(__('Ugradyjy we kabul ediji (talyp) 2015-nji ýyldan soňra Türkmenistanyň raýatynyň pasportyny ikinji gezek alandan soňra birinji gezek alan pasportynyň seriýasy baradaky maglumaty bilmeýän ,bolsa onda polisiýanyň degişli edaralaryndan birinji alan pasportynyň seriýasy baradaky güwänamasy')),
|
||||
]),
|
||||
]),
|
||||
|
||||
Tab::make(__('Payee information'))
|
||||
->columns(8)
|
||||
->schema([
|
||||
TextEntry::make('reciever_full_name')
|
||||
->label(__('Name, Surname, Patronic name'))
|
||||
->columnSpan(5)
|
||||
->placeholder('-'),
|
||||
|
||||
TextEntry::make('reciever_passport')
|
||||
->label(__('Passport serie and number'))
|
||||
->formatStateUsing(function ($record) {
|
||||
$serie = TurkmenPassportRepository::values()[$record->reciever_passport_serie] ?? $record->reciever_passport_serie;
|
||||
|
||||
return $serie.' '.$record->reciever_passport_number;
|
||||
})
|
||||
->columnSpan(3)
|
||||
->placeholder('-'),
|
||||
|
||||
Section::make(__('Files'))
|
||||
->description('PNG, JPEG, PDF')
|
||||
->columnSpanFull()
|
||||
->columns(2)
|
||||
->schema([
|
||||
SpatieMediaLibraryFileEntry::make('receiver_requisite')
|
||||
->collection('receiver_requisite')
|
||||
->label(__('Talyba degişli walýuta "VISA" kartyň rekwizitleri'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_document_stating_he_is_studying')
|
||||
->collection('receiver_document_stating_he_is_studying')
|
||||
->label(__('Talybyň daşary ýurt döwletiniň ýokary okuw mekdebinde okaýandygy baradaky güwänamasy'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_ticket')
|
||||
->collection('receiver_ticket')
|
||||
->label(__('Talybyň bilediniň göçürmesi'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_passport_local')
|
||||
->collection('receiver_passport_local')
|
||||
->label(__('Talyba degişli Türkmenistanyň raýatynyň (içki milli) pasportynyň asyl görnüşi we göçürmesi'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_passport_international')
|
||||
->collection('receiver_passport_international')
|
||||
->label(__('Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin (zagran) pasportynyň göçürmesi'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_visa')
|
||||
->collection('receiver_visa')
|
||||
->label(__('Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin pasportyndaky daşary ýurtda galyp okap bilýändigi baradaky berlen möhleti hereket edýän rugsatnamasynyň (wizasynyň) bellenen sahypasynyň göçürmesi'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_travel_stamp_on_passport')
|
||||
->collection('receiver_travel_stamp_on_passport')
|
||||
->label(__('Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin pasportyndaky Türkmenistandan çykandygy we daşary ýurt döwletine girendigi baradaky ştamplaryň (seneli ştampyň) bellenen sahypasynyň göçürmesi'))
|
||||
->columnSpan(1),
|
||||
|
||||
SpatieMediaLibraryFileEntry::make('receiver_document_stating_he_is_studying_2')
|
||||
->collection('receiver_document_stating_he_is_studying_2')
|
||||
->label(__('Talybyň daşary ýurt döwletiniň ýokary okuw mekdebinde okaýandygy baradaky güwänamasyndaky maglumatyň doly takyk däl ýagdaýynda takyk däl maglumatyň sebäpleri baradaky daşary ýurt döwletiniň ýokary okuw mekdebinden haty'))
|
||||
->columnSpan(1),
|
||||
]),
|
||||
]),
|
||||
])->columnSpanFull(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Tables;
|
||||
|
||||
use App\Modules\DefaultQueryForResourceIndex\Repositories\DefaultQueryForResourceIndexRepository;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use App\Modules\Region\Repositories\RegionRepository;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class VisaMasterPaymentOrdersTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', direction: 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label(__('ID'))
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('type')
|
||||
->label(__('Type'))
|
||||
->formatStateUsing(fn (string $state) => Str::upper($state)),
|
||||
|
||||
TextColumn::make('status')
|
||||
->label(__('Status'))
|
||||
->color(OrderStatusRepository::statusColorMatching())
|
||||
->formatStateUsing(fn (string $state) => OrderStatusRepository::statusFormatted($state))
|
||||
->badge(),
|
||||
|
||||
TextColumn::make('created_at')
|
||||
->label(__('Created At'))
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('region')
|
||||
->label(__('Region'))
|
||||
->formatStateUsing(fn (string $state): string => RegionRepository::label($state))
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('branch.name')
|
||||
->label(__('Branch'))
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('sender_full_name')
|
||||
->label(__('Full Name'))
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('phone')
|
||||
->label(__('Phone'))
|
||||
->searchable(),
|
||||
|
||||
IconColumn::make('paid')
|
||||
->label(sprintf('%s (%s)', __('Paid'), __('This month')))
|
||||
->boolean(),
|
||||
|
||||
])
|
||||
->filters([
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders;
|
||||
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages\CreateVisaMasterPaymentOrder;
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages\EditVisaMasterPaymentOrder;
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages\ListVisaMasterPaymentOrders;
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Pages\ViewVisaMasterPaymentOrder;
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Schemas\VisaMasterPaymentOrderForm;
|
||||
use App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Tables\VisaMasterPaymentOrdersTable;
|
||||
use App\Filament\Clusters\VisaMasterPayments\VisaMasterPaymentsCluster;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class VisaMasterPaymentOrderResource extends Resource
|
||||
{
|
||||
protected static ?int $navigationSort = 1;
|
||||
|
||||
protected static ?string $model = VisaMasterPaymentOrder::class;
|
||||
|
||||
protected static ?string $cluster = VisaMasterPaymentsCluster::class;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'unique_id';
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'icon-visa-plain';
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Visa/Master payments');
|
||||
}
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('Visa/Master payment');
|
||||
}
|
||||
|
||||
public static function getPluralModelLabel(): string
|
||||
{
|
||||
return __('Visa/Master payments');
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return VisaMasterPaymentOrderForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return VisaMasterPaymentOrdersTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListVisaMasterPaymentOrders::route('/'),
|
||||
'create' => CreateVisaMasterPaymentOrder::route('/create'),
|
||||
'view' => ViewVisaMasterPaymentOrder::route('/{record}/view'),
|
||||
'edit' => EditVisaMasterPaymentOrder::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query for the record route binding
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder<\App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder>
|
||||
*/
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments;
|
||||
|
||||
use BackedEnum;
|
||||
use Filament\Clusters\Cluster;
|
||||
use Filament\Pages\Enums\SubNavigationPosition;
|
||||
|
||||
class VisaMasterPaymentsCluster extends Cluster
|
||||
{
|
||||
protected static ?int $navigationSort = 3;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'icon-visa-plain';
|
||||
|
||||
protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::Top;
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('International payments');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Infolists\Components;
|
||||
|
||||
use Closure;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Infolists\Components\Entry;
|
||||
use Filament\Support\Concerns\HasMediaFilter;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
use Throwable;
|
||||
|
||||
class SpatieMediaLibraryFileEntry extends Entry
|
||||
{
|
||||
use HasMediaFilter;
|
||||
|
||||
public function getViewMediaActionName(): string
|
||||
{
|
||||
return 'view_media_'.$this->getName();
|
||||
}
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->registerActions([
|
||||
Action::make($this->getViewMediaActionName())
|
||||
->label(__('Watch Full'))
|
||||
->modalContent(fn (array $arguments) => view('filament.infolists.components.image-modal', ['url' => $arguments['url']]))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelAction(false)
|
||||
->modalWidth('5xl'),
|
||||
]);
|
||||
}
|
||||
|
||||
protected string $view = 'filament.infolists.components.spatie-media-library-file-entry';
|
||||
|
||||
protected string|Closure|null $collection = null;
|
||||
|
||||
protected string|Closure|null $conversion = null;
|
||||
|
||||
protected string|Closure $visibility = 'private';
|
||||
|
||||
protected bool|Closure $isDownloadable = true;
|
||||
|
||||
protected bool|Closure $isPreviewable = true;
|
||||
|
||||
public function collection(string|Closure|null $collection): static
|
||||
{
|
||||
$this->collection = $collection;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function conversion(string|Closure|null $conversion): static
|
||||
{
|
||||
$this->conversion = $conversion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function visibility(string|Closure $visibility): static
|
||||
{
|
||||
$this->visibility = $visibility;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function downloadable(bool|Closure $condition = true): static
|
||||
{
|
||||
$this->isDownloadable = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function previewable(bool|Closure $condition = true): static
|
||||
{
|
||||
$this->isPreviewable = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCollection(): ?string
|
||||
{
|
||||
return $this->evaluate($this->collection);
|
||||
}
|
||||
|
||||
public function getConversion(): ?string
|
||||
{
|
||||
return $this->evaluate($this->conversion);
|
||||
}
|
||||
|
||||
public function getVisibility(): string
|
||||
{
|
||||
return (string) $this->evaluate($this->visibility);
|
||||
}
|
||||
|
||||
public function isDownloadable(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isDownloadable);
|
||||
}
|
||||
|
||||
public function isPreviewable(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isPreviewable);
|
||||
}
|
||||
|
||||
public function getMediaUrl(Media $media, ?string $conversion = null): string
|
||||
{
|
||||
if ($this->getVisibility() === 'private') {
|
||||
try {
|
||||
return $media->getTemporaryUrl(
|
||||
now()->addMinutes(30)->endOfHour(),
|
||||
$conversion ?? '',
|
||||
);
|
||||
} catch (Throwable $exception) {
|
||||
// This driver does not support creating temporary URLs.
|
||||
}
|
||||
}
|
||||
|
||||
return $media->getUrl($conversion ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the media for the entry
|
||||
*
|
||||
* @return Collection<array-key, Media>
|
||||
*/
|
||||
public function getMedia(): Collection
|
||||
{
|
||||
$record = $this->getRecord();
|
||||
|
||||
if (! $record) {
|
||||
return collect([]);
|
||||
}
|
||||
|
||||
if ($this->hasStateRelationship($record)) {
|
||||
$record = $this->getStateRelationshipResults($record);
|
||||
}
|
||||
|
||||
$records = Arr::wrap($record);
|
||||
|
||||
$allMedia = collect([]);
|
||||
|
||||
$collection = $this->getCollection() ?? 'default';
|
||||
|
||||
foreach ($records as $record) {
|
||||
/** @var Model $record */
|
||||
$media = $record->getRelationValue('media');
|
||||
|
||||
if (! $media) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filteredMedia = $media
|
||||
->when(
|
||||
is_string($collection),
|
||||
fn (MediaCollection $mediaCollection) => $mediaCollection->filter(fn (Media $media): bool => $media->getAttributeValue('collection_name') === $collection),
|
||||
)
|
||||
->when(
|
||||
$this->hasMediaFilter(),
|
||||
fn (Collection $media) => $this->filterMedia($media)
|
||||
)
|
||||
->sortBy('order_column');
|
||||
|
||||
$allMedia = $allMedia->merge($filteredMedia);
|
||||
}
|
||||
|
||||
return $allMedia;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ class UserForm
|
||||
->unique(ignoreRecord: true)
|
||||
->mask('99 99 99 99')
|
||||
->prefix('+993')
|
||||
->dehydrateStateUsing(fn ($state) => unMaskTurkmenNumber($state))
|
||||
->rules([
|
||||
new PhoneNumberVerificationRule,
|
||||
])
|
||||
|
||||
69
app/Http/Controllers/MigrationController.php
Normal file
69
app/Http/Controllers/MigrationController.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Database\Seeders\Migrators\ActionEventsMigrator;
|
||||
use Database\Seeders\Migrators\BranchUserMigrator;
|
||||
use Database\Seeders\Migrators\CurrencyRatesMigrator;
|
||||
use Database\Seeders\Migrators\LoanOrderRequiredDocsMigrator;
|
||||
use Database\Seeders\Migrators\LoanOrdersMigrator;
|
||||
use Database\Seeders\Migrators\LoanTypesMigrator;
|
||||
use Database\Seeders\Migrators\MediaMigrator;
|
||||
use Database\Seeders\Migrators\ProvincesMigrator;
|
||||
use Database\Seeders\Migrators\BranchesMigrator;
|
||||
use Database\Seeders\Migrators\UsersMigrator;
|
||||
use Database\Seeders\Migrators\CardStatesMigrator;
|
||||
use Database\Seeders\Migrators\CardTypesMigrator;
|
||||
use Database\Seeders\Migrators\VisaMasterPaymentOrdersMigrator;
|
||||
use Database\Seeders\Migrators\VerificationsMigrator;
|
||||
use Database\Seeders\Migrators\PersonalAccessTokensMigrator;
|
||||
use Database\Seeders\Migrators\CardOrdersMigrator;
|
||||
use Database\Seeders\Migrators\VisaMasterSettingsMigrator;
|
||||
use Database\Seeders\Migrators\CardPinOrdersMigrator;
|
||||
use Database\Seeders\Migrators\ModelHasRolesMigrator;
|
||||
use Database\Seeders\Migrators\OnlinePaymentsMigrator;
|
||||
|
||||
class MigrationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return $this->test();
|
||||
|
||||
$migrators = [
|
||||
new ActionEventsMigrator(),
|
||||
new UsersMigrator(),
|
||||
new ProvincesMigrator(),
|
||||
new BranchesMigrator(),
|
||||
new BranchUserMigrator(),
|
||||
new CardStatesMigrator(),
|
||||
new CardTypesMigrator(),
|
||||
new VerificationsMigrator(),
|
||||
new CurrencyRatesMigrator(),
|
||||
new LoanOrderRequiredDocsMigrator(),
|
||||
new PersonalAccessTokensMigrator(),
|
||||
new LoanTypesMigrator(),
|
||||
new CardOrdersMigrator(),
|
||||
new CardPinOrdersMigrator(),
|
||||
new LoanOrdersMigrator(),
|
||||
new ModelHasRolesMigrator(),
|
||||
new VisaMasterPaymentOrdersMigrator(),
|
||||
new OnlinePaymentsMigrator(),
|
||||
|
||||
new MediaMigrator(),
|
||||
];
|
||||
|
||||
foreach ($migrators as $migrator) {
|
||||
$migrator->migrate();
|
||||
}
|
||||
|
||||
return 'done';
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
(new OnlinePaymentsMigrator())->migrate();
|
||||
|
||||
return 'done';
|
||||
}
|
||||
}
|
||||
28
app/Http/Middleware/EnsureUserHasRole.php
Normal file
28
app/Http/Middleware/EnsureUserHasRole.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EnsureUserHasRole
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
// if user does not have any role, add role "client"
|
||||
/** @var \App\Models\User */
|
||||
$user = $request->user();
|
||||
|
||||
if ($user->roles->count() == 0) {
|
||||
$user->assignRole('client');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@ namespace App\Models;
|
||||
|
||||
use App\Modules\UserAdjustments\Traits\UserAdjustments;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Models\Contracts\HasAvatar;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -20,13 +22,14 @@ use Illuminate\Support\Facades\Date;
|
||||
* @property Date|null $created_at
|
||||
* @property Date|null $updated_at
|
||||
*/
|
||||
class User extends Authenticatable implements FilamentUser
|
||||
class User extends Authenticatable implements FilamentUser, HasAvatar
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory;
|
||||
|
||||
use Notifiable;
|
||||
use UserAdjustments;
|
||||
use HasApiTokens;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@@ -56,4 +59,12 @@ class User extends Authenticatable implements FilamentUser
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the avatar URL for the user.
|
||||
*/
|
||||
public function getFilamentAvatarUrl(): ?string
|
||||
{
|
||||
return '/assets/images/avatar.png';
|
||||
}
|
||||
}
|
||||
|
||||
64
app/Modules/ActivityLog/ActivityLogModule.php
Normal file
64
app/Modules/ActivityLog/ActivityLogModule.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\ActivityLog;
|
||||
|
||||
use App\Modules\Makeable;
|
||||
use App\Modules\ModuleContract;
|
||||
|
||||
class ActivityLogModule implements ModuleContract
|
||||
{
|
||||
use Makeable;
|
||||
|
||||
/**
|
||||
* Module is enabled
|
||||
*/
|
||||
protected bool $enabled = true;
|
||||
|
||||
/**
|
||||
* Check if is module enabled
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable module
|
||||
*/
|
||||
public function disable(): void
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable module
|
||||
*/
|
||||
public function enable(): void
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if module has a filament resource
|
||||
*/
|
||||
public function hasFilamentResource(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer requirements
|
||||
*/
|
||||
public function getComposerRequirements(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer suggestions
|
||||
*/
|
||||
public function getComposerSuggestions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\ActivityLog\Repositories;
|
||||
|
||||
class ActivityLogRepository {}
|
||||
@@ -14,6 +14,7 @@ use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -113,7 +114,7 @@ class LoginController extends Controller
|
||||
protected function validateLogin(Request $request): void
|
||||
{
|
||||
$request->validate([
|
||||
$this->username() => ['required', 'string', 'max:250'],
|
||||
$this->username() => ['required', 'string', 'max:250', Rule::notIn('65999990', 'ulanyjy_ady')],
|
||||
'password' => ['required', 'string', 'max:250'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -30,4 +30,5 @@ return [
|
||||
'go_back' => 'Yza',
|
||||
'successfully_changed_phone' => 'Telefon belgiňiz üýtgedildi',
|
||||
'resend' => 'Täze tassyklaýyş belgi ugratmak',
|
||||
'phone_or_username_placeholder' => 'meselem: 65999990 yada ulanyjy_ady',
|
||||
];
|
||||
|
||||
@@ -49,11 +49,12 @@ async function login(event) {
|
||||
id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="+99365999990 {{ __('or') }} {{ __('module.base-auth::base.username') }}"
|
||||
placeholder="65999990 {{ __('or') }} {{ __('module.base-auth::base.username') }}"
|
||||
autofocus=""
|
||||
value="{{ old('username') }}"
|
||||
>
|
||||
|
||||
<span class="text-gray-500 text-xs">{{ __('module.base-auth::base.phone_or_username_placeholder') }}</span>
|
||||
<span id="username-error-box" class="text-red-500 text-italic error-box"></span>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -109,7 +109,16 @@ class CardOrder extends Model implements BelongsToBranch, HasStatus
|
||||
parent::boot();
|
||||
|
||||
static::creating(LoanOrderRepository::creating());
|
||||
static::created(LoanOrderRepository::created());
|
||||
|
||||
static::created(function ($model) {
|
||||
$uniqueId = LoanOrderRepository::generateUniqueId($model);
|
||||
$model->update(['unique_id' => $uniqueId]);
|
||||
|
||||
sendSMS(
|
||||
$model->phone,
|
||||
__('module.card-order::base.card_order_created', ['order_id' => $uniqueId])
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,8 +19,8 @@ class CardOrderRepository
|
||||
/** @var \App\Modules\Branch\Models\Branch */
|
||||
$branch = $record->branch;
|
||||
|
||||
return OnlinePaymentRepository::make(relatedModel: $record)
|
||||
->paymentProvider(
|
||||
return OnlinePaymentRepository::make(relatedModel: $record, apiClient: 'billing')
|
||||
->setPaymentProvider(
|
||||
HalkbankOnlinePaymentRepository::make()
|
||||
->setUsername($branch->billingUsername())
|
||||
->setPassword($branch->billingPassword())
|
||||
|
||||
5
app/Modules/CardOrder/Resources/Lang/tk/base.php
Normal file
5
app/Modules/CardOrder/Resources/Lang/tk/base.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'card_order_created' => 'Kart sargydyňyz :order_id belgi bilen hasaba alyndy. Sargydy tassyklamak üçin operatorymyz habarlaşar.',
|
||||
];
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\CurrencyRate\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CurrencyRateController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
64
app/Modules/CurrencyRate/CurrencyRateModule.php
Normal file
64
app/Modules/CurrencyRate/CurrencyRateModule.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\CurrencyRate;
|
||||
|
||||
use App\Modules\Makeable;
|
||||
use App\Modules\ModuleContract;
|
||||
|
||||
class CurrencyRateModule implements ModuleContract
|
||||
{
|
||||
use Makeable;
|
||||
|
||||
/**
|
||||
* Module is enabled
|
||||
*/
|
||||
protected bool $enabled = true;
|
||||
|
||||
/**
|
||||
* Check if is module enabled
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable module
|
||||
*/
|
||||
public function disable(): void
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable module
|
||||
*/
|
||||
public function enable(): void
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if module has a filament resource
|
||||
*/
|
||||
public function hasFilamentResource(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer requirements
|
||||
*/
|
||||
public function getComposerRequirements(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer suggestions
|
||||
*/
|
||||
public function getComposerSuggestions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('currency_rates', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('currency_from');
|
||||
$table->string('currency_to');
|
||||
$table->string('value');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('currency_rates');
|
||||
|
||||
}
|
||||
};
|
||||
217
app/Modules/CurrencyRate/Models/CurrencyRate.php
Normal file
217
app/Modules/CurrencyRate/Models/CurrencyRate.php
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\CurrencyRate\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $currency_from
|
||||
* @property string $currency_to
|
||||
* @property string $value
|
||||
* @property \Illuminate\Support\Carbon $created_at
|
||||
* @property \Illuminate\Support\Carbon $updated_at
|
||||
*/
|
||||
class CurrencyRate extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*/
|
||||
protected $table = 'currency_rates';
|
||||
|
||||
/**
|
||||
* Get the user's first name.
|
||||
*
|
||||
* @return Attribute<string, void>
|
||||
*/
|
||||
protected function name(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn (): string => $this->currency_from.'-'.$this->currency_to,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Currencies
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function currencies(): array
|
||||
{
|
||||
return [
|
||||
'AED' => 'AED',
|
||||
'AFN' => 'AFN',
|
||||
'ALL' => 'ALL',
|
||||
'AMD' => 'AMD',
|
||||
'ANG' => 'ANG',
|
||||
'AOA' => 'AOA',
|
||||
'ARS' => 'ARS',
|
||||
'AUD' => 'AUD',
|
||||
'AWG' => 'AWG',
|
||||
'AZN' => 'AZN',
|
||||
'BAM' => 'BAM',
|
||||
'BBD' => 'BBD',
|
||||
'BDT' => 'BDT',
|
||||
'BGN' => 'BGN',
|
||||
'BHD' => 'BHD',
|
||||
'BIF' => 'BIF',
|
||||
'BMD' => 'BMD',
|
||||
'BND' => 'BND',
|
||||
'BOB' => 'BOB',
|
||||
'BRL' => 'BRL',
|
||||
'BSD' => 'BSD',
|
||||
'BTN' => 'BTN',
|
||||
'BWP' => 'BWP',
|
||||
'BYN' => 'BYN',
|
||||
'BZD' => 'BZD',
|
||||
'CAD' => 'CAD',
|
||||
'CDF' => 'CDF',
|
||||
'CHF' => 'CHF',
|
||||
'CKD' => 'CKD',
|
||||
'CLP' => 'CLP',
|
||||
'CNY' => 'CNY',
|
||||
'COP' => 'COP',
|
||||
'CRC' => 'CRC',
|
||||
'CUC' => 'CUC',
|
||||
'CUP' => 'CUP',
|
||||
'CVE' => 'CVE',
|
||||
'CZK' => 'CZK',
|
||||
'DJF' => 'DJF',
|
||||
'DKK' => 'DKK',
|
||||
'DOP' => 'DOP',
|
||||
'DZD' => 'DZD',
|
||||
'EGP' => 'EGP',
|
||||
'EHP' => 'EHP',
|
||||
'ERN' => 'ERN',
|
||||
'ETB' => 'ETB',
|
||||
'EUR' => 'EUR',
|
||||
'FJD' => 'FJD',
|
||||
'FKP' => 'FKP',
|
||||
'FOK' => 'FOK',
|
||||
'GBP' => 'GBP',
|
||||
'GEL' => 'GEL',
|
||||
'GGP' => 'GGP',
|
||||
'GHS' => 'GHS',
|
||||
'GIP' => 'GIP',
|
||||
'GMD' => 'GMD',
|
||||
'GNF' => 'GNF',
|
||||
'GTQ' => 'GTQ',
|
||||
'GYD' => 'GYD',
|
||||
'HKD' => 'HKD',
|
||||
'HNL' => 'HNL',
|
||||
'HRK' => 'HRK',
|
||||
'HTG' => 'HTG',
|
||||
'HUF' => 'HUF',
|
||||
'IDR' => 'IDR',
|
||||
'ILS' => 'ILS',
|
||||
'IMP' => 'IMP',
|
||||
'INR' => 'INR',
|
||||
'IQD' => 'IQD',
|
||||
'IRR' => 'IRR',
|
||||
'ISK' => 'ISK',
|
||||
'JEP' => 'JEP',
|
||||
'JMD' => 'JMD',
|
||||
'JOD' => 'JOD',
|
||||
'JPY' => 'JPY',
|
||||
'KES' => 'KES',
|
||||
'KGS' => 'KGS',
|
||||
'KHR' => 'KHR',
|
||||
'KID' => 'KID',
|
||||
'KMF' => 'KMF',
|
||||
'KPW' => 'KPW',
|
||||
'KRW' => 'KRW',
|
||||
'KWD' => 'KWD',
|
||||
'KYD' => 'KYD',
|
||||
'KZT' => 'KZT',
|
||||
'LAK' => 'LAK',
|
||||
'LBP' => 'LBP',
|
||||
'LKR' => 'LKR',
|
||||
'LRD' => 'LRD',
|
||||
'LSL' => 'LSL',
|
||||
'LYD' => 'LYD',
|
||||
'MAD' => 'MAD',
|
||||
'MDL' => 'MDL',
|
||||
'MGA' => 'MGA',
|
||||
'MKD' => 'MKD',
|
||||
'MMK' => 'MMK',
|
||||
'MNT' => 'MNT',
|
||||
'MOP' => 'MOP',
|
||||
'MRU' => 'MRU',
|
||||
'MUR' => 'MUR',
|
||||
'MVR' => 'MVR',
|
||||
'MWK' => 'MWK',
|
||||
'MXN' => 'MXN',
|
||||
'MYR' => 'MYR',
|
||||
'MZN' => 'MZN',
|
||||
'NAD' => 'NAD',
|
||||
'NGN' => 'NGN',
|
||||
'NIO' => 'NIO',
|
||||
'NOK' => 'NOK',
|
||||
'NPR' => 'NPR',
|
||||
'NZD' => 'NZD',
|
||||
'OMR' => 'OMR',
|
||||
'PAB' => 'PAB',
|
||||
'PEN' => 'PEN',
|
||||
'PGK' => 'PGK',
|
||||
'PHP' => 'PHP',
|
||||
'PKR' => 'PKR',
|
||||
'PLN' => 'PLN',
|
||||
'PND' => 'PND',
|
||||
'PRB' => 'PRB',
|
||||
'PYG' => 'PYG',
|
||||
'QAR' => 'QAR',
|
||||
'RON' => 'RON',
|
||||
'RSD' => 'RSD',
|
||||
'RUB' => 'RUB',
|
||||
'RWF' => 'RWF',
|
||||
'SAR' => 'SAR',
|
||||
'SBD' => 'SBD',
|
||||
'SCR' => 'SCR',
|
||||
'SDG' => 'SDG',
|
||||
'SEK' => 'SEK',
|
||||
'SGD' => 'SGD',
|
||||
'SHP' => 'SHP',
|
||||
'SLL' => 'SLL',
|
||||
'SLS' => 'SLS',
|
||||
'SOS' => 'SOS',
|
||||
'SRD' => 'SRD',
|
||||
'SSP' => 'SSP',
|
||||
'STN' => 'STN',
|
||||
'SVC' => 'SVC',
|
||||
'SYP' => 'SYP',
|
||||
'SZL' => 'SZL',
|
||||
'THB' => 'THB',
|
||||
'TJS' => 'TJS',
|
||||
'TMT' => 'TMT',
|
||||
'TND' => 'TND',
|
||||
'TOP' => 'TOP',
|
||||
'TRY' => 'TRY',
|
||||
'TTD' => 'TTD',
|
||||
'TVD' => 'TVD',
|
||||
'TWD' => 'TWD',
|
||||
'TZS' => 'TZS',
|
||||
'UAH' => 'UAH',
|
||||
'UGX' => 'UGX',
|
||||
'USD' => 'USD',
|
||||
'UYU' => 'UYU',
|
||||
'UZS' => 'UZS',
|
||||
'VED' => 'VED',
|
||||
'VES' => 'VES',
|
||||
'VND' => 'VND',
|
||||
'VUV' => 'VUV',
|
||||
'WST' => 'WST',
|
||||
'XAF' => 'XAF',
|
||||
'XCD' => 'XCD',
|
||||
'XOF' => 'XOF',
|
||||
'XPF' => 'XPF',
|
||||
'YER' => 'YER',
|
||||
'ZAR' => 'ZAR',
|
||||
'ZMW' => 'ZMW',
|
||||
'ZWB' => 'ZWB',
|
||||
'ZWL' => 'ZWL',
|
||||
'Abkhazia' => 'Abkhazia',
|
||||
'Artsakh' => 'Artsakh',
|
||||
];
|
||||
}
|
||||
}
|
||||
69
app/Modules/CurrencyRate/Policies/CurrencyRatePolicy.php
Normal file
69
app/Modules/CurrencyRate/Policies/CurrencyRatePolicy.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\CurrencyRate\Policies;
|
||||
|
||||
use App\Modules\CurrencyRate\Models\CurrencyRate;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
|
||||
class CurrencyRatePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CurrencyRate');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CurrencyRate $currencyRate): bool
|
||||
{
|
||||
return $authUser->can('View:CurrencyRate');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CurrencyRate');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CurrencyRate $currencyRate): bool
|
||||
{
|
||||
return $authUser->can('Update:CurrencyRate');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CurrencyRate $currencyRate): bool
|
||||
{
|
||||
return $authUser->can('Delete:CurrencyRate');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CurrencyRate $currencyRate): bool
|
||||
{
|
||||
return $authUser->can('Restore:CurrencyRate');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CurrencyRate $currencyRate): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CurrencyRate');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CurrencyRate');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CurrencyRate');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CurrencyRate $currencyRate): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CurrencyRate');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CurrencyRate');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\CurrencyRate\Repositories;
|
||||
|
||||
class CurrencyRateRepository {}
|
||||
@@ -17,7 +17,7 @@ class HalkbankOnlinePaymentController extends Controller
|
||||
]);
|
||||
|
||||
$onlinePaymentRepository = OnlinePaymentRepository::make()
|
||||
->paymentProvider(new HalkbankOnlinePaymentRepository);
|
||||
->setPaymentProvider(new HalkbankOnlinePaymentRepository);
|
||||
|
||||
$paymentStatus = $onlinePaymentRepository->checkPayment($request->string('orderId'));
|
||||
|
||||
|
||||
@@ -23,14 +23,20 @@ class HalkbankOnlinePaymentRepository implements PaymentProviderContract
|
||||
protected string $returnUrl = '',
|
||||
protected string $description = '',
|
||||
) {
|
||||
$this->username = config()->string('module.halkbank-online-payment.username');
|
||||
$this->password = config()->string('module.halkbank-online-payment.password');
|
||||
$this->returnUrl = config()->string('module.halkbank-online-payment.returnUrl');
|
||||
$this->orderNumber = $this->generateOrderNumber();
|
||||
$this->username = $username !== '' ? $username : config()->string('module.halkbank-online-payment.username');
|
||||
$this->password = $password !== '' ? $password : config()->string('module.halkbank-online-payment.password');
|
||||
|
||||
$this->amount = $amount;
|
||||
|
||||
$this->orderNumber = $orderNumber !== '' ? $orderNumber : $this->generateOrderNumber();
|
||||
|
||||
$this->returnUrl = $returnUrl !== '' ? $returnUrl : config()->string('module.halkbank-online-payment.returnUrl');
|
||||
|
||||
$this->description = $description !== '' ? $description : __('Payment');
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request to gatewat
|
||||
* Send request to gateway
|
||||
*/
|
||||
public function sendRequest(): Response
|
||||
{
|
||||
|
||||
49
app/Modules/OnlinePayment/Policies/OnlinePaymentPolicy.php
Normal file
49
app/Modules/OnlinePayment/Policies/OnlinePaymentPolicy.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\OnlinePayment\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Modules\OnlinePayment\Models\OnlinePayment;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class OnlinePaymentPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('ViewAny:OnlinePayment');
|
||||
}
|
||||
|
||||
public function view(User $user, OnlinePayment $onlinePayment): bool
|
||||
{
|
||||
return $user->can('View:OnlinePayment');
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('Create:OnlinePayment');
|
||||
}
|
||||
|
||||
public function update(User $user, OnlinePayment $onlinePayment): bool
|
||||
{
|
||||
return $user->can('Update:OnlinePayment');
|
||||
}
|
||||
|
||||
public function delete(User $user, OnlinePayment $onlinePayment): bool
|
||||
{
|
||||
return $user->can('Delete:OnlinePayment');
|
||||
}
|
||||
|
||||
public function restore(User $user, OnlinePayment $onlinePayment): bool
|
||||
{
|
||||
return $user->can('Restore:OnlinePayment');
|
||||
}
|
||||
|
||||
public function forceDelete(User $user, OnlinePayment $onlinePayment): bool
|
||||
{
|
||||
return $user->can('ForceDelete:OnlinePayment');
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ use App\Modules\OnlinePayment\Models\OnlinePayment;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Client\Response;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class OnlinePaymentRepository
|
||||
{
|
||||
@@ -43,6 +45,16 @@ class OnlinePaymentRepository
|
||||
*/
|
||||
protected Response $response;
|
||||
|
||||
/**
|
||||
* Online payment
|
||||
*/
|
||||
protected OnlinePayment $onlinePayment;
|
||||
|
||||
/**
|
||||
* API client
|
||||
*/
|
||||
protected string $apiClient;
|
||||
|
||||
/**
|
||||
* If payment is successful
|
||||
*/
|
||||
@@ -63,9 +75,10 @@ class OnlinePaymentRepository
|
||||
*/
|
||||
protected string $paymentLink;
|
||||
|
||||
public function __construct(?Model $relatedModel = null)
|
||||
public function __construct(?Model $relatedModel = null, string $apiClient = '')
|
||||
{
|
||||
$this->relatedModel = $relatedModel;
|
||||
$this->apiClient = $apiClient;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,13 +107,29 @@ class OnlinePaymentRepository
|
||||
/**
|
||||
* Payment provder
|
||||
*/
|
||||
public function paymentProvider(PaymentProviderContract $provider): self
|
||||
public function setPaymentProvider(PaymentProviderContract $provider): self
|
||||
{
|
||||
$this->provider = $provider;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment provider
|
||||
*/
|
||||
public function paymentProvider(): PaymentProviderContract
|
||||
{
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Online payment
|
||||
*/
|
||||
public function onlinePayment(): OnlinePayment
|
||||
{
|
||||
return $this->onlinePayment;
|
||||
}
|
||||
|
||||
/**
|
||||
* If payment has been successfull
|
||||
*/
|
||||
@@ -145,6 +174,21 @@ class OnlinePaymentRepository
|
||||
$this->paymentLink = string($this->response['formUrl']);
|
||||
|
||||
$this->createHistory();
|
||||
} else {
|
||||
Config::set('logging.channels.halkbank_payment_error', [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/halkbank_payment_error.log'),
|
||||
'level' => 'debug',
|
||||
]);
|
||||
|
||||
Log::channel('halkbank_payment_error')
|
||||
->error('Payment error', [
|
||||
'response' => [
|
||||
'title' => 'REGISTER',
|
||||
'error' => $this->response->body(),
|
||||
'file_line' => __FILE__.':'.__LINE__,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -173,6 +217,7 @@ class OnlinePaymentRepository
|
||||
'errorUrl' => $this->provider->returnUrl(),
|
||||
'username' => $this->provider->username(),
|
||||
'paymentStatus' => self::PENDING,
|
||||
'api_client' => $this->apiClient,
|
||||
];
|
||||
|
||||
if ($this->relatedModel) {
|
||||
@@ -180,7 +225,7 @@ class OnlinePaymentRepository
|
||||
$data['online_paymantable_type'] = $this->relatedModel::class;
|
||||
}
|
||||
|
||||
OnlinePayment::create($data);
|
||||
$this->onlinePayment = OnlinePayment::create($data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,16 +260,19 @@ class OnlinePaymentRepository
|
||||
/** @var \App\Modules\Branch\Models\Branch */
|
||||
$bankBranch = $relatedResource->branch;
|
||||
|
||||
if (! $bankBranch || is_null($bankBranch->billing_username) || is_null($bankBranch->billing_password)) { // @phpstan-ignore-line
|
||||
return $this->paymentFailed('(BRANCH NOT FOUND)');
|
||||
$username = $bankBranch->offsetExists($paymentHistory->api_client.'_username') ? $bankBranch->{$paymentHistory->api_client.'_username'} : '';
|
||||
$password = $bankBranch->offsetExists($paymentHistory->api_client.'_password') ? $bankBranch->{$paymentHistory->api_client.'_password'} : '';
|
||||
|
||||
if ($username === '' || $password === '') {
|
||||
return $this->paymentFailed('(USERNAME OR PASSWORD NOT FOUND)');
|
||||
}
|
||||
|
||||
$this->provider->setUsername($bankBranch->billing_username);
|
||||
$this->provider->setPassword($bankBranch->billing_password);
|
||||
$this->provider->setUsername($username);
|
||||
$this->provider->setPassword($password);
|
||||
$response = $this->provider->checkPayment($orderId);
|
||||
|
||||
if ($response['errorCode'] == '99') {
|
||||
return $this->paymentFailed('(REQUEST FAILURE)');
|
||||
if ($response['errorCode'] != '0') {
|
||||
return $this->paymentFailed($response['errorMessage']); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
return $response['paymentAmountInfo']['depositedAmount'] > 0 // @phpstan-ignore-line
|
||||
|
||||
@@ -15,6 +15,8 @@ class SmsRepository
|
||||
public static function sendSMS(string|int $phone, string|int $message): mixed
|
||||
{
|
||||
if (app()->environment('local')) {
|
||||
info('Sending SMS to '.$phone.' with message: '.$message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,6 @@ trait RoleCheckers
|
||||
*/
|
||||
public function isSystemUser(): bool
|
||||
{
|
||||
return $this->isAdmin() || $this->isOperator();
|
||||
return $this->isAdmin() || $this->isOperator() || $this->isCurrencyMaintainer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,4 +83,12 @@ trait UserAdjustments
|
||||
{
|
||||
return $this->hasMany(UserBranch::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Full name
|
||||
*/
|
||||
public function fullName(): string
|
||||
{
|
||||
return sprintf('%s %s', $this->first_name, $this->last_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class VisaMasterPaymentOrderController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Request $request): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('visa_master_payment_orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('unique_id')->nullable()->unique();
|
||||
|
||||
$table->string('type')->nullable();
|
||||
|
||||
$table->string('passport_name')->nullable();
|
||||
$table->string('passport_surname')->nullable();
|
||||
$table->string('phone')->nullable();
|
||||
$table->string('email')->nullable();
|
||||
$table->string('region')->nullable();
|
||||
|
||||
$table->foreignId('branch_id')->nullable()->constrained('branches')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->nullable()->constrained('users')->cascadeOnDelete();
|
||||
|
||||
$table->string('address')->nullable();
|
||||
|
||||
$table->json('sender_datas')->nullable();
|
||||
$table->json('payment_reciever')->nullable();
|
||||
|
||||
$table->json('documents')->nullable();
|
||||
|
||||
$table->string('status')->nullable();
|
||||
$table->string('notes')->nullable();
|
||||
|
||||
$table->string('sender_full_name')->nullable();
|
||||
$table->string('sender_passport_serie')->nullable();
|
||||
$table->string('sender_passport_number')->nullable();
|
||||
$table->string('sender_deposit_account')->nullable();
|
||||
|
||||
$table->string('reciever_full_name')->nullable();
|
||||
$table->string('reciever_passport_serie')->nullable();
|
||||
$table->string('reciever_passport_number')->nullable();
|
||||
$table->string('reciever_deposit_account')->nullable();
|
||||
|
||||
$table->boolean('paid')->default(false);
|
||||
|
||||
$table->softDeletes();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('visa_master_payment_orders');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('visa_master_settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->unique();
|
||||
$table->string('display_name');
|
||||
$table->text('value');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('visa_master_settings');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('visa_master_payment_order_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('visa_master_payment_order_id')->constrained('visa_master_payment_orders')->nullOnDelete();
|
||||
$table->foreignId('online_payment_id')->nullable()->constrained('online_payments')->nullOnDelete();
|
||||
|
||||
$table->string('payer_name')->nullable();
|
||||
$table->string('payer_card')->nullable();
|
||||
|
||||
$table->string('payment_order_number')->nullable();
|
||||
|
||||
$table->string('tmt_payment_amount');
|
||||
$table->string('usd_payment_amount');
|
||||
$table->boolean('paid')->default(false);
|
||||
$table->boolean('synced_with_system')->nullable()->default(false);
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('visa_master_payment_order_items');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Filament\Actions;
|
||||
|
||||
use App\Modules\CurrencyRate\Models\CurrencyRate;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use App\Modules\VisaMasterPaymentOrder\Repositories\VisaMasterPaymentOrderRepository;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Schemas\Components\Fieldset;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Livewire\Component;
|
||||
|
||||
class PayVisaMasterPaymentAction
|
||||
{
|
||||
public static function make(): Action
|
||||
{
|
||||
return Action::make('pay_visa_master_payment')
|
||||
->label(sprintf('%s %s', __('Make payment for:'), today()->translatedFormat('F')))
|
||||
->icon('heroicon-o-credit-card')
|
||||
->modal()
|
||||
->schema(function () {
|
||||
$usd_to_tmt = floatval(CurrencyRate::where('currency_from', 'USD')->where('currency_to', 'TMT')->first('value')?->value);
|
||||
|
||||
if (! $usd_to_tmt) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$visaMasterPaymentOrderRepository = VisaMasterPaymentOrderRepository::make();
|
||||
|
||||
$bankFee = $visaMasterPaymentOrderRepository->bankFee();
|
||||
$gbusFee = $visaMasterPaymentOrderRepository->gbusFee();
|
||||
|
||||
$max_value = number_format($usd_to_tmt * 250, 2);
|
||||
|
||||
return [
|
||||
Fieldset::make(__('Tax'))
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
'xl' => 3,
|
||||
])
|
||||
->schema([
|
||||
TextEntry::make('usd_to_tmt')
|
||||
->extraAttributes(['class' => 'uppercase tracking-wide font-bold text-xs'])
|
||||
->label(sprintf('1 USD = %s TMT', $usd_to_tmt)),
|
||||
|
||||
TextEntry::make('bank_fee')
|
||||
->extraAttributes(['class' => 'uppercase tracking-wide font-bold text-xs'])
|
||||
->label(sprintf('Bankyň tutumy: %s TMT', $bankFee)),
|
||||
|
||||
TextEntry::make('gbus_fee')
|
||||
->extraAttributes(['class' => 'uppercase tracking-wide font-bold text-xs'])
|
||||
->label(sprintf('GBÜS tutumy: %s TMT', $gbusFee)),
|
||||
]),
|
||||
|
||||
Fieldset::make()
|
||||
->columns([
|
||||
'default' => 1,
|
||||
'md' => 2,
|
||||
'xl' => 3,
|
||||
])
|
||||
->schema([
|
||||
TextInput::make('payment_amount')
|
||||
->label(sprintf('%s (%s)', __('Payment amount'), __('TMT')))
|
||||
->required()
|
||||
->numeric()
|
||||
->maxValue($max_value)
|
||||
->helperText(sprintf('Iň ýokary möçberi: %s TMT', $max_value))
|
||||
->live()
|
||||
->afterStateUpdated(function (Set $set, ?string $state) use ($usd_to_tmt, $bankFee, $gbusFee) {
|
||||
if (is_null($state) || $state == 0 || $state == '') {
|
||||
$set('usd_rate', '');
|
||||
|
||||
return;
|
||||
}
|
||||
$state = floatval($state);
|
||||
|
||||
$usd_rate = $state / $usd_to_tmt;
|
||||
$total_amount = $state + $bankFee + $gbusFee;
|
||||
|
||||
$set('usd_rate', number_format($usd_rate, 2, '.', ''));
|
||||
$set('total_amount', number_format($total_amount, 2, '.', ''));
|
||||
}),
|
||||
|
||||
TextInput::make('usd_rate')
|
||||
->label(__('USD rate'))
|
||||
->suffix('USD')
|
||||
->readOnly(),
|
||||
|
||||
TextInput::make('total_amount')
|
||||
->label(__('Total'))
|
||||
->suffix('TMT')
|
||||
->readOnly(),
|
||||
]),
|
||||
|
||||
];
|
||||
})
|
||||
->action(function (array $data, VisaMasterPaymentOrder $record, Component $livewire): void {
|
||||
/** @var array{payment_amount: float, usd_rate: float, total_amount: float} */
|
||||
$formData = $data;
|
||||
|
||||
$visaMasterPaymentOrderRepository = VisaMasterPaymentOrderRepository::make();
|
||||
|
||||
$today = today();
|
||||
|
||||
// Needs to be tested...
|
||||
if ($visaMasterPaymentOrderRepository->hasBeenPaidThisMonth($record, $today)) {
|
||||
Notification::make()
|
||||
->title(__('This month has already been paid').'!')
|
||||
->body(__('This month has already been paid'))
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Needs to be tested...
|
||||
if ($visaMasterPaymentOrderRepository->isEndOfMonth($today)) {
|
||||
Notification::make()
|
||||
->title(__('Payment cannot be accepted on the last day of the month').'!')
|
||||
->body(__('Payment cannot be accepted on the last day of the month'))
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Needs to be tested...
|
||||
if (! $record->branch || ! $record->branch->billing_visa_master_username) {
|
||||
Notification::make()
|
||||
->title(__('Contact with the operator').'!')
|
||||
->body(__('Billing information is not available in the branch! The branch cannot accept Visa/Master payments.'))
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$total_amount = $formData['payment_amount'] + $visaMasterPaymentOrderRepository->bankFee() + $visaMasterPaymentOrderRepository->gbusFee();
|
||||
|
||||
$onlinePaymentRepository = $visaMasterPaymentOrderRepository->createOnlinePaymentOrder($record, $total_amount);
|
||||
|
||||
if ($onlinePaymentRepository->failed()) {
|
||||
Notification::make()
|
||||
->title(__('Payment error').'!')
|
||||
->body(sprintf('%s. %s. %s.', __('Problem connecting on HALKBANK SYSTEM'), __('Error has been captured'), __('Please try again later')))
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$visaMasterPaymentOrderRepository->createPaymentRecord($record, $onlinePaymentRepository, $formData['usd_rate']);
|
||||
|
||||
// Tell Livewire to open it in a new tab
|
||||
$livewire->js("window.open('{$onlinePaymentRepository->paymentLink()}', '_blank')");
|
||||
})
|
||||
->modalSubmitActionLabel(__('Pay'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Modules\Branch\Interfaces\BelongsToBranch;
|
||||
use App\Modules\Branch\Models\Branch;
|
||||
use App\Modules\LoanOrder\Repositories\LoanOrderRepository;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $unique_id
|
||||
* @property string $type
|
||||
* @property string $passport_name
|
||||
* @property string $passport_surname
|
||||
* @property string $phone
|
||||
* @property string $email
|
||||
* @property string $region
|
||||
* @property string $address
|
||||
* @property array<string, string> $sender_datas
|
||||
* @property array<string, string> $payment_reciever
|
||||
* @property array<string, string> $documents
|
||||
* @property string $status
|
||||
* @property ?string $notes
|
||||
* @property string $sender_full_name
|
||||
* @property string $sender_passport_serie
|
||||
* @property string $sender_passport_number
|
||||
* @property string $sender_deposit_account
|
||||
* @property bool $paid
|
||||
* @property \Illuminate\Support\Carbon $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
*/
|
||||
class VisaMasterPaymentOrder extends Model implements BelongsToBranch, HasMedia
|
||||
{
|
||||
use InteractsWithMedia;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'visa_master_payment_orders';
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'sender_datas' => 'array',
|
||||
'payment_reciever' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* User
|
||||
*
|
||||
* @return BelongsTo<User, $this>
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Branch
|
||||
*
|
||||
* @return BelongsTo<Branch, $this>
|
||||
*/
|
||||
public function branch(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Branch::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment itmes
|
||||
*
|
||||
* @return HasMany<VisaMasterPaymentOrderItem, $this>
|
||||
*/
|
||||
public function paymentItems(): HasMany
|
||||
{
|
||||
return $this->hasMany(VisaMasterPaymentOrderItem::class, 'visa_master_payment_order_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get applications types
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function applicationTypes(): array
|
||||
{
|
||||
return [
|
||||
'visa' => __('Visa'),
|
||||
'master' => __('Master'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Media collections
|
||||
*/
|
||||
public function registerMediaCollections(): void
|
||||
{
|
||||
$this->addMediaCollection('receiver_requisite')->singleFile();
|
||||
$this->addMediaCollection('receiver_document_stating_he_is_studying')->singleFile();
|
||||
$this->addMediaCollection('receiver_ticket')->singleFile();
|
||||
$this->addMediaCollection('receiver_passport_local')->singleFile();
|
||||
$this->addMediaCollection('receiver_passport_international')->singleFile();
|
||||
$this->addMediaCollection('receiver_visa')->singleFile();
|
||||
$this->addMediaCollection('receiver_travel_stamp_on_passport')->singleFile();
|
||||
$this->addMediaCollection('receiver_document_stating_he_is_studying_2')->singleFile();
|
||||
|
||||
$this->addMediaCollection('sender_passport_local')->singleFile();
|
||||
$this->addMediaCollection('sender_passport_international')->singleFile();
|
||||
$this->addMediaCollection('sender_travel_stamp_on_passport')->singleFile();
|
||||
$this->addMediaCollection('sender_proof_of_kinship')->singleFile();
|
||||
$this->addMediaCollection('sender_passport_local_old')->singleFile();
|
||||
$this->addMediaCollection('sender_passport_local_old_replacement')->singleFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* "boot" method for model
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::created(LoanOrderRepository::created());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Models;
|
||||
|
||||
use App\Modules\OnlinePayment\Models\OnlinePayment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $visa_master_payment_order_id
|
||||
* @property int $online_payment_id
|
||||
* @property string $payer_name
|
||||
* @property string $payer_card
|
||||
* @property string $payment_order_number
|
||||
* @property string $tmt_payment_amount
|
||||
* @property string $usd_payment_amount
|
||||
* @property bool $paid
|
||||
* @property bool $synced_with_system
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
*/
|
||||
class VisaMasterPaymentOrderItem extends Model
|
||||
{
|
||||
/**
|
||||
* Table
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'visa_master_payment_order_items';
|
||||
|
||||
/**
|
||||
* Guarded attributes
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* Parent order
|
||||
*
|
||||
* @return BelongsTo<VisaMasterPaymentOrder, $this>
|
||||
*/
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(VisaMasterPaymentOrder::class, 'visa_master_payment_order_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Online payment
|
||||
*
|
||||
* @return BelongsTo<OnlinePayment, $this>
|
||||
*/
|
||||
public function onlinePayment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(OnlinePayment::class, 'online_payment_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $display_name
|
||||
* @property string $value
|
||||
*/
|
||||
class VisaMasterSettings extends Model
|
||||
{
|
||||
protected $table = 'visa_master_settings';
|
||||
|
||||
/**
|
||||
* The possible types of settings.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function types(): array
|
||||
{
|
||||
return [
|
||||
'payment_warning_text' => __('Warning text'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrderItem;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class VisaMasterPaymentOrderItemPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('ViewAny:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
|
||||
public function view(User $user, VisaMasterPaymentOrderItem $visaMasterPaymentOrderItem): bool
|
||||
{
|
||||
return $user->can('View:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('Create:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
|
||||
public function update(User $user, VisaMasterPaymentOrderItem $visaMasterPaymentOrderItem): bool
|
||||
{
|
||||
return $user->can('Update:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
|
||||
public function delete(User $user, VisaMasterPaymentOrderItem $visaMasterPaymentOrderItem): bool
|
||||
{
|
||||
return $user->can('Delete:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
|
||||
public function restore(User $user, VisaMasterPaymentOrderItem $visaMasterPaymentOrderItem): bool
|
||||
{
|
||||
return $user->can('Restore:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
|
||||
public function forceDelete(User $user, VisaMasterPaymentOrderItem $visaMasterPaymentOrderItem): bool
|
||||
{
|
||||
return $user->can('ForceDelete:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class VisaMasterPaymentOrderPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('ViewAny:VisaMasterPaymentOrder');
|
||||
}
|
||||
|
||||
public function view(User $user, VisaMasterPaymentOrder $visaMasterPaymentOrder): bool
|
||||
{
|
||||
return $user->can('View:VisaMasterPaymentOrder');
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('Create:VisaMasterPaymentOrder');
|
||||
}
|
||||
|
||||
public function update(User $user, VisaMasterPaymentOrder $visaMasterPaymentOrder): bool
|
||||
{
|
||||
return $user->can('Update:VisaMasterPaymentOrder');
|
||||
}
|
||||
|
||||
public function delete(User $user, VisaMasterPaymentOrder $visaMasterPaymentOrder): bool
|
||||
{
|
||||
return $user->can('Delete:VisaMasterPaymentOrder');
|
||||
}
|
||||
|
||||
public function restore(User $user, VisaMasterPaymentOrder $visaMasterPaymentOrder): bool
|
||||
{
|
||||
return $user->can('Restore:VisaMasterPaymentOrder');
|
||||
}
|
||||
|
||||
public function forceDelete(User $user, VisaMasterPaymentOrder $visaMasterPaymentOrder): bool
|
||||
{
|
||||
return $user->can('ForceDelete:VisaMasterPaymentOrder');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterSettings;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class VisaMasterSettingsPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('ViewAny:VisaMasterSettings');
|
||||
}
|
||||
|
||||
public function view(User $user, VisaMasterSettings $visaMasterSettings): bool
|
||||
{
|
||||
return $user->can('View:VisaMasterSettings');
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('Create:VisaMasterSettings');
|
||||
}
|
||||
|
||||
public function update(User $user, VisaMasterSettings $visaMasterSettings): bool
|
||||
{
|
||||
return $user->can('Update:VisaMasterSettings');
|
||||
}
|
||||
|
||||
public function delete(User $user, VisaMasterSettings $visaMasterSettings): bool
|
||||
{
|
||||
return $user->can('Delete:VisaMasterSettings');
|
||||
}
|
||||
|
||||
public function restore(User $user, VisaMasterSettings $visaMasterSettings): bool
|
||||
{
|
||||
return $user->can('Restore:VisaMasterSettings');
|
||||
}
|
||||
|
||||
public function forceDelete(User $user, VisaMasterSettings $visaMasterSettings): bool
|
||||
{
|
||||
return $user->can('ForceDelete:VisaMasterSettings');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder\Repositories;
|
||||
|
||||
use App\Modules\HalkbankOnlinePayment\Repositories\HalkbankOnlinePaymentRepository;
|
||||
use App\Modules\Makeable;
|
||||
use App\Modules\OnlinePayment\Repositories\OnlinePaymentRepository;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrderItem;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class VisaMasterPaymentOrderRepository
|
||||
{
|
||||
use Makeable;
|
||||
|
||||
/**
|
||||
* Bank fee
|
||||
*/
|
||||
public int|float $bankFee = 20;
|
||||
|
||||
/**
|
||||
* Gbus fee
|
||||
*/
|
||||
public int|float $gbusFee = 3;
|
||||
|
||||
/**
|
||||
* Bank fee
|
||||
*/
|
||||
public function bankFee(): int|float
|
||||
{
|
||||
return $this->bankFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gbus fee
|
||||
*/
|
||||
public function gbusFee(): int|float
|
||||
{
|
||||
return $this->gbusFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has been paid this month
|
||||
*/
|
||||
public function hasBeenPaidThisMonth(VisaMasterPaymentOrder $record, Carbon $today): bool
|
||||
{
|
||||
return $record->paymentItems->contains(
|
||||
fn (VisaMasterPaymentOrderItem $item): bool => $item->paid && $item->created_at->format('m Y') === $today->format('m Y')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is end of month
|
||||
*/
|
||||
public function isEndOfMonth(Carbon $today): bool
|
||||
{
|
||||
$lastDay = $today->copy()->endOfMonth();
|
||||
$lastDayOfWeek = $lastDay->format('l');
|
||||
|
||||
$oneDayBefore = $lastDay->copy()->subDay(); // Saturday...
|
||||
$twoDaysBefore = $lastDay->copy()->subDays(2); // Friday...
|
||||
|
||||
// Condition 1: Today is the last day
|
||||
if ($today->isSameDay($lastDay)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Condition 2: Last day is Sunday → forbid Friday & Saturday
|
||||
if ($lastDayOfWeek === 'Sunday' && ($today->isSameDay($oneDayBefore) || $today->isSameDay($twoDaysBefore))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Condition 3: Last day is Saturday → forbid Friday
|
||||
if ($lastDayOfWeek === 'Saturday' && $today->isSameDay($oneDayBefore)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Default: allow payment
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create online payment order
|
||||
*/
|
||||
public function createOnlinePaymentOrder(VisaMasterPaymentOrder $record, int|float|string $amount): OnlinePaymentRepository
|
||||
{
|
||||
/** @var \App\Modules\Branch\Models\Branch */
|
||||
$branch = $record->branch;
|
||||
|
||||
return OnlinePaymentRepository::make(relatedModel: $record, apiClient: 'billing_visa_master')
|
||||
->setPaymentProvider(
|
||||
HalkbankOnlinePaymentRepository::make(
|
||||
username: $branch->billing_visa_master_username,
|
||||
password: $branch->billing_visa_master_password,
|
||||
amount: $amount,
|
||||
returnUrl: route('halkbank-online-payment.store'),
|
||||
description: 'Visa/Master tölegi'
|
||||
)
|
||||
)
|
||||
->sendRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create payment record
|
||||
*/
|
||||
public function createPaymentRecord(VisaMasterPaymentOrder $record, OnlinePaymentRepository $onlinePaymentRepository, int|string|float $usdRate): void
|
||||
{
|
||||
VisaMasterPaymentOrderItem::create([
|
||||
'visa_master_payment_order_id' => $record->id,
|
||||
'online_payment_id' => $onlinePaymentRepository->onlinePayment()->id,
|
||||
'payment_order_number' => $onlinePaymentRepository->onlinePayment()->orderNumber,
|
||||
'tmt_payment_amount' => $onlinePaymentRepository->paymentProvider()->amount(),
|
||||
'usd_payment_amount' => $usdRate,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\VisaMasterPaymentOrder;
|
||||
|
||||
use App\Modules\Makeable;
|
||||
use App\Modules\ModuleContract;
|
||||
|
||||
class VisaMasterPaymentOrderModule implements ModuleContract
|
||||
{
|
||||
use Makeable;
|
||||
|
||||
/**
|
||||
* Module is enabled
|
||||
*/
|
||||
protected bool $enabled = true;
|
||||
|
||||
/**
|
||||
* Check if is module enabled
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable module
|
||||
*/
|
||||
public function disable(): void
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable module
|
||||
*/
|
||||
public function enable(): void
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if module has a filament resource
|
||||
*/
|
||||
public function hasFilamentResource(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer requirements
|
||||
*/
|
||||
public function getComposerRequirements(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer suggestions
|
||||
*/
|
||||
public function getComposerSuggestions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,12 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use AbdulmajeedJamaan\FilamentTranslatableTabs\TranslatableTabs;
|
||||
use BezhanSalleh\LanguageSwitch\Events\LocaleChanged;
|
||||
use BezhanSalleh\LanguageSwitch\LanguageSwitch;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Spatie\Translatable\HasTranslations;
|
||||
|
||||
@@ -33,6 +36,17 @@ class AppServiceProvider extends ServiceProvider
|
||||
->locales(array_keys(baseLocales()));
|
||||
});
|
||||
|
||||
LanguageSwitch::configureUsing(function (LanguageSwitch $switch) {
|
||||
$switch
|
||||
->locales(['tk', 'en', 'ru']);
|
||||
});
|
||||
|
||||
Event::listen(function (LocaleChanged $event) {
|
||||
if (array_key_exists($event->locale, baseLocales())) {
|
||||
user()->update(['locale' => $event->locale]);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Order by translation for spatie/laravel-translatable
|
||||
*
|
||||
|
||||
@@ -8,6 +8,18 @@ use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
\App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder::class => \App\Modules\VisaMasterPaymentOrder\Policies\VisaMasterPaymentOrderPolicy::class,
|
||||
\App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrderItem::class => \App\Modules\VisaMasterPaymentOrder\Policies\VisaMasterPaymentOrderItemPolicy::class,
|
||||
\App\Modules\VisaMasterPaymentOrder\Models\VisaMasterSettings::class => \App\Modules\VisaMasterPaymentOrder\Policies\VisaMasterSettingsPolicy::class,
|
||||
\App\Modules\OnlinePayment\Models\OnlinePayment::class => \App\Modules\OnlinePayment\Policies\OnlinePaymentPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Register services.
|
||||
*/
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
namespace App\Providers\Filament;
|
||||
|
||||
use App\Http\Middleware\EnsureProfileIsFilled;
|
||||
use App\Http\Middleware\EnsureUserHasRole;
|
||||
use App\Livewire\UserProfileFields;
|
||||
use App\Modules\BaseAuth\Middleware\RedirectIfUserPhoneIsUnVerfied;
|
||||
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
|
||||
use CraftForge\FilamentLanguageSwitcher\FilamentLanguageSwitcherPlugin;
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
use Filament\Http\Middleware\AuthenticateSession;
|
||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||
@@ -16,6 +16,7 @@ use Filament\Panel;
|
||||
use Filament\PanelProvider;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Widgets\AccountWidget;
|
||||
use Filament\Widgets\FilamentInfoWidget;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
@@ -23,13 +24,12 @@ use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
use Joaopaulolndev\FilamentEditProfile\FilamentEditProfilePlugin;
|
||||
use RalphJSmit\Filament\Upload\FilamentUpload;
|
||||
|
||||
class WorkPanelProvider extends PanelProvider
|
||||
{
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
// #content\.form-actions > div
|
||||
|
||||
return $panel
|
||||
->default()
|
||||
->id('work')
|
||||
@@ -46,6 +46,7 @@ class WorkPanelProvider extends PanelProvider
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
|
||||
->widgets([
|
||||
AccountWidget::class,
|
||||
FilamentInfoWidget::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
@@ -63,25 +64,23 @@ class WorkPanelProvider extends PanelProvider
|
||||
FilamentShieldPlugin::make()
|
||||
->navigationGroup('Roles and permissions'),
|
||||
|
||||
FilamentLanguageSwitcherPlugin::make()
|
||||
->locales([
|
||||
['code' => 'tk', 'name' => 'Turkmen', 'flag' => 'tm'],
|
||||
['code' => 'en', 'name' => 'English', 'flag' => 'us'],
|
||||
['code' => 'ru', 'name' => 'Russian', 'flag' => 'ru'],
|
||||
]),
|
||||
|
||||
FilamentEditProfilePlugin::make()
|
||||
->setTitle(__('My profile'))
|
||||
->setNavigationLabel(__('My profile'))
|
||||
->setIcon('heroicon-o-user-circle')
|
||||
->setSort(4)
|
||||
->shouldShowEditProfileForm(false)
|
||||
->customProfileComponents([
|
||||
UserProfileFields::class,
|
||||
]),
|
||||
|
||||
FilamentUpload::make(),
|
||||
|
||||
])
|
||||
->authMiddleware([
|
||||
Authenticate::class,
|
||||
EnsureProfileIsFilled::class,
|
||||
EnsureUserHasRole::class,
|
||||
])
|
||||
->spa()
|
||||
->databaseTransactions()
|
||||
@@ -92,6 +91,7 @@ class WorkPanelProvider extends PanelProvider
|
||||
'primary' => Color::Indigo,
|
||||
'success' => Color::Emerald,
|
||||
'warning' => Color::Orange,
|
||||
]);
|
||||
])
|
||||
->viteTheme('resources/css/filament/work/theme.css');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware;
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
api: __DIR__.'/../routes/api.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
)
|
||||
|
||||
@@ -8,15 +8,21 @@
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"abdulmajeed-jamaan/filament-translatable-tabs": "^4.0",
|
||||
"bezhansalleh/filament-language-switch": "^4.0",
|
||||
"bezhansalleh/filament-shield": "^4.0",
|
||||
"craft-forge/filament-language-switcher": "^1.0",
|
||||
"filament/filament": "^4.0",
|
||||
"filament/spatie-laravel-media-library-plugin": "^4.0",
|
||||
"halaxa/json-machine": "^1.2",
|
||||
"joaopaulolndev/filament-edit-profile": "^2.0",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"laravel/ui": "^4.6",
|
||||
"mpdf/mpdf": "^8.2",
|
||||
"phpoffice/phpword": "dev-master",
|
||||
"ralphjsmit/laravel-filament-upload": "^1.1",
|
||||
"spatie/laravel-activitylog": "^4.10",
|
||||
"spatie/laravel-medialibrary": "^11.17",
|
||||
"spatie/laravel-translatable": "^6.11",
|
||||
"stevebauman/location": "^7.6"
|
||||
},
|
||||
@@ -47,6 +53,12 @@
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://satis.ralphjsmit.com"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
@@ -87,7 +99,8 @@
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"pestphp/pest-plugin": true,
|
||||
"php-http/discovery": true
|
||||
"php-http/discovery": true,
|
||||
"ralphjsmit/packages": true
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
|
||||
2789
composer.lock
generated
2789
composer.lock
generated
File diff suppressed because it is too large
Load Diff
52
config/activitylog.php
Normal file
52
config/activitylog.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
* If set to false, no activities will be saved to the database.
|
||||
*/
|
||||
'enabled' => env('ACTIVITY_LOGGER_ENABLED', true),
|
||||
|
||||
/*
|
||||
* When the clean-command is executed, all recording activities older than
|
||||
* the number of days specified here will be deleted.
|
||||
*/
|
||||
'delete_records_older_than_days' => 365,
|
||||
|
||||
/*
|
||||
* If no log name is passed to the activity() helper
|
||||
* we use this default log name.
|
||||
*/
|
||||
'default_log_name' => 'default',
|
||||
|
||||
/*
|
||||
* You can specify an auth driver here that gets user models.
|
||||
* If this is null we'll use the current Laravel auth driver.
|
||||
*/
|
||||
'default_auth_driver' => null,
|
||||
|
||||
/*
|
||||
* If set to true, the subject returns soft deleted models.
|
||||
*/
|
||||
'subject_returns_soft_deleted_models' => false,
|
||||
|
||||
/*
|
||||
* This model will be used to log activity.
|
||||
* It should implement the Spatie\Activitylog\Contracts\Activity interface
|
||||
* and extend Illuminate\Database\Eloquent\Model.
|
||||
*/
|
||||
'activity_model' => \Spatie\Activitylog\Models\Activity::class,
|
||||
|
||||
/*
|
||||
* This is the name of the table that will be created by the migration and
|
||||
* used by the Activity model shipped with this package.
|
||||
*/
|
||||
'table_name' => env('ACTIVITY_LOGGER_TABLE_NAME', 'activity_log'),
|
||||
|
||||
/*
|
||||
* This is the database connection that will be used by the migration and
|
||||
* the Activity model shipped with this package. In case it's not set
|
||||
* Laravel's database.default will be used instead.
|
||||
*/
|
||||
'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'),
|
||||
];
|
||||
303
config/media-library.php
Normal file
303
config/media-library.php
Normal file
@@ -0,0 +1,303 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
* The disk on which to store added files and derived images by default. Choose
|
||||
* one or more of the disks you've configured in config/filesystems.php.
|
||||
*/
|
||||
'disk_name' => env('MEDIA_DISK', 'public'),
|
||||
|
||||
/*
|
||||
* The maximum file size of an item in bytes.
|
||||
* Adding a larger file will result in an exception.
|
||||
*/
|
||||
'max_file_size' => 1024 * 1024 * 10, // 10MB
|
||||
|
||||
/*
|
||||
* This queue connection will be used to generate derived and responsive images.
|
||||
* Leave empty to use the default queue connection.
|
||||
*/
|
||||
'queue_connection_name' => env('QUEUE_CONNECTION', 'sync'),
|
||||
|
||||
/*
|
||||
* This queue will be used to generate derived and responsive images.
|
||||
* Leave empty to use the default queue.
|
||||
*/
|
||||
'queue_name' => env('MEDIA_QUEUE', ''),
|
||||
|
||||
/*
|
||||
* By default all conversions will be performed on a queue.
|
||||
*/
|
||||
'queue_conversions_by_default' => env('QUEUE_CONVERSIONS_BY_DEFAULT', true),
|
||||
|
||||
/*
|
||||
* Should database transactions be run after database commits?
|
||||
*/
|
||||
'queue_conversions_after_database_commit' => env('QUEUE_CONVERSIONS_AFTER_DB_COMMIT', true),
|
||||
|
||||
/*
|
||||
* The fully qualified class name of the media model.
|
||||
*/
|
||||
'media_model' => Spatie\MediaLibrary\MediaCollections\Models\Media::class,
|
||||
|
||||
/*
|
||||
* The fully qualified class name of the media observer.
|
||||
*/
|
||||
'media_observer' => Spatie\MediaLibrary\MediaCollections\Models\Observers\MediaObserver::class,
|
||||
|
||||
/*
|
||||
* When enabled, media collections will be serialised using the default
|
||||
* laravel model serialization behaviour.
|
||||
*
|
||||
* Keep this option disabled if using Media Library Pro components (https://medialibrary.pro)
|
||||
*/
|
||||
'use_default_collection_serialization' => false,
|
||||
|
||||
/*
|
||||
* The fully qualified class name of the model used for temporary uploads.
|
||||
*
|
||||
* This model is only used in Media Library Pro (https://medialibrary.pro)
|
||||
*/
|
||||
'temporary_upload_model' => Spatie\MediaLibraryPro\Models\TemporaryUpload::class,
|
||||
|
||||
/*
|
||||
* When enabled, Media Library Pro will only process temporary uploads that were uploaded
|
||||
* in the same session. You can opt to disable this for stateless usage of
|
||||
* the pro components.
|
||||
*/
|
||||
'enable_temporary_uploads_session_affinity' => true,
|
||||
|
||||
/*
|
||||
* When enabled, Media Library pro will generate thumbnails for uploaded file.
|
||||
*/
|
||||
'generate_thumbnails_for_temporary_uploads' => true,
|
||||
|
||||
/*
|
||||
* This is the class that is responsible for naming generated files.
|
||||
*/
|
||||
'file_namer' => Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer::class,
|
||||
|
||||
/*
|
||||
* The class that contains the strategy for determining a media file's path.
|
||||
*/
|
||||
'path_generator' => Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator::class,
|
||||
|
||||
/*
|
||||
* The class that contains the strategy for determining how to remove files.
|
||||
*/
|
||||
'file_remover_class' => Spatie\MediaLibrary\Support\FileRemover\DefaultFileRemover::class,
|
||||
|
||||
/*
|
||||
* Here you can specify which path generator should be used for the given class.
|
||||
*/
|
||||
'custom_path_generators' => [
|
||||
// Model::class => PathGenerator::class
|
||||
// or
|
||||
// 'model_morph_alias' => PathGenerator::class
|
||||
],
|
||||
|
||||
/*
|
||||
* When urls to files get generated, this class will be called. Use the default
|
||||
* if your files are stored locally above the site root or on s3.
|
||||
*/
|
||||
'url_generator' => Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class,
|
||||
|
||||
/*
|
||||
* Moves media on updating to keep path consistent. Enable it only with a custom
|
||||
* PathGenerator that uses, for example, the media UUID.
|
||||
*/
|
||||
'moves_media_on_update' => false,
|
||||
|
||||
/*
|
||||
* Whether to activate versioning when urls to files get generated.
|
||||
* When activated, this attaches a ?v=xx query string to the URL.
|
||||
*/
|
||||
'version_urls' => false,
|
||||
|
||||
/*
|
||||
* The media library will try to optimize all converted images by removing
|
||||
* metadata and applying a little bit of compression. These are
|
||||
* the optimizers that will be used by default.
|
||||
*/
|
||||
'image_optimizers' => [
|
||||
Spatie\ImageOptimizer\Optimizers\Jpegoptim::class => [
|
||||
'-m85', // set maximum quality to 85%
|
||||
'--force', // ensure that progressive generation is always done also if a little bigger
|
||||
'--strip-all', // this strips out all text information such as comments and EXIF data
|
||||
'--all-progressive', // this will make sure the resulting image is a progressive one
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Pngquant::class => [
|
||||
'--force', // required parameter for this package
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Optipng::class => [
|
||||
'-i0', // this will result in a non-interlaced, progressive scanned image
|
||||
'-o2', // this set the optimization level to two (multiple IDAT compression trials)
|
||||
'-quiet', // required parameter for this package
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Svgo::class => [
|
||||
'--disable=cleanupIDs', // disabling because it is known to cause troubles
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Gifsicle::class => [
|
||||
'-b', // required parameter for this package
|
||||
'-O3', // this produces the slowest but best results
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Cwebp::class => [
|
||||
'-m 6', // for the slowest compression method in order to get the best compression.
|
||||
'-pass 10', // for maximizing the amount of analysis pass.
|
||||
'-mt', // multithreading for some speed improvements.
|
||||
'-q 90', // quality factor that brings the least noticeable changes.
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Avifenc::class => [
|
||||
'-a cq-level=23', // constant quality level, lower values mean better quality and greater file size (0-63).
|
||||
'-j all', // number of jobs (worker threads, "all" uses all available cores).
|
||||
'--min 0', // min quantizer for color (0-63).
|
||||
'--max 63', // max quantizer for color (0-63).
|
||||
'--minalpha 0', // min quantizer for alpha (0-63).
|
||||
'--maxalpha 63', // max quantizer for alpha (0-63).
|
||||
'-a end-usage=q', // rate control mode set to Constant Quality mode.
|
||||
'-a tune=ssim', // SSIM as tune the encoder for distortion metric.
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* These generators will be used to create an image of media files.
|
||||
*/
|
||||
'image_generators' => [
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Image::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Webp::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Avif::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Pdf::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Svg::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Video::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* The path where to store temporary files while performing image conversions.
|
||||
* If set to null, storage_path('media-library/temp') will be used.
|
||||
*/
|
||||
'temporary_directory_path' => null,
|
||||
|
||||
/*
|
||||
* The engine that should perform the image conversions.
|
||||
* Should be either `gd` or `imagick`.
|
||||
*/
|
||||
'image_driver' => env('IMAGE_DRIVER', 'gd'),
|
||||
|
||||
/*
|
||||
* FFMPEG & FFProbe binaries paths, only used if you try to generate video
|
||||
* thumbnails and have installed the php-ffmpeg/php-ffmpeg composer
|
||||
* dependency.
|
||||
*/
|
||||
'ffmpeg_path' => env('FFMPEG_PATH', '/usr/bin/ffmpeg'),
|
||||
'ffprobe_path' => env('FFPROBE_PATH', '/usr/bin/ffprobe'),
|
||||
|
||||
/*
|
||||
* The timeout (in seconds) that will be used when generating video
|
||||
* thumbnails via FFMPEG.
|
||||
*/
|
||||
'ffmpeg_timeout' => env('FFMPEG_TIMEOUT', 900),
|
||||
|
||||
/*
|
||||
* The number of threads that FFMPEG should use. 0 means that FFMPEG
|
||||
* may decide itself.
|
||||
*/
|
||||
'ffmpeg_threads' => env('FFMPEG_THREADS', 0),
|
||||
|
||||
/*
|
||||
* Here you can override the class names of the jobs used by this package. Make sure
|
||||
* your custom jobs extend the ones provided by the package.
|
||||
*/
|
||||
'jobs' => [
|
||||
'perform_conversions' => Spatie\MediaLibrary\Conversions\Jobs\PerformConversionsJob::class,
|
||||
'generate_responsive_images' => Spatie\MediaLibrary\ResponsiveImages\Jobs\GenerateResponsiveImagesJob::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* When using the addMediaFromUrl method you may want to replace the default downloader.
|
||||
* This is particularly useful when the url of the image is behind a firewall and
|
||||
* need to add additional flags, possibly using curl.
|
||||
*/
|
||||
'media_downloader' => Spatie\MediaLibrary\Downloaders\DefaultDownloader::class,
|
||||
|
||||
/*
|
||||
* When using the addMediaFromUrl method the SSL is verified by default.
|
||||
* This is option disables SSL verification when downloading remote media.
|
||||
* Please note that this is a security risk and should only be false in a local environment.
|
||||
*/
|
||||
'media_downloader_ssl' => env('MEDIA_DOWNLOADER_SSL', true),
|
||||
|
||||
/*
|
||||
* The default lifetime in minutes for temporary urls.
|
||||
* This is used when you call the `getLastTemporaryUrl` or `getLastTemporaryUrl` method on a media item.
|
||||
*/
|
||||
'temporary_url_default_lifetime' => env('MEDIA_TEMPORARY_URL_DEFAULT_LIFETIME', 5),
|
||||
|
||||
'remote' => [
|
||||
/*
|
||||
* Any extra headers that should be included when uploading media to
|
||||
* a remote disk. Even though supported headers may vary between
|
||||
* different drivers, a sensible default has been provided.
|
||||
*
|
||||
* Supported by S3: CacheControl, Expires, StorageClass,
|
||||
* ServerSideEncryption, Metadata, ACL, ContentEncoding
|
||||
*/
|
||||
'extra_headers' => [
|
||||
'CacheControl' => 'max-age=604800',
|
||||
],
|
||||
],
|
||||
|
||||
'responsive_images' => [
|
||||
/*
|
||||
* This class is responsible for calculating the target widths of the responsive
|
||||
* images. By default we optimize for filesize and create variations that each are 30%
|
||||
* smaller than the previous one. More info in the documentation.
|
||||
*
|
||||
* https://docs.spatie.be/laravel-medialibrary/v9/advanced-usage/generating-responsive-images
|
||||
*/
|
||||
'width_calculator' => Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator::class,
|
||||
|
||||
/*
|
||||
* By default rendering media to a responsive image will add some javascript and a tiny placeholder.
|
||||
* This ensures that the browser can already determine the correct layout.
|
||||
* When disabled, no tiny placeholder is generated.
|
||||
*/
|
||||
'use_tiny_placeholders' => true,
|
||||
|
||||
/*
|
||||
* This class will generate the tiny placeholder used for progressive image loading. By default
|
||||
* the media library will use a tiny blurred jpg image.
|
||||
*/
|
||||
'tiny_placeholder_generator' => Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* When enabling this option, a route will be registered that will enable
|
||||
* the Media Library Pro Vue and React components to move uploaded files
|
||||
* in a S3 bucket to their right place.
|
||||
*/
|
||||
'enable_vapor_uploads' => env('ENABLE_MEDIA_LIBRARY_VAPOR_UPLOADS', false),
|
||||
|
||||
/*
|
||||
* When converting Media instances to response the media library will add
|
||||
* a `loading` attribute to the `img` tag. Here you can set the default
|
||||
* value of that attribute.
|
||||
*
|
||||
* Possible values: 'lazy', 'eager', 'auto' or null if you don't want to set any loading instruction.
|
||||
*
|
||||
* More info: https://css-tricks.com/native-lazy-loading/
|
||||
*/
|
||||
'default_loading_attribute_value' => null,
|
||||
|
||||
/*
|
||||
* You can specify a prefix for that is used for storing all media.
|
||||
* If you set this to `/my-subdir`, all your media will be stored in a `/my-subdir` directory.
|
||||
*/
|
||||
'prefix' => env('MEDIA_PREFIX', ''),
|
||||
|
||||
/*
|
||||
* When forcing lazy loading, media will be loaded even if you don't eager load media and you have
|
||||
* disabled lazy loading globally in the service provider.
|
||||
*/
|
||||
'force_lazy_loading' => env('FORCE_MEDIA_LIBRARY_LAZY_LOADING', true),
|
||||
];
|
||||
84
config/sanctum.php
Normal file
84
config/sanctum.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Stateful Domains
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Requests from the following domains / hosts will receive stateful API
|
||||
| authentication cookies. Typically, these should include your local
|
||||
| and production domains which access your API via a frontend SPA.
|
||||
|
|
||||
*/
|
||||
|
||||
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
|
||||
'%s%s',
|
||||
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
|
||||
Sanctum::currentApplicationUrlWithPort(),
|
||||
// Sanctum::currentRequestHost(),
|
||||
))),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Guards
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This array contains the authentication guards that will be checked when
|
||||
| Sanctum is trying to authenticate a request. If none of these guards
|
||||
| are able to authenticate the request, Sanctum will use the bearer
|
||||
| token that's present on an incoming request for authentication.
|
||||
|
|
||||
*/
|
||||
|
||||
'guard' => ['web'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Expiration Minutes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value controls the number of minutes until an issued token will be
|
||||
| considered expired. This will override any values set in the token's
|
||||
| "expires_at" attribute, but first-party sessions are not affected.
|
||||
|
|
||||
*/
|
||||
|
||||
'expiration' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Token Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Sanctum can prefix new tokens in order to take advantage of numerous
|
||||
| security scanning initiatives maintained by open source platforms
|
||||
| that notify developers if they commit tokens into repositories.
|
||||
|
|
||||
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
||||
|
|
||||
*/
|
||||
|
||||
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When authenticating your first-party SPA with Sanctum you may need to
|
||||
| customize some of the middleware Sanctum uses while processing the
|
||||
| request. You may change the middleware listed below as required.
|
||||
|
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
|
||||
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
|
||||
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
|
||||
],
|
||||
|
||||
];
|
||||
34
database/migrations/2025_11_07_012811_create_media_table.php
Normal file
34
database/migrations/2025_11_07_012811_create_media_table.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('media')) {
|
||||
Schema::create('media', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->morphs('model');
|
||||
$table->uuid()->nullable()->unique();
|
||||
$table->string('collection_name');
|
||||
$table->string('name');
|
||||
$table->string('file_name');
|
||||
$table->string('mime_type')->nullable();
|
||||
$table->string('disk');
|
||||
$table->string('conversions_disk')->nullable();
|
||||
$table->unsignedBigInteger('size');
|
||||
$table->json('manipulations');
|
||||
$table->json('custom_properties');
|
||||
$table->json('generated_conversions');
|
||||
$table->json('responsive_images');
|
||||
$table->unsignedInteger('order_column')->nullable()->index();
|
||||
|
||||
$table->nullableTimestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('action_events', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('batch_id')->nullable();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->index();
|
||||
|
||||
$table->string('name')->index();
|
||||
|
||||
$table->string('actionable_type')->nullable()->index();
|
||||
$table->unsignedBigInteger('actionable_id')->nullable()->index();
|
||||
|
||||
$table->string('target_type')->nullable()->index();
|
||||
$table->unsignedBigInteger('target_id')->nullable()->index();
|
||||
|
||||
$table->string('model_type')->nullable()->index();
|
||||
$table->unsignedBigInteger('model_id')->nullable()->index();
|
||||
|
||||
$table->text('fields')->nullable();
|
||||
$table->string('status')->index()->default('finished');
|
||||
$table->text('exception')->nullable();
|
||||
$table->json('original')->nullable();
|
||||
$table->json('changes')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('action_events');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->text('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
@@ -13,9 +13,7 @@ class DatabaseSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
// UsersTableSeeder::class,
|
||||
// ShieldSeeder::class,
|
||||
// FillJsonData::class,
|
||||
ShieldSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,78 @@ class FillJsonData extends Seeder
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
public function run(): void
|
||||
{
|
||||
// provinces
|
||||
|
||||
}
|
||||
|
||||
protected function seedUsers(): void
|
||||
{
|
||||
(new Migrators\UsersMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedLoanTypes(): void
|
||||
{
|
||||
(new Migrators\LoanTypesMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedProvinces(): void
|
||||
{
|
||||
(new Migrators\ProvincesMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedBranches(): void
|
||||
{
|
||||
(new Migrators\BranchesMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function loanOrderRequiredDocs(): void
|
||||
{
|
||||
(new Migrators\LoanOrderRequiredDocsMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedLoanOrders(): void
|
||||
{
|
||||
(new Migrators\LoanOrdersMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedCardStates(): void
|
||||
{
|
||||
(new Migrators\CardStatesMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedCardTypes(): void
|
||||
{
|
||||
(new Migrators\CardTypesMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function cardOrders(): void
|
||||
{
|
||||
(new Migrators\CardOrdersMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function cardPinOrders(): void
|
||||
{
|
||||
(new Migrators\CardPinOrdersMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedVisaMasterPaymentOrders(): void
|
||||
{
|
||||
(new Migrators\VisaMasterPaymentOrdersMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedActionEvents(): void
|
||||
{
|
||||
(new Migrators\ActionEventsMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedBranchUser(): void
|
||||
{
|
||||
(new Migrators\BranchUserMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedCurrencyRates(): void
|
||||
{
|
||||
(new Migrators\CurrencyRatesMigrator)->migrate();
|
||||
}
|
||||
}
|
||||
|
||||
29
database/seeders/Migrators/ActionEventsMigrator.php
Normal file
29
database/seeders/Migrators/ActionEventsMigrator.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class ActionEventsMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('action_events')->truncate();
|
||||
|
||||
$path = database_path('data/tested/action_events.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (! $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('action_events')->insert((array) $item);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('action_events_id_seq', (SELECT MAX(id) from action_events));");
|
||||
DB::statement("SELECT nextval('action_events_id_seq');");
|
||||
}
|
||||
}
|
||||
29
database/seeders/Migrators/BranchUserMigrator.php
Normal file
29
database/seeders/Migrators/BranchUserMigrator.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class BranchUserMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('branch_user')->truncate();
|
||||
|
||||
$path = database_path('data/tested/branch_user.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (! $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('branch_user')->insert((array) $item);
|
||||
|
||||
DB::statement("SELECT setval('branch_user_id_seq', (SELECT MAX(id) from branch_user));");
|
||||
DB::statement("SELECT nextval('branch_user_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user