diff --git a/README.md b/README.md index 9044719..8a620ed 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ -# MDFe-PHP-SDK \ No newline at end of file + +

+ +

+ +# MDF-e PHP SDK +SDK de comunicação com API 2.0 da Webmania para MDF-e. +Através do emissor de Nota Fiscal de Serviço da Webmania®, você conta com a emissão e arquivamento das seus MDF-e, encerramento, cancelamento e impressão dos documentos. Realize a integração do seu sistema com esta SDK para o MDF-e. + +- Emissor de Nota Fiscal Webmania®: [Saiba mais](https://webmaniabr.com/nota-fiscal-eletronica/) +- Documentação REST API: [Visualizar](https://webmaniabr.com/docs/rest-api-mdfe/) + +## Requisitos + +- Contrate um dos planos de MDF-e da Webmania® para obter suas credenciais de acesso: [Conheça os Planos (Teste 30 dias grátis!)](https://webmaniabr.com/nota-fiscal-eletronica/#plans-section). +- Obtenha o [Composer](https://getcomposer.org/) e instale o pacote da SDK e suas dependências. + +## Endpoints + +A SDK possui os recursos necessários para utilizar os endpoints de Emissão, Consulta, Encerramento, Cancelamento e Inclusão de Condutor para o MDF-e. + +## Utilização +Instale o módulo da Webmania® via composer ou baixe nosso repositório e utilize as classes de emissão mencionadas mais abaixo: + +```php +composer require webmaniabr/mdfe +``` + +Após executar o composer, adicione o require no topo do seu arquivo, dessa forma as classes da SDK serão carregadas automaticamente. + +```php +require_once __DIR__ . '/vendor/autoload.php'; +``` + +Para emissão, deve ser usada a classe MDFe + +```php +\Webmaniabr\Mdfe\Api\Connection::getInstance()->setBearerToken('SEU_TOKEN_AUTENTICACAO'); +$MDFe = new \Webmaniabr\Mdfe\Models\MDFe(); +$MDFe->emitente = \Webmaniabr\Mdfe\Enums\TipoEmitente::PRESTADOR_DE_SERVICO; +$MDFe->transportador = \Webmaniabr\Mdfe\Enums\TipoTransportador::TAC; +$MDFe->ufCarregamento = \Webmaniabr\Mdfe\Enums\UF::GOIAS; +$MDFe->ufDescarregamento = \Webmaniabr\Mdfe\Enums\UF::PARANA; +$MDFe->valorCarga = 500; +... +echo $MDFe->emitir()->getMessage(); +``` + +## Suporte + +Qualquer dúvida entre em contato na nossa [Central de Ajuda](https://ajuda.webmaniabr.com) ou acesse o [Painel de Controle](https://webmaniabr.com/painel/) para conversar em tempo real no Chat ou Abrir um chamado. \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..11b599f --- /dev/null +++ b/composer.json @@ -0,0 +1,27 @@ +{ + "name": "webmaniabr/mdfe", + "type": "library", + "license": "GPL-3.0-or-later", + "description": "PHP SDK da API de MDF-e da Webmania", + "keywords": [ "documento fiscal", "api", "mdfe", "mdf-e", "webmaniabr", "webmania", "transporte", "ferroviario", "aereo", "aquaviario", "rodoviario"], + "homepage": "https://webmaniabr.com/docs/rest-api-mdfe/", + "prefer-stable": true, + "authors": [ + { + "name": "Equipe Webmania" + } + ], + "require": { + "php": ">=5.2.0", + "guzzlehttp/guzzle": "^7.0" + }, + "require-dev": { + "php": ">=5.2.0", + "guzzlehttp/guzzle": "^7.0" + }, + "autoload": { + "psr-4": { + "Webmaniabr\\Mdfe\\": "src/" + } + } +} \ No newline at end of file diff --git a/sample/Cancelamento.php b/sample/Cancelamento.php new file mode 100644 index 0000000..1534288 --- /dev/null +++ b/sample/Cancelamento.php @@ -0,0 +1,8 @@ +setBearerToken('SEU_TOKEN_AUTENTICACAO'); +$MDFe = new \Webmaniabr\Mdfe\Models\MDFe(); +$MDFe->chave = '00000000000000000000000000000000000000000000'; +$MDFe->cancelar('Erro de emissão'); \ No newline at end of file diff --git a/sample/Consulta.php b/sample/Consulta.php new file mode 100644 index 0000000..6018cfd --- /dev/null +++ b/sample/Consulta.php @@ -0,0 +1,8 @@ +setBearerToken('SEU_TOKEN_AUTENTICACAO'); +$MDFe = new \Webmaniabr\Mdfe\Models\MDFe(); +$MDFe->chave = '00000000000000000000000000000000000000000000'; +$MDFe->consultar(); \ No newline at end of file diff --git a/sample/Emissao.php b/sample/Emissao.php new file mode 100644 index 0000000..1f5ce6d --- /dev/null +++ b/sample/Emissao.php @@ -0,0 +1,27 @@ +setBearerToken('SEU_TOKEN_AUTENTICACAO'); +$MDFe = new \Webmaniabr\Mdfe\Models\MDFe(); +$MDFe->emitente = \Webmaniabr\Mdfe\Enums\TipoEmitente::PRESTADOR_DE_SERVICO; +$MDFe->transportador = \Webmaniabr\Mdfe\Enums\TipoTransportador::TAC; +$MDFe->ufCarregamento = \Webmaniabr\Mdfe\Enums\UF::GOIAS; +$MDFe->ufDescarregamento = \Webmaniabr\Mdfe\Enums\UF::PARANA; +$MDFe->valorCarga = 500; +$MDFe->unidade = \Webmaniabr\Mdfe\Enums\Unidade::KG; +$MDFe->pesoBruto = 50000; +$Carregamento = $MDFe->newCarregamento(); +$Carregamento->codigoMunicipio = '5208707'; +$Carregamento->nomeMunicipio = 'Goiânia'; +$Descarregamento = $MDFe->newDescarregamento(); +$Descarregamento->codigoMunicipio = '4106902'; +$Descarregamento->nomeMunicipio = 'Curitiba'; +$DocumentoFiscal = $Descarregamento->newDocumentoFiscal(); +$DocumentoFiscal->chave = '00000000000000000000000000000000000000000000'; +$MDFe->Percurso->GO()->MG()->SP()->PR(); +$Rodoviario = $MDFe->Rodoviario(); +$Rodoviario->rntrc = '12313'; +$ValePedagio = $Rodoviario->newValePedagio(); +$ValePedagio->valor = 40; +$MDFe->emitir(); \ No newline at end of file diff --git a/sample/Encerramento.php b/sample/Encerramento.php new file mode 100644 index 0000000..af5d569 --- /dev/null +++ b/sample/Encerramento.php @@ -0,0 +1,8 @@ +setBearerToken('SEU_TOKEN_AUTENTICACAO'); +$MDFe = new \Webmaniabr\Mdfe\Models\MDFe(); +$MDFe->chave = '00000000000000000000000000000000000000000000'; +$MDFe->encerrar(\Webmaniabr\Mdfe\Enums\UF::PARANA, "Curitiba"); \ No newline at end of file diff --git a/sample/IncluirCondutor.php b/sample/IncluirCondutor.php new file mode 100644 index 0000000..5bcb4d7 --- /dev/null +++ b/sample/IncluirCondutor.php @@ -0,0 +1,11 @@ +setBearerToken('SEU_TOKEN_AUTENTICACAO'); +$MDFe = new \Webmaniabr\Mdfe\Models\MDFe(); +$MDFe->chave = '00000000000000000000000000000000000000000000'; +$Condutor = new \Webmaniabr\Mdfe\Models\Modalidades\Rodoviario\Condutor(); +$Condutor->nome = 'Fulano de Tal'; +$Condutor->cpf = "000.000.000-00"; +$MDFe->incluirCondutor($Condutor); \ No newline at end of file diff --git a/src/Api/Connection.php b/src/Api/Connection.php new file mode 100644 index 0000000..0674359 --- /dev/null +++ b/src/Api/Connection.php @@ -0,0 +1,79 @@ +bearerToken = $token; + } + + /** + * Retorna o token de autenticação. + * @return string + */ + public function getBearerToken() : string + { + return $this->bearerToken; + } + + /** + * Define as informações do proxy. + * @param array $proxy + */ + public function setProxy(array $proxy) + { + $this->proxy = $proxy; + } + + /** + * {@inheritDoc} + */ + public function getDomain() : string + { + return 'https://api.webmaniabr.com'; + } + + /** + * {@inheritDoc} + */ + public function getProxy() : array + { + return $this->proxy; + } +} \ No newline at end of file diff --git a/src/Api/Endpoint.php b/src/Api/Endpoint.php new file mode 100644 index 0000000..ee6911c --- /dev/null +++ b/src/Api/Endpoint.php @@ -0,0 +1,44 @@ +url = $url; + $this->method = $method; + $this->headers = $headers; + } + + /** + * Retorna a URL do endpoint. + * @return string + */ + public function getUrl() : string + { + return $this->url; + } + + /** + * Retorna o método HTTP da requisição. + * @return string + */ + public function getMethod() : string + { + return $this->method; + } + + /** + * Retorna os cabeçalhos para a requisição. + * @return array + */ + public function getHeaders() : array + { + return $this->headers; + } +} \ No newline at end of file diff --git a/src/Api/Exceptions/APIException.php b/src/Api/Exceptions/APIException.php new file mode 100644 index 0000000..afc8223 --- /dev/null +++ b/src/Api/Exceptions/APIException.php @@ -0,0 +1,10 @@ +getEndpoint(); + $url = Connection::getInstance()->getDomain() . $endpoint->getUrl(); + $request = new Request($endpoint->getMethod(), $url, $endpoint->getHeaders(), $operation->getContentToSend()); + try { + $response = (new GuzzleHttpClient())->sendAsync($request)->wait(); + } catch (ClientException $ex) { + $response = $ex->getResponse(); + } + return FactoryResponse::getResponseInstance($response); + } +} \ No newline at end of file diff --git a/src/Api/Operations/AddDriver.php b/src/Api/Operations/AddDriver.php new file mode 100644 index 0000000..441f088 --- /dev/null +++ b/src/Api/Operations/AddDriver.php @@ -0,0 +1,90 @@ +MDFe = $MDFe; + } + + /** + * Define o novo condutor. + * @param Condutor $Condutor + */ + public function setCondutor(Condutor $Condutor): void + { + $this->Condutor = $Condutor; + } + + /** + * {@inheritDoc} + */ + public function getContentToSend() + { + return json_encode($this->toSend); + } + + /** + * {@inheritDoc} + */ + public function getEndpoint() : Endpoint + { + return new Endpoint('/2/mdfe/condutor', 'PUT', [ 'Authorization' => 'Bearer '. Connection::getInstance()->getBearerToken(), + 'Content-Type' => 'application/json' ]); + } + + /** + * {@inheritDoc} + */ + public function execute() : APIResponse + { + $this->makeJSON(); + return (new Client())->send($this); + } + + /** + * Cria o JSON de envio. + */ + protected function makeJSON() + { + $this->toSend = new stdClass(); + if (isset($this->MDFe->uuid)) { + $this->toSend->uuid =$this->MDFe->uuid; + } else if (isset($this->MDFe->chave)) { + $this->toSend->chave =$this->MDFe->chave; + } + if (isset($this->Condutor)) { + $this->toSend->cpf = $this->Condutor->cpf; + $this->toSend->nome = $this->Condutor->nome; + } + } +} \ No newline at end of file diff --git a/src/Api/Operations/Cancel.php b/src/Api/Operations/Cancel.php new file mode 100644 index 0000000..a157ba3 --- /dev/null +++ b/src/Api/Operations/Cancel.php @@ -0,0 +1,85 @@ +MDFe = $MDFe; + } + + /** + * @param string $motivo + */ + public function setMotivo(string $motivo): void + { + $this->motivo = $motivo; + } + + /** + * {@inheritDoc} + */ + public function getContentToSend() + { + return json_encode($this->toSend); + } + + /** + * {@inheritDoc} + */ + public function getEndpoint() : Endpoint + { + return new Endpoint('/2/mdfe/cancelar', 'PUT', [ 'Authorization' => 'Bearer '. Connection::getInstance()->getBearerToken(), + 'Content-Type' => 'application/json' ]); + } + + /** + * {@inheritDoc} + */ + public function execute() : APIResponse + { + $this->makeJSON(); + return (new Client())->send($this); + } + + /** + * Cria o JSON de emissão. + */ + protected function makeJSON() + { + $this->toSend = new stdClass(); + if (isset($this->MDFe->uuid)) { + $this->toSend->uuid =$this->MDFe->uuid; + } else if (isset($this->MDFe->chave)) { + $this->toSend->chave =$this->MDFe->chave; + } + $this->toSend->motivo = $this->motivo; + } +} \ No newline at end of file diff --git a/src/Api/Operations/Close.php b/src/Api/Operations/Close.php new file mode 100644 index 0000000..5c678b7 --- /dev/null +++ b/src/Api/Operations/Close.php @@ -0,0 +1,115 @@ +MDFe = $MDFe; + } + + /** + * @param string $uf + */ + public function setUf(string $uf): void + { + $this->uf = $uf; + } + + /** + * @param string $municipio + */ + public function setMunicipio(string $municipio): void + { + $this->municipio = $municipio; + } + + /** + * @param string $municipioIBGE + */ + public function setMunicipioIBGE(string $municipioIBGE): void + { + $this->municipioIBGE = $municipioIBGE; + } + + /** + * {@inheritDoc} + */ + public function getContentToSend() + { + return json_encode($this->toSend); + } + + /** + * {@inheritDoc} + */ + public function getEndpoint() : Endpoint + { + return new Endpoint('/2/mdfe/encerrar', 'PUT', [ 'Authorization' => 'Bearer '. Connection::getInstance()->getBearerToken(), + 'Content-Type' => 'application/json' ]); + } + + /** + * {@inheritDoc} + */ + public function execute() : APIResponse + { + $this->makeJSON(); + return (new Client())->send($this); + } + + /** + * Cria o JSON de emissão. + */ + protected function makeJSON() + { + $this->toSend = new stdClass(); + if (isset($this->MDFe->uuid)) { + $this->toSend->uuid =$this->MDFe->uuid; + } else if (isset($this->MDFe->chave)) { + $this->toSend->chave =$this->MDFe->chave; + } + $this->toSend->uf = $this->uf; + $this->toSend->municipio = $this->municipio; + if ($this->municipioIBGE != '') { + $this->toSend->codigo_municipio = $this->municipioIBGE; + } + } +} \ No newline at end of file diff --git a/src/Api/Operations/Consult.php b/src/Api/Operations/Consult.php new file mode 100644 index 0000000..a718300 --- /dev/null +++ b/src/Api/Operations/Consult.php @@ -0,0 +1,55 @@ +MDFe = $MDFe; + } + + /** + * {@inheritDoc} + */ + public function getContentToSend() + { + return ''; + } + + /** + * {@inheritDoc} + */ + public function getEndpoint() : Endpoint + { + return new Endpoint("/2/mdfe/consulta/{$this->MDFe->chave}", 'POST', [ 'Authorization' => 'Bearer '. Connection::getInstance()->getBearerToken(), + 'Content-Type' => 'application/json' ]); + } + + /** + * {@inheritDoc} + */ + public function execute() : APIResponse + { + return (new Client())->send($this); + } +} \ No newline at end of file diff --git a/src/Api/Operations/Issue.php b/src/Api/Operations/Issue.php new file mode 100644 index 0000000..769db2a --- /dev/null +++ b/src/Api/Operations/Issue.php @@ -0,0 +1,350 @@ +ForIssuance = $Document; + } + + /** + * Define se será utilizado o ambiente de produção. + * @param bool $prodEnviroment + */ + public function setProductionEnviroment(bool $prodEnviroment) + { + $this->productionEnviroment = $prodEnviroment; + } + + /** + * {@inheritDoc} + */ + public function getContentToSend() + { + return json_encode($this->toSend); + } + + /** + * {@inheritDoc} + */ + public function getEndpoint() : Endpoint + { + return new Endpoint('/2/mdfe/emissao', 'POST', [ 'Authorization' => 'Bearer '. Connection::getInstance()->getBearerToken(), + 'Content-Type' => 'application/json' ]); + } + + /** + * {@inheritDoc} + */ + public function execute() : APIResponse + { + $this->makeJSON(); + return (new Client())->send($this); + } + + /** + * Cria o JSON de emissão. + */ + protected function makeJSON() + { + $this->toSend = new stdClass(); + $this->toSend->ambiente = $this->productionEnviroment ? 1 : 2; + if (!is_null($this->ForIssuance->getUrlNotificacao())) { + $this->toSend->url_notificacao = $this->ForIssuance->getUrlNotificacao(); + } + $this->convertDocumentToJSON(); + $this->removeEmptyProperties($this->toSend); + } + + /** + * Cria o JSON do MDFe. + * @throws APIException + */ + private function convertDocumentToJSON() + { + $this->toSend->emitente = $this->ForIssuance->emitente ?? null; + $this->toSend->transportador = $this->ForIssuance->transportador ?? null; + if (!isset($this->ForIssuance->Modalidade)) { + throw new APIException('É obrigatória a escolha de uma das modalidades'); + } + $this->toSend->modalidade = $this->ForIssuance->Modalidade->getCode(); + $this->toSend->uf_carregamento = $this->ForIssuance->ufCarregamento ?? null; + $this->toSend->uf_descarregamento = $this->ForIssuance->ufDescarregamento ?? null; + $this->toSend->valor_carga = $this->ForIssuance->valorCarga ?? null; + $this->toSend->unidade = $this->ForIssuance->unidade ?? null; + $this->toSend->peso_bruto = $this->ForIssuance->pesoBruto ?? null; + if (isset($this->ForIssuance->InicioViagem)) { + $this->toSend->data_inicio_viagem = $this->ForIssuance->InicioViagem->format('Y-m-d H:i:s'); + } + $this->toSend->carregamento = []; + foreach ($this->ForIssuance->Carregamentos as $Carregamento) { + $this->toSend->carregamento[] = (object) [ 'nome_municipio' => $Carregamento->nomeMunicipio ?? null, + 'codigo_municipio' => $Carregamento->codigoMunicipio ?? null ]; + } + $this->toSend->descarregamento = []; + foreach ($this->ForIssuance->Descarregamentos as $Descarregamento) { + $documentosFiscais = []; + foreach ($Descarregamento->DocumentosFiscais as $DocumentoFiscal) { + $unidadesTransporte = []; + foreach ($DocumentoFiscal->unidadesTransporte as $UnidadeTransporte) { + $unidadesCarga = []; + foreach ($UnidadeTransporte->unidadesCarga as $UnidadeCarga) { + $unidadesCarga[] = (object) [ 'tipo' => $UnidadeCarga->tipo ?? null, + 'identificacao' => $UnidadeCarga->identificacao ?? null, + 'lacres' => $UnidadeCarga->lacres ?? null, + 'quantidade_rateada' => $UnidadeCarga->quantidadeRateada ?? null ]; + } + $unidadesTransporte[] = (object) [ 'tipo' => $UnidadeTransporte->tipo ?? null, + 'identificacao' => $UnidadeTransporte->identificacao ?? null, + 'lacres' => $UnidadeTransporte->lacres ?? null, + 'quantidade_rateada' => $UnidadeTransporte->quantidadeRateada ?? null, + 'unidade_carga' => $unidadesCarga ?? null ]; + } + $documentosFiscais[] = (object) [ 'chave' => $DocumentoFiscal->chave ?? null, + 'codigo_barra' => $DocumentoFiscal->codigoBarras ?? null, + 'indicador_reentrega' => $DocumentoFiscal->indicadorReentrega ?? null, + 'unidade_transporte' => $unidadesTransporte ?? null ]; + } + $this->toSend->descarregamento[] = (object) [ 'nome_municipio' => $Descarregamento->nomeMunicipio ?? null, + 'codigo_municipio' => $Descarregamento->codigoMunicipio ?? null, + 'documentos_fiscais' => $documentosFiscais ?? null ]; + } + $this->toSend->percurso = $this->ForIssuance->Percurso->percurso; + $this->toSend->produto_predominante = (object) [ 'tipo_carga' => $this->ForIssuance->ProdutoPredominante->tipoCarga ?? null, + 'nome' => $this->ForIssuance->ProdutoPredominante->nome ?? null, + 'gtin' => $this->ForIssuance->ProdutoPredominante->gtin ?? null, + 'ncm' => $this->ForIssuance->ProdutoPredominante->ncm ?? null, + 'lotacao' => (object) [ 'carregamento' => (object) [ 'cep' => $this->ForIssuance->ProdutoPredominante->LotacaoCarregamento->cep ?? null, + 'latitude' => $this->ForIssuance->ProdutoPredominante->LotacaoCarregamento->latitude ?? null, + 'longitude' => $this->ForIssuance->ProdutoPredominante->LotacaoCarregamento->longitude ?? null ], + 'descarregamento' => (object) [ 'cep' => $this->ForIssuance->ProdutoPredominante->LotacaoDescarregamento->cep ?? null, + 'latitude' => $this->ForIssuance->ProdutoPredominante->LotacaoDescarregamento->latitude ?? null, + 'longitude' => $this->ForIssuance->ProdutoPredominante->LotacaoDescarregamento->longitude ?? null ] ] ]; + $this->toSend->seguro = []; + foreach ($this->ForIssuance->Seguros as $Seguro) { + $this->toSend->seguro[] = (object) [ 'responsavel' => (object) [ 'tipo_responsavel' => $Seguro->Responsavel->tipoResponsavel ?? null, + 'cnpj' => $Seguro->Responsavel->cnpj ?? null, + 'cpf' => $Seguro->Responsavel->cpf ?? null ], + 'seguradora' => (object) [ 'nome_seguradora' => $Seguro->Seguradora->nome ?? null, + 'cnpj' => $Seguro->Seguradora->cnpj ?? null ], + 'numero_apolice' => $Seguro->numeroApolice ?? null, + 'numero_averbacao' => $Seguro->numerosAverbacoes ?? null ]; + } + switch ($this->ForIssuance->Modalidade->getCode()) { + case 1: + $this->makeJSONRodoviario(); + break; + case 2: + $this->makeJSONAereo(); + break; + case 3: + $this->makeJSONAquaviario(); + break; + case 4: + $this->makeJSONFerroviario(); + break; + } + } + + /** + * Cria o JSON para o modelo rodoviário. + */ + private function makeJSONRodoviario() + { + $Rodoviario = $this->ForIssuance->Rodoviario(); + $VeiculosReboque = []; + foreach ($Rodoviario->VeiculosReboque as $VeiculoReboque) { + $VeiculosReboque[] = (object) [ 'codigo_interno' => $VeiculoReboque->codigoInterno ?? null, + 'placa' => $VeiculoReboque->placa ?? null, + 'renavam' => $VeiculoReboque->renavam ?? null, + 'tara' => $VeiculoReboque->tara ?? null, + 'capacidade_kg' => $VeiculoReboque->capacidadeKg ?? null, + 'capacidade_m3' => $VeiculoReboque->capacidadeM3 ?? null, + 'tipo_rodado' => $VeiculoReboque->tipoRodado ?? null, + 'tipo_carroceria' => $VeiculoReboque->tipoCarroceria ?? null, + 'uf_licenciamento' => $VeiculoReboque->ufLicenciamento ?? null, + 'proprietario' => (object) [ 'cpf' => $VeiculoReboque->Proprietario->cpf ?? null, + 'cnpj' => $VeiculoReboque->Proprietario->cnpj ?? null, + 'nome_completo' => $VeiculoReboque->Proprietario->nomeCompleto ?? null, + 'razao_social' => $VeiculoReboque->Proprietario->razaoSocial ?? null, + 'ie' => $VeiculoReboque->Proprietario->ie ?? null, + 'rntrc' => $VeiculoReboque->Proprietario->rntrc ?? null, + 'uf' => $VeiculoReboque->Proprietario->uf ?? null, + 'tipo_proprietario' => $VeiculoReboque->Proprietario->tipoProprietario ?? null ] ]; + } + $Condutores = []; + foreach ($Rodoviario->Condutores as $Condutor) { + $Condutores[] = (object) [ 'cpf' => $Condutor->cpf ?? null, + 'nome' => $Condutor->nome ?? null ]; + } + $CIOTs = []; + foreach ($Rodoviario->Ciot as $CIOT) { + $CIOTs[] = (object) [ 'codigo_ciot' => $CIOT->codigoCiot ?? null, + 'cpf_responsavel' => $CIOT->cpfResponsavel ?? null, + 'cnpj_responsavel' => $CIOT->cnpjResponsavel ?? null ]; + } + $ValesPedagio = []; + foreach ($Rodoviario->ValesPedagio as $ValePedagio) { + $ValesPedagio[] = (object) [ 'cnpj_fornecedor' => $ValePedagio->cnpjFornecedor ?? null, + 'cpf_responsavel' => $ValePedagio->cpfResponsavel ?? null, + 'cnpj_responsavel' => $ValePedagio->cnpjResponsavel ?? null, + 'comprovante' => $ValePedagio->comprovante ?? null, + 'valor' => $ValePedagio->valor ?? null ]; + } + $Contratantes = []; + foreach ($Rodoviario->Contratantes as $Contratante) { + $Contratantes[] = (object) [ 'cpf' => $Contratante->cpf ?? null, + 'cnpj' => $Contratante->cnpj ?? null ]; + } + $this->toSend->rodoviario = (object) [ 'rntrc' => $Rodoviario->rntrc ?? null, + 'veiculo_tracao' => (object) [ 'codigo_interno' => $Rodoviario->VeiculoTracao->codigoInterno ?? null, + 'placa' => $Rodoviario->VeiculoTracao->placa ?? null, + 'renavam' => $Rodoviario->VeiculoTracao->renavam ?? null, + 'tara' => $Rodoviario->VeiculoTracao->tara ?? null, + 'capacidade_kg' => $Rodoviario->VeiculoTracao->capacidadeKg ?? null, + 'capacidade_m3' => $Rodoviario->VeiculoTracao->capacidadeM3 ?? null, + 'tipo_rodado' => $Rodoviario->VeiculoTracao->tipoRodado ?? null, + 'tipo_carroceria' => $Rodoviario->VeiculoTracao->tipoCarroceria ?? null, + 'uf_licenciamento' => $Rodoviario->VeiculoTracao->ufLicenciamento ?? null, + 'proprietario' => (object) [ 'cpf' => $Rodoviario->VeiculoTracao->Proprietario->cpf ?? null, + 'cnpj' => $Rodoviario->VeiculoTracao->Proprietario->cnpj ?? null, + 'nome_completo' => $Rodoviario->VeiculoTracao->Proprietario->nomeCompleto ?? null, + 'razao_social' => $Rodoviario->VeiculoTracao->Proprietario->razaoSocial ?? null, + 'ie' => $Rodoviario->VeiculoTracao->Proprietario->ie ?? null, + 'rntrc' => $Rodoviario->VeiculoTracao->Proprietario->rntrc ?? null, + 'uf' => $Rodoviario->VeiculoTracao->Proprietario->uf ?? null, + 'tipo_proprietario' => $Rodoviario->VeiculoTracao->Proprietario->tipoProprietario ?? null ] ], + 'veiculo_reboque' => $VeiculosReboque, + 'condutor' => $Condutores, + 'ciot' => $CIOTs, + 'vale_pedagio' => $ValesPedagio, + 'contratante' => $Contratantes ]; + } + + /** + * Cria o JSON para o modelo aéreo. + */ + private function makeJSONAereo() + { + $Aereo = $this->ForIssuance->Aereo(); + $this->toSend->aereo = (object) [ 'nacionalidade_aeronave' => $Aereo->nacionalidadeAeronave ?? null, + 'matricula_aeronave' => $Aereo->matriculaAeronave ?? null, + 'numero_voo' => $Aereo->numeroVoo ?? null, + 'aerodromo_embarque' => $Aereo->aerodromoEmbarque ?? null, + 'aerodromo_destino' => $Aereo->aerodromoDestino ?? null, + 'data_voo' => isset($Aereo->dataVoo) ? $Aereo->dataVoo->format('Y-m-d') : null ]; + } + + /** + * Cria o JSON para o modelo aquaviário. + */ + private function makeJSONAquaviario() + { + $Aquaviario = $this->ForIssuance->Aquaviario(); + $TerminaisCarregamento = []; + foreach ($Aquaviario->TerminaisCarregamento as $TerminalCarregamento) { + $TerminaisCarregamento[] = (object) [ 'codigo' => $TerminalCarregamento->codigo ?? null, + 'nome' => $TerminalCarregamento->nome ?? null ]; + } + $TerminaisDescarregamento = []; + foreach ($Aquaviario->TerminaisDescarregamento as $TerminalDescarregamento) { + $TerminaisDescarregamento[] = (object) [ 'codigo' => $TerminalDescarregamento->codigo ?? null, + 'nome' => $TerminalDescarregamento->nome ?? null ]; + } + $EmbarcacoesComboio = []; + foreach ($Aquaviario->EmbarcacoesComboio as $EmbarcacaoComboio) { + $EmbarcacoesComboio[] = (object) [ 'codigo' => $EmbarcacaoComboio->codigo ?? null, + 'identificador_balsa' => $EmbarcacaoComboio->identificadorBalsa ?? null ]; + } + $CargasVazia = []; + foreach ($Aquaviario->CargasVazias as $CargaVazia) { + $CargasVazia[] = (object) [ 'identificador' => $CargaVazia->identificador ?? null, + 'tipo_unidade' => $CargaVazia->tipoUnidade ?? null ]; + } + $TransportesVazio = []; + foreach ($Aquaviario->TransportesVazios as $TransporteVazio) { + $TransportesVazio[] = (object) [ 'identificador' => $TransporteVazio->identificador ?? null, + 'tipo_unidade' => $TransporteVazio->tipoUnidade ?? null ]; + } + $this->toSend->aquaviario = (object) [ 'irin' => $Aquaviario->irin ?? null, + 'tipo_embarcacao' => $Aquaviario->tipoEmbarcacao ?? null, + 'codigo_embarcacao' => $Aquaviario->codigoEmbarcacao ?? null, + 'nome_embarcacao' => $Aquaviario->nomeEmbarcacao ?? null, + 'numero_viagem' => $Aquaviario->numeroViagem ?? null, + 'codigo_porto_embarque' => $Aquaviario->codigoPortoEmbarque ?? null, + 'codigo_porto_destino' => $Aquaviario->codigoPortoDestino ?? null, + 'porto_transbordo' => $Aquaviario->portoTransbordo ?? null, + 'tipo_navegacao' => $Aquaviario->tipoNavegacao ?? null, + 'terminal_carregamento' => $TerminaisCarregamento ?? null, + 'terminal_descarregamento' => $TerminaisDescarregamento ?? null, + 'embarcacao_comboio' => $EmbarcacoesComboio ?? null, + 'carga_vazia' => $CargasVazia ?? null, + 'transporte_vazio' => $TransportesVazio ?? null ]; + } + + /** + * Cria o JSON para o modelo ferroviário. + */ + private function makeJSONFerroviario() + { + $Ferroviario = $this->ForIssuance->Ferroviario(); + $Vagoes = []; + foreach ($Ferroviario->Vagoes as $Vagao) { + $Vagoes[] = (object) [ 'peso_bc' => $Vagao->pesoBC ?? null, + 'peso_real' => $Vagao->pesoReal ?? null, + 'tipo_vagao' => $Vagao->tipoVagao ?? null, + 'serie' => $Vagao->serie ?? null, + 'numero' => $Vagao->numero ?? null, + 'sequencia_vagao' => $Vagao->sequenciaVagao ?? null, + 'tonelada_util' => $Vagao->toneladaUtil ?? null ]; + } + $this->toSend->ferroviario = (object) [ 'trem' => (object) [ 'prefixo' => $Ferroviario->Trem->prefixo ?? null, + 'data_liberacao' => isset($Ferroviario->Trem->dataLiberacao) ? $Ferroviario->Trem->dataLiberacao->format('Y-m-d H:i:s') : null, + 'origem' => $Ferroviario->Trem->origem ?? null, + 'destino' => $Ferroviario->Trem->destino ?? null ], + 'vagoes' => $Vagoes ]; + } + + /** + * Remove do JSON tudo que não foi informado. + * @param $json + */ + private function removeEmptyProperties(&$json) + { + foreach ($json as $key => $property) { + if (empty($property)) { + unset($json->{$key}); + } else if (!is_scalar($property)) { + $this->removeEmptyProperties($property); + $arrayProperty = (array) $property; + if (empty($arrayProperty) && !in_array($key, [ 'aereo', 'rodoviario', 'aquaviario' , 'ferroviario'])) { + unset($json->{$key}); + } + } + } + } +} \ No newline at end of file diff --git a/src/Api/Responses/ErrorResponse.php b/src/Api/Responses/ErrorResponse.php new file mode 100644 index 0000000..8619d8e --- /dev/null +++ b/src/Api/Responses/ErrorResponse.php @@ -0,0 +1,50 @@ +Response = $response; + $this->content = $content; + } + + /** + * {@inheritDoc} + */ + public function getSuccess(): bool + { + return false; + } + + /** + * {@inheritDoc} + */ + public function getMessage() + { + if ($json = json_decode($this->content)) { + if (isset($json->error)) { + return $json->error; + } + if (isset($json->msg)) { + return $json->msg; + } + } + return ''; + } + + /** + * {@inheritDoc} + */ + public function getObjectResponse(): Response + { + return $this->Response; + } +} \ No newline at end of file diff --git a/src/Api/Responses/FactoryResponse.php b/src/Api/Responses/FactoryResponse.php new file mode 100644 index 0000000..ca126e1 --- /dev/null +++ b/src/Api/Responses/FactoryResponse.php @@ -0,0 +1,38 @@ +getBody()->getContents(); + if (self::isErrorResponse()) { + return new ErrorResponse(self::$response, self::$content); + } + return new SuccessResponse(self::$response, self::$content); + } + + /** + * Identifica se ocorreu erro na requisição. + * @return bool + */ + private static function isErrorResponse() : bool + { + $json = json_decode(self::$content); + if (self::$response->getStatusCode() != 200 || ( $json && isset($json->error) )) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/Api/Responses/SuccessResponse.php b/src/Api/Responses/SuccessResponse.php new file mode 100644 index 0000000..748c886 --- /dev/null +++ b/src/Api/Responses/SuccessResponse.php @@ -0,0 +1,51 @@ +Response = $response; + $this->content = $content; + } + + /** + * {@inheritDoc} + */ + public function getSuccess(): bool + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getMessage() + { + return $this->content; + } + + /** + * {@inheritDoc} + */ + public function getObjectResponse(): Response + { + return $this->Response; + } + + /** + * Retorna o objeto JSON retornado na requisição. + * @return object + */ + public function getResponse() + { + return json_decode($this->content); + } +} \ No newline at end of file diff --git a/src/Enums/TipoCarroceria.php b/src/Enums/TipoCarroceria.php new file mode 100644 index 0000000..cb1dcf5 --- /dev/null +++ b/src/Enums/TipoCarroceria.php @@ -0,0 +1,13 @@ +DocumentosFiscais[] = $DocumentoFiscal; + return $DocumentoFiscal; + } + + /** + * Adiciona novo documento. + * @param DocumentoFiscal $documentoFiscal + */ + public function addDocumentoFiscal(DocumentoFiscal $documentoFiscal) + { + $this->DocumentosFiscais[] = $documentoFiscal; + } +} \ No newline at end of file diff --git a/src/Models/DocumentoFiscal.php b/src/Models/DocumentoFiscal.php new file mode 100644 index 0000000..fb811a8 --- /dev/null +++ b/src/Models/DocumentoFiscal.php @@ -0,0 +1,58 @@ +unidadesTransporte[] = $unidadeTransporte; + return $unidadeTransporte; + } + + /** + * Adiciona uma nova unidade de transporte. + * @param UnidadeTransporte $unidadeTransporte + */ + public function addUnidadeTransporte(UnidadeTransporte $unidadeTransporte) + { + $this->unidadesTransporte[] = $unidadeTransporte; + } + + +} \ No newline at end of file diff --git a/src/Models/EntregaParcial.php b/src/Models/EntregaParcial.php new file mode 100644 index 0000000..5700cb4 --- /dev/null +++ b/src/Models/EntregaParcial.php @@ -0,0 +1,18 @@ +Modalidade) || !($this->Modalidade instanceof Rodoviario)) { + $this->Modalidade = Factory::loadByModality(1); + } + return $this->Modalidade; + } + + /** + * Retorna a modalidade aérea. + * @return Aereo + */ + public function Aereo(): Aereo + { + if (!isset($this->Modalidade) || !($this->Modalidade instanceof Aereo)) { + $this->Modalidade = Factory::loadByModality(2); + } + return $this->Modalidade; + } + + /** + * Retorna a modalidade ferroviária. + * @return Ferroviario + */ + public function Ferroviario(): Ferroviario + { + if (!isset($this->Modalidade) || !($this->Modalidade instanceof Ferroviario)) { + $this->Modalidade = Factory::loadByModality(4); + } + return $this->Modalidade; + } + + /** + * Retorna a modalidade aquaviária. + * @return Aquaviario + */ + public function Aquaviario(): Aquaviario + { + if (!isset($this->Modalidade) || !($this->Modalidade instanceof Aquaviario)) { + $this->Modalidade = Factory::loadByModality(3); + } + return $this->Modalidade; + } + + /** + * Adiciona um novo Seguro. + * @param Seguro $Seguro + */ + public function addSeguro(Seguro $Seguro) + { + $this->Seguros[] = $Seguro; + } + + /** + * Adiciona e retorna um novo Seguro. + * @return Seguro + */ + public function newSeguro() + { + $Seguro = new Seguro(); + $this->Seguros[] = $Seguro; + return $Seguro; + } + + /** + * Adiciona e retorna um novo descarregamento. + * @return Descarregamento + */ + public function newDescarregamento(): Descarregamento + { + $Descarregamento = new Descarregamento(); + $this->Descarregamentos[] = $Descarregamento; + return $Descarregamento; + } + + /** + * Adiciona um novo descarregamento + * @param Descarregamento $Descarregamento + */ + public function addDescarregamento(Descarregamento $Descarregamento) + { + $this->Descarregamentos[] = $Descarregamento; + } + + /** + * Adiciona e retorna novo local de carregamento. + * @return Carregamento + */ + public function newCarregamento(): Carregamento + { + $carregamento = new Carregamento(); + $this->Carregamentos[] = $carregamento; + return $carregamento; + } + + /** + * Adiciona novo local de carregamento; + * @param Carregamento $carregamento + */ + public function addCarregamento(Carregamento $carregamento) + { + $this->Carregamentos[] = $carregamento; + } + + public function __construct() + { + $this->ProdutoPredominante = new ProdutoPredominante(); + $this->Percurso = new Percurso(); + } + + /** + * {@inheritDoc} + */ + public function getUrlNotificacao() + { + if (isset($this->urlNotificacao)){ + return $this->urlNotificacao; + } + } + + /** + * {@inheritDoc} + */ + public function emitir() : APIResponse + { + $issueOperation = new Issue(); + $issueOperation->setDocumentForIssuance($this); + return $issueOperation->execute(); + } + + /** + * {@inheritDoc} + */ + public function emitirHomologacao() : APIResponse + { + $issueOperation = new Issue(); + $issueOperation->setDocumentForIssuance($this); + $issueOperation->setProductionEnviroment(false); + return $issueOperation->execute(); + } + + /** + * Consulta a MDF-e. + * @return APIResponse + */ + public function consultar() : APIResponse + { + $consultOperation = new Consult(); + $consultOperation->setMDFe($this); + return $consultOperation->execute(); + } + + /** + * Encerra a MDF-e. + * @param string $uf + * @param string $municipio + * @param string $municipioIBGE + * @return APIResponse + */ + public function encerrar(string $uf, string $municipio, string $municipioIBGE = '') + { + $closeOperation = new Close(); + $closeOperation->setMDFe($this); + $closeOperation->setUf($uf); + $closeOperation->setMunicipio($municipio); + $closeOperation->setMunicipioIBGE($municipioIBGE); + return $closeOperation->execute(); + } + + /** + * Cancela a MDF-e + * @param string $motivo + * @return APIResponse + */ + public function cancelar(string $motivo) : APIResponse + { + $cancelOperation = new Cancel(); + $cancelOperation->setMDFe($this); + $cancelOperation->setMotivo($motivo); + return $cancelOperation->execute(); + } + + public function incluirCondutor(Rodoviario\Condutor $Condutor) + { + $operationAddDriver = new AddDriver(); + $operationAddDriver->setMDFe($this); + $operationAddDriver->setCondutor($Condutor); + + } +} \ No newline at end of file diff --git a/src/Models/Modalidades/Aereo.php b/src/Models/Modalidades/Aereo.php new file mode 100644 index 0000000..e1ca38d --- /dev/null +++ b/src/Models/Modalidades/Aereo.php @@ -0,0 +1,52 @@ +TransportesVazios[] = $TransporteVazio; + } + + /** + * Adiciona e retorna um novo transporte vazio. + * @return UnidadeVazia + */ + public function newTransporteVazio() + { + $TransporteVazio = new UnidadeVazia(); + $this->TransportesVazios[] = $TransporteVazio; + return $TransporteVazio; + } + + /** + * Adiciona uma nova carga vazia. + * @param UnidadeVazia $CargaVazia + */ + public function addCargaVazia(UnidadeVazia $CargaVazia) + { + $this->CargasVazias[] = $CargaVazia; + } + + /** + * Adiciona e retorna uma nova carga vazia. + * @return UnidadeVazia + */ + public function newCargaVazia() + { + $CargaVazia = new UnidadeVazia(); + $this->CargasVazias[] = $CargaVazia; + return $CargaVazia; + } + + /** + * Adiciona uma nova embarcação. + * @param EmbarcacaoComboio $Embarcacao + */ + public function addEmbarcacaoComboio(EmbarcacaoComboio $Embarcacao) + { + $this->EmbarcacoesComboio[] = $Embarcacao; + } + + /** + * Adiciona e retorna uma nova embarcação. + * @return EmbarcacaoComboio + */ + public function newEmbarcacaoComboio() + { + $Embarcacao = new EmbarcacaoComboio(); + $this->EmbarcacoesComboio[] = $Embarcacao; + return $Embarcacao; + } + + /** + * Adiciona um novo Terminal de Carregamento. + * @param Terminal $Terminal + */ + public function addTerminalCarregamento(Terminal $Terminal) + { + $this->TerminaisCarregamento[] = $Terminal; + } + + /** + * Cria e retorna um novo Terminal de Carregamento. + * @return Terminal + */ + public function newTerminalCarregamento() + { + $Terminal = new Terminal(); + $this->TerminaisCarregamento[] = $Terminal; + return $Terminal; + } + + /** + * Adiciona um novo Terminal de Descarregamento. + * @param Terminal $Terminal + */ + public function addTerminalDescarregamento(Terminal $Terminal) + { + $this->TerminaisDescarregamento[] = $Terminal; + } + + /** + * Cria e retorna um novo Terminal de Descarregamento. + * @return Terminal + */ + public function newTerminalDescarregamento() + { + $Terminal = new Terminal(); + $this->TerminaisDescarregamento[] = $Terminal; + return $Terminal; + } + + /** + * {@inheritDoc} + */ + public function getCode(): int + { + return 3; + } +} \ No newline at end of file diff --git a/src/Models/Modalidades/Aquaviario/EmbarcacaoComboio.php b/src/Models/Modalidades/Aquaviario/EmbarcacaoComboio.php new file mode 100644 index 0000000..ed1ad73 --- /dev/null +++ b/src/Models/Modalidades/Aquaviario/EmbarcacaoComboio.php @@ -0,0 +1,18 @@ +Vagoes[] = $Vagao; + } + + /** + * Adiciona e retorna um novo vagão. + * @return Vagao + */ + public function newVagao() + { + $Vagao = new Vagao(); + $this->Vagoes[] = $Vagao; + return $Vagao; + } + + public function __construct() + { + $this->Trem = new Trem(); + } + + /** + * {@inheritDoc} + */ + public function getCode(): int + { + return 4; + } +} \ No newline at end of file diff --git a/src/Models/Modalidades/Ferroviario/Trem.php b/src/Models/Modalidades/Ferroviario/Trem.php new file mode 100644 index 0000000..5ae8ab3 --- /dev/null +++ b/src/Models/Modalidades/Ferroviario/Trem.php @@ -0,0 +1,30 @@ +Contratantes[] = $Contratante; + } + + /** + * Cria e retorna um novo contratante. + * @return Contratante + */ + public function newContratante() + { + $Contratante = new Contratante(); + $this->Contratantes[] = $Contratante; + return $Contratante; + } + + /** + * Adiciona um novo vale pedágio. + * @param ValePedagio $ValePedagio + */ + public function addValePedagio(ValePedagio $ValePedagio) + { + $this->ValesPedagio[] = $ValePedagio; + } + + /** + * Cria e e retorna um novo Vale Pedágio. + * @return ValePedagio + */ + public function newValePedagio() + { + $ValePedagio = new ValePedagio(); + $this->ValesPedagio[] = $ValePedagio; + return $ValePedagio; + } + + /** + * Adiciona um novo CIOT. + * @param CIOT $Ciot + */ + public function addCIOT(CIOT $Ciot) + { + $this->Ciot[] = $Ciot; + } + + /** + * Cria e retorna um novo CIOT. + * @return CIOT + */ + public function newCIOT() + { + $Ciot = new CIOT(); + $this->Ciot[] = $Ciot; + return $Ciot; + } + + /** + * Adiciona um novo condutor. + * @param Condutor $Condutor + */ + public function addCondutor(Condutor $Condutor) + { + $this->Condutores[] = $Condutor; + } + + /** + * Cria e retorna um novo Condutor. + * @return Condutor + */ + public function newCondutor() + { + $Condutor = new Condutor(); + $this->Condutores[] = $Condutor; + return $Condutor; + } + + /** + * Adiciona um novo veículo de reboque. + * @param Veiculo $VeiculoReboque + */ + public function addVeiculoReboque(Veiculo $VeiculoReboque) + { + $this->VeiculosReboque[] = $VeiculoReboque; + } + + /** + * Cria e retorna um novo veículo de reboque. + * @return Veiculo + */ + public function newVeiculoReboque() + { + $VeiculoReboque = new Veiculo(); + $this->VeiculosReboque[] = $VeiculoReboque; + return $VeiculoReboque; + } + + /** + * {@inheritDoc} + */ + public function getCode(): int + { + return 1; + } +} \ No newline at end of file diff --git a/src/Models/Modalidades/Rodoviario/CIOT.php b/src/Models/Modalidades/Rodoviario/CIOT.php new file mode 100644 index 0000000..6fa5238 --- /dev/null +++ b/src/Models/Modalidades/Rodoviario/CIOT.php @@ -0,0 +1,24 @@ +Proprietario = new Proprietario(); + } +} \ No newline at end of file diff --git a/src/Models/Percurso.php b/src/Models/Percurso.php new file mode 100644 index 0000000..9caf497 --- /dev/null +++ b/src/Models/Percurso.php @@ -0,0 +1,49 @@ +percurso[] = $uf; + return $this; + } + throw new \BadMethodCallException(); + } +} \ No newline at end of file diff --git a/src/Models/Periculosidade.php b/src/Models/Periculosidade.php new file mode 100644 index 0000000..4f8369b --- /dev/null +++ b/src/Models/Periculosidade.php @@ -0,0 +1,53 @@ +EntregaParcial = new EntregaParcial(); + } +} \ No newline at end of file diff --git a/src/Models/ProdutoPredominante.php b/src/Models/ProdutoPredominante.php new file mode 100644 index 0000000..e33c712 --- /dev/null +++ b/src/Models/ProdutoPredominante.php @@ -0,0 +1,51 @@ +LotacaoCarregamento = new Lotacao(); + $this->LotacaoDescarregamento = new Lotacao(); + } +} \ No newline at end of file diff --git a/src/Models/Responsavel.php b/src/Models/Responsavel.php new file mode 100644 index 0000000..c6a1b69 --- /dev/null +++ b/src/Models/Responsavel.php @@ -0,0 +1,27 @@ +Seguradora = new Seguradora(); + $this->Responsavel = new Responsavel(); + } +} \ No newline at end of file diff --git a/src/Models/UnidadeCarga.php b/src/Models/UnidadeCarga.php new file mode 100644 index 0000000..be705ca --- /dev/null +++ b/src/Models/UnidadeCarga.php @@ -0,0 +1,42 @@ +lacres[] = $lacre; + } +} \ No newline at end of file diff --git a/src/Models/UnidadeTransporte.php b/src/Models/UnidadeTransporte.php new file mode 100644 index 0000000..3b79a1b --- /dev/null +++ b/src/Models/UnidadeTransporte.php @@ -0,0 +1,67 @@ +lacres[] = $lacre; + } + + /** + * Adiciona e retorna uma unidade de carga. + * @return UnidadeCarga + */ + public function newUnidadeCarga(): UnidadeCarga + { + $unidadeCarga = new UnidadeCarga(); + $this->unidadesCarga[] = $unidadeCarga; + return $unidadeCarga; + } + + /** + * Adiciona uma unidade de carga. + * @param UnidadeCarga $unidadeCarga + */ + public function addUnidadeCarga(UnidadeCarga $unidadeCarga) + { + $this->unidadesCarga[] = $unidadeCarga; + } +} \ No newline at end of file