Inicio > Contabilidad, Programing > Administrar la recepción de CFD/CFDI – Script que lee XML de un Comprobante Fistal Digital

Administrar la recepción de CFD/CFDI – Script que lee XML de un Comprobante Fistal Digital


Esta nota surge de una idea orginal AdanGQ y su nota original se puede consulta en El Arte de Programar, Administrar la recepción de CFD/CFDi y que a petición de el en un twit de crear una versión usando Python, no he logrando no participar… esto era casi irresistible… el código en python claro!

Y el resultado es el que muestro a continuación y lo he creado usando funciones estandar para que funcione en la mayoría de las plataforma!

#!/usr/bin/env python
# -*- coding: utf-8 -*-

###############################################################################
# ADMINCFD - Administra archivos de CFD
# Autor: Ricardo Torres
# email: rictor@cuhrt.com
# blog: htpp://rctorr.wordpress.com
# twitter: @rctorr
#
# Descripción
# Este script ayuda a leer un CFD para despues formatear el nombre del archivo
# de la siguiente manera:
#    Fecha_RFCemisor_serie_folio_subtotal_iva_total.xml
#
# Fecha: Fecha en que se generó el comprobante
# RFCemisor: RFC de quien emite el cfd/cfdi
# Serie y Folio: Numero de Serie y folio de la factura
# Subtotal, iva, total: Importes de la factura.
#
# El nombre del xml se proporciona desde la línea de comandos, de tal forma que
# se puede usar en algún otro script para automatizar el proceso.
#
###############################################################################

# Ver 1.0
# - Se lee el nombre del archivo desde la línea de comando
# - Se leer los atributos del archivo xml
# - Genera el nombre con la sintaxis solicitada
# - Renombra el archivo xml al nuevo nombre
#

import sys
import os.path
import datetime
import os
from optparse import OptionParser
import ConfigParser
from xml.dom import minidom

class XmlCFD(object):
    """
       Esta clase se encarga de realizar todas las operaciones relacionadas
       con la manipulación del archivo xml de facturación electrónica
    """
    nomFileXml = ''

    def __init__(self, nomFileXml):
        """ Initialize instance. """
        self.nomFileXml = nomFileXml
        self.atributos = dict()

    def getAtributos(self):
        """ Regresa los atributos necesario para formar el nombre del archivo. """

        if os.path.isfile(self.nomFileXml):
            xmlDoc = minidom.parse(self.nomFileXml)
            nodes = xmlDoc.childNodes
            comprobante = nodes[0]

            compAtrib = dict(comprobante.attributes.items())
            self.atributos['serie'] = compAtrib['serie']
            self.atributos['folio'] = compAtrib['folio']
            # Se trunca la parte de la hora de emisión
            self.atributos['fecha'] = compAtrib['fecha'][:10]
            self.atributos['total'] = compAtrib['total'].rjust(10,'0')
            self.atributos['subTotal'] = compAtrib['subTotal'].rjust(10,'0')

            emisor = comprobante.getElementsByTagName('Emisor')
            self.atributos['rfc'] = emisor[0].getAttribute('rfc')
            self.atributos['nombre'] = emisor[0].getAttribute('nombre')

            impuestos = comprobante.getElementsByTagName('Impuestos')
            self.atributos['iva'] = impuestos[0].getAttribute('totalImpuestosTrasladados').rjust(10,'0')

        return self.atributos

    def rename(self):
        """ Renombra el archivo xml de la forma:
                Fecha_RFCemisor_serie_folio_subtotal_iva_total.xml

            Regresa el nuevo nombre del archivo
        """

        self.getAtributos()

        nomFileXmlNew = self.atributos['fecha']
        nomFileXmlNew = '_'+self.atributos['rfc']
        nomFileXmlNew += '_'+self.atributos['serie']
        nomFileXmlNew += '_'+self.atributos['folio']
        nomFileXmlNew += '_'+self.atributos['subTotal']
        nomFileXmlNew += '_'+self.atributos['iva']
        nomFileXmlNew += '_'+self.atributos['total']
        nomFileXmlNew += '.xml'

        os.rename(self.nomFileXml, nomFileXmlNew)

        return nomFileXmlNew

def main(argv):

    usage = "%prog [opciones] archivocfd.xml"
    add_help_option = False
    parser = OptionParser(usage=usage, add_help_option,add_help_option)
    parser.add_option("-h", "--help", action="help",
         help=u"muestra este mensaje de ayuda y termina")
    (options, args) = parser.parse_args()

    if len(args) == 0:
        parser.error("Se tiene que indicar el nombre del archivo xml")
    else:
        nomFileXml = args[0]

    print
    print
    print
    print """
    _       _           _          ____ _____ ____  _
   / \   __| |_ __ ___ (_)_ __    / ___|  ___|  _ \( )___
  / _ \ / _` | '_ ` _ \| | '_ \  | |   | |_  | | | |// __|
 / ___ \ (_| | | | | | | | | | | | |___|  _| | |_| | \__ \\
/_/   \_\__,_|_| |_| |_|_|_| |_|  \____|_|   |____/  |___/

            """
    print '13-08-2012'
    print 'rictor@cuhrt.com'
    print
    print
    print

    if not os.path.isfile(nomFileXml):
        print "El archivo "+nomFileXml+" no existe, vuelve a intentarlo!"
        sys.exit(1)

    xmlcfd = XmlCFD(nomFileXml)
    nomFileXmlNew = xmlcfd.rename()

    print "Renombrando: "+ nomFileXml + " a: "+nomFileXmlNew
    print

if __name__ == "__main__":
  main(sys.argv[1:])

Y bueno solucionado de momento, pero interesante para seguir complementándolo!

¿Algún comentario o sugerencia?

¿En realidad es útil de esta manera? o ¿De que manera se puede mejorar aún más?

Salu2+

Anuncios
  1. Aún no hay comentarios.
  1. 14 enero, 2014 en 19:32

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

PiKon

3D Printing + Raspberry Pi Camera = PiKon Telescope

gvSIG blog

gvSIG project blog

Python Adventures

Welcome to the Jungle!

A %d blogueros les gusta esto: