Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Complemento Carta Porte 3.1 #122

Merged
merged 13 commits into from
Jun 18, 2024
Merged
61 changes: 61 additions & 0 deletions development/ElementsMaker/specifications/cartaporte31.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"php-namespace": "CfdiUtils\\Elements\\CartaPorte31",
"prefix": "cartaporte31",
"xml-namespace": "http://www.sat.gob.mx/CartaPorte31",
"xml-schemalocation": "http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte31.xsd",
"version-attribute": "Version",
"version-value": "3.1",
"root-element": "CartaPorte",
"structure": {
"RegimenesAduaneros" : {
"RegimenAduaneroCCP" : {
"multiple": true
}
},
"Ubicaciones": {
"Ubicacion": {
"multiple": true,
"Domicilio": {}
}
},
"Mercancias": {
"Mercancia": {
"multiple": true,
"DocumentacionAduanera": {"multiple": true},
"GuiasIdentificacion": {"multiple": true},
"CantidadTransporta": {"multiple": true},
"DetalleMercancia": {}
},
"Autotransporte": {
"IdentificacionVehicular": {},
"Seguros": {},
"Remolques": {
"Remolque": {"multiple": true}
}
},
"TransporteMaritimo": {
"Contenedor": {
"multiple": true,
"RemolquesCCP": {
"RemolqueCCP": {"multiple": true}
}
}
},
"TransporteAereo": {},
"TransporteFerroviario": {
"DerechosDePaso": {"multiple": true},
"Carro": {
"multiple": true,
"Contenedor": {"multiple": true}
}
}
},
"FiguraTransporte": {
"TiposFigura": {
"multiple": true,
"PartesTransporte": {"multiple": true},
"Domicilio": {}
}
}
}
}
9 changes: 7 additions & 2 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@
- Remove deprecated constant `CfdiUtils\Retenciones\Retenciones::RET_NAMESPACE`.
- Remove deprecated class `CfdiUtils\Utils\Crp20277Fixer`.

## Version 2.28.2 2024-02-20
## Version 2.29.0 2024-06-18

- Wrap OpenSSL command run on a *try/catch* block to throw OpenSSLException.
Add `CfdiUtils\Elements\CartaPorte31` *Elements* to work with "Carta Porte 3.1".
Thanks `@alejandrogova1` for your contribution.

## Version 2.28.2 2024-06-09

- Wrap OpenSSL command run on a *try/catch* block to throw an `OpenSSLException` exception.
- Refactor certificate downloader test helper. Now it uses curl instead of native PHP. It was failing on PHP 7.3.
- Remove old dependencies for *ReadTheDocs*: `mkdocs:1.2.3` and `jinja2<3.1.0`. Thanks to `@dependabot`.
- On build workflow:
Expand Down
Binary file added docs/_assets/diagrama-carta-porte-31.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 8 additions & 8 deletions docs/crear/complemento-carta-porte-30.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ En este caso, `addElemento` siempre agrega un nuevo elemento.

```php
<?php
$nomina = new \CfdiUtils\Elements\CartaPorte30\CartaPorte();
$cartaPorte = new \CfdiUtils\Elements\CartaPorte30\CartaPorte();

// acceso por prefijo get (Ubicaciones es de 1 aparición)
$ubicaciones = $CartaPorte30->getUbicaciones();
$ubicaciones = $cartaPorte->getUbicaciones();

// agregar con prefijo add (Ubicacion es de 1 aparición)
$ubicacion = $ubicaciones->addUbicacion(['TipoUbicacion'=> 'Origen', ...]);
Expand All @@ -55,7 +55,7 @@ $ubicacion->multiDomicilio(

### Métodos de ayuda de los elementos

#### Elemento `Carta Porte`
#### Elemento `CartaPorte`

- `CartaPorte::getUbicaciones(): Ubicaciones`.
- `CartaPorte::addUbicaciones(array $attributes): Ubicaciones`.
Expand Down Expand Up @@ -159,10 +159,10 @@ el elemento `CartaPorte` al comprobante.
$creator = new \CfdiUtils\CfdiCreator40();
// acceso al elemento Comprobante (el nodo principal del CFDI)
$comprobante = $creator->comprobante();

$cartaporte30 = new \CfdiUtils\Elements\CartaPorte30\CartaPorte();
// ... llenar la información de $cartaporte30

// agregar $cartaporte30 como complemento del $comprobante
$comprobante->addComplemento($cartaporte30);
$cartaPorte = new \CfdiUtils\Elements\CartaPorte30\CartaPorte();
// ... llenar la información de $cartaPorte

// agregar $cartaPorte como complemento del $comprobante
$comprobante->addComplemento($cartaPorte);
```
183 changes: 183 additions & 0 deletions docs/crear/complemento-carta-porte-31.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Complemento de Carta Porte 3.1

