Skip to content
This repository was archived by the owner on Mar 26, 2022. It is now read-only.

Commit 40746ce

Browse files
kdmnkluksan47
andauthored
Economic committee module: KKT and Netreg (#380)
* main functions * Apply fixes from StyleCI * made it work * Apply fixes from StyleCI * main page with statistics, and custom transactions * Apply fixes from StyleCI * finalized * Apply fixes from StyleCI * connected to student-committee role * Apply fixes from StyleCI * fix * code rebase * Extended internet access * Apply fixes from StyleCI * fix typo * added delete and minor changes * mobile friendly * fix * Apply fixes from StyleCI * modified test * fix * deleted test Co-authored-by: Norbert Luksa <[email protected]>
1 parent d26c953 commit 40746ce

31 files changed

+1189
-10
lines changed

app/Checkout.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Checkout extends Model
8+
{
9+
protected $fillable = ['name', 'password'];
10+
protected $hidden = ['password'];
11+
12+
public function transactions()
13+
{
14+
return $this->hasMany('App\Transaction');
15+
}
16+
17+
public function balance()
18+
{
19+
return $this->transactions->sum('amount');
20+
}
21+
22+
public function balanceInCheckout()
23+
{
24+
return $this->transactions
25+
->where('moved_to_checkout', '<>', null)
26+
->sum('amount');
27+
}
28+
29+
public function kktSum(Semester $semester)
30+
{
31+
return $this->transactions
32+
->where('payment_type_id', PaymentType::where('name', 'KKT')->firstOrFail()->id)
33+
->where('semester_id', $semester->id)
34+
->sum('amount');
35+
}
36+
}

app/Http/Controllers/InternetController.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,19 @@ public function editInternetAccess(Request $request, $id)
133133
->where('user_id', '=', $internetAccess->user_id)->first();
134134
}
135135

