from decimal import Decimal
from satcfdi.models import Signer
from satcfdi.create.cfd import cfdi40
from satcfdi.create.cfd.catalogos import RegimenFiscal, UsoCFDI, MetodoPago, Impuesto, TipoFactor

from satcfdi.cfdi import CFDI
from satcfdi import render
from satcfdi.pacs import Environment, PAC , Accept


# # From finkok Manual example
# from zeep import Client
# import logging
# import base64
# from lxml import etree
# from zeep.plugins import HistoryPlugin
# 
# logging.basicConfig(level=logging.INFO)
# logging.getLogger('zeep.client').setLevel(logging.DEBUG)
# logging.getLogger('zeep.transport').setLevel(logging.DEBUG)
# logging.getLogger('zeep.xsd.schema').setLevel(logging.DEBUG)
# logging.getLogger('zeep.wsdl').setLevel(logging.DEBUG)


from satcfdi.pacs.finkok import Finkok
pac = Finkok(username="finkok@gsttransportes.com", password="P1$$w0rd#.", environment=Environment.TEST)


# Load signing certificate
signer = Signer.load(
    certificate=open('csd/Personas Morales/IVD920810GU2_CSD.cer', 'rb').read(),
    key=open('csd/Personas Morales/IVD920810GU2_CSD.key', 'rb').read(),
    password=open('csd/Personas Morales/IVD920810GU2_CSD.txt', 'r').read()
)

print(signer)

# create Comprobante
invoice = cfdi40.Comprobante(
    emisor=cfdi40.Emisor(
        rfc=signer.rfc,
        #nombre=signer.legal_name,
        nombre="INNOVACION VALOR Y DESARROLLO SA",
        regimen_fiscal=RegimenFiscal.GENERAL_DE_LEY_PERSONAS_MORALES
    ),
    lugar_expedicion="58000",
    receptor=cfdi40.Receptor(
        rfc='GCA000415UX7',
        nombre='GRUPO DE CONSTRUCCION ARQUITECTONICA NACIONAL',
        uso_cfdi=UsoCFDI.GASTOS_EN_GENERAL,
        domicilio_fiscal_receptor="11830",
        regimen_fiscal_receptor=RegimenFiscal.GENERAL_DE_LEY_PERSONAS_MORALES
    ),
    tipo_de_comprobante='I',
    forma_pago='99',
    metodo_pago=MetodoPago.PAGO_EN_PARCIALIDADES_O_DIFERIDO,
    serie="A",
    folio="123463",
    conceptos=[
        cfdi40.Concepto(
            clave_prod_serv='81111806',
            cantidad=Decimal('1.00'),
            clave_unidad='E48',
            descripcion='SERVICIOS DE FACTURACION',
            valor_unitario=Decimal('1250.30'),
            impuestos=cfdi40.Impuestos(
                traslados=cfdi40.Traslado(
                        impuesto=Impuesto.IVA,
                        tipo_factor=TipoFactor.TASA,
                        tasa_o_cuota=Decimal('0.160000'),
                    ),
                retenciones=[
                    cfdi40.Retencion(
                        impuesto=Impuesto.ISR,
                        tipo_factor=TipoFactor.TASA,
                        tasa_o_cuota=Decimal('0.100000'),
                    ),
                    cfdi40.Retencion(
                        impuesto=Impuesto.IVA,
                        tipo_factor=TipoFactor.TASA,
                        tasa_o_cuota=Decimal('0.106667'),
                    )
                ],
            )
        )
    ]
)

#print(invoice)
invoice.sign(signer)
invoice = invoice.process()
print(invoice)


##################################################################
doc = pac.stamp(invoice, accept=Accept.XML)
with open('_stamped_.xml', 'wb') as f:
    f.write(doc.xml)
# catch signed xml from file
inv = CFDI.from_file('_stamped_.xml')

pdf = render.pdf_bytes(inv)
render.pdf_write(inv, "xxaz_comprobante_.pdf")

##################################################################
# NOTE MANUAL STAGE
##################################################################

# # XML
# xml = invoice.xml_bytes()
# # save to file
# invoice.xml_write("folio_comprobante_124.xml")
# 
# ### NOTE 
# # Username and Password, assigned by FINKOK
# username = 'finkok@gsttransportes.com'
# password = 'P1$$w0rd#.'
# 
# # Read the xml file and encode it on base64
# invoice_path = "folio_comprobante_124.xml"
# 
# #Read the xml file and turn in in bytes
# file = open(invoice_path)
# lines = "".join(file.readlines())
# xml = lines.encode("UTF-8")
# 
# # Consuming the stamp service
# url = "https://demo-facturacion.finkok.com/servicios/soap/stamp.wsdl"
# 
# history = HistoryPlugin()
# client = Client(wsdl = url, plugins = [history])
# contenido = client.service.stamp(xml, username, password)
# xml = contenido.xml
# print(contenido)
# 
# # Get stamped xml
# archivo = open("stamp.xml","w")
# archivo.write(str(xml))
# archivo.close()
# 
# 
# # Get SOAP Request
# request = etree.tostring(history.last_sent["envelope"])
# req_file = open('request.xml', 'w')
# req_file.write(request.decode("UTF-8") )
# req_file.close()
# 
# # Get SOAP Response
# response = etree.tostring(history.last_received["envelope"])
# res_file = open('response.xml', 'w')
# res_file.write(response.decode("UTF-8") )
# res_file.close()
# 
# 
# 
# # catch signed xml from file
# inv = CFDI.from_file('stamp.xml')
# 
# pdf = render.pdf_bytes(inv)
# # save to file
# render.pdf_write(inv, "xxa_comprobante_.pdf")
# # 
