Passed
Push — master ( 82f4a5...a09b17 )
by Martin
17:51
created

Project   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 49
c 1
b 0
f 0
dl 0
loc 111
rs 10
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A events() 0 3 1
B getHelgaMetrics() 0 84 5
1
<?php
2
3
namespace App;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Facades\DB;
7
8
class Project extends Model
9
{
10
    //
11
    protected $fillable = ['name', 'description'];
12
13
    public function events()
14
    {
15
        return $this->hasMany('App\Event');
16
    }
17
18
    /**
19
     * Return a table with the metrics the Theater in der Werkstatt (Kirchdorf) needs for analysis
20
     * 
21
     * Header of table:
22
     * - Event date
23
     * - free tickets
24
     * - count of ticket type #x
25
     * - count of no shows of ticket type #x
26
     * - sum of ticket type #x
27
     * - count all tickets
28
     * - sum all sold tickets
29
     * - sum sold tickets by vendor
30
     * - Box Office sales
31
     * - no-shows
32
     * 
33
     * @return void 
34
     */
35
    public function getHelgaMetrics()
36
    {
37
        // Challenges on generating these stats:
38
        // 1. variable amount of vendors and price categories used per event
39
        // 2. Substract box office sales from regular sales
40
        
41
        $result = [];
42
43
        // Get all event-ids of the project
44
        $eventIds = $this->events()->pluck('id');
45
46
        // base query that joins all required tables to one big table of tickets
47
        $viewQuery = DB::table('tickets')
48
                        ->join('price_categories', 'tickets.price_category_id', '=', 'price_categories.id')
49
                        ->join('purchases', 'tickets.purchase_id', '=', 'purchases.id')
50
                        ->join('users', 'purchases.vendor_id', '=', 'users.id');
51
52
        // First we fetch the result-table-headers. By using "with()" we can reuse the base query for all other queries.
53
        // + Group by price categories
54
        // + Group by vendors
55
        $priceCategories = with(clone $viewQuery)->whereIn('tickets.event_id', $eventIds)
56
                                        ->groupBy('price_categories.id')
57
                                        ->select('price_categories.id as id', 'price_categories.name as name')
58
                                        ->get();
59
60
        $vendors = with(clone $viewQuery)->whereIn('tickets.event_id', $eventIds)
61
                            ->groupBy('purchases.vendor_id')
62
                            ->select('users.id as id', 'users.name as name')
63
                            ->get();
64
        
65
        // Iterate over all events and fill in the values for each fetched header
66
        foreach( $this->events as $event ) {
67
            $eventResults = [];
68
69
            $eventResults['date'] = $event->start_date;
70
71
            // Set free tickets
72
            $eventResults['free_tickets'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)
73
                                                                ->where('purchases.state', 'free')
74
                                                                ->count();
75
76
            // Get ticket category stats
77
            foreach( $priceCategories as $cat) {
78
                // Get the number of tickets sold of this category
79
                $eventResults[$cat->name . '_total'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)
80
                                                                            ->where('purchases.state', 'paid')
81
                                                                            ->where('price_categories.id', $cat->id)
82
                                                                            ->count();
83
                // Get the amount of money by sold tickets of this category
84
                $eventResults[$cat->name . '_sum'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)
85
                                                                            ->where('purchases.state', 'paid')
86
                                                                            ->where('price_categories.id', $cat->id)
87
                                                                            ->sum('price_categories.price');
88
                // Get the number of not consumed tickets (=no shows)
89
                $eventResults[$cat->name . '_no-show'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)
90
                                                                            ->where('purchases.state', 'paid')
91
                                                                            ->where('price_categories.id', $cat->id)
92
                                                                            ->where('tickets.state', '<>', 'consumed')
93
                                                                            ->count();
94
            }
95
96
            $eventResults['total_visits'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)->count();
97
            $eventResults['total_sum'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)->sum('price_categories.price');
98
99
            // Get the sales for each vendor
100
            foreach( $vendors as $vendor ) {
101
                $eventResults[$vendor->name . '_sum'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)
102
                                                                            ->where('purchases.vendor_id', $vendor->id)
103
                                                                            ->sum('price_categories.price');
104
            }
105
106
            // if a box office purchase exists, write the result, else 0
107
            $eventResults['boxoffice'] = $event->boxoffice ? $eventResults->boxoffice->total() : 0;
108
            // Amount of money gained without people showing up
109
            $eventResults['no-shows_sum'] = with(clone $viewQuery)->where('tickets.event_id', $event->id)
110
                                                                ->where('tickets.state', '<>', 'consumed')
111
                                                                ->sum('price_categories.price');
112
113
114
115
            // add the results to the end of the 
116
            array_push($result, $eventResults);
117
        }
118
        return $result;
119
    }
120
}
121