Passed
Pull Request — main (#63)
by Thierry
06:38
created

DataSyncService::syncPool()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 26
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 39
rs 8.5706
1
<?php
2
3
namespace Siak\Tontine\Service\Planning;
4
5
use Closure;
6
use Illuminate\Support\Facades\DB;
7
use Siak\Tontine\Exception\MessageException;
8
use Siak\Tontine\Model\Pool;
9
10
use function trans;
11
12
class DataSyncService
13
{
14
    /**
15
     * @param string $table
16
     * @param string $relation
17
     *
18
     * @return Closure
19
     */
20
    private function filter(string $table, string $relation): Closure
21
    {
22
        return function($query) use($relation, $table) {
23
            $query->select(DB::raw(1))
24
                ->from($relation)
25
                ->whereColumn("$relation.session_id", "$table.session_id")
26
                ->whereColumn("$relation.pool_id", 'subscriptions.pool_id');
27
        };
28
    }
29
30
    /**
31
     * @param string $table
32
     *
33
     * @return Closure
34
     */
35
    private function filters(string $table): Closure
36
    {
37
        return function($query) use($table) {
38
            $query->orWhereNotExists($this->filter($table, 'v_pool_session'))
39
                ->orWhereExists($this->filter($table, 'pool_session_disabled'));
40
        };
41
    }
42
43
    /**
44
     * @param Pool $pool
45
     * @param bool $filter
46
     *
47
     * @return void
48
     * @throws MessageException
49
     */
50
    public function syncPool(Pool $pool, bool $filter): void
51
    {
52
        // Check for existing remitments.
53
        $payables = DB::table('payables')
54
            ->join('subscriptions', 'payables.subscription_id', '=', 'subscriptions.id')
55
            ->where('subscriptions.pool_id', $pool->id)
56
            ->when($filter, fn($query) => $query->where($this->filters('payables')))
57
            ->select('payables.id')
58
            ->distinct()
59
            ->pluck('id');
60
        if($payables->count() > 0 &&
61
            DB::table('remitments')->whereIn('payable_id', $payables)->count() > 0)
62
        {
63
            throw new MessageException(trans('tontine.errors.action') .
64
                '<br/>' . trans('tontine.pool.errors.payments'));
65
        }
66
        // Check for existing deposits.
67
        $receivables = DB::table('receivables')
68
            ->join('subscriptions', 'receivables.subscription_id', '=', 'subscriptions.id')
69
            ->where('subscriptions.pool_id', $pool->id)
70
            ->when($filter, fn($query) => $query->where($this->filters('receivables')))
71
            ->select('receivables.id')
72
            ->distinct()
73
            ->pluck('id');
74
        if($receivables->count() > 0 &&
75
            DB::table('deposits')->whereIn('receivable_id', $receivables)->count() > 0)
76
        {
77
            throw new MessageException(trans('tontine.errors.action') .
78
                '<br/>' . trans('tontine.pool.errors.payments'));
79
        }
80
        // Detach the payables from their sessions.
81
        if($payables->count() > 0)
82
        {
83
            DB::table('payables')->whereIn('id', $payables)->update(['session_id' => null]);
84
        }
85
        // Delete the receivables.
86
        if($receivables->count() > 0)
87
        {
88
            DB::table('receivables')->whereIn('id', $receivables)->delete();
89
        }
90
    }
91
}
92