El espacio de nombres de `CfdiUtils\Elements\CartaPorte31` permite trabajar en forma más fácil con los nodos
con nombres y acciones específicas para implementar el Complemento de Carta Porte versión 3.1, vigente a
partir del 17 de julio del 2024.

La documentación del complemento la puedes encontrar en el sitio oficial del SAT:

- Página del complemento: <http://omawww.sat.gob.mx/tramitesyservicios/Paginas/complemento_carta_porte.htm>.
- La ruta del archivo de excel con los nuevos catálogos: <http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/CatalogosCartaPorte31.xls>.
- Ruta del XSD del CCP 3.1: <http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte31.xsd>.
- Ruta del XSLT para la secuencia de cadena original CCP 3.1: <http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte31.xslt>.
- Ruta matriz de errores CCP 3.1: <http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Matriz_Errores_CCP_V31.xls>.
- Ruta XSD catálogos CCP: <http://www.sat.gob.mx/sitio_internet/cfd/catalogos/CartaPorte/catCartaPorte.xsd>.
- Ruta del estándar: <http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Carta_Porte_31.pdf>.

Según la documentación técnica el XML debe cumplir con la siguiente especificación:

- Prefijo de namespace: `cartaporte31`.
- Namespace: <http://www.sat.gob.mx/CartaPorte31>.
- Archivo XSD: <http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte31.xsd>.

## Jerarquía de nodos

En la siguiente imagen se puede ver la jerarquía, el orden y el número de apariciones mínimas y máximas de los nodos en el Complemento Carta Porte 3.1.

![Diagrama del Complemento Carta Porte 3.1](../_assets/diagrama-carta-porte-31.png)

## Métodos para agregar nodos

Los métodos de ayuda para nodos de máximo una sola aparición tienen la forma `getElemento(): Elemento`
y `addElemento(array $attributes): Elemento`. En donde `Elemento` se sustituye por el nombre del nodo.
En este caso, `addElemento` siempre trabaja con el elemento que previamente exista.

Los métodos de ayuda para nodos de múltiples apariciones tienen la forma `addElemento(array $attributes): Elemento`
y `multiElemento(array $attributes): self`. En donde `Elemento` se sustituye por el nombre del nodo y `self` es el
elemento que contiene el componente.
En este caso, `addElemento` siempre agrega un nuevo elemento.

```php
<?php
$cartaPorte = new \CfdiUtils\Elements\CartaPorte31\CartaPorte();

// acceso por prefijo get (Ubicaciones es de 1 aparición)
$ubicaciones = $cartaPorte->getUbicaciones();

// agregar con prefijo add (Ubicacion es de 1 aparición)
$ubicacion = $ubicaciones->addUbicacion(['TipoUbicacion'=> 'Origen', ...]);

// agregar con prefijo multi (Domicilio es de múltiples)
$ubicacion->multiDomicilio(
['Calle' => 'xxx', 'NumeroExterior' => 'xxx', ...],
['Calle' => 'xxx', 'NumeroExterior' => 'xxx', ...]
);
```

### Métodos de ayuda de los elementos

#### Elemento `CartaPorte`

- `CartaPorte::getRegimenesAduaneros(): RegimenesAduaneros`.
- `CartaPorte::getUbicaciones(): Ubicaciones`.
- `CartaPorte::addUbicaciones(array $attributes): Ubicaciones`.
- `CartaPorte::getMercancias(): Mercancias`.
- `CartaPorte::addMercancias(array $attributes): Mercancias`.
- `CartaPorte::getFiguraTransporte(): FiguraTransporte`.
- `CartaPorte::addFiguraTransporte(array $attributes): FiguraTransporte`.

