Test Failed
Push — master ( 85c479...e17ab3 )
by Carlos
09:39 queued 54s
created

InvoiceTrait::delete()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 17
nc 7
nop 0
dl 0
loc 31
rs 8.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of FacturaScripts
4
 * Copyright (C) 2013-2024 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\Model\Base;
21
22
use FacturaScripts\Core\Base\DataBase\DataBaseWhere;
23
use FacturaScripts\Core\Tools;
24
use FacturaScripts\Dinamic\Lib\Accounting\InvoiceToAccounting;
25
use FacturaScripts\Dinamic\Lib\ReceiptGenerator;
26
use FacturaScripts\Dinamic\Model\Asiento;
27
28
/**
29
 * Description of InvoiceTrait
30
 *
31
 * @author Carlos García Gómez <[email protected]>
32
 */
33
trait InvoiceTrait
34
{
35
    use AccEntryRelationTrait;
36
37
    /** @var string */
38
    public $codigorect;
39
40
    /** @var bool */
41
    public $editable;
42
43
    /** @var string */
44
    public $fecha;
45
46
    /** @var string */
47
    public $fechadevengo;
48
49
    /** @var int */
50
    public $idfactura;
51
52
    /** @var int */
53
    public $idfacturarect;
54
55
    /** @var bool */
56
    public $pagada;
57
58
    /** @var array */
59
    private $refunds;
60
61
    /** @return bool */
62
    public $vencida;
63
64
    abstract public static function all(array $where = [], array $order = [], int $offset = 0, int $limit = 50): array;
65
66
    abstract public function getReceipts(): array;
67
68
    abstract public function testDate(): bool;
69
70
    public function delete(): bool
71
    {
72
        if (false === $this->editable) {
73
            Tools::log()->warning('non-editable-document');
74
            return false;
75
        }
76
77
        // si tiene rectificativas, no se puede eliminar
78
        if (!empty($this->getRefunds())) {
79
            Tools::log()->warning('cant-remove-invoice-refund');
80
            return false;
81
        }
82
83
        // remove receipts
84
        foreach ($this->getReceipts() as $receipt) {
85
            $receipt->disableInvoiceUpdate(true);
86
            if (false === $receipt->delete()) {
87
                Tools::log()->warning('cant-remove-receipt');
88
                return false;
89
            }
90
        }
91
92
        // remove accounting
93
        $acEntry = $this->getAccountingEntry();
94
        $acEntry->editable = true;
95
        if ($acEntry->exists() && false === $acEntry->delete()) {
96
            Tools::log()->warning('cant-remove-accounting-entry');
97
            return false;
98
        }
99
100
        return parent::delete();
101
    }
102
103
    /**
104
     * @return static[]
105
     */
106
    public function getRefunds(): array
107
    {
108
        if (empty($this->idfactura)) {
109
            return [];
110
        }
111
112
        if (!isset($this->refunds)) {
113
            $where = [new DataBaseWhere('idfacturarect', $this->idfactura)];
114
            $this->refunds = $this->all($where, ['idfactura' => 'DESC'], 0, 0);
115
        }
116
117
        return $this->refunds;
118
    }
119
120
    /**
121
     * This function is called when creating the model table. Returns the SQL
122
     * that will be executed after the creation of the table. Useful to insert values
123
     * default.
124
     *
125
     * @return string
126
     */
127
    public function install(): string
128
    {
129
        $sql = parent::install();
130
        new Asiento();
131
132
        return $sql;
133
    }
134
135
    public function paid(): bool
136
    {
137
        return $this->pagada;
138
    }
139
140
    /**
141
     * Returns all parent document of this one.
142
     *
143
     * @return TransformerDocument[]
144
     */
145
    public function parentDocuments(): array
146
    {
147
        $parents = parent::parentDocuments();
148
        $where = [new DataBaseWhere('idfactura', $this->idfacturarect)];
149
        foreach ($this->all($where, ['idfactura' => 'DESC'], 0, 0) as $invoice) {
150
            // is this invoice in parents?
151
            foreach ($parents as $parent) {
152
                if ($parent->primaryColumnValue() == $invoice->primaryColumnValue()) {
153
                    continue 2;
154
                }
155
            }
156
157
            $parents[] = $invoice;
158
        }
159
160
        return $parents;
161
    }
162
163
    /**
164
     * Returns the name of the column that is the model's primary key.
165
     *
166
     * @return string
167
     */
168
    public static function primaryColumn(): string
169
    {
170
        return 'idfactura';
171
    }
172
173
    /**
174
     * @param string $field
175
     *
176
     * @return bool
177
     */
178
    protected function onChange($field)
179
    {
180
        if (false === parent::onChange($field)) {
181
            return false;
182
        }
183
184
        switch ($field) {
185
            case 'codcliente':
186
            case 'codproveedor':
187
                // prevent from removing paid receipts
188
                foreach ($this->getReceipts() as $receipt) {
189
                    if ($receipt->pagado) {
190
                        Tools::log()->warning('paid-receipts-prevent-action');
191
                        return false;
192
                    }
193
                }
194
            // no break
195
            case 'codpago':
196
                // remove unpaid receipts
197
                foreach ($this->getReceipts() as $receipt) {
198
                    if (false === $receipt->pagado && false === $receipt->delete()) {
199
                        Tools::log()->warning('cant-remove-receipt');
200
                        return false;
201
                    }
202
                }
203
            // no break
204
            case 'fecha':
205
                if (false === $this->testDate()) {
206
                    return false;
207
                }
208
            // no break
209
            case 'fechadevengo':
210
            case 'total':
211
                return $this->onChangeTotal();
212
        }
213
214
        return true;
215
    }
216
217
    protected function onChangeTotal(): bool
218
    {
219
        // remove accounting entry
220
        $asiento = $this->getAccountingEntry();
221
        $asiento->editable = true;
222
        if ($asiento->exists() && false === $asiento->delete()) {
223
            Tools::log()->warning('cant-remove-account-entry');
224
            return false;
225
        }
226
227
        // create a new accounting entry
228
        $this->idasiento = null;
229
        $tool = new InvoiceToAccounting();
230
        $tool->generate($this);
231
232
        // check receipts
233
        $generator = new ReceiptGenerator();
234
        $generator->generate($this);
235
        $generator->update($this);
236
237
        return true;
238
    }
239
240
    protected function setPreviousData(array $fields = [])
241
    {
242
        $more = ['fechadevengo'];
243
        parent::setPreviousData(array_merge($more, $fields));
244
    }
245
}
246