Complemento Otros Derechos e Impuestos

En este ocasión vamos a ver cómo crear un complemento utilizando las clases base de la Librería CFDI la cual necesitan tener a la mano.

Clase para Complementos

La clase base para todos los complementos debe ser "TMDCfdiComplementoItem"


Lo siguiente a definir serían los atributos de la clase; esto se hace con la clase "TMDXmlElement" que cuenta con los siguientes parámetros:

TMDXmlElement(string name, string version, int elementType, string cfdiVersion, Type xmlElementGenerator)


los parámetros se definen como:

    name: nombre del complemento
    version: versión del complemento
    elementType: tipo de elemento; valores válidos 0 - CFDI, 1 - CFDI Property, 2 - Complemento Concepto, 3 - Complemento, 4 - Addenda (actualmente sin uso)
    cfdiVersion: indica la version del cfdi que soporta (actualmente sin uso)
    xmlElementGenerator: clase que implementa la interfaz IMDXmlElementGenerator

Interfaz IMDXmlElementGenerator

La interfaz cuenta con 3 métodos:

    void AddXmlNameSpace(ref List<string> nameSpaceList): Permite agregar referencias a "Namespaces" al CFDI
    void AddXmlSchemas(ref List<string> schemasList): Permite agregar "Schemas" al CFDI
    bool HasData { get; } : Indica si el elemento cuenta con información para agregar al CFDI al momento de estar generando el archivo xml

Esta interfaz ya es implementada por la clase  "TMDCfdiComplementoItem" permitiendo sobre-escribir (override) la cual cuenta con los métodos virtuales para aplicar "override" e implementar el código necesario.


Las propiedades de la clase (Atributos de un Nodo Xml)

Se definen como cualquier propiedad de una clase pero para que la librería reconozca la propiedad sea relacionada con el atributo del nodo xml (del archivo xml del cfdi) en necesario establecer un atributo a esa propiedad con la clase TMDXmlAttribute la cual tiene los siguientes parámetros:

TMDXmlAttributeAttribute(string name, bool requiered, Type formatter, Type patternVerifier)

Los parámetros se definen como:
    name: nombre del atributo (sensible a mayúsculas y minúsculas)
    required: indica si el atributo es requerido
    formatter: tipo de objeto el cual da formato al valor de la propiedad
    patternVerifier: tipo de objeto el cual verifica la estructura de los datos de la propiedad (actualmente no se usa)

El nombre de la propiedad no tiene que coincidir con la del atributo en el archivo xml del CFDI, pero el nombre en el parámetro "name" debe ser exactamente igual

Un ejemplo de uso de la clase de atributo TMDXmlAttribute se muestra en la clase TMDComplementoNomina12, particularmente en la propiedad FechaPago


Como observan, la propiedad FechaPago está definida de tipo DateTime; lo que hace el parámetro formatter cuando se está creando el archivo xml del CFDI se llama a la clase definida en el atributo y de ahí se obtiene el formato requerido.


La clase TMDXmlFechaCorta es una subclase de TMDXmlStringFormat, la cual tiene un método virtual string DoGetFormatedValue(object objValue) - el parámetro objValue es el objeto de la propiedad - el cual se puede modificar y regresar el valor que se necesita en un objeto de tipo string.


Propiedades de tipo coleccion

Las propiedades de este tipo colección deben derivar de la clase TMDXmlCollection y los objetos que contendrá esa colección deberán ser una subclase de TMDCollectionItem


La clase de los objetos de la colección deberá tener el atributo de la clase TMDXmlElement, definiendo el nombre del nodo que se encuentra en el archivo xml del cfdi.



Propiedades de los atributos

En la definición de las variables de las propiedades deberán marcarse todas como nulas utilizando para ello la clase MDINullValue (como se observa en la imagen anterior), las propiedades que no son nulas son las que se consideran al momento de generar el archivo xml, las nulas se ignoran.

Definiendo la propiedad colección en la clase Complemento