#### Elemento `RegimenesAduaneros`

- `RegimenesAduaneros::addRegimenAduaneroCCP(array $attributes): RegimenAduaneroCCP`.
- `RegimenesAduaneros::multiRegimenAduaneroCCP(array ...$elementAttributes): self`.

#### Elemento `Ubicaciones`

- `Ubicaciones::addUbicacion(array $attributes): Ubicacion`.
- `Ubicaciones::multiUbicacion(array ...$elementAttributes): self`.

#### Elemento `Ubicacion`

- `Ubicacion::getDomicilio(): Domicilio`.
- `Ubicacion::addDomicilio(array $attributes): Domicilio`.

#### Elemento `Mercancias`

- `Mercancias::addMercancia(array $attributes): Mercancia`.
- `Mercancias::multiMercancia(array ...$elementAttributes): self`.
- `Mercancias::getAutotransporte(): Autotransporte`.
- `Mercancias::addAutotransporte(array $attributes): Autotransporte`.
- `Mercancias::getTransporteMaritimo(): TransporteMaritimo`.
- `Mercancias::addTransporteMaritimo(array $attributes): TransporteMaritimo`.
- `Mercancias::getTransporteAereo(): TransporteAereo`.
- `Mercancias::addTransporteAereo(array $attributes): TransporteAereo`.
- `Mercancias::getTransporteFerroviario(): TransporteFerroviario`.
- `Mercancias::addTransporteFerroviario(array $attributes): TransporteFerroviario`.

#### Elemento `Mercancia`

- `Mercancia::addDocumentacionAduanera(array $attributes): DocumentacionAduanera`.
- `Mercancia::multiDocumentacionAduanera(array ...$elementAttributes): self`.
- `Mercancia::addGuiasIdentificacion(array $attributes): GuiasIdentificacion`.
- `Mercancia::multiGuiasIdentificacion(array ...$elementAttributes): self`.
- `Mercancia::addCantidadTransporta(array $attributes): CantidadTransporta`.
- `Mercancia::multiCantidadTransporta(array ...$elementAttributes): self`.
- `Mercancia::getDetalleMercancia(): DetalleMercancia`.
- `Mercancia::addDetalleMercancia(array $attributes): DetalleMercancia`.

#### Elemento `Autotransporte`

- `Autotransporte::getIdentificacionVehicular(): IdentificacionVehicular`.
- `Autotransporte::addIdentificacionVehicular(array $attributes): IdentificacionVehicular`.
- `Autotransporte::getSeguros(): Seguros`.
- `Autotransporte::addSeguros(array $attributes): Seguros`.
- `Autotransporte::getRemolques(): Remolques`.
- `Autotransporte::addRemolques(array $attributes): Remolques`.

#### Elemento `Remolques`

- `Remolques::addRemolque(array $attributes): Remolque`.
- `Remolques::multiRemolque(array ...$elementAttributes): self`.

#### Elemento `TransporteMaritimo`

- `TransporteMaritimo::addContenedor(array $attributes): ContenedorMaritimo`.
- `TransporteMaritimo::multiContenedor(array ...$elementAttributes): self`.

#### Elemento `ContenedorMaritimo`

- El nombre del elemento es `Contenedor`.
- `ContenedorMaritimo::getRemolquesCCP(): RemolquesCCP`.
- `ContenedorMaritimo::addRemolquesCCP(array $attributes): RemolquesCCP`.

#### Elemento `RemolquesCCP`

- `RemolquesCCP::addRemolque(array $attributes): Remolque`.
- `RemolquesCCP::multiRemolque(array ...$elementAttributes): self`.

#### Elemento `TransporteFerroviario`

- `TransporteFerroviario::addDerechosDePaso(array $attributes): DerechosDePaso`.
- `TransporteFerroviario::multiDerechosDePaso(array ...$elementAttributes): self`.
- `TransporteFerroviario::addCarro(array $attributes): Carro`.
- `TransporteFerroviario::multiCarro(array ...$elementAttributes): self`.

#### Elemento `Carro`

- `Carro::addContenedor(array $attributes): ContenedorFerroviario`.
- `Carro::multiContenedor(array ...$elementAttributes): self`.

