# Copyright (C) 2020  Luis Felipe Mileo - KMEE
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from unittest import TestCase

from erpbrasil.base.fiscal.edoc import ChaveCFeSAT
from erpbrasil.base.fiscal.edoc import ChaveEdoc
from erpbrasil.base.fiscal.edoc import detectar_chave_edoc


class Tests(TestCase):

    def test_mdfe_chave_objeto(self):
        cnpj = '48.740.351/0117-95'
        ano_mes = '1312'
        codigo_uf = 50
        forma_emissao = '1'
        modelo_documento = '58'
        numero_documento = '149000153'
        numero_serie = '000'
        chave = '50131248740351011795580001490001531345952745'
        edoc_1 = ChaveEdoc(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.ano_emissao, 2013, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.codigo_aleatorio, '34595274', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.digito_verificador, '5', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 12, 'Key: mes_emissao failed')

        edoc_2 = ChaveEdoc(
            ano_mes=ano_mes,
            cnpj_emitente=cnpj,
            codigo_uf=codigo_uf,
            forma_emissao=forma_emissao,
            modelo_documento=modelo_documento,
            numero_documento=numero_documento,
            numero_serie=numero_serie,
        )

        self.assertEqual(chave, edoc_2.chave)
        self.assertEqual(edoc_1.chave, chave)

        self.assertEqual(
            edoc_1.partes(),
            edoc_2.partes(),
            'Key: partes failed'
        )

    def test_cte_chave_objeto(self):
        cnpj = '32.438.772/0001-04'
        ano_mes = '1712'
        codigo_uf = 32
        forma_emissao = '1'
        modelo_documento = '57'
        numero_documento = '000199075'
        numero_serie = '001'

        chave = '32171232438772000104570010001990751153183825'
        edoc_1 = ChaveEdoc(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.ano_emissao, 2017, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.codigo_aleatorio, '15318382', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.digito_verificador, '5', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 12, 'Key: mes_emissao failed')

        edoc_2 = ChaveEdoc(
            ano_mes=ano_mes,
            cnpj_emitente=cnpj,
            codigo_uf=codigo_uf,
            forma_emissao=forma_emissao,
            modelo_documento=modelo_documento,
            numero_documento=numero_documento,
            numero_serie=numero_serie,
        )

        self.assertEqual(chave, edoc_2.chave)
        self.assertEqual(edoc_1.chave, chave)

        self.assertEqual(
            edoc_1.partes(),
            edoc_2.partes(),
            'Key: partes failed'
        )

    def test_nfce_chave_objeto(self):
        cnpj = '01.098.983/0106-80'
        ano_mes = '1402'
        codigo_uf = 43
        forma_emissao = '1'
        modelo_documento = '65'
        numero_documento = '000000599'
        numero_serie = '796'

        chave = '43140201098983010680657960000005991148127446'
        edoc_1 = ChaveEdoc(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.ano_emissao, 2014, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.codigo_aleatorio, '14812744', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.digito_verificador, '6', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 2, 'Key: mes_emissao failed')

        edoc_2 = ChaveEdoc(
            ano_mes=ano_mes,
            cnpj_emitente=cnpj,
            codigo_uf=codigo_uf,
            forma_emissao=forma_emissao,
            modelo_documento=modelo_documento,
            numero_documento=numero_documento,
            numero_serie=numero_serie,
        )

        self.assertEqual(chave, edoc_2.chave)
        self.assertEqual(edoc_1.chave, chave)

        self.assertEqual(
            edoc_1.partes(),
            edoc_2.partes(),
            'Key: partes failed'
        )

    def test_nfe_chave_objeto(self):
        cnpj = '20.695.448/0001-84'
        ano_mes = '2103'
        codigo_uf = 35
        forma_emissao = '1'
        modelo_documento = '55'
        numero_documento = '000003589'
        numero_serie = '001'

        chave = '35210320695448000184550010000035891981839923'
        edoc_1 = ChaveEdoc(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.ano_emissao, 2021, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.codigo_aleatorio, '98183992', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.digito_verificador, '3', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 3, 'Key: mes_emissao failed')

        edoc_2 = ChaveEdoc(
            ano_mes=ano_mes,
            cnpj_emitente=cnpj,
            codigo_uf=codigo_uf,
            forma_emissao=forma_emissao,
            modelo_documento=modelo_documento,
            numero_documento=numero_documento,
            numero_serie=numero_serie,
        )

        self.assertEqual(chave, edoc_2.chave)
        self.assertEqual(edoc_1.chave, chave)

        self.assertEqual(
            edoc_1.partes(),
            edoc_2.partes(),
            'Key: partes failed'
        )

    def test_nfe_prefixo_chave_objeto(self):
        cnpj = '20.695.448/0001-84'
        ano_mes = '2103'
        codigo_uf = 35
        forma_emissao = '1'
        modelo_documento = '55'
        numero_documento = '000003589'
        numero_serie = '001'

        chave = '35210320695448000184550010000035891981839923'
        edoc_1 = ChaveEdoc(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.ano_emissao, 2021, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.codigo_aleatorio, '98183992', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.digito_verificador, '3', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 3, 'Key: mes_emissao failed')

        edoc_2 = ChaveEdoc(
            ano_mes=ano_mes,
            cnpj_emitente=cnpj,
            codigo_uf=codigo_uf,
            forma_emissao=forma_emissao,
            modelo_documento=modelo_documento,
            numero_documento=numero_documento,
            numero_serie=numero_serie,
        )

        self.assertEqual(chave, edoc_2.chave)
        self.assertEqual(edoc_1.chave, chave)
        self.assertEqual(edoc_1.prefixo_chave, edoc_2.prefixo_chave)

        self.assertEqual(
            edoc_1.partes(),
            edoc_2.partes(),
            'Key: partes failed'
        )

    def test_cfe_chave_objeto(self):
        cnpj = '08.723.218/0001-86'
        ano_mes = '1508'
        codigo_uf = 35
        forma_emissao = ''
        modelo_documento = '59'
        numero_documento = '000055'
        numero_serie = '900004019'

        chave = '35150808723218000186599000040190000557255950'
        edoc_1 = ChaveCFeSAT(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.codigo_aleatorio, '725595', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.ano_emissao, 2015, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.digito_verificador, '0', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 8, 'Key: mes_emissao failed')

        self.assertEqual(edoc_1.chave, chave)

        self.assertEqual(
            edoc_1.partes(),
            ['3515', '0808', '7232', '1800', '0186', '5990', '0004', '0190', '0005', '5725', '5950'],
            'Key: partes failed'
        )

    def test_cfe2_chave_objeto(self):
        cnpj = '08.723.218/0001-86'
        ano_mes = '1508'
        codigo_uf = 35
        forma_emissao = ''
        modelo_documento = '59'
        numero_documento = '000024'
        numero_serie = '900004019'

        chave = '35150808723218000186599000040190000241114257'
        edoc_1 = ChaveCFeSAT(chave=chave)

        self.assertEqual(edoc_1.ano_mes, ano_mes, 'Key: ano_mes failed')
        self.assertEqual(edoc_1.cnpj_emitente, cnpj, 'Key: cnpj_emitente failed')
        self.assertEqual(edoc_1.codigo_uf, codigo_uf, 'Key: codigo_uf failed')
        self.assertEqual(edoc_1.forma_emissao, forma_emissao, 'Key: forma_emissao failed')
        self.assertEqual(edoc_1.modelo_documento, modelo_documento, 'Key: modelo_documento failed')
        self.assertEqual(edoc_1.numero_documento, numero_documento, 'Key: numero_documento failed')
        self.assertEqual(edoc_1.numero_serie, numero_serie, 'Key: numero_serie failed')

        self.assertEqual(edoc_1.ano_emissao, 2015, 'Key: ano_emissao failed')
        self.assertEqual(edoc_1.codigo_aleatorio, '111425', 'Key: codigo_aleatorio failed')
        self.assertEqual(edoc_1.digito_verificador, '7', 'Key: digito_verificador failed')
        self.assertEqual(edoc_1.mes_emissao, 8, 'Key: mes_emissao failed')

        self.assertEqual(edoc_1.chave, chave)

        self.assertEqual(
            edoc_1.partes(),
            ['3515', '0808', '7232', '1800', '0186', '5990', '0004', '0190', '0002', '4111', '4257'],
            'Key: partes failed'
        )

    def test_invalid_key(self):

        chaves_invalidas = [
            # número do CNPJ emitente inválido
            '35150808723218000187599000040190000241114259',

            # NF-E
            '35210320695448000184550010000035891981839924',
            # Modelo invalido - 54
            '35210320695448000184540010000035891981839924',
            # NFE em maiusculo
            '35210320695448000184540010000035891981839924',
        ]
        for chave in chaves_invalidas:
            with self.assertRaises(ValueError):
                detectar_chave_edoc(chave=chave)

    def test_valid_key(self):

        chaves_validas = [
            '50131248740351011795580001490001531345952745',
            '43140201098983010680657960000005991148127446',
            '35210320695448000184550010000035891981839923',
            '32171232438772000104570010001990751153183825',
            '35150808723218000186599000040190000241114257',
            '35150808723218000186599000040190000557255950'
        ]
        for chave in chaves_validas:
            edoc = detectar_chave_edoc(chave=chave)
            self.assertTrue(edoc, 'Erro chave edoc')
