Passed
Pull Request — main (#49)
by Thierry
14:14
created

EventTrait   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 76
c 2
b 0
f 0
dl 0
loc 202
rs 10
wmc 23

8 Methods

Rating   Name   Duplication   Size   Complexity  
A createRoundBill() 0 9 1
A createTontineBill() 0 8 1
A chargeCreated() 0 11 3
A createBill() 0 7 1
A createSessionBill() 0 9 1
A memberCreated() 0 7 2
B roundOpened() 0 36 7
B sessionOpened() 0 40 7
1
<?php
2
3
namespace Siak\Tontine\Service\Traits;
4
5
use DateTime;
6
use Illuminate\Database\Eloquent\Builder;
7
use Siak\Tontine\Model\Bill;
8
use Siak\Tontine\Model\TontineBill;
9
use Siak\Tontine\Model\RoundBill;
10
use Siak\Tontine\Model\SessionBill;
11
use Siak\Tontine\Model\Charge;
12
use Siak\Tontine\Model\Member;
13
use Siak\Tontine\Model\Round;
14
use Siak\Tontine\Model\Session;
15
use Siak\Tontine\Model\Tontine;
16
17
use function now;
18
19
trait EventTrait
20
{
21
    /**
22
     * @param Charge $charge
23
     * @param DateTime $today
24
     *
25
     * @return Bill
26
     */
27
    private function createBill(Charge $charge, DateTime $today): Bill
28
    {
29
        return Bill::create([
30
            'charge' => $charge->name,
31
            'amount' => $charge->amount,
32
            'lendable' => $charge->lendable,
33
            'issued_at' => $today,
34
        ]);
35
    }
36
37
    /**
38
     * @param Charge $charge
39
     * @param Member $member
40
     * @param DateTime $today
41
     *
42
     * @return void
43
     */
44
    private function createTontineBill(Charge $charge, Member $member, DateTime $today)
45
    {
46
        $bill = $this->createBill($charge, $today);
47
        $tontineBill = new TontineBill();
48
        $tontineBill->bill()->associate($bill);
49
        $tontineBill->charge()->associate($charge);
50
        $tontineBill->member()->associate($member);
51
        $tontineBill->save();
52
    }
53
54
    /**
55
     * @param Charge $charge
56
     * @param Member $member
57
     * @param Round $round
58
     * @param DateTime $today
59
     *
60
     * @return void
61
     */
62
    private function createRoundBill(Charge $charge, Member $member, Round $round, DateTime $today)
63
    {
64
        $bill = $this->createBill($charge, $today);
65
        $roundBill = new RoundBill();
66
        $roundBill->bill()->associate($bill);
67
        $roundBill->charge()->associate($charge);
68
        $roundBill->member()->associate($member);
69
        $roundBill->round()->associate($round);
70
        $roundBill->save();
71
    }
72
73
    /**
74
     * @param Charge $charge
75
     * @param Member $member
76
     * @param Session $session
77
     * @param DateTime $today
78
     *
79
     * @return void
80
     */
81
    private function createSessionBill(Charge $charge, Member $member, Session $session, DateTime $today)
82
    {
83
        $bill = $this->createBill($charge, $today);
84
        $sessionBill = new SessionBill();
85
        $sessionBill->bill()->associate($bill);
86
        $sessionBill->charge()->associate($charge);
87
        $sessionBill->member()->associate($member);
88
        $sessionBill->session()->associate($session);
89
        $sessionBill->save();
90
    }
91
92
    /**
93
     * @param Tontine $tontine
94
     * @param Charge $charge
95
     *
96
     * @return void
97
     */
98
    protected function chargeCreated(Tontine $tontine, Charge $charge)
99
    {
100
        if(!$charge->period_once)
101
        {
102
            return;
103
        }
104
        $today = now();
105
        // Create a tontine bill for each member
106
        foreach($tontine->members()->get() as $member)
107
        {
108
            $this->createTontineBill($charge, $member, $today);
109
        }
110
    }
111
112
    /**
113
     * @param Tontine $tontine
114
     * @param Member $member
115
     *
116
     * @return void
117
     */
118
    protected function memberCreated(Tontine $tontine, Member $member)
119
    {
120
        $today = now();
121
        // Create a tontine bill for each charge
122
        foreach($tontine->charges()->active()->once()->get() as $charge)
123
        {
124
            $this->createTontineBill($charge, $member, $today);
125
        }
126
    }
127
128
    /**
129
     * @param Tontine $tontine
130
     * @param Round $round
131
     *
132
     * @return void
133
     */
134
    protected function roundOpened(Tontine $tontine, Round $round)
135
    {
136
        $today = now();
137
        $members = $tontine->members()->with([
138
            'tontine_bills',
139
            'round_bills' => function($query) use($round) {
140
                $query->where('round_id', $round->id);
141
            },
142
        ])->get();
143
        $roundCharges = $tontine->charges()->active()->round()->get();
144
        // Create a round bill for each member
145
        foreach($members as $member)
146
        {
147
            foreach($roundCharges as $charge)
148
            {
149
                $count = $member->round_bills->filter(function($bill) use($charge) {
150
                    return $bill->charge_id = $charge->id;
151
                })->count();
152
                if($count === 0)
153
                {
154
                    $this->createRoundBill($charge, $member, $round, $today);
155
                }
156
            }
157
        }
158
        $tontineCharges = $tontine->charges()->active()->once()->get();
159
        // Create a tontine bill for each member
160
        foreach($members as $member)
161
        {
162
            foreach($tontineCharges as $charge)
163
            {
164
                $count = $member->tontine_bills->filter(function($bill) use($charge) {
165
                    return $bill->charge_id = $charge->id;
166
                })->count();
167
                if($count === 0)
168
                {
169
                    $this->createTontineBill($charge, $member, $today);
170
                }
171
            }
172
        }
173
    }
174
175
    /**
176
     * @param Tontine $tontine
177
     * @param Session $session
178
     *
179
     * @return void
180
     */
181
    protected function sessionOpened(Tontine $tontine, Session $session)
182
    {
183
        // Make sure the round is also opened.
184
        $this->roundOpened($tontine, $session->round);
185
186
        $today = now();
187
        $members = $tontine->members()->with([
188
            'session_bills' => function($query) use($session) {
189
                $query->where('session_id', $session->id);
190
            },
191
        ])->get();
192
        $sessionCharges = $tontine->charges()->active()->session()->get();
193
194
        // Sync the session bills for each member and each session charge
195
        foreach($sessionCharges as $charge)
196
        {
197
            foreach($members as $member)
198
            {
199
                $count = $member->session_bills->filter(function($bill) use($charge) {
200
                    return $bill->charge_id = $charge->id;
201
                })->count();
202
                if($count === 0)
203
                {
204
                    $this->createSessionBill($charge, $member, $session, $today);
205
                }
206
            }
207
        };
208
209
        // Sync the receivables for each subscription on each pool
210
        foreach($session->round->pools as $pool)
211
        {
212
            if($session->enabled($pool))
213
            {
214
                $subscriptions = $pool->subscriptions()
215
                    ->whereDoesntHave('receivables', function(Builder $query) use($session) {
216
                        return $query->where('session_id', $session->id);
217
                    });
218
                foreach($subscriptions->get() as $subscription)
219
                {
220
                    $subscription->receivables()->create(['session_id' => $session->id]);
221
                }
222
            }
223
        }
224
    }
225
}
226