La definición de la propiedad colección se hace como cualquier propiedad de tipo clase con la diferencia que se agregará el atributo TMDXmlElement especificando el tipo de elemento que acepta la colección (será el mismo atributo que el definido en la clase de objetos de la colección)


Descarga el código fuente del complemento 


Cómo usar el código fuente:

Agrega el archivo del código al proyecto MDCfdiComplementos de la librería Cfdi y utiliza el siguiente código (dentro de un evento click de un botón por ejemplo) para generar un archivo CFDI, agregarle el complemento "Otros Derechos e Impuestos" y Timbrarlo son nuestros amigos de Smarter Web en su ambiente de pruebas:

     TMDCfdiConfig.FIELDirectory = string.Format(@"C:\Users\{0}\Desktop\MDTestCfdiV3\Fiel", TMDWinUtils.WindowsUserName);
            TMDCfdiConfig.CerFile = "CSD_Pruebas_CFDI_LAN7008173R5.cer"; // "CSD_Prueba_CFDI_LAN8507268IA.cer";
            TMDCfdiConfig.KeyFile = "CSD_Pruebas_CFDI_LAN7008173R5.key"; // "CSD_Prueba_CFDI_LAN8507268IA.key";
            TMDCfdiConfig.KeyFilePassword = "12345678a"/*"12345678a"*/;

            TMDCfdiConfig.UseOnLineXsltFiles = false;
            TMDCfdiConfig.XsltFilesDirectory = string.Format(@"C:\Users\{0}\Desktop\MDTestCfdiV3\XSL Files", TMDWinUtils.WindowsUserName);


            /**/
            TMDCfdi33 _cfdi = MDCfdiTestSourceCodes.LoadBasicCfdi();

            TMDComplementoImpLocales _impLocales = new TMDComplementoImpLocales();
            _impLocales.TotaldeRetenciones = 500m;
            _impLocales.TotaldeTraslados = 500m;

            TMDImpLocalRetencionesLocalesItem _retencion = _impLocales.RetencionesLocales.Add();
            _retencion.ImpLocRetenido = "Retención 5 % al millar";
            _retencion.TasadeRetencion = 5m;
            _retencion.Importe = 500.00m;

            TMDImpLocalTrasladosLocalesItem _traslado = _impLocales.TrasladosLocales.Add();
            _traslado.ImpLocTrasladado = "5 % al millar";
            _traslado.TasadeTraslado = 5.00m;
            _traslado.Importe = 500.00m;

            _cfdi.Complemento.Any.Add(_impLocales);

            _cfdi.SellaCfdi(true);

            TMDPAC _swPac = new TMDPAC_SmarterWebpRUEBAS();
            object _customResult;
            if (_cfdi.Timbra(_swPac, out _customResult))
                MessageBox.Show("CFDI timbrado exitosamente", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
            else
                MessageBox.Show("Error en timbrado", "", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);



/* ************************************************************* */
EL SOFTWARE SE PROPORCIONA "TAL CUAL" Y EL AUTOR RECHAZA TODAS LAS  GARANTÍAS CON RESPECTO A ESTE SOFTWARE, INCLUIDAS TODAS LAS GARANTÍAS  IMPLÍCITAS DE COMERCIABILIDAD Y ADECUACIÓN. EN NINGÚN CASO EL AUTOR SERÁ  RESPONSABLE POR CUALQUIER DAÑO ESPECIAL, DIRECTO, INDIRECTO O CONSECUENTE, O CUALQUIER DAÑO QUE RESULTE DE LA PÉRDIDA DE USO, DATOS O BENEFICIOS, YA SEA EN UNA ACCIÓN DE CONTRATO, NEGLIGENCIA U OTRA ACCIÓN EXTRACONTRACTUAL QUE SURJA DE O EN CONEXIÓN CON EL USO O RENDIMIENTO DE ESTE SOFTWARE


THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Comentarios

Entradas populares de este blog

Tipo de cambio FIX con WebService de Banxico

Complemento - Leyendas Fiscales

Colecciones en C# - Implementación IList e IBindingList