SellTicketsController::sellTickets()   C
last analyzed

Complexity

Conditions 14
Paths 31

Size

Total Lines 90
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 51
c 1
b 0
f 0
nc 31
nop 2
dl 0
loc 90
rs 6.2666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Http\Controllers\Retail;
4
5
use Illuminate\Support\Facades\DB;
6
use App\Http\Controllers\Controller;
7
use App\Http\Requests\SellTickets;
8
use App\Project;
9
use App\Purchase;
10
use App\Ticket;
11
use App\Event;
12
use Illuminate\Support\Facades\Auth;
13
use Illuminate\Support\Facades\Log;
14
use Illuminate\Support\Str;
15
16
class SellTicketsController extends Controller
17
{
18
    /**
19
     * Display all available events
20
     */
21
    public function events()
22
    {
23
        $projects = Project::where('is_archived', 0)->with(['events' => function ($query) {
24
            $query->where('retailer_sell_stop', '>=', new \DateTime())->orderBy('start_date', 'ASC');
25
        }, 'events.location'])->get();
26
27
        $currentProjects = $projects->filter(function ($project) {
28
            return $project->events->count() > 0;
29
        })->all();
30
31
        return view('retail.events', ['projects' => $currentProjects]);
32
    }
33
34
    /**
35
     * Display available price categories for the selected event
36
     */
37
    public function seats(Event $event)
38
    {
39
        $seatMapView = 'retail.seatmaps.seatmap-js';
40
        if ($event->seatMap->layout === null) {
41
            $seatMapView = 'retail.seatmaps.no-seats';
42
        }
43
44
        return view($seatMapView, ['event' => $event]);
45
    }
46
47
    /**
48
     * Create a paid purchase mapped on the current logged in user as vendor
49
     */
50
    public function sellTickets(SellTickets $request, Event $event)
51
    {
52
        if( new \DateTime($event->retailer_sell_stop) < new \DateTime() ) {
53
            Log::warning('Tickets-Sell-Action after retailer_sell_stop by user#' . Auth::user()->id . ' failed');
54
            // Redirect user to select a valid amount of tickets
55
            return redirect()->route('retail.sell.seats', [$event])
56
                ->with('status', 'Sell stop for this event has already been reached!');
57
        }
58
59
        $validated = $request->validated();
60
        $tickets = $validated['tickets'];
61
        $action = $validated['action'];
62
63
        // If the purchase shall be a reservation, check if the user has the permission to do so
64
        if ($action === 'reserved' && !Auth::user()->hasPermission('RESERVE_TICKETS')) {
65
            Log::warning('Unauthorized action "RESERVE_TICKETS" by user#' . Auth::user()->id . ' failed');
66
            // Redirect user to select a valid amount of tickets
67
            return redirect()->route('retail.sell.seats', [$event])
68
                ->with('status', 'You are not allowed to perform this action. This will be reported!');
69
        }
70
71
        // If the purchase shall be a reservation, check if the user has the permission to do so
72
        if ($action === 'free' && !Auth::user()->hasPermission('HANDLING_FREE_TICKETS')) {
73
            Log::warning('Unauthorized action "HANDLING_FREE_TICKETS" by user#' . Auth::user()->id . ' failed');
74
            // Redirect user to select a valid amount of tickets
75
            return redirect()->route('retail.sell.seats', [$event])
76
                ->with('status', 'You are not allowed to perform this action. This will be reported!');
77
        }
78
79
        // Check if customer data was sent. Then handle the user.
80
        if (array_key_exists('customer-name', $validated)) {
81
            $customerName = $validated['customer-name'];
82
        }
83
84
        // Start a transaction for inserting all session data into database
85
        // and generating a purchase.
86
        // Checks at the end validate if tickets are still free/available
87
        DB::beginTransaction();
88
89
        $ticketSum = array_sum($tickets);
90
        if ($event->freeTickets() < $ticketSum) {
91
            // End transaction
92
            DB::rollbackTransaction();
93
            // Redirect user to select a valid amount of tickets
94
            return redirect()->route('retail.sell.seats', [$event])
95
                ->with('status', 'There are not as many tickets as you chose left. Please only choose a lesser amount of tickets!');
96
        }
97
98
        if ($event->seatMap->layout !== null) {
99
            // Check if seats are still free and not booked by a concurrent transaction in the meantime
100
            $seats = $validated['selected-seats'];
101
            if (!$event->areSeatsFree($seats)) {
102
                // End transaction
103
                DB::rollBackTransaction();
104
                // redirect user to select a new set of seats
105
                return redirect()->route('retail.sell.seats', [$event])
106
                    ->with('status', 'Not all of your selected seats are still free. Please choose a new set of seats!');
107
            }
108
        }
109
110
        $prices = $event->priceList->categories;
111
        $prices = $prices->keyBy('id');
112
113
        $purchase = new Purchase();
114
        $purchase->generateSecrets();
115
        $purchase->state = $action;
116
        $purchase->vendor_id = auth()->user()->id;
117
        $purchase->customer_name = isset($customerName) ? $customerName : null;
118
        $purchase->save();
119
120
        $seatsIndex = 0;
121
        foreach ($tickets as $ticketCategory => $ticketCount) {
122
            for ($i = 0; $i < $ticketCount; $i++) {
123
                Ticket::create([
124
                    'random_id' => Str::random(32),
125
                    'seat_number' => isset($seats) ? $seats[$seatsIndex] : 0,
126
                    'purchase_id' => $purchase->id,
127
                    'event_id' => $event->id,
128
                    'price_category_id' => $prices[$ticketCategory]->id
129
                ]);
130
                $seatsIndex++;
131
            }
132
        }
133
134
        DB::commit();
135
136
        Log::info('[Retail user#' . Auth::user()->id . '] Created purchase#' . $purchase->id . ' with state ' . $action);
137
        // On successful sale, redirect browser to purchase overview
138
        return redirect()->route('ticket.purchase', ['purchase' => $purchase->random_id])
139
            ->with('status', 'Purchase successful!');
140
    }
141
}
142