Completed
Push — master ( 6373eb...219b62 )
by Elizandro
18s queued 11s
created

Tnt::setAdditionalServices()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Trixpua\Shipping\Tnt\Quote;
4
5
6
use GuzzleHttp\Client;
7
use Meng\AsyncSoap\Guzzle\Factory;
8
use Trixpua\Shipping\ShippingInfo;
9
10
11
/**
12
 * Class Tnt
13
 * @author Elizandro Echer <https://github.com/Trixpua>
14
 * @package Trixpua\Shipping
15
 * @version 2.0.0
16
 */
17
class Tnt
18
{
19
20
    /** @var string */
21
    private $senderZipCode;
22
23
    /** @var string */
24
    private $login;
25
26
    /** @var string */
27
    private $password;
28
29
    /** @var int|string */
30
    private $clientDivisionCode;
31
32
    /** @var string */
33
    private $senderTaxId;
34
35
    /** @var string */
36
    private $senderStateRegistrationNumber;
37
38
    /** @var string */
39
    private $senderPersonType;
40
41
    /** @var string */
42
    private $senderTaxSituation;
43
44
    /** @var int|float|string */
45
    private $weight;
46
47
    /** @var string|null */
48
    private $shippingModal;
49
50
    /** @var string|null */
51
    private $shippingIncoterm;
52
53
    /** @var string|null */
54
    private $receiverPersonType;
55
56
    /** @var string|null */
57
    private $receiverTaxSituation;
58
59
    /** @var string|null */
60
    private $receiverTaxId;
61
62
    /** @var string|null */
63
    private $receiverStateRegistrationNumber;
64
65
    /** @var ShippingInfo */
66
    private $shippingInfo;
67
68
    /** @var \stdClass */
69
    private $result;
70
71
    /**
72
     * Tnt constructor.
73
     * @param string $senderZipCode Define the sender ZIP code
74
     * @param string $login Define the login registered to access TNT services
75
     * @param string $password Define the password registered to access TNT services
76
     * @param int|string $clientDivisionCode Define the client division code provided by TNT
77
     * @param string $senderTaxSituation Define the sender tax situation ('CI' => 'Contribuinte Incentivado' | 'ON' => 'Órgão Público Não Contribuinte' | 'PN' => 'Produtor Rural Não Contribuinte' | 'MN' => 'ME/EPP/Simples Nacional Não Contribuinte' | 'CN' => 'Cia. Mista Não Contribuinte' | 'OF' => 'Órgão Público - Progr. Fortalecimento Modernização Estadual' | 'CM' => 'Cia. Mista Contribuinte' | 'CO' => 'Contribuinte' | 'ME' => 'ME/EPP/Simples Nacional Contribuinte' | 'NC' => 'Não Contribuinte' | 'OP' => 'Órgão Público Contribuinte' | 'PR' => 'Produtor Rural Contribuinte')
78
     * @param string $senderTaxId Define the sender tax ID (CPF / CNPJ)
79
     * @param string $senderStateRegistrationNumber Define the sender state registration number (IE)
80
     * @param string $senderPersonType OPTIONAL (DEFAULT 'J') - Define the sender person type ('J' => 'Jurídica' | 'F' => 'Física')
81
     */
82
    public function __construct(
83
        string $senderZipCode,
84
        string $login,
85
        string $password,
86
        $clientDivisionCode,
87
        string $senderTaxSituation,
88
        string $senderTaxId,
89
        string $senderStateRegistrationNumber,
90
        string $senderPersonType = 'J'
91
    ) {
92
        $this->result = new \stdClass();
93
        $this->setSenderZipCode($senderZipCode);
94
        $this->setLogin($login);
95
        $this->setPassword($password);
96
        $this->setClientDivisionCode($clientDivisionCode);
97
        $this->setSenderTaxSituation($senderTaxSituation);
98
        $this->setSenderTaxId($senderTaxId);
99
        $this->setSenderStateRegistrationNumber($senderStateRegistrationNumber);
100
        $this->setSenderPersonType($senderPersonType);
101
    }
102
103
    /**
104
     * @param string $senderZipCode Define the sender ZIP code
105
     */
106
    public function setSenderZipCode(string $senderZipCode): void
107
    {
108
        $this->senderZipCode = preg_replace('/[^0-9]/', '', $senderZipCode);
109
    }
110
111
    /**
112
     * @param string $login Define the login registered to access TNT services
113
     */
114
    public function setLogin(string $login): void
115
    {
116
        $this->login = $login;
117
    }
118
119
    /**
120
     * @param string $password Define the password registered to access TNT services
121
     */
122
    public function setPassword(string $password): void
123
    {
124
        $this->password = $password;
125
    }
126
127
    /**
128
     * @param int|string $clientDivisionCode Define the client division code provided by TNT
129
     */
130
    public function setClientDivisionCode($clientDivisionCode): void
131
    {
132
        $this->clientDivisionCode = preg_replace('/[^0-9]/', '', $clientDivisionCode);
133
    }
134
135
    /**
136
     * @param string $senderTaxSituation Define the sender tax situation ('CI' =>
137
     * 'Contribuinte Incentivado' | 'ON' => 'Órgão Público Não Contribuinte' | 'PN' => 'Produtor Rural Não
138
     * Contribuinte' | 'MN' => 'ME/EPP/Simples Nacional Não Contribuinte' | 'CN' => 'Cia. Mista Não Contribuinte' |
139
     * 'OF' => 'Órgão Público - Progr. Fortalecimento Modernização Estadual' | 'CM' => 'Cia. Mista Contribuinte' |
140
     * 'CO' => 'Contribuinte' | 'ME' => 'ME/EPP/Simples Nacional Contribuinte' | 'NC' => 'Não Contribuinte' | 'OP' =>
141
     * 'Órgão Público Contribuinte' | 'PR' => 'Produtor Rural Contribuinte')
142
     */
143
    public function setSenderTaxSituation(string $senderTaxSituation): void
144
    {
145
        $this->senderTaxSituation = strtoupper($senderTaxSituation);
146
    }
147
148
    /**
149
     * @param string $senderTaxId Define the sender tax ID (CPF / CNPJ)
150
     */
151
    public function setSenderTaxId(string $senderTaxId): void
152
    {
153
        $this->senderTaxId = preg_replace('/[^0-9]/', '', $senderTaxId);
154
    }
155
156
    /**
157
     * @param string $senderStateRegistrationNumber Define the sender state registration number (IE)
158
     */
159
    public function setSenderStateRegistrationNumber(string $senderStateRegistrationNumber): void
160
    {
161
        $this->senderStateRegistrationNumber = preg_replace('/[^0-9]/', '', $senderStateRegistrationNumber);
162
    }
163
164
    /**
165
     * @param string $senderPersonType OPTIONAL (DEFAULT 'J') - Define the sender person type ('J' => 'Jurídica' |
166
     * 'F' => 'Física')
167
     */
168
    public function setSenderPersonType(string $senderPersonType = 'J'): void
169
    {
170
        $this->senderPersonType = strtoupper($senderPersonType) === 'F' ? 'F' : 'J';
171
    }
172
173
    /**
174
     * @param ShippingInfo $shippingInfo
175
     * @param string|null $shippingModal - OPTIONAL (DEFAULT 'RNC') - Define the shipping modal ('RNC' => 'Rodoviário Nacional Convencional' ou 'ANC' => 'Aéreo Nacional Convencional')
176
     * @param string|null $shippingIncoterm OPTIONAL (DEFAULT 'C') - Define the shipping incoterm ('C' => 'CIF' ou 'F' => 'FOB')
177
     * @param string|null $receiverPersonType OPTIONAL (DEFAULT 'F') - Define the receiver person type ('J' => 'Jurídica' | 'F' => 'Física')
178
     * @param string|null $receiverTaxSituation OPTIONAL (DEFAULT 'NC') - Define the receiver tax situation ('CI' => 'Contribuinte Incentivado' | 'ON' => 'Órgão Público Não Contribuinte' | 'PN' => 'Produtor Rural Não Contribuinte' | 'MN' => 'ME/EPP/Simples Nacional Não Contribuinte' | 'CN' => 'Cia. Mista Não Contribuinte' | 'OF' => 'Órgão Público - Progr. Fortalecimento Modernização Estadual' | 'CM' => 'Cia. Mista Contribuinte' | 'CO' => 'Contribuinte' | 'ME' => 'ME/EPP/Simples Nacional Contribuinte' | 'NC' => 'Não Contribuinte' | 'OP' => 'Órgão Público Contribuinte' | 'PR' => 'Produtor Rural Contribuinte')
179
     * @param string|null $receiverTaxId OPTIONAL (DEFAULT '0000000000') - Define the receiver tax ID (CPF / CNPJ)
180
     * @param string|null $receiverStateRegistrationNumber OPTIONAL (DEFAULT null) - Define the receiver state registration number (IE)
181
     */
182
    public function setData(
183
        ShippingInfo $shippingInfo,
184
        ?string $shippingModal = null,
185
        ?string $shippingIncoterm = null,
186
        ?string $receiverPersonType = null,
187
        ?string $receiverTaxSituation = null,
188
        ?string $receiverTaxId = null,
189
        ?string $receiverStateRegistrationNumber = null
190
    ): void {
191
        $this->shippingInfo = $shippingInfo;
192
        $this->setShippingModal($shippingModal);
193
        $this->setShippingIncoterm($shippingIncoterm);
194
        $this->setReceiverPersonType($receiverPersonType);
195
        $this->setReceiverTaxSituation($receiverTaxSituation);
196
        $this->setReceiverTaxId($receiverTaxId);
197
        $this->setReceiverStateRegistrationNumber($receiverStateRegistrationNumber);
198
    }
199
200
    /**
201
     * @param string|null $shippingModal - OPTIONAL (DEFAULT 'RNC') - Define the shipping modal ('RNC' => 'Rodoviário
202
     * Nacional Convencional' ou 'ANC' => 'Aéreo Nacional Convencional')
203
     */
204
    public function setShippingModal(?string $shippingModal = null): void
205
    {
206
        $this->shippingModal = strtoupper($shippingModal) === 'ANC' ? 'ANC' : 'RNC';
207
    }
208
209
    /**
210
     * @param string|null $shippingIncoterm OPTIONAL (DEFAULT 'C') - Define the shipping incoterm ('C' => 'CIF' ou 'F' => 'FOB')
211
     */
212
    public function setShippingIncoterm(?string $shippingIncoterm = null): void
213
    {
214
        $this->shippingIncoterm = strtoupper($shippingIncoterm) === 'F' ? 'F' : 'C';
215
    }
216
217
    /**
218
     * @param string|null $receiverPersonType OPTIONAL (DEFAULT 'F') - Define the receiver person type ('J' => 'Jurídica' |
219
     * 'F' => 'Física')
220
     */
221
    public function setReceiverPersonType(?string $receiverPersonType = null): void
222
    {
223
        $this->receiverPersonType = strtoupper($receiverPersonType) === 'J' ? 'J' : 'F';
224
    }
225
226
    /**
227
     * @param string|null $receiverTaxSituation OPTIONAL (DEFAULT 'NC') - Define the receiver tax situation ('CI' =>
228
     * 'Contribuinte Incentivado' | 'ON' => 'Órgão Público Não Contribuinte' | 'PN' => 'Produtor Rural Não
229
     * Contribuinte' | 'MN' => 'ME/EPP/Simples Nacional Não Contribuinte' | 'CN' => 'Cia. Mista Não Contribuinte' |
230
     * 'OF' => 'Órgão Público - Progr. Fortalecimento Modernização Estadual' | 'CM' => 'Cia. Mista Contribuinte' |
231
     * 'CO' => 'Contribuinte' | 'ME' => 'ME/EPP/Simples Nacional Contribuinte' | 'NC' => 'Não Contribuinte' | 'OP' =>
232
     * 'Órgão Público Contribuinte' | 'PR' => 'Produtor Rural Contribuinte')
233
     */
234
    public function setReceiverTaxSituation(?string $receiverTaxSituation = null): void
235
    {
236
        $this->receiverTaxSituation = strtoupper($receiverTaxSituation) ?: 'NC';
237
    }
238
239
    /**
240
     * @param string|null $receiverTaxId OPTIONAL (DEFAULT '0000000000') - Define the receiver tax ID (CPF / CNPJ)
241
     */
242
    public function setReceiverTaxId(?string $receiverTaxId = null): void
243
    {
244
        $this->receiverTaxId = preg_replace('/[^0-9]/', '', $receiverTaxId) ?: '0000000000';
245
    }
246
247
    /**
248
     * @param string|null $receiverStateRegistrationNumber OPTIONAL (DEFAULT null) - Define the receiver state registration
249
     * number (IE)
250
     */
251
    public function setReceiverStateRegistrationNumber(?string $receiverStateRegistrationNumber = null): void
252
    {
253
        $this->receiverStateRegistrationNumber = $receiverStateRegistrationNumber;
254
    }
255
256
    /**
257
     * Make the request to the web service
258
     */
259
    public function makeRequest(): void
260
    {
261
262
        $factory = new Factory();
263
        $client = $factory->create(new Client(), 'http://200.248.69.12/tntws/CalculoFrete?wsdl');
264
265
        try {
266
            $this->setQuoteWeight();
267
            $promise = $client->callAsync('calculaFrete', $this->buildRequest())->then(function ($response) {
268
                $this->parseResult($response);
269
            });
270
            $promise->wait();
271
        } catch (\Exception $e) {
272
            $this->result->status = 'ERROR';
273
            $this->result->errors[] = 'Soap Error: ' . $e->getMessage();
274
        }
275
    }
276
277
    /**
278
     * Calculates the cubic weight and defines the weight to be used to quote
279
     */
280
    private function setQuoteWeight(): void
281
    {
282
        if ($this->shippingInfo->getVolume() && !$this->shippingInfo->isQuoteByWeight()) {
283
            $cubedWeight = $this->shippingModal === 'ANC' ? $this->shippingInfo->getVolume() * 166.667 : $this->shippingInfo->getVolume() * 300;
284
            if ($cubedWeight > $this->shippingInfo->getWeight()) {
285
                $this->weight = number_format($cubedWeight, 4, '.', '');
286
                return;
287
            }
288
        }
289
        $this->weight = $this->shippingInfo->getWeight();
290
    }
291
292
    /**
293
     * Mount the request that will be sent to the web service
294
     * @return array
295
     */
296
    private function buildRequest(): array
297
    {
298
        return [
299
            'calculaFrete' => [
300
                'in0' => [
301
                    'login' => new \SoapVar($this->login, XSD_STRING, 'string', null, 'login', 'http://model.vendas.lms.mercurio.com'),
302
                    'senha' => new \SoapVar($this->password, XSD_STRING, 'string', null, 'senha', 'http://model.vendas.lms.mercurio.com'),
303
                    'tpPessoaRemetente' => new \SoapVar($this->senderPersonType, XSD_STRING, 'string', null, 'tpPessoaRemetente', 'http://model.vendas.lms.mercurio.com'),
304
                    'tpSituacaoTributariaRemetente' => new \SoapVar($this->senderTaxSituation, XSD_STRING, 'string', null, 'tpSituacaoTributariaRemetente', 'http://model.vendas.lms.mercurio.com'),
305
                    'cdDivisaoCliente' => new \SoapVar($this->clientDivisionCode, XSD_STRING, 'string', null, 'cdDivisaoCliente', 'http://model.vendas.lms.mercurio.com'),
306
                    'nrIdentifClienteRem' => new \SoapVar($this->senderTaxId, XSD_STRING, 'string', null, 'nrIdentifClienteRem', 'http://model.vendas.lms.mercurio.com'),
307
                    'nrInscricaoEstadualRemetente' => new \SoapVar($this->senderStateRegistrationNumber, XSD_STRING, 'string', null, 'nrInscricaoEstadualRemetente', 'http://model.vendas.lms.mercurio.com'),
308
                    'cepOrigem' => new \SoapVar($this->senderZipCode, XSD_STRING, 'string', null, 'cepOrigem', 'http://model.vendas.lms.mercurio.com'),
309
                    'tpFrete' => new \SoapVar($this->shippingIncoterm, XSD_STRING, 'string', null, 'tpFrete', 'http://model.vendas.lms.mercurio.com'),
310
                    'tpServico' => new \SoapVar($this->shippingModal, XSD_STRING, 'string', null, 'tpServico', 'http://model.vendas.lms.mercurio.com'),
311
                    'tpPessoaDestinatario' => new \SoapVar($this->receiverPersonType, XSD_STRING, 'string', null, 'tpPessoaDestinatario', 'http://model.vendas.lms.mercurio.com'),
312
                    'tpSituacaoTributariaDestinatario' => new \SoapVar($this->receiverTaxSituation, XSD_STRING, 'string', null, 'tpSituacaoTributariaDestinatario', 'http://model.vendas.lms.mercurio.com'),
313
                    'nrIdentifClienteDest' => new \SoapVar($this->receiverTaxId, XSD_STRING, 'string', null, 'nrIdentifClienteDest', 'http://model.vendas.lms.mercurio.com'),
314
                    'nrInscricaoEstadualDestinatario' => new \SoapVar($this->receiverStateRegistrationNumber, XSD_STRING, 'string', null, 'nrInscricaoEstadualDestinatario', 'http://model.vendas.lms.mercurio.com'),
315
                    'cepDestino' => new \SoapVar($this->shippingInfo->getReceiverZipCode(), XSD_STRING, 'string', null, 'cepDestino', 'http://model.vendas.lms.mercurio.com'),
316
                    'psReal' => new \SoapVar($this->weight, XSD_STRING, 'string', null, 'psReal', 'http://model.vendas.lms.mercurio.com'),
317
                    'vlMercadoria' => new \SoapVar($this->shippingInfo->getCommodityValue(), XSD_STRING, 'string', null, 'vlMercadoria', 'http://model.vendas.lms.mercurio.com')
318
                ]
319
            ]
320
        ];
321
    }
322
323
    /**
324
     * Parse the response from the webservice and set the result
325
     * @param \stdClass $response
326
     */
327
    private function parseResult(\stdClass $response): void
328
    {
329
        if (!property_exists($response->out, 'errorList')) {
330
            $this->result->status = 'OK';
331
            $this->result->shippingCost = number_format((($response->out->vlTotalFrete + $this->shippingInfo->getAdditionalCharge()) / (1 - ($this->shippingInfo->getAdditionalPercent() / 100))), 2, '.', '');
332
333
            $this->result->deliveryTime = $response->out->prazoEntrega + $this->shippingInfo->getShipmentDelay();
334
335
            $this->result->senderName = property_exists($response->out, 'nmRemetente') ? $response->out->nmRemetente : '';
336
            $this->result->originCity = property_exists($response->out, 'nmMunicipioOrigem') ? $response->out->nmMunicipioOrigem : '';
337
            $this->result->originBranchPhone = property_exists($response->out, 'nrDDDFilialOrigem') && property_exists($response->out, 'nrTelefoneFilialOrigem') ? $response->out->nrDDDFilialOrigem . ' ' .
338
                $response->out->nrTelefoneFilialOrigem : '';
339
            $this->result->receiverName = property_exists($response->out, 'nmDestinatario') ? $response->out->nmDestinatario : '';
340
            $this->result->destinyCity = property_exists($response->out, 'nmMunicipioDestino') ? $response->out->nmMunicipioDestino : '';
341
            $this->result->destinyBranchPhone = property_exists($response->out, 'nrDDDFilialDestino') && property_exists($response->out, 'nrTelefoneFilialDestino') ? $response->out->nrDDDFilialDestino . ' ' .
342
                $response->out->nrTelefoneFilialDestino : '';
343
            $this->result->discountValue = property_exists($response->out, 'vlDesconto') ? $response->out->vlDesconto : '';
344
            $this->result->icmsStValue = property_exists($response->out, 'vlICMSubstituicaoTributaria') ? $response->out->vlICMSubstituicaoTributaria : '';
345
            $this->result->taxesValue = property_exists($response->out, 'vlImposto') ? $response->out->vlImposto : '';
346
            $this->result->ctrcTotalvalue = property_exists($response->out, 'vlTotalCtrc') ? $response->out->vlTotalCtrc : '';
347
            $this->result->serviceTotalvalue = property_exists($response->out, 'vlTotalServico') ? $response->out->vlTotalServico : '';
348
            $this->setParcels($response->out->parcelas);
349
            $this->setAdditionalServices($response->out->servicosAdicionais);
350
351
        } else {
352
            if (is_array($response->out->errorList)) {
353
                $this->result->status = 'ERROR';
354
                foreach ($response->out->errorList as $error) {
355
                    $this->result->errors[] = $error;
356
                }
357
            } else {
358
                $this->result->status = 'ERROR';
359
                $this->result->errors[] = $response->out->errorList;
360
            }
361
362
        }
363
    }
364
365
    /**
366
     * Set the parcels
367
     * @param $parcels
368
     */
369
    private function setParcels(object $parcels): void
370
    {
371
        $this->result->parcels = new \stdClass();
372
        foreach ($parcels->ParcelasFreteWebService as $key => $parcel) {
373
            $this->result->parcels->{$key} = new \stdClass();
374
            $this->result->parcels->{$key}->description = $parcel->dsParcela;
375
            $this->result->parcels->{$key}->value = $parcel->vlParcela;
376
        }
377
    }
378
379
    /**
380
     * Set the additional services
381
     * @param $additionalServices
382
     */
383
    private function setAdditionalServices(object $additionalServices): void
384
    {
385
        $this->result->additionalServices = new \stdClass();
386
        foreach ($additionalServices->ServicoAdicionalWebService as $key => $additionalService) {
387
            $this->result->additionalServices->{$key} = new \stdClass();
388
            $this->result->additionalServices->{$key}->service = $additionalService->nmServico;
389
            $this->result->additionalServices->{$key}->description = $additionalService->dsComplemento;
390
            $this->result->additionalServices->{$key}->currency = $additionalService->sgMoeda;
391
            $this->result->additionalServices->{$key}->value = $additionalService->vlServico;
392
        }
393
    }
394
395
    /**
396
     * @return \stdClass
397
     */
398
    public function getResult(): \stdClass
399
    {
400
        return $this->result;
401
    }
402
403
404
}