Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use periodic events for KKT/Netreg #646

Open
wants to merge 3 commits into
base: decouple-periodic-events
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions app/Http/Controllers/Network/AdminInternetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ public function index(): View
{
$this->authorize('handleAny', InternetAccess::class);

return view('network.admin.app', [
'activation_date' => InternetAccess::getInternetDeadline()->format('Y-m-d H:i'),
]);
return view('network.admin.app');
}

/**
Expand All @@ -46,7 +44,7 @@ public function indexInternetAccesses(): LengthAwarePaginator
->select('internet_accesses.*')
->with('user')
)
->sortable(['auto_approved_mac_slots', 'has_internet_until', 'user.name'])
->sortable(['auto_approved_mac_slots', 'has_internet_until', 'user.name', 'netreg_paid'])
->filterable(['auto_approved_mac_slots', 'has_internet_until', 'user.name'])
->paginate();

Expand Down Expand Up @@ -84,10 +82,10 @@ public function extend(Request $request, InternetAccess $internetAccess): Carbon
$this->authorize('extend', $internetAccess);

$request->validate([
'has_internet_until' => 'nullable|date',
'has_internet_until' => 'date',
]);

return $internetAccess->extendInternetAccess($request->get('has_internet_until'));
return $internetAccess->extendInternetAccess(Carbon::parse($request->get('has_internet_until')));
}

/**
Expand Down
62 changes: 48 additions & 14 deletions app/Http/Controllers/StudentsCouncil/EconomicController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,39 @@

namespace App\Http\Controllers\StudentsCouncil;

use App\Events\KKTNetregPeriodStart;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Network\InternetController;
use App\Models\Checkout;
use App\Models\Internet\InternetAccess;
use App\Models\PaymentType;
use App\Models\PeriodicEvent;
use App\Models\Role;
use App\Models\RoleObject;
use App\Models\Semester;
use App\Models\Transaction;
use App\Models\User;
use App\Models\WorkshopBalance;
use App\Utils\CheckoutHandler;
use App\Utils\PeriodicEventController;
use Carbon\Carbon;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;

class EconomicController extends Controller
class EconomicController extends PeriodicEventController
{
use CheckoutHandler;

public function __construct()
{
parent::__construct(PeriodicEvent::KKT_NETREG_PAYMENT_PERIOD);
}

/**
* Return the route base for the checkout of the students council.
*/
Expand All @@ -32,6 +43,35 @@ public static function routeBase(): string
return 'economic_committee';
}

/**
* Update the PeriodicEvent for the payments.
*
* @param Request $request
* @return RedirectResponse
* @throws AuthorizationException
*/
public function updatePaymentPeriod(Request $request): RedirectResponse
{
$this->authorize('administrate', Checkout::studentsCouncil());
if($this->periodicEvent()) {
throw new \Exception('Már meglévő periódus módosítása nem lehetséges.');
}

$request->validate([
'semester_id' => 'required|exists:semesters,id',
'end_date' => 'required|date|after:now'
]);

$semester = Semester::find($request->semester_id);
$startDate = Carbon::parse(now());
$endDate = Carbon::parse($request->end_date);

$this->updatePeriodicEvent($semester, $startDate, $endDate);
InternetAccess::resetInternetAccessPeriod($endDate);

return back()->with('message', __('general.successful_modification'));
}

/**
* Return the checkout of the students council.
*/
Expand All @@ -51,7 +91,9 @@ public function index()
return view(
'student-council.economic-committee.app',
array_merge($this->getData($this->checkout()), [
'users_not_paid' => User::hasToPayKKTNetreg()->get()
'users_not_paid' => User::hasToPayKKTNetreg()->get(),
'periodicEvent' => $this->periodicEvent(),
'isPaymentPeriod' => $this->isActive()
])
);
}
Expand Down Expand Up @@ -107,9 +149,9 @@ public static function payKKTNetregLogic(User $payer, User $receiver, int $kkt_a

WorkshopBalance::generateBalances(Semester::current());

$new_expiry_date = $payer->internetAccess->extendInternetAccess();
$payer->internetAccess->update(['netreg_paid' => true, 'has_internet_until' => null]);

return [$kkt, $netreg, $new_expiry_date];
return [$kkt, $netreg];
}

