Completed
Push — master ( cf322c...76fc12 )
by Reginaldo
37:12 queued 18:07
created

ProdutoController::salvar_imagem()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 22
nc 3
nop 1
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
require_once(ROOT . DS . 'vendor' . DS . 'autoload.php');
4
5
use Dompdf\Dompdf;
6
7
class ProdutoController extends AppController{		
8
9
	public function listar_cadastros() {
10
		$this->layout = 'wadmin';
11
	}
12
13
	public function listar_cadastros_ajax() {
0 ignored issues
show
Coding Style introduced by
listar_cadastros_ajax uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
14
		$this->layout = 'ajax';
15
16
		$aColumns = array( 'sku', 'imagem', 'nome', 'preco', 'estoque' );
17
		
18
		$conditions = array('conditions' =>
19
			array(
20
				'ativo' => 1,
21
				'id_usuario' => $this->instancia
22
			)
23
		);
24
25
		$allProdutos = $this->Produto->find('all', $conditions);
26
		
27 View Code Duplication
		if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
28
		{
29
			$conditions['offset'] = $_GET['iDisplayStart'];
30
			$conditions['limit'] = $_GET['iDisplayLength'];
31
		}
32
33 View Code Duplication
		if ( isset( $_GET['iSortCol_0'] ) )
34
		{
35
			for ( $i=0 ; $i < intval( $_GET['iSortingCols'] ) ; $i++ )
36
			{
37
				if ( $_GET[ 'bSortable_' . intval($_GET['iSortCol_' . $i]) ] == "true" )
38
				{
39
					$conditions['order'] = array('Produto.' . $aColumns[intval($_GET['iSortCol_' . $i])] => $_GET['sSortDir_'.$i]);
40
				}
41
			}
42
		}
43
44 View Code Duplication
		if ( isset( $_GET['sSearch'] ) && !empty( $_GET['sSearch'] ) )
45
		{
46
			$conditions['conditions']['Produto.nome LIKE '] = '%' . $_GET['sSearch'] . '%';
47
		}
48
		
49
		$produtos = $this->Produto->find('all', $conditions);
50
51
		$output = array(
52
			"sEcho" => intval($_GET['sEcho']),
53
			"iTotalDisplayRecords" => count($allProdutos),
54
			"iTotalRecords" => count($produtos),
55
			"aaData" => array()
56
		);
57
58
		foreach ( $produtos as $i => $produto )
59
		{
60
			$row = array();
61
62
			for ( $i=0 ; $i < count($aColumns) ; $i++ )
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
63
			{
64
				$value = $produto['Produto'][$aColumns[$i]];
65
66
				if ($aColumns[$i] == "imagem")
67
				{
68
					$value = '<img src="/uploads/produto/imagens/' . $produto['Produto'][$aColumns[$i]] . '" width="120" height="120">';
69
70
					if (!isset($produto['Produto'][$aColumns[$i]]) || empty($produto['Produto'][$aColumns[$i]]))
71
					{
72
						$value = '<img src="/images/no_image.png" width="120" height="120">';
73
					}
74
				}
75
				
76
				$row[] = $value;
77
			}
78
79
			$btEdit = '<a class="btn btn-info" href="/produto/editar_cadastro/' . $produto['Produto']['id'] . '"><i class="fa fa-pencil"></i></a>';
80
81
			$btImage = ' <a class="btn btn-primary" href="/produto/imagens/' . $produto['Produto']['id'] . '"><i class="fa fa-picture-o"></i></a>';
82
83
			$row[] = $btEdit . $btImage;
84
85
			$output['aaData'][] = $row;
86
		}
87
		
88
		echo json_encode($output);
89
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method listar_cadastros_ajax() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
90
	}
91
92
	public function imagens($id) {
93
		$this->layout = 'wadmin';
94
95
		$produto = $this->Produto->find('first', array(
96
				'conditions' => array(
97
					'Produto.id' => $id
98
				)
99
			)
100
		);
101
102
		$this->loadModel('Imagen');
103
		$imagens = $this->Imagen->find('all', array(
104
				'conditions' => array(
105
					'Imagen.produto_id' => $id,
106
					'Imagen.usuario_id' => $this->instancia,
107
					'Imagen.ativo' => 1
108
				)
109
			)
110
		);
111
112
		$this->set('imagens', $imagens);
113
		$this->set('produto', $produto);
114
	}
115
116
	public function listar_cadastros_estoque_minimo(){
117
		$this->layout = 'wadmin';
118
	}
119
120
	public function listar_cadastros_estoque_minimo_ajax(){
0 ignored issues
show
Coding Style introduced by
listar_cadastros_estoque_minimo_ajax uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
121
122
		$this->layout = 'ajax';
123
124
		$aColumns = array( 'sku', 'imagem', 'nome', 'preco', 'estoque' );
125
126
		$this->loadModel('Usuario');
127
128
		$usuario = $this->Usuario->find('all', array('conditions' =>
129
				array(
130
					'Usuario.id' => $this->instancia
131
				)
132
			)
133
		)[0]['Usuario'];
134
		
135
		$conditions = array('conditions' =>
136
			array(
137
				'ativo' => 1,
138
				'id_usuario' => $this->instancia,
139
				'Produto.estoque < ' => 'Produto.quantidade_minima',
140
				//'OR' => array(
141
				//	'Produto.estoque <= ' => $usuario['estoque_minimo']
142
				//)
143
			)
144
		);
145
146
		$allProdutos = $this->Produto->query("select * from produtos where estoque < quantidade_minima and id_usuario = " . $this->instancia . " and ativo = 1");
147
148
		
149
		$sql = "select * from produtos as Produto where estoque < quantidade_minima and id_usuario = " . $this->instancia . " and ativo = 1";
150
151
		if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
152
		{
153
			$sql .= ' LIMIT ' . $_GET['iDisplayLength'] . ' OFFSET ' . $_GET['iDisplayStart'];
154
		}
155
156 View Code Duplication
		if ( isset( $_GET['iSortCol_0'] ) )
157
		{
158
			for ( $i=0 ; $i < intval( $_GET['iSortingCols'] ) ; $i++ )
159
			{
160
				if ( $_GET[ 'bSortable_' . intval($_GET['iSortCol_' . $i]) ] == "true" )
161
				{
162
					$conditions['order'] = array('Produto.' . $aColumns[intval($_GET['iSortCol_' . $i])] => $_GET['sSortDir_'.$i]);
163
				}
164
			}
165
		}
166
		
167 View Code Duplication
		if ( isset( $_GET['sSearch'] ) && !empty( $_GET['sSearch'] ) )
168
		{
169
			$conditions['conditions']['Produto.nome LIKE '] = '%' . $_GET['sSearch'] . '%';
170
		}
171
172
		$produtos = $this->Produto->query($sql);
173
174
		$output = array(
175
			"sEcho" => intval($_GET['sEcho']),
176
			"iTotalDisplayRecords" => count($allProdutos),
177
			"iTotalRecords" => count($produtos),
178
			"aaData" => array()
179
		);
180
181
		foreach ( $produtos as $i => $produto )
182
		{
183
			$row = array();
184
185
			for ( $i=0 ; $i < count($aColumns) ; $i++ )
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
186
			{
187
				$value = $produto['Produto'][$aColumns[$i]];
188
189
				if ($aColumns[$i] == "imagem")
190
				{
191
					$value = '<img src="/uploads/produto/imagens/' . $produto['Produto'][$aColumns[$i]] . '" width="120" height="120">';
192
193
					if (!isset($produto['Produto'][$aColumns[$i]]) || empty($produto['Produto'][$aColumns[$i]]))
194
					{
195
						$value = '<img src="/images/no_image.png" width="120" height="120">';
196
					}
197
				}
198
				
199
				$row[] = $value;
200
			}
201
202
			$output['aaData'][] = $row;
203
		}
204
		
205
		echo json_encode($output);
206
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method listar_cadastros_estoque_minimo_ajax() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
207
	}
208
209
	public function baixar_estoque_minimo_pdf() {
210
		$this->loadModel('Produto');
211
		$this->loadModel('Usuario');
212
213
		$dompdf = new Dompdf();
214
215
		$usuario = $this->Usuario->find('all', array('conditions' =>
216
				array(
217
					'Usuario.id' => $this->instancia
218
				)
219
			)
220
		)[0]['Usuario'];
221
222
		$conditions = array('conditions' =>
223
			array(
224
				'ativo' => 1,
225
				'id_usuario' => $this->instancia,
226
				'Produto.estoque < ' => 'Produto.quantidade_minima',
227
				//'OR' => array(
228
				//	'Produto.estoque <= ' => $usuario['estoque_minimo']
229
				//)
230
			)
231
		);
232
233
		$produtos = $this->Produto->query("select * from produtos as Produto where estoque < quantidade_minima and id_usuario = " . $this->instancia . " and ativo = 1");
234
		
235
		$html = $this->getProdutosEstoqueMinimoComoHtml($produtos);
236
237
		$dompdf->loadHtml($html);
238
239
		$dompdf->set_paper(array(0, 0, 595.28, count($produtos) * 25));
0 ignored issues
show
Deprecated Code introduced by
The method Dompdf\Dompdf::set_paper() has been deprecated.

This method has been deprecated.

Loading history...
240
241
		$dompdf->render();
242
243
		$dompdf->stream();
244
245
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method baixar_estoque_minimo_pdf() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
246
	}
247
248
	public function getProdutosEstoqueMinimoComoHtml($produtos) {
249
    	ob_start();
250
251
		$html = '';
252
		$html .= '<html>';
253
		$html .= '<head>';
254
		$html .= '	<title></title>';
255
		$html .= '</head>';
256
		$html .= '<body>';
257
		$html .= '';
258
		$html .= '	<table style="background-color: #cacaca;"  width="100%" valign="center" align="center">';
259
		$html .= '		<tr align="center">';
260
		$html .= '			<td>';
261
		$html .= '				<h2>Produtos com quantidade de estoque minimo</h2>';
262
		$html .= '			</td>';
263
		$html .= '		</tr> ';
264
		$html .= '	</table>';
265
		$html .= '	<br>';
266
		$html .= '	<br>';
267
		$html .= '	<table  width="100%" valign="center" align="center">';
268
		$html .= '		<tr style="background-color: #cacaca;" align="center">';
269
		$html .= '			<td>';
270
		$html .= '				<h2>Produtos</h2>';
271
		$html .= '			</td>';
272
		$html .= '		</tr> ';
273
		$html .= '	</table>';
274
		$html .= '	<br>';
275
		$html .= '	<table  width="100%" valign="center" align="center">';
276
		$html .= '		<tr>';
277
		$html .= '			<td>';
278
		$html .= '				<table width="100%" valign="center" align="center">';
279
		$html .= '					<tr style="background-color: #cacaca;">';
280
		$html .= '						<td>Nome Produto</td>';
281
		$html .= '						<td>Quantidade</td>';
282
		$html .= '						<td>Custo</td>';
283
		$html .= '					</tr>';
284
		$html .= '';
285
286
		foreach ($produtos as $i => $produto) {
287
			$html .= '					<tr>';
288
			$html .= '						<td>' . $produto['Produto']['nome'] . '</td>';
289
			$html .= '						<td>' . $produto['Produto']['estoque'] . '</td>';
290
			$html .= '						<td>R$ ' . number_format($produto['Produto']['custo'], 2, ',', '.') . '</td>';
291
			$html .= '					</tr>';
292
		}
293
294
		$html .= '				</table>';
295
		$html .= '			</td>';
296
		$html .= '		</tr>';
297
		$html .= '	</table>';
298
		$html .= '	<br>';
299
		$html .= '';
300
		$html .= '</body>';
301
		$html .= '</html>';
302
		echo $html;exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method getProdutosEstoqueMinimoComoHtml() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
303
		return $html;
0 ignored issues
show
Unused Code introduced by
return $html; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
304
	}
305
306 View Code Duplication
	public function adicionar_cadastro() {
307
		$this->loadModel('Categoria');
308
309
		$this->set('categorias', $this->Categoria->find('all', 
310
				array('conditions' => 
311
					array('ativo' => 1,
312
						  'usuario_id' => $this->instancia
313
					)
314
				)
315
			)
316
		);	
317
318
		$this->layout = 'wadmin';
319
	}
320
321
	public function s_adicionar_cadastro() {
0 ignored issues
show
Coding Style introduced by
s_adicionar_cadastro uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
322
		$dados  = $this->request->data('dados');
323
324
		$variacoes = $this->request->data('variacao');
325
326
		$image  = $_FILES['imagem'];
327
328
		$retorno = $this->uploadImage($image);
329
330
		if (!$retorno['status']) 
331
			$this->Session->setFlash('Não foi possivel salvar a imagem tente novamente');
332
333
		$dados['imagem'] = $retorno['nome'];
334
		$dados['id_usuario'] = $this->instancia;
335
		$dados['ativo'] = 1;
336
		$dados['id_alias'] = $this->id_alias();
337
		$dados['preco'] = str_replace(',', '', $dados['preco']);
338
339
		if($this->Produto->save($dados)) {
340
			$produto_id = $this->Produto->getLastInsertId();
341
			
342
			require 'VariacaoController.php';
343
344
			$objVariacaoController = new VariacaoController();
345
346
			$objVariacaoController->s_adicionar_variacao($variacoes, $produto_id, $this->instancia);			
347
348
			if ($this->verificar_modulo_ativo('pluggto'))
349
			{
350
				require 'PluggtoController.php';
351
				$objPluggTo = new PluggtoController();
352
				$produto_pluggto = $objPluggTo->enviar_produto($dados, $variacoes);
353
354
				if (!isset($produto_pluggto->Product->id)) 
355
				{
356
					$this->Session->setFlash('Produto não foi enviado para o Plugg.to!');
357
				}
358
			}
359
360
			$this->Session->setFlash('Produto salvo com sucesso!');
361
            
362
            return $this->redirect('/produto/listar_cadastros');
363
		} else {
364
			$this->Session->setFlash('Ocorreu um erro ao salva o produto!');
365
            
366
            return $this->redirect('/produto/listar_cadastros');
367
		}
368
	}
369
370
	public function editar_cadastro($id) {
371
		$this->layout = 'wadmin';
372
373
		$this->loadModel('Variacao');
374
375
		$query = array (
376
			'joins' => array(
377
				    array(
378
				        'table' => 'produtos',
379
				        'alias' => 'Produto',
380
				        'type' => 'LEFT',
381
				        'conditions' => array(
382
				            'Variacao.produto_id = Produto.id',
383
				        ),
384
				    )
385
				),
386
	        'conditions' => array('Variacao.produto_id' => $id, 'Variacao.ativo' => 1),
387
	        'fields' => array('Produto.id, Variacao.*'),
388
		);
389
390
		$variacoes = $this->set('variacoes', $this->Variacao->find('all', $query));
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $variacoes is correct as $this->set('variacoes', ...o->find('all', $query)) (which targets Controller::set()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
391
392
		$this->set('produto', $this->Produto->find('all', 
393
				array('conditions' => 
394
					array('ativo' => 1,
395
						  'id' => $id
396
					)
397
				)
398
			)[0]
399
		);
400
401
		$this->loadModel('Categoria');
402
403
		$this->set('categorias', $this->Categoria->find('all', 
404
				array('conditions' => 
405
					array('ativo' => 1,
406
						  'usuario_id' => $this->instancia
407
					)
408
				)
409
			)
410
		);	
411
	}
412
413
	public function s_editar_cadastro($id) {
0 ignored issues
show
Coding Style introduced by
s_editar_cadastro uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
414
		$dados = $this->request->data('dados');
415
416
		$variacoes = $this->request->data('variacao');
417
418
		$image  = $_FILES['imagem'];
419
		
420 View Code Duplication
		if (!empty($image['name'])) {
421
			$retorno = $this->uploadImage($image);
422
			
423
			if (!$retorno['status']) 
424
				$this->Session->setFlash('Não foi possivel salvar a imagem tente novamente');
425
			
426
			$dados['imagem'] = $retorno['nome'];
427
		}
428
429
430
		$dados['id_usuario'] = $this->instancia;
431
		$dados['ativo'] = 1;
432
		$dados['id_alias'] = $this->id_alias();
433
		$dados['preco'] = str_replace(',', '', $dados['preco']);
434
435
		$this->Produto->id = $id;
436
		
437
		if ($this->Produto->save($dados)) {
438
439
			require 'VariacaoController.php';
440
			$objVariacaoController = new VariacaoController();
441
			$objVariacaoController->desativar_variacoes($id);
442
			$objVariacaoController->s_adicionar_variacao($variacoes, $id, $this->instancia);	
443
444
			$this->Session->setFlash('Produto editado com sucesso!','default','good');
445
            return $this->redirect('/produto/listar_cadastros');
446
		} else {
447
			$this->Session->setFlash('Ocorreu um erro ao editar o produto!','default','good');
448
            return $this->redirect('/produto/listar_cadastros');
449
		}
450
	}
451
452 View Code Duplication
	public function excluir_cadastro() {
453
		$this->layout = 'ajax';
454
455
		$id = $this->request->data('id');
456
457
		$dados = array('ativo' => '0');
458
		$parametros = array('id' => $id);
459
460
		if ($this->Produto->updateAll($dados, $parametros)) {
461
			echo json_encode(true);
462
		} else {
463
			echo json_encode(false);
464
		}
465
	}
466
467
	public function id_alias() {
468
		$id_alias = $this->Produto->find('first', array(
469
				'conditions' => array('Produto.ativo' => 1),
470
				'order' => array('Produto.id' => 'desc')
471
			)
472
		);
473
474
		return $id_alias['Produto']['id_alias'] + 1;
475
	}
476
477
	public function carregar_dados_venda_ajax() {
478
		$this->layout = 'ajax';
479
480
		$retorno = $this->Produto->find('first', 
481
			array('conditions' => 
482
				array('Produto.ativo' => 1,
483
					  'Produto.id_usuario' => $this->instancia,
484
					  'Produto.id' => $this->request->data('id')
485
				)
486
			)
487
		);
488
489
		if (!$this->validar_estoque($retorno)) {
490
			return false;
491
		}
492
493
		$retorno['Produto']['total'] = $this->calcular_preco_produto_venda($retorno['Produto']['preco'], $this->request->data('qnt'));
494
495
		$retorno['Produto']['preco'] = (float) $retorno['Produto']['preco'];
496
		
497
		echo json_encode($retorno);
498
	}
499
500 View Code Duplication
	public function getUserActive($id) {
501
		$this->loadModel('Usuario');
502
503
		$user = $this->Usuario->find('all', 
504
			array('conditions' => 
505
				array('Usuario.id' => $id)
506
			)
507
		);
508
		
509
		return $user;
510
	}
511
512
	public function validar_estoque($produto) {
513
514
		$user_active = $this->getUserActive($produto['Produto']['id_usuario']);
515
516
		if ($user_active[0]['Usuario']['sale_without_stock'])
517
			return true;
518
519
		if (empty($produto) && !isset($produto)) {
520
			return false;
521
		}
522
		
523
		if ($produto['Produto']['estoque'] <= 0) {
524
			return false;
525
		}
526
527
		return true;
528
	}
529
530
	public function calcular_preco_produto_venda($preco, $qnt) {
531
		if (empty($preco) || !isset($preco)) {
532
			return false;
533
		}
534
535
		if (!is_numeric($qnt)) {
536
			return false;
537
		}
538
539
		$retorno = $preco * $qnt;
540
541
		return (float) $retorno;
542
	}
543
544
	public function uploadImage(&$image) {
545
		$type = substr($image['name'], -4);
546
		$nameImage = uniqid() . md5($image['name']) . $type;
547
		$dir = APP . 'webroot/uploads/produto/imagens/';
548
		
549
		$returnUpload = move_uploaded_file($image['tmp_name'], $dir . $nameImage);
550
551
		if (!$returnUpload)
552
			return array('nome' => null, 'status' => false);
553
554
		return array('nome' => $nameImage, 'status' => true);
555
	}
556
557
	public function visualizar_cadastro($id) {
558
		$this->layout = 'wadmin';
559
560
		$produto = $this->Produto->find('all', 
561
			array('conditions' => 
562
				array('ativo' => 1,
563
					  'id' => $id
564
				)
565
			)
566
		);
567
568
		if (empty($produto)) {
569
			$this->Session->setFlash("Produto não encotrado, tente novamente");
570
			$this->redirect("/produto/listar_cadastros");
571
		}
572
573
		$this->set('produto', $produto[0]);
574
	}
575
576
	public function exportar_excel_exemplo() {
577
		include(APP . 'Vendor/PHPExcel/PHPExcel.php');
578
		include(APP . 'Vendor/PHPExcel/PHPExcel/IOFactory.php');
579
580
        $objPHPExcel = new PHPExcel();
581
        // Definimos o estilo da fonte
582
        $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
583
584
        $objPHPExcel->getActiveSheet()->getRowDimension('1')->setRowHeight(40);
585
586
        // Criamos as colunas
587
        $objPHPExcel->setActiveSheetIndex(0)
0 ignored issues
show
Bug introduced by
The method setCellValue does only exist in PHPExcel_Worksheet, but not in PHPExcel_Cell.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
588
                    ->setCellValue('A1', "Nome do Produto")
589
                    ->setCellValue('B1', "Preço ")
590
                    ->setCellValue("C1", "Peso Bruto")
591
                    ->setCellValue("D1", "Peso Liquido")
592
                    ->setCellValue("E1", "Estoque")
593
                    ->setCellValue("F1", "Descrição");
594
595
        // Podemos renomear o nome das planilha atual, lembrando que um único arquivo pode ter várias planilhas
596
        $objPHPExcel->getActiveSheet()->setTitle('Listagem de produtos');
597
598
        // Cabeçalho do arquivo para ele baixar
599
        header('Content-Type: application/vnd.ms-excel');
600
        header('Content-Disposition: attachment;filename="planilha_importacao_exemplo.xls"');
601
        header('Cache-Control: max-age=0');
602
        // Se for o IE9, isso talvez seja necessário
603
        header('Cache-Control: max-age=1');
604
605
        // Acessamos o 'Writer' para poder salvar o arquivo
606
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
607
608
        // Salva diretamente no output, poderíamos mudar arqui para um nome de arquivo em um diretório ,caso não quisessemos jogar na tela
609
        $objWriter->save('php://output'); 
610
611
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method exportar_excel_exemplo() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
612
    }
613
614
    public function importar_produtos_planilha() {
0 ignored issues
show
Coding Style introduced by
importar_produtos_planilha uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
615
        if (!isset($_FILES['arquivo']['tmp_name']) && empty($_FILES['arquivo']['tmp_name']))
616
        {
617
			$this->Session->setFlash("Erro ao subir a planilha, tente novamente.");
618
			$this->redirect("/produto/listar_cadastros");        	
619
        }
620
621
        $typesPermissions = ['application/vnd.ms-excel'];
622
623
        if (!in_array($_FILES['arquivo']['type'], $typesPermissions))
624
        {
625
			$this->Session->setFlash("O arquivo deve ser no formato .xls.");
626
			$this->redirect("/produto/listar_cadastros");                	
627
        }
628
629
        $caminho = APP . 'webroot/uploads/produto/planilhas/' . uniqid() . '.xls';
630
631
        $inputFileName = $_FILES['arquivo']['tmp_name'];
632
633
        move_uploaded_file($inputFileName, $caminho);
634
635
        $data = [
636
        	'caminho' => $caminho,
637
        	'usuario_id' => $this->instancia,
638
        	'processado' => 0,
639
        	'ativo' => 1
640
        ];
641
642
        $this->loadModel('QueueProduct');
643
644
        if ($this->QueueProduct->save($data))
645
        {
646
			$this->Session->setFlash("O arquivo está na fila para ser importado, iremos enviar um e-mail quando terminar.");
647
			$this->redirect("/produto/listar_cadastros");  
648
        }
649
        else 
650
        {
651
			$this->Session->setFlash("Ocorreu um erro, tente novamente.");
652
			$this->redirect("/produto/listar_cadastros");          	
653
        }
654
    }
655
656
    public function processar_planilhas_na_fila() {
657
    	$this->loadModel('QueueProduct');
658
659
    	$planilhas = $this->QueueProduct->loadPlanilhasNotProcesseds();
660
661
    	$response = [];
662
    	foreach ($planilhas as $planilha) {
663
    		$response[] = $this->processar_planilhas($planilha['caminho'], $planilha['usuario_id'], $planilha['id']);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $response[] is correct as $this->processar_planilh..._id'], $planilha['id']) (which targets ProdutoController::processar_planilhas()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
664
    	}
665
666
    	return $response;
667
    }
668
669
    public function processar_planilhas($inputFileName, $usuarioId, $planilhaId) {
670
		include(APP . 'Vendor/PHPExcel/PHPExcel.php');
671
		include(APP . 'Vendor/PHPExcel/PHPExcel/IOFactory.php');
672
    	
673
        $objPHPExcel = new PHPExcel();
674
675
		try {
676
		    $inputFileType 	= PHPExcel_IOFactory::identify($inputFileName);
677
		    $objReader 		= PHPExcel_IOFactory::createReader($inputFileType);
678
		    $objPHPExcel 	= $objReader->load($inputFileName);
679
		} catch(Exception $e) {
680
		    die('Error loading file "' . pathinfo($inputFileName, PATHINFO_BASENAME) . '": ' . $e->getMessage());
0 ignored issues
show
Coding Style Compatibility introduced by
The method processar_planilhas() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
681
		}
682
683
		$dados = [];
684
685
		$rows = $objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
686
687
		for ($row = 2; $row <= $rows; $row++) {
688
			
689
			$rowInterator = $objPHPExcel->getActiveSheet()->getRowIterator($row)->current();
690
691
			$cellIterator = $rowInterator->getCellIterator();
692
			$cellIterator->setIterateOnlyExistingCells(false);
693
694
			foreach ($cellIterator as $i => $cell) {
695
				switch ($i) {
696
					case 0: //Codigo/SKU
697
						$dados[$row]['sku'] = $cell->getValue();
698
					break; 
699
					case 1: // Nome/Descrição 
700
						$dados[$row]['nome'] = $cell->getValue();						
701
					break;
702
					case 2: // QtdAtual
703
						//$dados[$row]['sku'] = $cell->getValue();						
704
					break;
705
					case 3: // QtdMinima  
706
						$dados[$row]['quantidade_minima'] = $cell->getValue();						
707
					break;
708
					case 4: // QtdTotal
709
						$dados[$row]['estoque'] = $cell->getValue();						
710
					break;
711
					case 5: // ValCusto
712
						$dados[$row]['custo'] = $cell->getValue();						
713
					break;
714
					case 6:  // ValVenda
715
						$dados[$row]['preco'] = $cell->getValue();						
716
					break;
717
				}
718
			}
719
720
			$dados[$row]['id_usuario'] = $usuarioId;	
721
			$dados[$row]['ativo'] = 1;
722
723
		}
724
725
		$errors = $this->processar_lista_produtos($dados);
726
727
		if (isset($errors) && !empty($errors))
728
		{
729
			$this->QueueProduct->planilhaProcessedIncomplete($planilhaId);
730
		}
731
732
		$this->QueueProduct->planilhaProcessedComplete($planilhaId);
733
734
		echo json_encode(array('sucess' => true));
735
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method processar_planilhas() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
736
    }
737
738
    public function processar_lista_produtos($dados) {
739
    	$errors = [];
740
741
    	foreach ($dados as $dado) {
742
    		$this->loadModel('Produto');
743
    		
744
    		$existProduto = $this->Produto->find('all',
745
    			array(
746
    				'conditions' => array(
747
    					'Produto.sku' => $dado['sku'],
748
    					'Produto.ativo' => 1
749
    				)
750
    			)
751
    		);
752
753
    		if (isset($existProduto) && !empty($existProduto))
754
    		{
755
    			$this->Produto->id = $existProduto[0]['Produto']['id'];
756
    			$this->Produto->save($dado);
757
    			continue;
758
    		}
759
760
			$this->Produto->create();
761
762
    		if (!$this->Produto->save($dado))
763
    		{
764
    			$errors[] = $dado;
765
    		}
766
    	}
767
768
    	return $errors;
769
    }
770
771
    public function salvar_imagem($id) {
0 ignored issues
show
Coding Style introduced by
salvar_imagem uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
772
		$image  = $_FILES['arquivo'];
773
		
774
		$retorno = $this->uploadImage($image);
775
776
		if (!$retorno['status']) {
777
			$this->Session->setFlash('A imagem não foi salva tente novamente ou contate o suporte!');
778
            return $this->redirect('/produto/imagens/' . $id);
779
		}
780
781
		$photo = $this->request->data('photo');
782
783
		$data = array(
784
			'arquivo' => $retorno['nome'],
785
			'order' => $photo['order'],
786
			'alt' => $photo['alt'],
787
			'title' => $photo['title'],
788
			'ativo' => 1,
789
			'usuario_id' => $this->instancia,
790
			'produto_id' => $id
791
		);
792
793
		$this->loadModel('Imagen');
794
795
		$retorno = $this->Imagen->save($data);
796
797
		if (!$retorno) {
798
			$this->Session->setFlash('A imagem não foi salva tente novamente ou contate o suporte!');
799
            return $this->redirect('/produto/imagens/' . $id);
800
		}
801
802
		$this->Session->setFlash('A salva com sucesso!');
803
        return $this->redirect('/produto/imagens/' . $id);
804
    }
805
806
    public function imagem_excluir_cadastro($id) {
807
    	$this->loadModel('Imagen');
808
809
    	$this->Imagen->id = $id;
810
811
    	$this->Imagen->save(['ativo' => 0]);
812
813
    	echo json_encode(array('success' => true));
814
    	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method imagem_excluir_cadastro() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
815
    }
816
817
}
818