136+
public static function extendUsersInternetAccess(User $user)
137+
{
138+
$internetAccess = $user->internetAccess;
139+
if ($internetAccess != null) {
140+
$internetAccess->has_internet_until = \App\EventTrigger::internetActivationDeadline();
141+
$internetAccess->save();
142+
143+
return $internetAccess->has_internet_until;
144+
} else {
145+
return null;
146+
}
147+
}
148+
136149
public function addMacAddress(Request $request)
137150
{
138151
$validator = Validator::make($request->all(), [
@@ -188,4 +201,11 @@ public function translateStates(): \Closure
188201
return $data;
189202
};
190203
}
204+
205+
public function showCheckout()
206+
{
207+
$users = User::where('verified', false)->get();
208+
209+
return view('admin.checkout', ['users' => $users]);
210+
}
191211
}
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\StudentCouncil;
4+
5+
use App\Http\Controllers\Controller;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Facades\Gate;
8+
use Illuminate\Support\Facades\Auth;
9+
use Illuminate\Support\Facades\Mail;
10+
use Illuminate\Support\Facades\Validator;
11+
12+
use App\Http\Controllers\InternetController;
13+
14+
use App\Checkout;
15+
use App\PaymentType;
16+
use App\Semester;
17+
use App\Transaction;
18+
use App\User;
19+
use App\Workshop;
20+
21+
22+
class EconomicController extends Controller
23+
{
24+
public function index($redirected = false)
25+
{
26+
if(!Auth::user()->hasRole(\App\Role::COLLEGIST)) abort(403); //TODO make policy
27+
$transactions = [];
28+
$checkout = Checkout::where('name', 'VALASZTMANY')->firstOrFail();
29+
$semesters = Semester::allUntilCurrent()
30+
->sortByDesc(function ($semester, $key) {
31+
return $semester->getStartDate();
32+
})->filter(function ($semester, $key){
33+
return $semester->transactions()->count()>0;
34+
});
35+
36+
$data = [];
37+
foreach ($semesters as $semester) {
38+
//transactions
39+
$transactions = [];
40+
$transactions['income'] = $semester->transactionsInCheckout($checkout)
41+
->where('payment_type_id', PaymentType::where('name', 'INCOME')->firstOrFail()->id)
42+
->get();
43+
44+
$transactions['expense'] = $semester->transactionsInCheckout($checkout)
45+
->where('payment_type_id', PaymentType::where('name', 'EXPENSE')->firstOrFail()->id)
46+
->get();
47+
$transactions['kkt'] = $checkout->kktSum($semester);
48+
$transactions['sum'] = $semester->transactionsInCheckout($checkout)
49+
->sum('amount');
50+
51+
$data[$semester->tag().' ('.$semester->getStartDate()->format('Y.m.d').'-'.$semester->getEndDate()->format('Y.m.d').')'] = [
52+
'transactions' => $transactions,
53+
'workshop_balances' => $semester->workshopBalances
54+
];
55+
};
56+
57+
//checkout balances
58+
$current_balance = $checkout->balance();
59+
$current_balance_in_checkout = $checkout->balanceInCheckout();
60+
61+
if($redirected){
62+
return view('student-council.economic-committee.app',[
63+
'data' => $data,
64+
'current_balance' => $current_balance,
65+
'current_balance_in_checkout' => $current_balance_in_checkout,
66+
])->with('message', __('general.successfully_added'));
67+
} else {
68+
return view('student-council.economic-committee.app',[
69+
'data' => $data,
70+
'current_balance' => $current_balance,
71+
'current_balance_in_checkout' => $current_balance_in_checkout]);
72+
}
73+
}
74+
75+
public function indexKKTNetreg()
76+
{
77+
$user = Auth::user();
78+
if(!$user->hasRole(\App\Role::STUDENT_COUNCIL)) abort(403); //TODO make policy
79+
$users = User::all();
80+
81+
$my_transactions_not_in_checkout = Transaction::where('receiver_id', $user->id)
82+
->where('moved_to_checkout', null)->get();
83+
$sum = $my_transactions_not_in_checkout->sum('amount');
84+
85+
$semester = Semester::current();
86+
$all_kktnetreg_transaction = Transaction::where(function ($query) {
87+
$query->where('payment_type_id', PaymentType::where('name', 'KKT')->firstOrFail()->id)
88+
->orWhere('payment_type_id', PaymentType::where('name', 'NETREG')->firstOrFail()->id);
89+
})->get();
90+
91+
return view('student-council.economic-committee.kktnetreg', [
92+
'users' => $users,
93+
'my_transactions' => $my_transactions_not_in_checkout,
94+
'sum_my_transactions' => $sum,
95+
'all_transactions' => $all_kktnetreg_transaction,
96+
'current_semester' => $semester->tag()
97+
]);
98+
}
99+
100+
public function indexTransaction()
101+
{
102+
$user = Auth::user();
103+
if(!$user->hasRole(\App\Role::STUDENT_COUNCIL)) abort(403); //TODO make policy
104+
return view('student-council.economic-committee.transaction');
105+
106+
}
107+
108+
public function payKKTNetreg(Request $request)
109+
{
110+
$user = Auth::user();
111+
if(!$user->hasRole(\App\Role::STUDENT_COUNCIL)) abort(403); //TODO make policy
112+
$validator = Validator::make($request->all(), [
113+
'user_id' => 'required|integer|exists:users,id',
114+
'kkt' => 'required|integer|min:0',
115+
'netreg' => 'required|integer|min:0',
116+
]);
117+
if ($validator->fails()) {
118+
return back()->withErros($validator)->withInput();
119+
}
120+
121+
$valasztmany_checkout = Checkout::where('name', 'VALASZTMANY')->firstOrFail();
122+
$admin_checkout = Checkout::where('name', 'ADMIN')->firstOrFail();
123+
124+
/** Creating transactions even if amount is 0.
125+
* Paying 0 means that the user payed their netreg+kkt depts (which is 0 in this case).
126+
*/
127+
$kkt = Transaction::create([
128+
'checkout_id' => $valasztmany_checkout->id,
129+
'receiver_id' => $user->id,
130+
'payer_id' => $request->user_id,
131+
'semester_id' => Semester::current()->id,
132+
'amount' => $request->kkt,
133+
'payment_type_id' => PaymentType::where('name', 'KKT')->firstOrFail()->id,
134+
'comment' => null,
135+
'moved_to_checkout' => null,
136+
]);
137+
138+
$netreg = Transaction::create([
139+
'checkout_id' => $admin_checkout->id,
140+
'receiver_id' => $user->id,
141+
'payer_id' => $request->user_id,
142+
'semester_id' => Semester::current()->id,
143+
'amount' => $request->netreg,
144+
'payment_type_id' => PaymentType::where('name', 'NETREG')->firstOrFail()->id,
145+
'comment' => null,
146+
'moved_to_checkout' => null,
147+
]);
148+
$payer = User::find($request->user_id);
149+
150+
$new_internet_expire_date = InternetController::extendUsersInternetAccess($payer);
151+
if (config('mail.active')) {
152+
if ($new_internet_expire_date == null){
153+
Mail::to($payer)
154+
->queue(new \App\Mail\PayedTransaction(
155+
$payer->name, [$kkt, $netreg]));
156+
} else {
157+
Mail::to($payer)
158+
->queue(new \App\Mail\PayedTransaction(
159+
$payer->name, [$kkt, $netreg],
160+
__('internet.expiration_extended',
161+
['new_date' => $new_internet_expire_date->format('Y-m-d')])));
162+
}
163+
}
164+
165+
return redirect()->back()->with('message', __('general.successfully_added'));
166+
}
167+
168+
public function KKTNetregToCheckout(Request $request)
169+
{
170+
$user = Auth::user();
171+
if(!$user->hasRole(\App\Role::STUDENT_COUNCIL)) abort(403); //TODO make policy
172+
173+
/* Moving the Netreg amount from Valasztmany to Admins is not tracked (yet) */
174+
$checkout_password = Checkout::where('name', 'VALASZTMANY')->firstOrFail()->password;
175+
$validator = Validator::make($request->all(), [
176+
'password' => 'required|in:'.$checkout_password, //TODO bug on wrong pwd
177+
]);
178+
if ($validator->fails()) {
179+
return back()->withErros($validator)->withInput();
180+
}
181+
182+
//TODO log? (because the password is not encrypted)
183+
184+
$transactions = Transaction::where('receiver_id', $user->id)
185+
->where('moved_to_checkout', null)->get();
186+
187+
foreach ($transactions as $transaction) {
188+
$transaction->moved_to_checkout = \Carbon\Carbon::now();
189+
$transaction->save();
190+
}
191+
192+
return redirect()->back()->with('message', __('general.successfully_added'));
193+
}
194+
195+
public function addTransaction(Request $request)
196+
{
197+
$user = Auth::user();
198+
if(!$user->hasRole(\App\Role::STUDENT_COUNCIL)) abort(403); //TODO make policy
199+
200+
$checkout_password = Checkout::where('name', 'VALASZTMANY')->firstOrFail()->password;
201+
$validator = Validator::make($request->all(), [
202+
'comment' => 'required|string',
203+
'amount' => 'required|integer',
204+
'password' => 'required|in:'.$checkout_password, //TODO bug on wrong pwd
205+
]);
206+
$validator->validate();
207+
if ($validator->fails()) {
208+
return back()->withErros($validator)->withInput();
209+
}
210+
211+
$checkout = Checkout::firstWhere('name', 'VALASZTMANY');
212+
$type = ($request->amount > 0 ? 'INCOME' : 'EXPENSE');
213+
Transaction::create([
214+
'checkout_id' => $checkout->id,
215+
'receiver_id' => null,
216+
'payer_id' => $user->id, //null would be enough, just store for logging
217+
'semester_id' => Semester::current()->id,
218+
'amount' => $request->amount,
219+
'payment_type_id' => PaymentType::where('name', $type)->firstOrFail()->id,
220+
'comment' => $request->comment,
221+
'moved_to_checkout' => \Carbon\Carbon::now(), //TODO? option to add to checkout later
222+
]);
223+
224+
return redirect()->action(
225+
[EconomicController::class, 'index'], ['redirected' => true]
226+
);
227+
}
228+
229+
public function deleteTransaction(Request $request)
230+
{
231+
$user = Auth::user();
232+
$transaction = Transaction::findOrFail($request->transaction);
233+
if(!$user->hasRole(\App\Role::STUDENT_COUNCIL)) abort(403); //TODO make policy
234+
$transaction->delete();
235+
return redirect()->back()->with('message', __('general.successfully_deleted'));
236+
}
237+
238+
public function calculateWorkshopBalance(Semester $semester)
239+
{
240+
//TODO (#382)
241+
//for every active member in a workshop
242+
//payed kkt * (if resident: 0.6, if day-boarder: 0.45) / user's workshops' count
243+
//or the proportions should be edited?
244+
245+
/* $payed_member_num = $workshop_balance->workshop->users->filter(function ($user, $key) use ($workshop_balance) {
246+
return ($user->isActiveIn($workshop_balance->semester)
247+
&& !$user->haveToPayKKTNetregInSemester($workshop_balance->semester));
248+
})->count();
249+
$remaining_member_num = $workshop_balance->workshop->users->filter(function ($user, $key) use ($workshop_balance) {
250+
return ($user->haveToPayKKTNetregInSemester($workshop_balance->semester));
251+
})->count(); */
252+
253+
}
254+
}