/**
Expand All @@ -128,21 +170,13 @@ public function payKKTNetreg(Request $request)

$payer = User::findOrFail($request->user_id);
// the current user will be the receiver
[$kkt, $netreg, $new_internet_expire_date]
= self::payKKTNetregLogic($payer, Auth::user(), $request->kkt, $request->netreg);

$internet_expiration_message = null;
if ($new_internet_expire_date !== null) {
$internet_expiration_message = __('internet.expiration_extended', [
'new_date' => Carbon::parse($new_internet_expire_date)->format('Y-m-d'),
]);
}
[$kkt, $netreg] = self::payKKTNetregLogic($payer, Auth::user(), $request->kkt, $request->netreg);

Mail::to($payer)->queue(new \App\Mail\Transactions(
$payer->name,
[$kkt, $netreg],
"Tranzakció létrehozva",
$internet_expiration_message
"Az internet hozzáférésed meg lett hosszabbítva."
));

return redirect()->back()->with('message', __('general.successfully_added'));
Expand Down
35 changes: 22 additions & 13 deletions app/Models/Internet/InternetAccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* @property mixed $user_id
* @property string $wifi_username
* @property Carbon $has_internet_until
* @property boolean $netreg_paid
* @property string $wifi_password
* @property User $user
* @property WifiConnection[]|Collection $wifiConnections
Expand All @@ -46,10 +47,17 @@ class InternetAccess extends Model
{
protected $primaryKey = 'user_id';

protected $fillable = ['user_id', 'wifi_username', 'has_internet_until', 'wifi_password'];
protected $fillable = [
'user_id',
'wifi_username',
'has_internet_until', // custom value, usually for guests
'netreg_paid', // whether the collegist paid for current period
'wifi_password',
];

protected $casts = [
'has_internet_until' => 'datetime',
'netreg_paid' => 'boolean'
];

protected const PASSWORD_LENGTH = 8;
Expand Down Expand Up @@ -92,7 +100,7 @@ public function macAddresses(): HasMany
*/
public function isActive(): bool
{
return $this->has_internet_until != null && $this->has_internet_until > date('Y-m-d');
return $this->has_internet_until != null ? $this->has_internet_until > date('Y-m-d') : $this->netreg_paid;
}

/**
Expand Down Expand Up @@ -120,28 +128,29 @@ public function resetPassword(): void
}

/**
* @param string|Carbon|null $newDate
* @param Carbon $newDate
* @return Carbon
*/
public function extendInternetAccess(Carbon|string $newDate = null): Carbon
public function extendInternetAccess(Carbon $newDate): Carbon
{
if ($newDate != null) {
$newDate = Carbon::parse($newDate);
} else {
$newDate = InternetAccess::getInternetDeadline();
}
$this->update(['has_internet_until' => $newDate]);

return $newDate;
}

