This commit is contained in:
2025-05-24 14:27:43 +05:00
parent ebded8c39d
commit 778bd9030c
11 changed files with 386 additions and 212 deletions

View File

@@ -2,51 +2,25 @@
namespace App\Http\Controllers;
use App\Repos\System\Settings\Legal\PassportRepo;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
class ApiTesterController extends Controller
{
public function index(Request $request)
{
$data = $request->validate([
'passport_serie' => 'I-AH',
'passport_number' => '152304',
'card_number_masked' => '993403******8088',
'card_expire_date' => '02/34',
$request->validate([
'passport_serie' => ['required', 'string', Rule::in(PassportRepo::values())],
'passport_number' => ['required', 'numeric', 'digits:6'],
'card_number_masked' => ['required', 'string', 'max:255'],
'card_expire_date' => ['required', 'string', 'max:255'],
'start_date' => ['required', 'date'],
'end_date' => ['required', 'date'],
]);
return $data;
// $this->fetchApi($data['foo']);
// return "<pre>{$response}</pre>";
}
public function fetchApi(
string $passport_serie,
string $passport_number,
string $card_number_masked,
string $card_expire_date
) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'http://10.3.158.102:9999/api/clientinfo/all',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => sprintf('{ "idSeria": "%s", "idNo": "%s", "clientType": "recipient", "cardMaskNumber": "%s", "expDate": "%s", "fromDate" : "01.01.2020", "toDate" : "09.05.2025" }', $passport_serie, $passport_number, $card_number_masked, $card_expire_date),
CURLOPT_HTTPHEADER => [
'Authorization: Basic dGJ1c2VyOlFBWndzeDEyMw==',
'Content-Type: application/json',
],
]);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}

View File

@@ -4,16 +4,22 @@ namespace App\Models\Order\Card\CardTransaction;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Nova\Actions\Actionable;
/**
* @property int $id
* @property string $passport_serie
* @property string $passport_number
* @property string $card_number_masked
* @property string $card_expire_date
* @property string $passport_id
* @property string $card_number
* @property string $card_month
* @property string $card_year
* @property \Illuminate\Support\Carbon $created_at
* @property \Illuminate\Support\Carbon $updated_at
*/
class CardTransaction extends Model
{
use Actionable;
use HasFactory;
use SoftDeletes;
}

View File