app/Mail/PayedTransaction.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace App\Mail;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Mail\Mailable;
7+
use Illuminate\Queue\SerializesModels;
8+
9+
class PayedTransaction extends Mailable
10+
{
11+
use Queueable, SerializesModels;
12+
13+
public $recipent;
14+
public array $transactions;
15+
public $additional_message;
16+
17+
/**
18+
* Create a new message instance.
19+
*
20+
* @return void
21+
*/
22+
public function __construct($recipent, array $transactions, $additional_message = null)
23+
{
24+
$this->recipent = $recipent;
25+
$this->transactions = $transactions;
26+
$this->additional_message = $additional_message;
27+
}
28+
29+
/**
30+
* Build the message.
31+
*
32+
* @return $this
33+
*/
34+
public function build()
35+
{
36+
return $this->markdown('emails.payed_transaction')
37+
->subject(__('checkout.pay'));
38+
}
39+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace App\Policies;
4+
5+
use App\Role;
6+
use App\User;
7+
use Illuminate\Auth\Access\HandlesAuthorization;
8+
9+
class TransactionsPolicy
10+
{
11+
use HandlesAuthorization;
12+
13+
/**
14+
* Determine whether the user can view the Economic Committee's statistics.
15+
*/
16+
public function viewEconomicStat(User $user)
17+
{
18+
if ($user->hasRole(Role::Collegist)) {
19+
return true;
20+
}
21+
}
22+
23+
/**
24+
* Determine whether the user can create Economic Committee transactions.
25+
*
26+
* @param \App\User $user
27+
* @return mixed
28+
*/
29+
public function createEconomicTransaction(User $user)
30+
{
31+
if ($user->hasRole(Role::STUDENT_COUNCIL)) {
32+
return true;
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)