1<?php
2
3/**
4 * This file is part of the Phalcon Framework.
5 *
6 * (c) Phalcon Team <team@phalcon.io>
7 *
8 * For the full copyright and license information, please view the
9 * LICENSE.txt file that was distributed with this source code.
10 */
11
12declare(strict_types=1);
13
14namespace Phalcon\Test\Database\Mvc\Model;
15
16use DatabaseTester;
17use Phalcon\Mvc\Model\Resultset\Simple;
18use Phalcon\Mvc\Model\Transaction\Manager;
19use Phalcon\Storage\Exception;
20use Phalcon\Test\Fixtures\Migrations\InvoicesMigration;
21use Phalcon\Test\Fixtures\Traits\DiTrait;
22use Phalcon\Test\Fixtures\Traits\RecordsTrait;
23use Phalcon\Test\Models\Invoices;
24
25class SumCest
26{
27    use DiTrait;
28    use RecordsTrait;
29
30    /**
31     * @var InvoicesMigration
32     */
33    private $invoiceMigration;
34
35    /**
36     * Executed before each test
37     *
38     * @param DatabaseTester $I
39     *
40     * @return void
41     */
42    public function _before(DatabaseTester $I): void
43    {
44        try {
45            $this->setNewFactoryDefault();
46        } catch (Exception $e) {
47            $I->fail($e->getMessage());
48        }
49
50        $this->setDatabase($I);
51
52        $this->invoiceMigration = new InvoicesMigration($I->getConnection());
53    }
54
55
56    public function _after(DatabaseTester $I): void
57    {
58        /**
59         * @var Manager $transactionManager
60         */
61        $transactionManager = $this->getDi()->getShared('transactionManager');
62
63        if ($transactionManager->has()) {
64            $transactionManager->rollback();
65        }
66    }
67
68    /**
69     * Tests Phalcon\Mvc\Model :: sum()
70     *
71     * @param DatabaseTester $I
72     *
73     * @author Phalcon Team <team@phalcon.io>
74     * @since  2020-01-30
75     *
76     * @group  mysql
77     * @group  pgsql
78     */
79    public function mvcModelSum(DatabaseTester $I)
80    {
81        /**
82         * @todo The following tests are skipped for sqlite because we will get
83         *       a General Error 5 database is locked error.
84         */
85        $invId = ('sqlite' === $I->getDriver()) ? 'null' : 'default';
86
87        $this->insertDataInvoices($this->invoiceMigration, 7, $invId, 2, 'ccc');
88        $this->insertDataInvoices($this->invoiceMigration, 1, $invId, 3, 'aaa');
89        $this->insertDataInvoices($this->invoiceMigration, 11, $invId, 1, 'aaa');
90
91
92        $total = Invoices::sum(
93            [
94                'column' => 'inv_total',
95            ]
96        );
97        $I->assertEquals(266.00, $total);
98
99        $total = Invoices::sum(
100            [
101                'column'   => 'inv_total',
102                'distinct' => 'inv_cst_id',
103            ]
104        );
105        $I->assertEquals(6, $total);
106
107        $total = Invoices::sum(
108            [
109                'column' => 'inv_total',
110                'inv_cst_id = 2',
111            ]
112        );
113        $I->assertEquals(33.00, $total);
114
115        $total = Invoices::sum(
116            [
117                'column' => 'inv_total',
118                'where'  => 'inv_cst_id = 2',
119            ]
120        );
121        $I->assertEquals(266.00, $total);
122
123        $total = Invoices::sum(
124            [
125                'column'     => 'inv_total',
126                'conditions' => 'inv_cst_id = :custId:',
127                'bind'       => [
128                    'custId' => 2,
129                ],
130            ]
131        );
132        $I->assertEquals(33.00, $total);
133
134        $results = Invoices::sum(
135            [
136                'column' => 'inv_total',
137                'group'  => 'inv_cst_id',
138                'order'  => 'inv_cst_id',
139            ]
140        );
141        $I->assertInstanceOf(Simple::class, $results);
142        $I->assertEquals(1, (int)$results[0]->inv_cst_id);
143        $I->assertEquals(232, (int)$results[0]->sumatory);
144        $I->assertEquals(2, (int)$results[1]->inv_cst_id);
145        $I->assertEquals(33, (int)$results[1]->sumatory);
146        $I->assertEquals(3, (int)$results[2]->inv_cst_id);
147        $I->assertEquals(1, (int)$results[2]->sumatory);
148
149        $results = Invoices::sum(
150            [
151                'column' => 'inv_total',
152                'group'  => 'inv_cst_id',
153                'order'  => 'inv_cst_id DESC',
154            ]
155        );
156        $I->assertInstanceOf(Simple::class, $results);
157        $I->assertEquals(3, (int)$results[0]->inv_cst_id);
158        $I->assertEquals(1, (int)$results[0]->sumatory);
159        $I->assertEquals(2, (int)$results[1]->inv_cst_id);
160        $I->assertEquals(33, (int)$results[1]->sumatory);
161        $I->assertEquals(1, (int)$results[2]->inv_cst_id);
162        $I->assertEquals(232, (int)$results[2]->sumatory);
163    }
164
165    /**
166     * Tests Phalcon\Mvc\Model :: sum()
167     *
168     * @param DatabaseTester $I
169     *
170     * @author Phalcon Team <team@phalcon.io>
171     * @since  2020-01-30
172     *
173     * @group  mysql
174     * @group  pgsql
175     */
176    public function mvcModelSumTransaction(DatabaseTester $I)
177    {
178        $I->wantToTest('Phalcon\Mvc\Model :: sum() - with transaction');
179
180        $this->insertDataInvoices($this->invoiceMigration, 7, 'default', 2, 'ccc');
181        $this->insertDataInvoices($this->invoiceMigration, 1, 'default', 3, 'aaa');
182        $this->insertDataInvoices($this->invoiceMigration, 11, 'default', 1, 'aaa');
183
184        $originalTotal = Invoices::sum(
185            [
186                'column' => 'inv_total'
187            ]
188        );
189
190        /**
191         * @var Manager $transactionManager
192         */
193        $transactionManager = $this->getDi()->getShared('transactionManager');
194        $transaction        = $transactionManager->get();
195
196        /**
197         * @var Invoices $deletedInvoice
198         */
199        $deletedInvoice = Invoices::findFirst();
200        $deletedInvoice->setTransaction($transaction);
201        $deletedInvoice->delete();
202
203        $total = Invoices::sum(
204            [
205                'column'      => 'inv_total',
206                'transaction' => $transaction
207            ]
208        );
209
210        $I->assertEquals(
211            $originalTotal - $deletedInvoice->inv_total,
212            $total
213        );
214
215        $transaction->rollback();
216    }
217}
218