Issues (459)

Core/Lib/Accounting/ClosingToAcounting.php (2 issues)

1
<?php
2
/**
3
 * This file is part of FacturaScripts
4
 * Copyright (C) 2018-2021 Carlos Garcia Gomez <[email protected]>
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, either version 3 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace FacturaScripts\Core\Lib\Accounting;
21
22
use FacturaScripts\Core\Base\DataBase;
23
use FacturaScripts\Core\Base\DataBase\DataBaseWhere;
24
use FacturaScripts\Core\Model\Ejercicio;
25
use FacturaScripts\Dinamic\Lib\Import\CSVImport;
26
use FacturaScripts\Dinamic\Model\CuentaEspecial;
27
use FacturaScripts\Dinamic\Model\FacturaCliente;
28
use FacturaScripts\Dinamic\Model\FacturaProveedor;
29
30
/**
31
 * Class that performs accounting closures
32
 *
33
 * @author Carlos García Gómez  <[email protected]>
34
 * @author Jose Antonio Cuello Principal <[email protected]>
35
 */
36
class ClosingToAcounting
37
{
38
39
    /**
40
     * Indicates whether the accounting account plan should be copied
41
     * to the new fiscal year.
42
     *
43
     * @var bool
44
     */
45
    protected $copySubAccounts;
46
47
    /**
48
     * It provides direct access to the database.
49
     *
50
     * @var DataBase
51
     */
52
    protected static $dataBase;
53
54
    /**
55
     * Exercise where the accounting process is performed.
56
     *
57
     * @var Ejercicio
58
     */
59
    protected $exercise;
60
61
    /**
62
     * Journal Id for closing accounting entry.
63
     *
64
     * @var int
65
     */
66
    protected $journalClosing;
67
68
    /**
69
     * Journal Id for opening accounting entry.
70
     *
71
     * @var int
72
     */
73
    protected $journalOpening;
74
75
    /**
76
     * Class Constructor
77
     */
78
    public function __construct()
79
    {
80
        if (self::$dataBase === null) {
81
            self::$dataBase = new DataBase();
82
        }
83
    }
84
85
    /**
86
     * Execute the delete process, deleting selected entry accounts
87
     * and reopening exercise.
88
     *
89
     * @param Ejercicio $exercise
90
     * @param array $data
91
     *
92
     * @return bool
93
     */
94
    public function delete($exercise, $data): bool
95
    {
96
        $this->exercise = $exercise;
97
        $closing = $data['deleteClosing'] ?? true;
98
        $opening = $data['deleteOpening'] ?? true;
99
100
        self::$dataBase->beginTransaction();
101
102
        try {
103
            $exercise->estado = Ejercicio::EXERCISE_STATUS_OPEN;
104
            $exercise->save();
105
106
            if ($opening && !$this->deleteOpening()) {
107
                return false;
108
            }
109
110
            if ($closing && (!$this->deleteClosing() || !$this->deleteRegularization())) {
111
                return false;
112
            }
113
114
            self::$dataBase->commit();
115
        } finally {
116
            $result = !self::$dataBase->inTransaction();
117
            if ($result == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
118
                self::$dataBase->rollback();
119
            }
120
        }
121
122
        return $result;
123
    }
124
125
    /**
126
     * Execute the main process of regularization, closing and opening
127
     * of accounts.
128
     *
129
     * @param Ejercicio $exercise
130
     * @param array $data
131
     *
132
     * @return bool
133
     */
134
    public function exec($exercise, $data): bool
135
    {
136
        $this->exercise = $exercise;
137
        $this->journalClosing = $data['journalClosing'] ?? 0;
138
        $this->journalOpening = $data['journalOpening'] ?? 0;
139
        $this->copySubAccounts = $data['copySubAccounts'] ?? false;
140
141
        self::$dataBase->beginTransaction();
142
143
        try {
144
            $this->updateSpecialAccounts();
145
146
            if ($this->execCloseInvoices() && $this->execRegularization() && $this->execClosing() && $this->execOpening()) {
147
                $this->exercise->estado = Ejercicio::EXERCISE_STATUS_CLOSED;
148
                $this->exercise->save();
149
                self::$dataBase->commit();
150
            }
151
        } finally {
152
            $result = !self::$dataBase->inTransaction();
153
            if ($result == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
154
                self::$dataBase->rollback();
155
            }
156
        }
157
158
        return $result;
159
    }
160
161
    /**
162
     * Delete closing accounting entry
163
     *
164
     * @return bool
165
     */
166
    protected function deleteClosing(): bool
167
    {
168
        $closing = new AccountingClosingClosing();
169
        return $closing->delete($this->exercise);
170
    }
171
172
    /**
173
     * Delete opening accounting entry
174
     *
175
     * @return bool
176
     */
177
    protected function deleteOpening(): bool
178
    {
179
        $opening = new AccountingClosingOpening();
180
        return $opening->delete($this->exercise);
181
    }
182
183
    /**
184
     * Delete regularization accounting entry
185
     *
186
     * @return bool
187
     */
188
    protected function deleteRegularization(): bool
189
    {
190
        $regularization = new AccountingClosingRegularization();
191
        return $regularization->delete($this->exercise);
192
    }
193
194
    /**
195
     * Lock all invoices from this exercise.
196
     *
197
     * @return bool
198
     */
199
    protected function execCloseInvoices(): bool
200
    {
201
        // apply to customer invoices
202
        $customerInvoice = new FacturaCliente();
203
        $status1 = $customerInvoice->getAvailableStatus();
204
        $where = [
205
            new DataBaseWhere('editable', true),
206
            new DataBaseWhere('codejercicio', $this->exercise->codejercicio)
207
        ];
208
        foreach ($status1 as $stat) {
209
            if ($stat->editable || $stat->generadoc) {
210
                continue;
211
            }
212
213
            foreach ($customerInvoice->all($where, [], 0, 0) as $invoice) {
214
                $invoice->idestado = $stat->idestado;
215
                if (false === $invoice->save()) {
216
                    return false;
217
                }
218
            }
219
            break;
220
        }
221
222
        // apply to supplier invoices
223
        $supplierInvoice = new FacturaProveedor();
224
        $status2 = $supplierInvoice->getAvailableStatus();
225
        foreach ($status2 as $stat) {
226
            if ($stat->editable || $stat->generadoc) {
227
                continue;
228
            }
229
230
            foreach ($supplierInvoice->all($where, [], 0, 0) as $invoice) {
231
                $invoice->idestado = $stat->idestado;
232
                if (false === $invoice->save()) {
233
                    return false;
234
                }
235
            }
236
            break;
237
        }
238
239
        return true;
240
    }
241
242
    /**
243
     * Execute account closing
244
     *
245
     * @return bool
246
     */
247
    protected function execClosing(): bool
248
    {
249
        $closing = new AccountingClosingClosing();
250
        return $closing->exec($this->exercise, $this->journalClosing);
251
    }
252
253
    /**
254
     * Execute account opening
255
     *
256
     * @return bool
257
     */
258
    protected function execOpening(): bool
259
    {
260
        $opening = new AccountingClosingOpening();
261
        $opening->setCopySubAccounts($this->copySubAccounts);
262
        return $opening->exec($this->exercise, $this->journalOpening);
263
    }
264
265
    /**
266
     * Execute account regularization
267
     *
268
     * @return bool
269
     */
270
    protected function execRegularization(): bool
271
    {
272
        $regularization = new AccountingClosingRegularization();
273
        return $regularization->exec($this->exercise, $this->journalClosing);
274
    }
275
276
    /**
277
     * Update special accounts from data file.
278
     */
279
    protected function updateSpecialAccounts()
280
    {
281
        $sql = CSVImport::updateTableSQL(CuentaEspecial::tableName());
282
        if (!empty($sql) && self::$dataBase->tableExists(CuentaEspecial::tableName())) {
283
            self::$dataBase->exec($sql);
284
        }
285
    }
286
}
287