Passed
Push — master ( 64043f...33d76f )
by Carlos
04:40
created

ProductoTest::testCostPriceNoPolicy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
dl 0
loc 32
rs 9.6333
c 1
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * This file is part of FacturaScripts
4
 * Copyright (C) 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\Test\Core\Model;
21
22
use FacturaScripts\Core\App\AppSettings;
23
use FacturaScripts\Core\Model\Base\ModelCore;
24
use FacturaScripts\Core\Model\Fabricante;
25
use FacturaScripts\Core\Model\Familia;
26
use FacturaScripts\Core\Model\Impuesto;
27
use FacturaScripts\Core\Model\Producto;
28
use FacturaScripts\Core\Model\ProductoProveedor;
29
use FacturaScripts\Core\Model\Proveedor;
30
use FacturaScripts\Core\Model\Stock;
31
use FacturaScripts\Test\Core\LogErrorsTrait;
32
use PHPUnit\Framework\TestCase;
33
34
final class ProductoTest extends TestCase
35
{
36
    use LogErrorsTrait;
37
38
    public function testCreate()
39
    {
40
        $product = $this->getTestProduct();
41
        $this->assertTrue($product->save(), 'product-cant-save');
42
        $this->assertNotNull($product->primaryColumnValue(), 'estado-product-not-stored');
43
        $this->assertTrue($product->exists(), 'product-cant-persist');
44
        $this->assertTrue($product->delete(), 'product-cant-delete');
45
    }
46
47
    public function testCreateWithOutReference()
48
    {
49
        $product = new Producto();
50
        $product->descripcion = 'Test Product';
51
        $this->assertFalse($product->save(), 'product-cant-save');
52
    }
53
54
    public function testBlocked()
55
    {
56
        $product = $this->getTestProduct();
57
        $product->secompra = true;
58
        $product->sevende = true;
59
        $product->publico = true;
60
        $product->bloqueado = true;
61
        $this->assertTrue($product->save(), 'product-cant-save');
62
63
        // leemos de la base de datos y comprobamos los valores guardados
64
        $product->loadFromCode($product->primaryColumnValue());
65
        $this->assertFalse($product->publico, 'product-blocked-can-public');
66
        $this->assertFalse($product->secompra, 'product-blocked-can-buy');
67
        $this->assertFalse($product->sevende, 'product-blocked-can-sale');
68
        $this->assertTrue($product->delete(), 'product-cant-delete');
69
    }
70
71
    public function testFamily()
72
    {
73
        // creamos la familia
74
        $family = new Familia();
75
        $family->descripcion = 'Test Family';
76
        $this->assertTrue($family->save(), 'family-cant-save');
77
78
        // creamos un producto con esta familia
79
        $product = $this->getTestProduct();
80
        $product->codfamilia = $family->primaryColumnValue();
81
        $this->assertTrue($product->save(), 'product-cant-save');
82
83
        // eliminamos la familia
84
        $this->assertTrue($family->delete(), 'product-cant-delete');
85
86
        // recargamos el producto para ver que se ha desvinculado la familia
87
        $product->loadFromCode($product->primaryColumnValue());
88
        $this->assertNull($product->codfamilia, 'product-family-not-empty');
89
        $this->assertTrue($product->delete(), 'product-cant-delete');
90
    }
91
92
    public function testManufacturer()
93
    {
94
        // creamos un fabricante
95
        $manufacturer = new Fabricante();
96
        $manufacturer->nombre = 'Test Manufacturer';
97
        $this->assertTrue($manufacturer->save(), 'manufacturer-cant-save');
98
99
        // creamos un producto con este fabricante
100
        $product = $this->getTestProduct();
101
        $product->codfabricante = $manufacturer->primaryColumnValue();
102
        $this->assertTrue($product->save(), 'product-cant-save');
103
104
        // eliminamos el fabricante
105
        $this->assertTrue($manufacturer->delete(), 'manufacturer-cant-delete');
106
107
        // recargamos el producto para ver que se ha desvinculado el fabricante
108
        $product->loadFromCode($product->primaryColumnValue());
109
        $this->assertNull($product->codfabricante, 'product-manufacturer-not-empty');
110
        $this->assertTrue($product->delete(), 'product-cant-delete');
111
    }
112
113
    public function testTax()
114
    {
115
        // creamos un impuesto
116
        $tax = new Impuesto();
117
        $tax->descripcion = 'Test Tax';
118
        $tax->iva = 99;
119
        $this->assertTrue($tax->save(), 'tax-cant-save');
120
121
        // creamos un producto con este impuesto
122
        $product = $this->getTestProduct();
123
        $product->codimpuesto = $tax->primaryColumnValue();
124
        $this->assertTrue($product->save(), 'product-cant-save');
125
126
        // eliminamos el impuesto
127
        $this->assertTrue($tax->delete(), 'tax-cant-delete');
128
129
        // recargamos el producto para ver que se ha desvinculado el impuesto
130
        $product->loadFromCode($product->primaryColumnValue());
131
        $this->assertNull($product->codimpuesto, 'product-tax-not-empty');
132
        $this->assertTrue($product->delete(), 'product-cant-delete');
133
    }
134
135
    public function testCostPriceNoPolicy()
136
    {
137
        // asignamos ninguna política de precio de coste
138
        $settings = new AppSettings();
139
        $settings->set('default', 'costpricepolicy', '');
140
141
        // creamos un producto con coste 100
142
        $product = $this->getTestProduct();
143
        $this->assertTrue($product->save(), 'product-cant-save');
144
        $variant = $product->getVariants()[0];
145
        $variant->coste = 100;
146
        $this->assertTrue($variant->save(), 'variant-cant-save');
147
148
        // creamos un proveedor
149
        $supplier = $this->getTestSupplier();
150
        $this->assertTrue($supplier->save(), 'supplier-cant-save');
151
152
        // creamos un producto de proveedor con este proveedor y este producto
153
        $supplierProduct = new ProductoProveedor();
154
        $supplierProduct->codproveedor = $supplier->codproveedor;
155
        $supplierProduct->referencia = $product->referencia;
156
        $supplierProduct->idproducto = $product->idproducto;
157
        $supplierProduct->precio = 200;
158
        $this->assertTrue($supplierProduct->save(), 'supplier-product-cant-save');
159
160
        // recargamos la variante para comprobar que NO se ha actualizado el coste, ya que no hay política asignada
161
        $variant->loadFromCode($variant->primaryColumnValue());
162
        $this->assertTrue($variant->coste == 100, 'variant-cost-should-not-change');
163
164
        // eliminamos
165
        $this->assertTrue($product->delete(), 'product-cant-delete');
166
        $this->assertTrue($supplier->delete(), 'supplier-cant-delete');
167
    }
168
169
    public function testCostPricePolicyLastPrice()
170
    {
171
        // asignamos la política de precio de coste último precio
172
        $settings = new AppSettings();
173
        $settings->set('default', 'costpricepolicy', 'last-price');
174
175
        // creamos un producto con coste 50
176
        $product = $this->getTestProduct();
177
        $this->assertTrue($product->save(), 'product-cant-save');
178
        $variant = $product->getVariants()[0];
179
        $variant->coste = 50;
180
        $this->assertTrue($variant->save(), 'variant-cant-save');
181
182
        // creamos el proveedor 1
183
        $supplier1 = $this->getTestSupplier();
184
        $this->assertTrue($supplier1->save(), 'supplier-1-cant-save');
185
186
        // creamos un producto de proveedor con este proveedor y este producto
187
        $supplierProduct1 = new ProductoProveedor();
188
        $supplierProduct1->codproveedor = $supplier1->codproveedor;
189
        $supplierProduct1->referencia = $product->referencia;
190
        $supplierProduct1->idproducto = $product->idproducto;
191
        $supplierProduct1->precio = 100;
192
        $supplierProduct1->actualizado = date(ModelCore::DATETIME_STYLE, strtotime("- 1 days"));
193
        $this->assertTrue($supplierProduct1->save(), 'supplier-product-1-cant-save');
194
195
        // creamos el proveedor 2
196
        $supplier2 = $this->getTestSupplier();
197
        $this->assertTrue($supplier2->save(), 'supplier-2-cant-save');
198
199
        // creamos un producto de proveedor con este proveedor y este producto
200
        $supplierProduct2 = new ProductoProveedor();
201
        $supplierProduct2->codproveedor = $supplier2->codproveedor;
202
        $supplierProduct2->referencia = $product->referencia;
203
        $supplierProduct2->idproducto = $product->idproducto;
204
        $supplierProduct2->precio = 200;
205
        $this->assertTrue($supplierProduct2->save(), 'supplier-product-2-cant-save');
206
207
        // recargamos la variante para comprobar que SI se ha actualizado el coste
208
        $variant->loadFromCode($variant->primaryColumnValue());
209
        $this->assertTrue($variant->coste == 200, 'variant-cost-not-last');
210
211
        // eliminamos
212
        $this->assertTrue($product->delete(), 'product-cant-delete');
213
        $this->assertTrue($supplier1->delete(), 'supplier-cant-delete');
214
        $this->assertTrue($supplier2->delete(), 'supplier-cant-delete');
215
    }
216
217
    public function testCostPricePolicyAveragePrice()
218
    {
219
        // asignamos la política de precio de coste último precio
220
        $settings = new AppSettings();
221
        $settings->set('default', 'costpricepolicy', 'average-price');
222
223
        // creamos un producto con coste 50
224
        $product = $this->getTestProduct();
225
        $this->assertTrue($product->save(), 'product-cant-save');
226
        $variant = $product->getVariants()[0];
227
        $variant->coste = 50;
228
        $this->assertTrue($variant->save(), 'variant-cant-save');
229
230
        // creamos el proveedor 1
231
        $supplier1 = $this->getTestSupplier();
232
        $this->assertTrue($supplier1->save(), 'supplier-1-cant-save');
233
234
        // creamos un producto de proveedor con este proveedor y este producto
235
        $supplierProduct1 = new ProductoProveedor();
236
        $supplierProduct1->codproveedor = $supplier1->codproveedor;
237
        $supplierProduct1->referencia = $product->referencia;
238
        $supplierProduct1->idproducto = $product->idproducto;
239
        $supplierProduct1->precio = 100;
240
        $this->assertTrue($supplierProduct1->save(), 'supplier-product-cant-save');
241
242
        // creamos el proveedor 1
243
        $supplier2 = $this->getTestSupplier();
244
        $this->assertTrue($supplier2->save(), 'supplier-2-cant-save');
245
246
        // creamos un producto de proveedor con este proveedor y este producto
247
        $supplierProduct2 = new ProductoProveedor();
248
        $supplierProduct2->codproveedor = $supplier2->codproveedor;
249
        $supplierProduct2->referencia = $product->referencia;
250
        $supplierProduct2->idproducto = $product->idproducto;
251
        $supplierProduct2->precio = 200;
252
        $this->assertTrue($supplierProduct2->save(), 'supplier-product-cant-save');
253
254
        // recargamos la variante para comprobar que SI se ha actualizado el coste
255
        $variant->loadFromCode($variant->primaryColumnValue());
256
        $this->assertTrue($variant->coste == 150, 'variant-cost-not-average');
257
258
        // eliminamos
259
        $this->assertTrue($product->delete(), 'product-cant-delete');
260
        $this->assertTrue($supplier1->delete(), 'supplier-cant-delete');
261
        $this->assertTrue($supplier2->delete(), 'supplier-cant-delete');
262
    }
263
264
    public function testStock()
265
    {
266
        // creamos el producto
267
        $product = $this->getTestProduct();
268
        $this->assertTrue($product->save(), 'product-cant-save');
269
270
        // creamos el stock
271
        $stock = new Stock();
272
        $stock->idproducto = $product->idproducto;
273
        $stock->referencia = $product->referencia;
274
        $stock->cantidad = 99;
275
        $this->assertTrue($stock->save(), 'stock-cant-save');
276
277
        // recargamos el producto para comprobar que el stock se ha actualizado
278
        $product->loadFromCode($product->primaryColumnValue());
279
        $variant = $product->getVariants()[0];
280
        $this->assertTrue($product->stockfis == $stock->cantidad, 'product-different-stock');
281
        $this->assertTrue($variant->stockfis == $stock->cantidad, 'variant-different-stock');
282
283
        // indicamos que el producto no tiene stock
284
        $product->nostock = true;
285
        $this->assertTrue($product->save(), 'product-cant-save');
286
287
        // recargamos el producto para comprobar que el stock se ha actualizado
288
        $product->loadFromCode($product->primaryColumnValue());
289
        $this->assertEquals(0, $product->stockfis, 'product-cant-stock');
290
        $variant->loadFromCode($variant->primaryColumnValue());
291
        $this->assertEquals(0, $variant->stockfis, 'variant-cant-stock');
292
293
        // Comprobamos que el stock ha sido eliminado
294
        $this->assertFalse($stock->loadFromCode($stock->primaryColumnValue()), 'stock-cant-load-after-delete');
295
296
        // eliminamos
297
        $this->assertTrue($product->delete(), 'product-cant-delete');
298
    }
299
300
    public function testVariante()
301
    {
302
        // creamos un producto con precio
303
        $product = $this->getTestProduct();
304
        $product->precio = 10;
305
        $this->assertTrue($product->save(), 'product-cant-save');
306
307
        // obtenemos las variantes
308
        $variants = $product->getVariants();
309
        $this->assertCount(1, $variants, 'product-more-than-one-variant');
310
311
        // comprobamos que precio y referencia son correctos
312
        $this->assertEquals($product->referencia, $variants[0]->referencia, 'product-variant-different-reference');
313
        $this->assertEquals($product->precio, $variants[0]->precio, 'product-variant-different-price');
314
315
        // comprobamos que no podemos eliminar la única variante
316
        $this->assertFalse($variants[0]->delete(), 'can-delete-only-variant');
317
318
        // modificamos el precio de la variante
319
        $variants[0]->precio = 133;
320
        $this->assertTrue($variants[0]->save(), 'variant-cant-save');
321
322
        // recargamos producto y comprobamos que se ha actualizado el precio
323
        $this->assertTrue($product->loadFromCode($product->idproducto));
324
        $this->assertEquals(133, $product->precio, 'product-price-not-updated');
325
326
        // comprobamos que el precio se calcula a partir de coste y margen
327
        $variants[0]->coste = 100;
328
        $variants[0]->margen = 20;
329
        $this->assertTrue($variants[0]->save(), 'variant-cant-save');
330
331
        // recargamos variante y comprobamos precio
332
        $this->assertTrue($variants[0]->loadFromCode($variants[0]->primaryColumnValue()), 'cant-reload-variant');
333
        $this->assertEquals(120, $variants[0]->precio, 'variant-difference-price');
334
335
        // recargamos producto y comprobamos precio
336
        $this->assertTrue($product->loadFromCode($product->idproducto));
337
        $this->assertEquals(120, $product->precio, 'product-price-not-updated');
338
339
        // eliminamos
340
        $this->assertTrue($product->delete(), 'product-cant-delete');
341
        $this->assertFalse($variants[0]->exists(), 'variant-still-exists');
342
    }
343
344
    private function getTestProduct(): Producto
345
    {
346
        $product = new Producto();
347
        $product->referencia = 'Test';
348
        $product->descripcion = 'Test Product';
349
        return $product;
350
    }
351
352
    private function getTestSupplier(): Proveedor
353
    {
354
        $num = mt_rand(1, 999);
355
        $supplier = new Proveedor();
356
        $supplier->codproveedor = 'TEST' . $num;
357
        $supplier->nombre = 'Test Supplier ' . $num;
358
        $supplier->cifnif = $num . '345678A';
359
        return $supplier;
360
    }
361
362
    protected function tearDown()
363
    {
364
        $this->logErrors();
365
    }
366
}
367