/**
* Get the current date until the internet accesses should be set.
* @return \Carbon\Carbon
* Reset's all collegists 'netreg_paid' field and sets the 'has_internet_until' instead to a new date.
* @param Carbon $newDate
* @return void
*/
public static function getInternetDeadline(): \Carbon\Carbon
public static function resetInternetAccessPeriod(Carbon $newDate): void
{
return Semester::next()->getStartDate()->addMonth();
$collegists = User::collegists()->pluck('id');

InternetAccess::whereIn('user_id', $collegists)->update([
'netreg_paid' => false,
'has_internet_until' => $newDate
]);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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::table('internet_accesses', function (Blueprint $table) {
$table->boolean('netreg_paid')->default(false);
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('internet_accesses', function (Blueprint $table) {
$table->dropColumn('netreg_paid');
});
}
};
28 changes: 8 additions & 20 deletions resources/views/network/admin/internet_access.blade.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<span class="card-title">Internetelérés</span>
<blockquote>
<p>Az aktuális internetelérés határidő: <span class="coli-text text-orange">{{ $activation_date }}</span></p>
<p>Collegisták esetén a Netreg befizetésekor automatikusan beállítja a rendszer a hozzáférésüket eddig a
dátumig.</p>
<p>Collegisták esetén a Netreg befizetésekor automatikusan beállítja a rendszer a hozzáférésüket a következő periódusig.</p>
<p>Vendégek esetén belépéskor meg kell adniuk a kiköltözés dátumát, amihez szinkronizáljuk az internet
hozzáférésüket. Ha egy volt colis kér netet, csak adj neki vendég jogosultságot, és első belépéskor be tudja
állítani már a netet magának.</p>
Expand All @@ -16,21 +14,7 @@
<script type="text/javascript" src="{{ mix('js/moment.min.js') }}"></script>
<script type="application/javascript">
$(document).ready(function () {
var activation_date = new Date("{{ $activation_date }}");
var now = new Date();
var extendAction = function (cell, formatterParams, onRendered) {
var data = cell.getRow().getData();
var active = (new Date(data.has_internet_until))
onRendered(function () {
$('.tooltipped').tooltip();
});
return $(`<button class="btn-floating tooltipped" style="margin-right: 10px" data-position="top" data-tooltip="Meghosszabbít: {{$activation_date}}">
<i class="material-icons">update</i></button>
`)
.click(function () {
sendExtendRequest(cell, data.user_id, "{{ $activation_date }}");
}).toggle(data.has_internet_until == null || active < activation_date)[0];
};

var revokeAction = function (cell, formatterParams, onRendered) {
var data = cell.getRow().getData();
Expand All @@ -57,7 +41,7 @@
if (value) {
value = moment(value).format("YYYY. MM. DD. HH:mm");
} else {
value = 'Nincs hozzáférés'
value = 'N/A'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be something like 'Unlimited until next kkt period' for those having paid kkt; it would be easier to understand.

}
const data = cell.getRow().getData();
return $("<input type=\"text\" class=\"datepicker\" value=\"" + value + "\"/>")
Expand Down Expand Up @@ -134,13 +118,17 @@
minWidth: 150,
},
{
title: "Internetelérés",
title: "Netreg fizetett",
field: "netreg_paid",
minWidth: 50,
},
{
title: "Egyéni hozzáférés eddig",
field: "has_internet_until",
sorter: "datetime",
formatter: dateFormatter,
minWidth: 50,
},
{title: "", field: "state", headerSort: false, formatter: extendAction, width: 80},
{title: "", field: "state", headerSort: false, formatter: revokeAction, width: 80},
],
ajaxResponse: function (url, params, response) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<div class="row">
<div class="col s12">
@include('utils.checkout.status')
@include('student-council.economic-committee.period')
<div class="row">
@can('addKKTNetreg', \App\Models\Checkout::class)
<div class="col s12">
Expand All @@ -29,7 +30,7 @@
A Netreg tranzakcióid a <a href="{{route('admin.checkout')}}"> rendszergazdai kasszában</a> láthatod.
</blockquote>
@can('administrate', $checkout)
<blockquote>A gazdasági alelnök, a kulturális bizottság tagjai és a rendszergazdák szedhetnek be KKT-t/Netreget. Ezeket a tranzakciókat a tartozások alatt találod.</blockquote>
<blockquote>A gazdasági alelnök, a rendszergazdák, és a KKT jogosultsággal rendelkező collegisták szedhetnek be KKT-t/Netreget. Ezeket a tranzakciókat a tartozások alatt találod.</blockquote>
@endcan
<x-input.select l=4 :elements="$users_not_paid" id="user_id" text="general.user" :formatter="function($user) { return $user->uniqueName; }" />
<x-input.text m=6 l=4 id="kkt" text="KKT" type="number" required min="0" :value="config('custom.kkt')" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@can('administrate', $checkout)
<div class="card">
<form action="{{route('kktnetreg.period.update')}}" method="POST">
@csrf
<div class="card-content">
<div class="card-title">
KKT / Netreg fizetés időszak
</div>
@if($periodicEvent?->isActive())
<blockquote>Jelenleg a KKT/Netreg fizetési időszak aktív. A határidő: {{$periodicEvent?->endDate()}}. </blockquote>
@else
<blockquote>Jelenleg a KKT/Netreg fizetési időszak nem aktív. Az aktiváláshoz add meg a határidőt, ami az internet hozzáférés vége lesz.</blockquote>
<div class="row">
<!-- These are using html datetime-local attribute because we don't have datetime picker. The labels are not compatible with our components. -->
<x-input.select m="3" id="semester_id" :elements="\App\Models\Semester::all()" :value="$periodicEvent?->semester_id" :default="\App\Models\Semester::current()->id" helper="Szemeszter"/>
<x-input.text m="3" id="end_date" type="datetime-local" without-label helper="Határidő" :value="$periodicEvent?->end_date"/>
</div>
<blockquote class="error">Megnyitás után a határidő nem módosítható, de a határidő lejárata után is lehet még fizetést felvinni.</blockquote>

<x-input.button floating class="right" icon="save"/>
@endif
</div>
</form>
</div>
@endcan
1 change: 1 addition & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
Route::post('/economic_committee/mark_as_paid/{user}', [EconomicController::class, 'markAsPaid'])->name('economic_committee.pay');
Route::post('/economic_committee/to_checkout', [EconomicController::class, 'toCheckout'])->name('economic_committee.to_checkout');

Route::post('/admission/kktnetreg/period/update', [EconomicController::class, 'updatePaymentPeriod'])->name('kktnetreg.period.update');
Route::get('/economic_committee/kktnetreg', [EconomicController::class, 'indexKKTNetreg'])->name('kktnetreg');
Route::post('/economic_committee/kktnetreg/pay', [EconomicController::class, 'payKKTNetreg'])->name('kktnetreg.pay');
Route::get('/economic_committee/calculate_workshop_balance', [EconomicController::class, 'calculateWorkshopBalance'])->name('economic_committee.workshop_balance');
Expand Down
18 changes: 0 additions & 18 deletions tests/Feature/AdminInternetControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,24 +117,6 @@ public function test_extend_internet_access(): void
$response->assertSee($date->format('Y-m-d'));
}

/**
* Test that an admin can extend an internet access to the default value.
*/
public function test_extend_internet_access_default(): void
{
$date = InternetAccess::getInternetDeadline();
$response = $this->actingAs($this->admin)->post(route('internet.internet_accesses.extend', $this->user->internetAccess));

$response->assertStatus(200);

$this->assertDatabaseHas('internet_accesses', [
'user_id' => $this->user->id,
'has_internet_until' => $date,
]);

$response->assertSee($date->format('Y-m-d'));
}

/**
* Test that an admin can revoke an internet access.
*/
Expand Down