@@ -20,6 +20,24 @@ class DateHelperRepository
return $month;
}
public static function staticNumberMonths(): array
{
return [
'01' => '01',
'02' => '02',
'03' => '03',
'04' => '04',
'05' => '05',
'06' => '06',
'07' => '07',
'08' => '08',
'09' => '09',
'10' => '10',
'11' => '11',
'12' => '12',
];
}
/**
* Years until
*
@@ -39,4 +57,77 @@ class DateHelperRepository
return $years;
}
public static function staticNumberYears(): array
{
return [
'2024' => '2024',
'2025' => '2025',
'2026' => '2026',
'2027' => '2027',
'2028' => '2028',
'2029' => '2029',
'2030' => '2030',
'2031' => '2031',
'2032' => '2032',
'2033' => '2033',
'2034' => '2034',
'2035' => '2035',
'2036' => '2036',
'2037' => '2037',
'2038' => '2038',
'2039' => '2039',
'2040' => '2040',
'2041' => '2041',
'2042' => '2042',
'2043' => '2043',
'2044' => '2044',
'2045' => '2045',
'2046' => '2046',
'2047' => '2047',
'2048' => '2048',
'2049' => '2049',
'2050' => '2050',
'2051' => '2051',
'2052' => '2052',
'2053' => '2053',
'2054' => '2054',
'2055' => '2055',
'2056' => '2056',
'2057' => '2057',
'2058' => '2058',
'2059' => '2059',
'2060' => '2060',
'2061' => '2061',
'2062' => '2062',
'2063' => '2063',
'2064' => '2064',
'2065' => '2065',
'2066' => '2066',
'2067' => '2067',
'2068' => '2068',
'2069' => '2069',
'2070' => '2070',
'2071' => '2071',
'2072' => '2072',
'2073' => '2073',
'2074' => '2074',
'2075' => '2075',
'2076' => '2076',
'2077' => '2077',
'2078' => '2078',
'2079' => '2079',
'2080' => '2080',
'2081' => '2081',
'2082' => '2082',
'2083' => '2083',
'2084' => '2084',
'2085' => '2085',
'2086' => '2086',
'2087' => '2087',
'2088' => '2088',
'2089' => '2089',
'2090' => '2090',
];
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace App\Nova\Resources\Order\Card\CardTransaction\Actions;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Http\Requests\NovaRequest;
class DownloadCardTransaction extends Action
{
use InteractsWithQueue, Queueable;
/**
* Name.
*/
public function name(): string
{
return __('Download');
}
/**
* Perform the action on the given models.
*
* @param \Laravel\Nova\Fields\ActionFields $fields
* @param \Illuminate\Support\Collection $models
* @return mixed
*/
public function handle(ActionFields $fields, Collection $models)
{
/** @var \App\Models\Order\Card\CardTransaction\CardTransaction */
$model = $models->first();
$start_date = Carbon::create($fields['start_date']);
$end_date = Carbon::create($fields['end_date']);
$response = $this->fetchApi(
passport_serie: $model->passport_serie,
passport_id: $model->passport_id,
card_number_masked: Str::mask($model->card_number, '*', 6, 6),
card_expire_date: $model->card_month .'/'. substr($model->card_year, 2),
start_date: $start_date->format('d.m.Y'),
end_date: $end_date->format('d.m.Y'),
);
info($response);
}
/**
* Get the fields available on the action.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request): array
{
return [
Date::make(__('Start date'), 'start_date')
->default(date('Y-m-d', strtotime('-6 months')))
->rules('required'),
Date::make(__('End date'), 'end_date')
->default(date('Y-m-d'))
->rules('required'),
];
}
public function fetchApi(
string $passport_serie,
string $passport_id,
string $card_number_masked,
string $card_expire_date,
string $start_date,
string $end_date
) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'http://10.3.158.102:9999/api/clientinfo/all',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => sprintf('{ "idSeria": "%s", "idNo": "%s", "clientType": "recipient", "cardMaskNumber": "%s", "expDate": "%s", "fromDate" : "%s", "toDate" : "%s" }', $passport_serie, $passport_id, $card_number_masked, $card_expire_date, $start_date, $end_date),
CURLOPT_HTTPHEADER => [
'Authorization: Basic dGJ1c2VyOlFBWndzeDEyMw==',
'Content-Type: application/json',
],
]);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace App\Nova\Resources\Order\Card\CardTransaction;
use App\Modules\DateHelper\Repositories\DateHelperRepository;
use App\Nova\Resource;
use App\Nova\Resources\Order\Card\CardTransaction\Actions\DownloadCardTransaction;
use App\Repos\System\Settings\Legal\PassportRepo;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
use Nurmuhammet\NovaInputmask\NovaInputmask;
class CardTransaction extends Resource
{
/**
* The model the resource corresponds to.
*
* @var class-string<\App\Models\Order\Card\CardTransaction\CardTransaction>
*/
public static $model = \App\Models\Order\Card\CardTransaction\CardTransaction::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
*/
public static $search = [
'unique_id',
];
/**
* Get the displayable label of the resource.
*/
public static function label(): string
{
return __('Card transactions');
}
/**
* Get the displayable singular label of the resource.
*/
public static function singularLabel(): string
{
return __('Card transaction');
}
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request): array
{
return [
ID::make()->sortable(),
Hidden::make('user_id')
->default(auth()->id())
->hideWhenUpdating(),
Select::make(__('Passport serie'), 'passport_serie')
->displayUsingLabels()
->searchable()
->options(PassportRepo::values())
->size('w-1/2')
->rules('required'),
NovaInputmask::make(__('Passport id'), 'passport_id')
->mask('999999')
->size('w-1/2')
->rules('required', 'numeric', 'digits:6'),
NovaInputmask::make(__('Card number'), 'card_number')
->mask('9999-9999-9999-9999')
->storeRawValue()
->size('md:w-1/2')
->rules('required', 'digits:16'),
Select::make(__('Card').' '.__('Expiration month'), 'card_month')
->searchable()
->options(DateHelperRepository::staticNumberMonths())
->size('md:w-1/4')
->rules('required'),
Select::make(__('Card').' '.__('Expiration year'), 'card_year')
->searchable()
->options(DateHelperRepository::staticNumberYears())
->size('md:w-1/4')
->rules('required'),
];
}
/**
* Get the cards available for the request.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function cards(NovaRequest $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function filters(NovaRequest $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function lenses(NovaRequest $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
DownloadCardTransaction::make()
->icon('arrow-down-tray')
->sole(),
];
}
}

View File

@@ -11,6 +11,7 @@ use App\Nova\Resources\CurrencyRate;
use App\Nova\Resources\NovaVisaMasterSetting;
use App\Nova\Resources\Order\Card\CardOrder;
use App\Nova\Resources\Order\Card\CardState;
use App\Nova\Resources\Order\Card\CardTransaction\CardTransaction;
use App\Nova\Resources\Order\Card\CardType;
use App\Nova\Resources\Order\Card\Pin\CardPin;
use App\Nova\Resources\Order\Card\Requisite\CardRequisite;
@@ -58,6 +59,7 @@ class NovaMenuRepo
MenuItem::resource(CardOrder::class)->name(__('Order new card')),
MenuItem::resource(CardRequisite::class),
MenuItem::resource(CardPin::class),
MenuItem::resource(CardTransaction::class),
])->collapsedByDefault(),
MenuGroup::make(__('International payments'), [

View File

@@ -13,11 +13,18 @@ return new class extends Migration
{
Schema::create('card_transactions', function (Blueprint $table) {
$table->id();
$table->string('unique_id')->nullable()->unique();
$table->string('passport_serie');
$table->string('passport_number');
$table->string('card_number_masked');
$table->string('card_expire_date');
$table->string('passport_id');
$table->string('card_number');
$table->string('card_month');
$table->string('card_year');
$table->foreignId('user_id')->constrained('users')->restrictOnDelete();
$table->timestamps();
$table->softDeletes();
});
}

View File

@@ -342,5 +342,7 @@
"Settings": "Sazlamalar",
"Loan order created": "Karz sargydy döredildi",
"Loan order updated": "Karz sargydy üýtgedildi",
"Loan order deleted": "Karz sargydy pozuldy"
"Loan order deleted": "Karz sargydy pozuldy",
"Card transaction": "Kart herekedi",
"Card transactions": "Kart hereketleri"
}

View File

@@ -42,3 +42,9 @@ button[dusk="create-and-add-another-button"] {
.o1-table thead tr th:first-child {
padding-left: 5px;
}
@media (min-width: 768px) {
.md\:w-1\/2 {
width: 50%;
}
}

View File

@@ -166,172 +166,3 @@ async function fetchCardHistory(passport_serie, passport_id, card_number, card_e
Nova.$progress.done()
});
}
// window.LaravelNovaWizardStore = {
// data: {
// steps: 0,
// currentStep: 1,
// },
// fields: {
// buttonsContainerElement: {},
// cancelFormButton: {},
// createFormButton: {},
// prevButtonElement: {},
// nextButtonElement: {},
// },
// nextStep() {
// if (this.data.steps > 0 && this.data.currentStep < this.data.steps) {
// document.querySelector(`div[wizard-step="${this.data.currentStep}"]`).style.display = 'none';
// this.data.currentStep++;
// document.querySelector(`div[wizard-step="${this.data.currentStep}"]`).style.display = 'inherit';
// return;
// }
// if (this.data.currentStep === this.data.steps) {
// this.hideNextButton()
// this.showFormSubmitButton()
// } else {
// this.hideFormSubmitButton()
// this.showNextButton()
// }
// },
// prevStep() {
// if (this.data.currentStep > 1) {
// document.querySelector(`div[wizard-step="${this.data.currentStep}"]`).style.display = 'none';
// this.data.currentStep--;
// document.querySelector(`div[wizard-step="${this.data.currentStep}"]`).style.display = 'inherit';
// }
// },
// hideNovaFormButtons() {
// this.fields.cancelFormButton = document.querySelector('button[dusk="cancel-create-button"]');
// this.fields.createFormButton = document.querySelector('button[dusk="create-button"]');
// this.fields.buttonsContainerElement = this.fields.createFormButton.parentNode;
// this.hideFormSubmitButton();
// this.hideFormCancelButton();
// },
// addWizardButtons() {
// this.fields.buttonsContainerElement.insertAdjacentHTML('afterbegin', this.nextButtonTemplate());
// this.fields.buttonsContainerElement.insertAdjacentHTML('afterbegin', this.prevButtonTemplate());
// this.fields.nextButtonElement = document.getElementById('laravel-nova-wizard-next-button');
// this.fields.prevButtonElement = document.getElementById('laravel-nova-wizard-prev-button');
// this.fields.nextButtonElement.addEventListener('click', () => {
// this.nextStep()
// })
// this.fields.prevButtonElement.addEventListener('click', () => {
// this.prevStep()
// })
// },
// nextButtonTemplate() {
// return `
// <button type="button" id="laravel-nova-wizard-next-button" class="border text-left appearance-none cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring ring-primary-200 dark:ring-gray-600 relative disabled:cursor-not-allowed inline-flex items-center justify-center shadow h-9 px-3 bg-primary-500 border-primary-500 hover:[&amp;:not(:disabled)]:bg-primary-400 hover:[&amp;:not(:disabled)]:border-primary-400 text-white dark:text-gray-900">
// <span class="flex items-center gap-1">Next</span>
// </button>
// `;
// },
// prevButtonTemplate() {
// return `
// <button type="button" id="laravel-nova-wizard-prev-button" class="border text-left appearance-none cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring ring-primary-200 dark:ring-gray-600 relative disabled:cursor-not-allowed inline-flex items-center justify-center shadow h-9 px-3 bg-red-500 border-red-500 hover:[&amp;:not(:disabled)]:border-primary-400 text-white dark:text-gray-900">
// <span class="flex items-center gap-1">Previus</span>
// </button>
// `;
// },
// hidePrevButton() {
// this.fields.prevButtonElement.style.display = 'none'
// },
// showPrevButton() {
// this.fields.prevButtonElement.style.display = 'inherit'
// },
// hideNextButton() {
// this.fields.nextButtonElement.style.display = 'none'
// },
// showNextButton() {
// this.fields.nextButtonElement.style.display = 'inherit'
// },
// showFormSubmitButton() {
// this.fields.createFormButton.style.display = 'inherit';
// },
// hideFormSubmitButton() {
// this.fields.createFormButton.style.display = 'none';
// },
// hideFormCancelButton() {
// this.fields.cancelFormButton.style.display = 'none';
// }
// };
// function setupMultiStepWizard() {
// let refreshIntervalId = setInterval(() => {
// let formElement = document.querySelector('form');
// if (formElement) {
// clearInterval(refreshIntervalId)
// // Div container
// let fieldsContainerElement = formElement.firstChild;
// // Div elements
// let fieldElements = Array.from(fieldsContainerElement.children);
// // if there a less than 2 divs, no need to wizard it!
// if (fieldElements.length < 2) {
// return;
// }
// LaravelNovaWizardStore.data.steps = fieldElements.length;
// LaravelNovaWizardStore.hideNovaFormButtons()
// LaravelNovaWizardStore.addWizardButtons()
// let loopCount = 0;
// fieldElements.forEach(item => {
// loopCount++;
// item.setAttribute('wizard-step', loopCount)
// if (loopCount === 1) {
// return;
// }
// item.style.display = 'none'
// })
// }
// }, 300);
// }
// Nova.$on('liftedOff', () => {
// if (Nova.$router.page.component === 'Nova.Create') {
// setupMultiStepWizard()
// }
// })
// Nova.$router.on('success', (event) => {
// if (event.detail.page.component === 'Nova.Create') {
// setupMultiStepWizard()
// }
// })
// document.addEventListener('inertia:navigate', () => {
// console.log('page is updating')
// })
// // when app is booting
// Nova.booting((app, store) => {})