#### Elemento `ContenedorFerroviario`

- El nombre del elemento es `Contenedor`.

#### Elemento `FiguraTransporte`

- `FiguraTransporte::addTiposFigura(array $attributes): TiposFigura`.
- `FiguraTransporte::multiTiposFigura(array ...$elementAttributes): self`.

#### Elemento `TiposFigura`

- `TiposFigura::addPartesTransporte(array $attributes): PartesTransporte`.
- `TiposFigura::multiPartesTransporte(array ...$elementAttributes): self`.
- `TiposFigura::getDomicilio(): Domicilio`.
- `TiposFigura::addDomicilio(array $attributes): Domicilio`.

### Agregar el complemento carta porte al comprobante

Cuando se tiene un comprobante, se puede utilizar el método `Comprobante::addComplemento()` para insertar
el elemento `CartaPorte` al comprobante.

```php
<?php
// clase de ayuda de creación del CFDI 4.0
$creator = new \CfdiUtils\CfdiCreator40();
// acceso al elemento Comprobante (el nodo principal del CFDI)
$comprobante = $creator->comprobante();

$cartaPorte = new \CfdiUtils\Elements\CartaPorte31\CartaPorte();
// ... llenar la información de $cartaPorte

// agregar $cartaPorte como complemento del $comprobante
$comprobante->addComplemento($cartaporte);
```
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Solo hay métodos específicos para CFDI 3.3 y CFDI 4.0.
- [Elementos de CFDI 3.3](crear/elements-cfdi-40.md)
- [Elementos de Nómina 1.2 revisión B](crear/complemento-nomina12b.md)
- [Elementos de Carta Porte 3.0](crear/complemento-carta-porte-30.md)
- [Elementos de Carta Porte 3.1](crear/complemento-carta-porte-31.md)
- [Elementos de Comercio Exterior 2.0](crear/complemento-comercio-exterior-20.md)
- [Agregar complementos](crear/complementos-aun-no-implementados.md)
- [CFDI Retenciones](crear/cfdi-de-retenciones-e-informacion-de-pagos.md)
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ nav:
- crear/elements-cfdi-40.md
- crear/complemento-nomina12b.md
- crear/complemento-carta-porte-30.md
- crear/complemento-carta-porte-31.md
- crear/complemento-comercio-exterior-20.md
- crear/complementos-aun-no-implementados.md
- crear/cfdi-de-retenciones-e-informacion-de-pagos.md
Expand Down
58 changes: 58 additions & 0 deletions src/CfdiUtils/Elements/CartaPorte31/Autotransporte.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace CfdiUtils\Elements\CartaPorte31;

use CfdiUtils\Elements\Common\AbstractElement;

class Autotransporte extends AbstractElement
{
public function getElementName(): string
{
return 'cartaporte31:Autotransporte';
}

public function getChildrenOrder(): array
{
return [
'cartaporte31:IdentificacionVehicular',
'cartaporte31:Seguros',
'cartaporte31:Remolques',
];
}

public function getIdentificacionVehicular(): IdentificacionVehicular
{
return $this->helperGetOrAdd(new IdentificacionVehicular());
}

public function addIdentificacionVehicular(array $attributes = []): IdentificacionVehicular
{
$subject = $this->getIdentificacionVehicular();
$subject->addAttributes($attributes);
return $subject;
}

public function getSeguros(): Seguros
{
return $this->helperGetOrAdd(new Seguros());
}

public function addSeguros(array $attributes = []): Seguros
{
$subject = $this->getSeguros();
$subject->addAttributes($attributes);
return $subject;
}

public function getRemolques(): Remolques
{
return $this->helperGetOrAdd(new Remolques());
}

public function addRemolques(array $attributes = []): Remolques
{
$subject = $this->getRemolques();
$subject->addAttributes($attributes);
return $subject;
}
}
13 changes: 13 additions & 0 deletions src/CfdiUtils/Elements/CartaPorte31/CantidadTransporta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace CfdiUtils\Elements\CartaPorte31;

use CfdiUtils\Elements\Common\AbstractElement;

class CantidadTransporta extends AbstractElement
{
public function getElementName(): string
{
return 'cartaporte31:CantidadTransporta';
}
}
Loading