TuitionPaymentOrder

This commit is contained in:
2024-09-08 23:12:40 +05:00
parent fab7bfa193
commit 2a1dcdf85f
8 changed files with 711 additions and 3 deletions

View File

@@ -2,7 +2,7 @@
namespace App\Modules\SberPaymentOrder\Nova\Resources\Concerns;
use App\Modules\VisaMasterPaymentOrder\Nova\Resources\VisaMasterPaymentOrderFileFields;
use App\Modules\SberPaymentOrder\Nova\Resources\SberPaymentOrderFileFields;
use App\Nova\Resources\Branch\Branch;
use App\Repos\Order\OrderRepo;
use App\Repos\System\Settings\Legal\PassportRepo;
@@ -137,8 +137,8 @@ class SberPaymentOrderFieldsForDetail
])->maxRows(1)->minRows(1)->rules('required'),
]),
new Panel(__('Reciver files'), VisaMasterPaymentOrderFileFields::reciverFiles()),
new Panel(__('Sender files'), VisaMasterPaymentOrderFileFields::senderFiles()),
new Panel(__('Reciver files'), SberPaymentOrderFileFields::reciverFiles()),
new Panel(__('Sender files'), SberPaymentOrderFileFields::senderFiles()),
];
}
}

View File

@@ -0,0 +1,48 @@
<?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('tuition_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->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tuition_payment_orders');
}
};

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Modules\TuitionPaymentOrder\Models;
use App\Models\Branch\Branch;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class TuitionPaymentOrder extends Model implements HasMedia
{
use InteractsWithMedia;
/**
* Table
*
* @var string
*/
protected $table = 'tuition_payment_orders';
/**
* Guarded attributes
*/
protected $guarded = [];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'sender_datas' => 'array',
'payment_reciever' => 'array',
];
/**
* Media collections
*/
public function registerMediaCollections(): void
{
foreach (static::reciverFiles() as $reciverFile) {
$this->addMediaCollection($reciverFile['code'])->singleFile();
}
foreach (static::senderFiles() as $senderFile) {
$this->addMediaCollection($senderFile['code'])->singleFile();
}
}
/**
* Branch
*/
public function branch(): BelongsTo
{
return $this->belongsTo(Branch::class);
}
/**
* Required files
*/
public static function reciverFiles(): array
{
return [
[
'required' => true,
'code' => 'unv_contract',
'name' => 'Talybyň ýokary okuw mekdebi bilen baglaşan şertnamasy (asyl we göçürme nusgasy)',
],
[
'required' => false,
'code' => 'unv_semester_invoice',
'name' => 'Okuw mekdebinde degişli okuw döwri üçin tölemäge degişli hasap-faktura ýa-da inwoýs (asyl we göçürme nusgasy)',
],
[
'required' => false,
'code' => 'student_card',
'name' => 'Talybyň “Talyplyk şahadatnamasy” (göçürme nusgasy)',
],
[
'required' => false,
'code' => 'document_stating_he_is_studying',
'name' => 'Talybyň daşary ýurt döwletiniň ýokary okuw mekdebinde okaýandygy baradaky güwänamasy',
],
[
'required' => false,
'code' => 'passport_local',
'name' => 'Talyba degişli Türkmenistanyň raýatynyň (içki milli) pasportynyň asyl görnüşi we göçürmesi',
],
[
'required' => false,
'code' => 'passport_international',
'name' => 'Talybyň Türkmenistandan çykmak we Türkmenistana girmek üçin (zagran) pasportynyň (şol sanda 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ň) hem-de ýurda girmek we çykmak baradaky seneli ştampyň bellenen sahypalarynyň) göçürmesi',
],
[
'required' => false,
'code' => 'document_stating_he_is_studying_2',
'name' => 'Goşmaça resminamalar (şol sanda, 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)',
],
];
}
/**
* Sender files
*/
public static function senderFiles(): array
{
return [
[
'required' => true,
'code' => 'passport_local',
'name' => 'Ugradyja degişli Türkmenistanyň raýatynyň (içki milli) pasportynyň asyl görnüşi we göçürmesi ',
],
[
'required' => false,
'code' => 'passport_international',
'name' => 'Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin pasportynyň asyl görnüşi we göçürmesi ',
],
[
'required' => false,
'code' => 'travel_stamp_on_passport',
'name' => 'Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin (zagran) pasportynyň (şol sanda 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ň) hem-de ýurda girmek we çykmak baradaky seneli ştampyň bellenen sahypalarynyň) göçürmesi',
],
[
'required' => false,
'code' => 'proof_of_kinship',
'name' => 'Ugradyjynyň we kabul edijiniň (talybyň) özara garyndaşlyk derejesini tassyklaýjy resminamalarynyň göçürmesi ',
],
[
'required' => false,
'code' => 'passport_local_old',
'name' => '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 maglumaty ',
],
[
'required' => false,
'code' => 'passport_local_old_replacement',
'name' => '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 ',
],
];
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace App\Modules\TuitionPaymentOrder\Nova\Resources\Concerns;
use App\Modules\TuitionPaymentOrder\Nova\Resources\TuitionPaymentOrderFileFields;
use App\Nova\Resources\Branch\Branch;
use App\Repos\Order\OrderRepo;
use App\Repos\System\Settings\Legal\PassportRepo;
use App\Repos\System\Settings\Location\RegionRepo;
use Laravel\Nova\Fields\Badge;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Panel;
use Nurmuhammet\NovaInputmask\NovaInputmask;
use Outl1ne\NovaSimpleRepeatable\SimpleRepeatable;
class TuitionPaymentOrderFieldsForDetail
{
/**
* Get fields for detail view
*
* @return array
*/
public static function make($resource): array
{
return [
new Panel(__('Status'), [
ID::make()
->hideFromDetail(),
Hidden::make('user_id')
->default(auth()->id())
->hideWhenUpdating(),
Text::make(__('ID'), 'unique_id')
->exceptOnForms(),
Select::make(__('Status'), 'status')
->displayUsingLabels()
->searchable()
->options(OrderRepo::statusValues())
->default(OrderRepo::defaultStatus())
->fullWidth()
->hideFromDetail()
->rules('required')
->canSeeWhen('systemUser', $resource),
Badge::make(__('Status'), 'status')
->map(OrderRepo::statusClasses())
->addTypes([
'primary' => 'dark:bg-gray-900 bg-gray-600 text-white',
])
->labels(OrderRepo::statusValues())
->withIcons()
->icons(OrderRepo::statusIcons()),
Text::make(__('Note'), 'notes')
->fullWidth()
->canSeeWhen('systemUser', $resource),
]),
new Panel(__('Location'), [
Select::make(__('Region'), 'region')
->fullWidth()
->displayUsingLabels()
->searchable()
->options(RegionRepo::values())
->default(RegionRepo::default())
->rules('required')
->sortable(),
BelongsTo::make(__('Branch'), 'branch', Branch::class),
]),
new Panel(__('Personal data'), [
Text::make(__('Passport name'), 'passport_name')
->fullWidth()
->rules('required', 'string', 'max:255'),
Text::make(__('Passport surname'), 'passport_surname')
->fullWidth()
->rules('required', 'string', 'max:255'),
NovaInputmask::make(__('Phone'), 'phone')
->fullWidth()
->phonenumber('TM')
->rules('required', 'max:255')
->hideFromIndex(),
Text::make(__('Email'), 'email')
->fullWidth()
->rules('nullable', 'max:255', 'email')
->hideFromIndex(),
Text::make(__('Current Residence'), 'address')
->fullWidth()
->rules('required', 'string', 'max:255')
->hideFromIndex(),
]),
new Panel(__('Payment'), [
SimpleRepeatable::make(__('Payment sender data'), 'sender_datas', [
Select::make(__('Passport serie'), 'passport_serie')
->displayUsingLabels()
->searchable()
->options(PassportRepo::values())
->rules('required')
->sortable(),
NovaInputmask::make(__('Passport number'), 'passport_number')
->mask('999999')
->rules('required', 'max:255'),
Text::make(
name: sprintf('%s %s %s', __('Name'), __('Surname'), __('Patronic name')),
attribute: 'full_name'
)
->rules('required', 'max:255'),
])->minRows(1)->rules('required'),
SimpleRepeatable::make(__('Payee information'), 'payment_reciever', [
Select::make(__('Passport serie'), 'passport_serie')
->displayUsingLabels()
->searchable()
->options(PassportRepo::values())
->rules('required')
->sortable(),
NovaInputmask::make(__('Passport number'), 'passport_number')
->mask('999999')
->rules('required', 'max:255'),
Text::make(
name: sprintf('%s %s %s', __('Name'), __('Surname'), __('Patronic name')),
attribute: 'full_name'
)->rules('required', 'max:255'),
])->maxRows(1)->minRows(1)->rules('required'),
]),
new Panel(__('Reciver files'), TuitionPaymentOrderFileFields::reciverFiles()),
new Panel(__('Sender files'), TuitionPaymentOrderFileFields::senderFiles()),
];
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Modules\TuitionPaymentOrder\Nova\Resources\Concerns;
use App\Nova\Resources\Branch\Branch;
use App\Repos\Order\OrderRepo;
use App\Repos\System\Settings\Location\RegionRepo;
use Laravel\Nova\Fields\Badge;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\DateTime;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
class TuitionPaymentOrderFieldsForIndex
{
/**
* Loan Order fields for "create"
*/
public static function make($resource): array
{
return [
ID::make()->hide(),
Text::make(__('ID'), 'unique_id')->sortable(),
DateTime::make(__('Created at'), 'created_at')
->turkmenDateTime(),
Select::make(__('Region'), 'region')
->displayUsingLabels()
->options(RegionRepo::values())
->canSeeWhen('isAdmin', $resource)
->sortable(),
BelongsTo::make(__('Branch'), 'branch', Branch::class)
->canSeeWhen('isAdmin', $resource)
->filterable()
->sortable(),
Text::make(__('Name'), 'passport_name'),
Text::make(__('Surname'), 'passport_surname'),
Text::make(__('Phone'), 'phone'),
Badge::make(__('Status'), 'status')
->map(OrderRepo::statusClasses())
->addTypes([
'primary' => 'dark:bg-gray-900 bg-gray-600 text-white',
])
->labels(OrderRepo::statusValues())
->withIcons()
->icons(OrderRepo::statusIcons())
->sortable(),
];
}
}

View File

@@ -0,0 +1,247 @@
<?php
namespace App\Modules\TuitionPaymentOrder\Nova\Resources;
use App\Models\Branch\Branch;
use App\Modules\TuitionPaymentOrder\Nova\Resources\Concerns\TuitionPaymentOrderFieldsForDetail;
use App\Modules\TuitionPaymentOrder\Nova\Resources\Concerns\TuitionPaymentOrderFieldsForIndex;
use App\Nova\Resource;
use App\Repos\Order\Card\CardOrderRepo;
use App\Repos\Order\OrderRepo;
use App\Repos\System\Nova\NovaRepo;
use App\Repos\System\Settings\Legal\PassportRepo;
use App\Repos\System\Settings\Location\RegionRepo;
use Eminiarts\Tabs\Tab;
use Eminiarts\Tabs\Tabs;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Laravel\Nova\Fields\Badge;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
use Nurmuhammet\NovaInputmask\NovaInputmask;
use Outl1ne\NovaSimpleRepeatable\SimpleRepeatable;
/**
* @template TModel of \App\Modules\TuitionPaymentOrder\Models\TuitionPaymentOrder
*/
class NovaTuitionPaymentOrder extends Resource
{
/**
* The model the resource corresponds to.
*
* @var class-string<\App\Modules\TuitionPaymentOrder\Models\TuitionPaymentOrder>
*/
public static $model = \App\Modules\TuitionPaymentOrder\Models\TuitionPaymentOrder::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'unique_id';
/**
* The columns that should be searched.
*
* @var array<int, string>
*/
public static $search = [
'unique_id', 'passport_name', 'passport_surname', 'phone',
];
/**
* The relationships that should be eager loaded on index queries.
*
* @var array
*/
public static $with = ['branch'];
/**
* Get the displayable label of the resource.
*/
public static function label(): string
{
return sprintf(
'%s (%s)',
__('Tuition payments'),
Str::lower(__('For students'))
);
}
/**
* Get the displayable singular label of the resource.
*/
public static function singularLabel(): string
{
return sprintf(
'%s (%s)',
__('Tuition payment'),
Str::lower(__('For students'))
);
}
/**
* After resource created
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Model $model
*/
public static function afterCreate(NovaRequest $request, Model $model): void
{
$model->update(['unique_id' => CardOrderRepo::fillUniqueId($model)]);
}
/**
* Get the fields for index.
*/
public function fieldsForIndex(): array
{
return TuitionPaymentOrderFieldsForIndex::make($this);
}
/**
* Get the fields for detail
*/
public function fieldsForDetail(): array
{
return TuitionPaymentOrderFieldsForDetail::make($this);
}
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array<int, \Laravel\Nova\Fields\FieldElement|\Laravel\Nova\Panel>
*/
public function fields(NovaRequest $request): array
{
return [
Tabs::make('Wizard', [
new Tab(__('Status'), [
ID::make()
->hideFromDetail(),
Hidden::make('user_id')
->default(auth()->id())
->hideWhenUpdating(),
Text::make(__('ID'), 'unique_id')
->exceptOnForms(),
Select::make(__('Status'), 'status')
->displayUsingLabels()
->searchable()
->options(OrderRepo::statusValues())
->default(OrderRepo::defaultStatus())
->fullWidth()
->hideFromDetail()
->rules('required')
->canSeeWhen('systemUser', $this),
Badge::make(__('Status'), 'status')
->map(OrderRepo::statusClasses())
->addTypes([
'primary' => 'dark:bg-gray-900 bg-gray-600 text-white',
])
->labels(OrderRepo::statusValues())
->withIcons()
->icons(OrderRepo::statusIcons()),
Text::make(__('Note'), 'notes')
->fullWidth()
->canSeeWhen('systemUser', $this),
]),
new Tab(__('Location'), [
Select::make(__('Region'), 'region')
->fullWidth()
->displayUsingLabels()
->searchable()
->options(RegionRepo::values())
->default(RegionRepo::default())
->rules('required')
->sortable(),
Select::make(__('Branch'), 'branch_id')
->fullWidth()
->displayUsingLabels()
->searchable()
->dependsOn('region', NovaRepo::dependsOnRegion('region', Branch::class))
->rules('required')
->sortable(),
]),
new Tab(__('Personal data'), [
Text::make(__('Passport name'), 'passport_name')
->fullWidth()
->rules('required', 'string', 'max:255'),
Text::make(__('Passport surname'), 'passport_surname')
->fullWidth()
->rules('required', 'string', 'max:255'),
NovaInputmask::make(__('Phone'), 'phone')
->fullWidth()
->phonenumber('TM')
->rules('required', 'max:255')
->hideFromIndex(),
Text::make(__('Email'), 'email')
->fullWidth()
->rules('nullable', 'max:255', 'email')
->hideFromIndex(),
Text::make(__('Current Residence'), 'address')
->fullWidth()
->rules('required', 'string', 'max:255')
->hideFromIndex(),
]),
new Tab(__('Payment'), [
SimpleRepeatable::make(__('Payment sender data'), 'sender_datas', [
Select::make(__('Passport serie'), 'passport_serie')
->displayUsingLabels()
->searchable()
->options(PassportRepo::values())
->rules('required')
->sortable(),
NovaInputmask::make(__('Passport number'), 'passport_number')
->mask('999999')
->rules('required', 'max:255'),
Text::make(
name: sprintf('%s %s %s', __('Name'), __('Surname'), __('Patronic name')),
attribute: 'full_name'
)
->rules('required', 'max:255'),
])->minRows(1)->rules('required'),
SimpleRepeatable::make(__('Payee information'), 'payment_reciever', [
Select::make(__('Passport serie'), 'passport_serie')
->displayUsingLabels()
->searchable()
->options(PassportRepo::values())
->rules('required')
->sortable(),
NovaInputmask::make(__('Passport number'), 'passport_number')
->mask('999999')
->rules('required', 'max:255'),
Text::make(
name: sprintf('%s %s %s', __('Name'), __('Surname'), __('Patronic name')),
attribute: 'full_name'
)->rules('required', 'max:255'),
])->maxRows(1)->minRows(1)->rules('required'),
]),
new Tab(__('Reciver files'), TuitionPaymentOrderFileFields::reciverFiles()),
new Tab(__('Sender files'), TuitionPaymentOrderFileFields::senderFiles()),
], $request)->asWizard(),
];
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Modules\TuitionPaymentOrder\Nova\Resources;
use App\Modules\TuitionPaymentOrder\Models\TuitionPaymentOrder;
use Ebess\AdvancedNovaMediaLibrary\Fields\Files;
use Laravel\Nova\Fields\File;
use Laravel\Nova\Http\Requests\NovaRequest;
class TuitionPaymentOrderFileFields
{
/**
* Reciver files
*/
public static function reciverFiles(): array
{
return collect(TuitionPaymentOrder::reciverFiles())
->map(function (array $file) {
return File::make(__($file['name']), $file['code'])
->fullWidth()
->deletable(false)
->creationRules($file['required'] ? 'required' : 'nullable')
->updateRules('nullable')
->store(function (NovaRequest $request, $model) use ($file) {
return function () use ($model, $file) {
$model->addMediaFromRequest($file['code'])
->preservingOriginal()
->toMediaCollection($file['code']);
};
})
->preview(function ($value, $disk, $resource) use ($file) {
return $resource->getFirstMediaUrl($file['code']);
});
})
->toArray();
}
/**
* Sender files
*/
public static function senderFiles(): array
{
return collect(TuitionPaymentOrder::senderFiles())
->map(function (array $file) {
return File::make(__($file['name']), $file['code'])
->fullWidth()
->deletable(false)
->creationRules($file['required'] ? 'required' : 'nullable')
->updateRules('nullable')
->store(function (NovaRequest $request, $model) use ($file) {
return function () use ($model, $file) {
$model->addMediaFromRequest($file['code'])
->preservingOriginal()
->toMediaCollection($file['code']);
};
})
->preview(function ($value, $disk, $resource) use ($file) {
return $resource->getFirstMediaUrl($file['code']);
});
})
->toArray();
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Repos\System\Nova;
use App\Modules\SberPaymentOrder\Nova\Resources\NovaSberPaymentOrder;
use App\Modules\TuitionPaymentOrder\Nova\Resources\NovaTuitionPaymentOrder;
use App\Modules\VisaMasterPaymentOrder\Nova\Resources\NovaVisaMasterPaymentOrder;
use App\Nova\Dashboards\Main;
use App\Nova\Resources\Branch\Branch;
@@ -53,6 +54,7 @@ class NovaMenuRepo
MenuGroup::make(__('International payments'), [
MenuItem::resource(NovaVisaMasterPaymentOrder::class),
MenuItem::resource(NovaSberPaymentOrder::class),
MenuItem::resource(NovaTuitionPaymentOrder::class),
])->collapsedByDefault(),
])->icon('ticket')->collapsedByDefault(),