diff --git a/app/Http/Controllers/Api/LoanPaidOffLetterOrder/Requests/LoanPaidOffLetterOrderStoreRequest.php b/app/Http/Controllers/Api/LoanPaidOffLetterOrder/Requests/LoanPaidOffLetterOrderStoreRequest.php new file mode 100644 index 0000000..f48d7b2 --- /dev/null +++ b/app/Http/Controllers/Api/LoanPaidOffLetterOrder/Requests/LoanPaidOffLetterOrderStoreRequest.php @@ -0,0 +1,106 @@ +|string> + */ + public function rules(): array + { + return [ + /** + * Region (https://online.tbbank.gov.tm/api/base-app-enums) + */ + 'region' => ['required', 'string', Rule::in(array_keys(RegionRepo::values()))], + + /** + * Branch id (https://online.tbbank.gov.tm/api/branches) + */ + 'branch_id' => ['required', 'integer', Rule::exists('branches', 'id')], + + /** + * Customer name + * + * @example Mahmyt + */ + 'customer_name' => ['required', 'string', 'max:255'], + + /** + * Customer surname + * + * @example Allaberdiyev + */ + 'customer_surname' => ['required', 'string', 'max:255'], + + /** + * Customer patronic name + * + * @example Öwezowiç + */ + 'customer_patronic_name' => ['nullable', 'string', 'max:255'], + + /** + * Passport serie + */ + 'passport_serie' => ['required', 'string', Rule::in(PassportRepo::values())], + + /** + * Passport number + * + * @example 100999 + */ + 'passport_id' => ['required', 'numeric', 'digits:6'], + + /** + * Date of birth + * + * @example 2000 + */ + 'born_at' => ['required', 'before_or_equal:today'], + + /** + * Phone number + * + * @example 65999990 + */ + 'phone' => ['required', 'integer', 'between:61000000, 71999999'], + + /** + * Contract number + * + * @example 3242358989234 + */ + 'loan_contract_number' => ['required', 'string', 'max:255'], + + /** + * Contract date + * + * @example 20.34.23 + */ + 'loan_contract_date' => ['required', 'string', 'max:255'], + + /** + * Loan amount + * + * @example 20000 + */ + 'loan_amount' => ['required', 'string', 'max:255'], + + /** + * Loan reason + * + * @example Puldan pul yasamak ucin + */ + 'loan_reason' => ['required', 'string', 'max:255'], + ]; + } +} diff --git a/app/Http/Controllers/Api/LoanPaidOffLetterOrder/Resources/LoanPaidOffLetterOrderIndexResource.php b/app/Http/Controllers/Api/LoanPaidOffLetterOrder/Resources/LoanPaidOffLetterOrderIndexResource.php new file mode 100644 index 0000000..1150ca5 --- /dev/null +++ b/app/Http/Controllers/Api/LoanPaidOffLetterOrder/Resources/LoanPaidOffLetterOrderIndexResource.php @@ -0,0 +1,53 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'unique_id' => $this->unique_id, + 'user_id' => $this->user_id, + + 'region' => RegionRepo::label($this->region), + 'branch_id' => $this->branch?->name, + + 'customer_name' => $this->customer_name, + 'customer_surname' => $this->customer_surname, + 'customer_patronic_name' => $this->customer_patronic_name, + + 'born_at' => $this->born_at, + 'phone' => $this->phone, + 'passport_serie' => $this->passport_serie, + 'passport_id' => $this->passport_id, + + 'status' => OrderRepo::statusFormatted($this->status), + + 'notes' => $this->notes, + + 'loan_contract_number' => $this->loan_contract_number, + 'loan_contract_date' => $this->loan_contract_date, + + 'loan_amount' => $this->loan_amount, + 'loan_reason' => $this->loan_reason, + + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]; + } +} diff --git a/app/Http/Controllers/Api/LoanPaidOffLetterOrderController.php b/app/Http/Controllers/Api/LoanPaidOffLetterOrderController.php new file mode 100644 index 0000000..4a5a542 --- /dev/null +++ b/app/Http/Controllers/Api/LoanPaidOffLetterOrderController.php @@ -0,0 +1,47 @@ +json(LoanPaidOffLetterOrderIndexResource::collection( + LoanPaidOffLetterOrder::query() + ->with('branch') + ->where('user_id', auth()->id()) + ->paginate() + )); + } + + /** + * SAVE* Loan order. + */ + public function store(LoanPaidOffLetterOrderStoreRequest $request): JsonResponse + { + Log::channel('form_logs')->info('loan-order-store-request', $request->all()); + + $data = $request->validated(); + LoanPaidOffLetterOrder::forceCreate([ + ...$data, + ...[ + 'user_id' => auth()->id(), + 'status' => OrderRepo::PENDING, + 'source' => OrderRepo::MOBILE_DEVICE, + ], + ]); + + return response()->json(); + } +} diff --git a/app/Models/Order/Loan/LoanPaidOffLetterOrder.php b/app/Models/Order/Loan/LoanPaidOffLetterOrder.php index 5f84424..7622bbb 100644 --- a/app/Models/Order/Loan/LoanPaidOffLetterOrder.php +++ b/app/Models/Order/Loan/LoanPaidOffLetterOrder.php @@ -10,6 +10,29 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; use Laravel\Nova\Actions\Actionable; +/** + * @property int $id + * @property null|string $unique_id + * @property string $region + * @property int $branch_id + * @property string $customer_name + * @property string $customer_surname + * @property null|string $customer_patronic_name + * @property null|string $born_at + * @property null|string $phone + * @property string $passport_serie + * @property string $passport_id + * @property null|string $status + * @property null|string $notes + * @property int $user_id + * @property null|string $loan_contract_number + * @property null|string $loan_contract_date + * @property null|string $loan_amount + * @property null|string $loan_reason + * @property \Illuminate\Support\Carbon $created_at + * @property \Illuminate\Support\Carbon $updated_at + * @property \Illuminate\Support\Carbon $deleted_at + */ class LoanPaidOffLetterOrder extends Model { use Actionable; diff --git a/app/Nova/Actions/MakePaymentNovaVisaMaster.php b/app/Nova/Actions/MakePaymentNovaVisaMaster.php index 57ed33b..d1be36f 100644 --- a/app/Nova/Actions/MakePaymentNovaVisaMaster.php +++ b/app/Nova/Actions/MakePaymentNovaVisaMaster.php @@ -89,7 +89,6 @@ class MakePaymentNovaVisaMaster extends Action } $total_amount = floatval(number_format($payment_amount, 2, '.', '')) + 23; - $total_amount = 0.10; $payment = $this->order($resource, $total_amount); diff --git a/app/Nova/Resources/Order/Card/CardOrder.php b/app/Nova/Resources/Order/Card/CardOrder.php index f41c027..c423c04 100644 --- a/app/Nova/Resources/Order/Card/CardOrder.php +++ b/app/Nova/Resources/Order/Card/CardOrder.php @@ -23,7 +23,10 @@ use App\Rules\DowranAgaAllowed; use App\Rules\OnlyLetters; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Gate; +use Laravel\Nova\Actions\Action; +use Laravel\Nova\Fields\ActionFields; use Laravel\Nova\Fields\Date; use Laravel\Nova\Fields\Hidden; use Laravel\Nova\Fields\ID; @@ -377,4 +380,26 @@ class CardOrder extends Resource new StatusFilter, ]; } + + /** + * Actions + * + * @return array + */ + public function actions(NovaRequest $request): array + { + return [ + Action::using('Deactivate User', function (ActionFields $fields, Collection $models) { + $resource = $models->first(); + + $payment = (new OnlinePaymentRepo)->payCardOrder($resource); + + return $payment['status'] === 'success' + ? URL::remote($payment['url']) + : sprintf('resources/%s/%s', static::uriKey(), $resource->getKey()); + }) + ->icon('credit-card') + ->sole(), + ]; + } } diff --git a/database/migrations/2025_03_25_182704_add_source_to_loan_paid_off_letter_orders_table.php b/database/migrations/2025_03_25_182704_add_source_to_loan_paid_off_letter_orders_table.php new file mode 100644 index 0000000..998382a --- /dev/null +++ b/database/migrations/2025_03_25_182704_add_source_to_loan_paid_off_letter_orders_table.php @@ -0,0 +1,28 @@ +string('loan_paid_off_letter_orders')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('loan_paid_off_letter_orders', function (Blueprint $table) { + $table->dropColumn('loan_paid_off_letter_orders'); + }); + } +}; diff --git a/migrate.md b/migrate.md index b210586..77ce358 100644 --- a/migrate.md +++ b/migrate.md @@ -5,9 +5,9 @@ **completed** **cancelled** -Schema::getColumnListing('branches') +Schema::getColumnListing('loan_paid_off_letter_orders') -$a = collect(Schema::getColumns('users'))->map(fn ($column) => [ +$a = collect(Schema::getColumns('loan_paid_off_letter_orders'))->map(fn ($column) => [ 'name' => $column['name'], 'type' => ($column['nullable'] ? 'null|' : '') . dbTypeToPhp($column['type']), ])->pluck('type', 'name') diff --git a/routes/api.php b/routes/api.php index f4679ee..c027ea8 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,6 +2,7 @@ use App\Http\Controllers\AlertController; use App\Http\Controllers\Api\FetchLoanHistoryController; +use App\Http\Controllers\Api\LoanPaidOffLetterOrderController; use App\Http\Controllers\FetchCardHistoryController; use App\Http\Controllers\FetchLoanRemainingController; use App\Http\Controllers\MetricsController; @@ -73,6 +74,13 @@ Route::middleware(['auth:sanctum', 'not_banned'])->group(function () { // Loan remaning... Route::get('loan-remaining', [LoanRemainingOrderController::class, 'index']); + // Loan paid off letters... + Route::get('loan-paid-off-letter-orders', [LoanPaidOffLetterOrderController::class, 'index']); + Route::get('loan-paid-off-letter-orders/{order}', [LoanPaidOffLetterOrderController::class, 'show']); + Route::post('loan-paid-off-letter-orders', [LoanPaidOffLetterOrderController::class, 'store']); + Route::post('loan-paid-off-letter-orders/{order}', [LoanPaidOffLetterOrderController::class, 'update']); + Route::delete('loan-paid-off-letter-orders/{order}', [LoanPaidOffLetterOrderController::class, 'destory']); + // Alerts... Route::get('alerts', [AlertController::class, 'index']); });