Frete::getError()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace ThallesDKoester\Entregas;
4
5
use Exception;
6
7
/**
8
 * Thalles D. Koester | Class Frete
9
 *
10
 * @author  Thalles D. koester <[email protected]>
11
 * @package ThallesDKoester\Entregas
12
 */
13
class Frete
14
{
15
    use Curl;
16
    use Xml;
17
18
    const URL_CORREIOS = 'http://ws.correios.com.br/calculador/CalcPrecoPrazo.asmx/CalcPrecoPrazo';
19
20
    /** @var array */
21
    private $zipcode;
22
23
    /** @var string */
24
    private $types;
25
26
    /** @var array */
27
    private $item;
28
29
    /** @var string */
30
    private $error;
31
32
    /** @var array */
33
    private $options = [];
34
35
    /** @var array */
36
    private $methods = [
37
        'sedex' => '04014',
38
        'sedex_a_cobrar' => '04065',
39
        'sedex_10' => '40215',
40
        'sedex_hoje' => '40290',
41
        'pac' => '04510',
42
        'pac_a_cobrar' => '04707',
43
        'pac_contrato' => '04669',
44
        'sedex_contrato' => '04162',
45
        'esedex' => '81019',
46
    ];
47
48
    /**
49
     * Frete constructor.
50
     * @param array      $zipcode
51
     * @param array      $types
52
     * @param array      $item
53
     * @param array|null $options
54
     * @throws Exception
55
     */
56
    public function __construct(array $zipcode, array $types, array $item, ?array $options = null)
57
    {
58
        $this->setZipcode($zipcode);
59
        $this->setTypes($types);
60
        $this->setItem($item);
61
        $this->setOptions($options);
62
    }
63
64
    /**
65
     * @return string
66
     */
67
    public function getError(): string
68
    {
69
        return $this->error;
70
    }
71
72
    /**
73
     * @param string|null $type
74
     * @return array|string
75
     */
76
    public function getTypesAvailable(?string $type = null)
77
    {
78
        if ($type) {
79
            return $this->methods[$type];
80
        }
81
        return $this->methods;
82
    }
83
84
    /**
85
     * @param string $value
86
     * @return string
87
     */
88
    public function getTypesIndex(string $value): ?string
89
    {
90
        $data = array_search($value, $this->methods);
91
        return ($data ? $data : null);
92
    }
93
94
    /**
95
     * @return array|null
96
     */
97
    public function getFrete(): ?array
98
    {
99
        $url = self::URL_CORREIOS . '?' . $this->generatePayload();
100
        try {
101
            $data = $this->request($url, 'GET');
102
        } catch (Exception $e) {
103
            $this->error = $e;
104
            return null;
105
        }
106
107
        $fretes = $this->xml2array($data)['Servicos'][0]['cServico'];
108
109
        $return = [];
110
        foreach ($fretes as $frete) {
111
            $return[] = [
112
                'codigo' => (int)$frete['Codigo'][0],
113
                'valor' => $frete['Valor'][0],
114
                'prazo' => $frete['PrazoEntrega'][0],
115
                'mao_propria' => $frete['ValorMaoPropria'][0],
116
                'aviso_recebimento' => $frete['ValorAvisoRecebimento'][0],
117
                'valor_declarado' => $frete['ValorValorDeclarado'][0],
118
                'entrega_domiciliar' => ($frete['EntregaDomiciliar'][0] === 'S' ? true : false),
119
                'entrega_sabado' => ($frete['EntregaSabado'][0] === 'S' ? true : false),
120
                'error' => ['codigo' => (int)$frete['Erro'][0], 'mensagem' => $frete['MsgErro'][0]],
121
            ];
122
        }
123
        return $return;
124
    }
125
126
    /**
127
     * @param array $zipcode
128
     */
129
    private function setZipcode(array $zipcode): void
130
    {
131
        $this->zipcode = array_map(function ($zip) {
132
            return preg_replace("/[^0-9]/", "", $zip);
133
        }, $zipcode);
134
    }
135
136
    /**
137
     * @param array $types
138
     * @throws Exception
139
     */
140
    private function setTypes(array $types): void
141
    {
142
        $newTypes = [];
143
        foreach ($types as $key => $value) {
144
            if (empty($this->methods[$value])) {
145
                throw new Exception("Tipo de frete {$value} não está disponível para uso.");
146
            }
147
            $newTypes[] = $this->methods[$value];
148
        }
149
        $this->types = implode(",", $newTypes);
150
    }
151
152
    /**
153
     * @param array $item
154
     */
155
    private function setItem(array $item): void
156
    {
157
        $this->item['peso'] = floatval($item['peso'] / 1000);
158
        $this->item['altura'] = ($item['altura'] > 2 ? $item['altura'] : 2);
159
        $this->item['comprimento'] = ($item['comprimento'] > 11 ? $item['comprimento'] : 11);
160
        $this->item['largura'] = ($item['largura'] > 16 ? $item['largura'] : 16);
161
        $this->item['diametro'] = ($item['diametro'] ?? 0);
162
        $this->item['formato'] = ($this->item['formato'] ?? Entregas::FRETE_FORMATO_CAIXA);
163
    }
164
165
    /**
166
     * @param array $options
167
     */
168
    private function setOptions(?array $options): void
169
    {
170
        $this->options['senha'] = ($options['senha'] ?? '');
171
        $this->options['empresa'] = ($options['empresa'] ?? '');
172
        $this->options['mao_propria'] = (isset($options['mao_propria']) && $options['mao_propria'] ? 'S' : 'N');
173
        $this->options['valor_declarado'] = (!empty($options['valor_declarado'])
174
            ? number_format($options['valor_declarado'], '2', ',', '') : 0);
175
        $this->options['aviso_recebimento'] = (isset($options['aviso_recebimento']) && $options['aviso_recebimento']
176
            ? 'S' : 'N');
177
    }
178
179
    /**
180
     * @return string
181
     */
182
    private function generatePayload(): string
183
    {
184
        $payload = [
185
            'nCdServico' => $this->types,
186
            'nCdEmpresa' => $this->options['empresa'],
187
            'sDsSenha' => $this->options['senha'],
188
            'sCepOrigem' => $this->zipcode['origem'],
189
            'sCepDestino' => $this->zipcode['destino'],
190
            'nVlPeso' => $this->item['peso'],
191
            'nCdFormato' => $this->item['formato'],
192
            'nVlComprimento' => $this->item['comprimento'],
193
            'nVlAltura' => $this->item['altura'],
194
            'nVlLargura' => $this->item['largura'],
195
            'nVlDiametro' => $this->item['diametro'],
196
            'sCdMaoPropria' => $this->options['mao_propria'],
197
            'nVlValorDeclarado' => $this->options['valor_declarado'],
198
            'sCdAvisoRecebimento' => $this->options['aviso_recebimento'],
199
            'sDtCalculo' => date('d/m/Y'),
200
            'StrRetorno' => 'xml'
201
        ];
202
203
        return http_build_query($payload);
204
    }
205
}