From 8110945e8ae4b01574e0323a1b05db01e6de5c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 19 May 2023 17:18:31 -0300 Subject: [PATCH] [ADD] l10n_br_mdfe_spec generated by xsdata-odoo --- l10n_br_mdfe_spec/__init__.py | 1 + l10n_br_mdfe_spec/__manifest__.py | 14 + l10n_br_mdfe_spec/models/__init__.py | 2 + l10n_br_mdfe_spec/models/spec_models.py | 37 + l10n_br_mdfe_spec/models/v3_0/__init__.py | 5 + .../models/v3_0/ev_pagto_oper_mdfe_v3_00.py | 288 +++ .../models/v3_0/mdfe_modal_aereo_v3_00.py | 61 + .../v3_0/mdfe_modal_aquaviario_v3_00.py | 244 ++ .../v3_0/mdfe_modal_ferroviario_v3_00.py | 111 + .../v3_0/mdfe_modal_rodoviario_v3_00.py | 833 ++++++ .../models/v3_0/mdfe_tipos_basico_v3_00.py | 2236 +++++++++++++++++ .../models/v3_0/tipos_geral_mdfe_v3_00.py | 183 ++ l10n_br_mdfe_spec/readme/CONTRIBUTORS.rst | 1 + l10n_br_mdfe_spec/readme/DESCRIPTION.rst | 26 + l10n_br_mdfe_spec/static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 446 ++++ l10n_br_mdfe_spec/tests/__init__.py | 1 + l10n_br_mdfe_spec/tests/test_mdfe_import.py | 154 ++ .../odoo/addons/l10n_br_mdfe_spec | 1 + setup/l10n_br_mdfe_spec/setup.py | 6 + 20 files changed, 4650 insertions(+) create mode 100644 l10n_br_mdfe_spec/__init__.py create mode 100644 l10n_br_mdfe_spec/__manifest__.py create mode 100644 l10n_br_mdfe_spec/models/__init__.py create mode 100644 l10n_br_mdfe_spec/models/spec_models.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/__init__.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/ev_pagto_oper_mdfe_v3_00.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aereo_v3_00.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aquaviario_v3_00.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/mdfe_modal_ferroviario_v3_00.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/mdfe_modal_rodoviario_v3_00.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/mdfe_tipos_basico_v3_00.py create mode 100644 l10n_br_mdfe_spec/models/v3_0/tipos_geral_mdfe_v3_00.py create mode 100644 l10n_br_mdfe_spec/readme/CONTRIBUTORS.rst create mode 100644 l10n_br_mdfe_spec/readme/DESCRIPTION.rst create mode 100644 l10n_br_mdfe_spec/static/description/icon.png create mode 100644 l10n_br_mdfe_spec/static/description/index.html create mode 100644 l10n_br_mdfe_spec/tests/__init__.py create mode 100644 l10n_br_mdfe_spec/tests/test_mdfe_import.py create mode 120000 setup/l10n_br_mdfe_spec/odoo/addons/l10n_br_mdfe_spec create mode 100644 setup/l10n_br_mdfe_spec/setup.py diff --git a/l10n_br_mdfe_spec/__init__.py b/l10n_br_mdfe_spec/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/l10n_br_mdfe_spec/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_br_mdfe_spec/__manifest__.py b/l10n_br_mdfe_spec/__manifest__.py new file mode 100644 index 000000000000..f5b1b34abe89 --- /dev/null +++ b/l10n_br_mdfe_spec/__manifest__.py @@ -0,0 +1,14 @@ +{ + "name": "mdfe spec", + "version": "14.0.1.0.0", + "author": "Akretion, Odoo Community Association (OCA)", + "license": "LGPL-3", + "category": "Accounting", + "summary": "CT-e spec", + "depends": ["base"], + "installable": True, + "application": False, + "development_status": "Alpha", + "maintainers": ["rvalyi"], + "website": "https://github.com/OCA/l10n-brazil", +} diff --git a/l10n_br_mdfe_spec/models/__init__.py b/l10n_br_mdfe_spec/models/__init__.py new file mode 100644 index 000000000000..5fa2504e4d68 --- /dev/null +++ b/l10n_br_mdfe_spec/models/__init__.py @@ -0,0 +1,2 @@ +from . import spec_models +from . import v3_0 diff --git a/l10n_br_mdfe_spec/models/spec_models.py b/l10n_br_mdfe_spec/models/spec_models.py new file mode 100644 index 000000000000..53ebd7bb8fb4 --- /dev/null +++ b/l10n_br_mdfe_spec/models/spec_models.py @@ -0,0 +1,37 @@ +# Copyright 2023-TODAY Akretion - Raphael Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). + +from odoo import fields, models + + +class MdfeSpecMixin(models.AbstractModel): + _description = "Abstract Model" + _name = "spec.mixin.mdfe" + _field_prefix = "mdfe30_" + _schema_name = "mdfe" + _schema_version = "3.0.0" + _odoo_module = "l10n_br_mdfe" + _spec_module = ( + "odoo.addons.l10n_br_mdfe_spec.models.v3_0.mdfe_tipos_basico_v3_00.py" + ) + _binding_module = "nfelib.mdfe.bindings.v3_0.mdfe_v3_00.py" + _spec_tab_name = "mdfe" + + brl_currency_id = fields.Many2one( + comodel_name="res.currency", + string="Moeda", + # FIXME compute method is better, but not working in v14. + default=lambda self: self.env.ref("base.BRL"), + ) + + def _valid_field_parameter(self, field, name): + if name in ( + "xsd_type", + "xsd_required", + "choice", + "xsd_implicit", + "xsd_choice_required", + ): + return True + else: + return super()._valid_field_parameter(field, name) diff --git a/l10n_br_mdfe_spec/models/v3_0/__init__.py b/l10n_br_mdfe_spec/models/v3_0/__init__.py new file mode 100644 index 000000000000..dbfaa60482cf --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/__init__.py @@ -0,0 +1,5 @@ +from . import mdfe_tipos_basico_v3_00 +from . import mdfe_modal_aereo_v3_00 +from . import mdfe_modal_aquaviario_v3_00 +from . import mdfe_modal_ferroviario_v3_00 +from . import mdfe_modal_rodoviario_v3_00 diff --git a/l10n_br_mdfe_spec/models/v3_0/ev_pagto_oper_mdfe_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/ev_pagto_oper_mdfe_v3_00.py new file mode 100644 index 000000000000..81c14342b0de --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/ev_pagto_oper_mdfe_v3_00.py @@ -0,0 +1,288 @@ +# Copyright 2023 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + +"Tipo do Componente" +COMP_TPCOMP = [ + ("01", "Vale Pedágio"), + ("02", "Impostos, taxas e contribuições"), + ("03", "Despesas (bancárias, meios de pagamento, outras)"), + ("99", "Outros"), +] + +"Descrição do Evento - “Pagamento Operação MDF-e”" +EVPAGTOOPERMDFE_DESCEVENTO = [ + ("Pagamento Operação MDF-e", "Pagamento Operação MDF-e"), + ("Pagamento Operacao MDF-e", "Pagamento Operacao MDF-e"), +] + +"Indicador da Forma de Pagamento" +INFPAG_INDPAG = [ + ("0", "Pagamento à Vista"), + ("1", "Pagamento à Prazo"), +] + + +class EvPagtoOperMdfe(models.AbstractModel): + """Schema XML de validação do evento de pagamento da operação de transporte + 110116""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.evpagtoopermdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "EvPagtoOperMdfe" + + mdfe30_descEvento = fields.Selection( + EVPAGTOOPERMDFE_DESCEVENTO, + string="Descrição do Evento", + xsd_required=True, + help="Descrição do Evento - “Pagamento Operação MDF-e”", + ) + + mdfe30_nProt = fields.Char( + string="Número do Protocolo de Status do MDF-e", + xsd_required=True, + xsd_type="TProt", + help=( + "Número do Protocolo de Status do MDF-e. \n1 posição tipo de " + "autorizador (9 - SEFAZ Nacional ); \n2 posições ano;\n10 " + "seqüencial no ano." + ), + ) + + mdfe30_infViagens = fields.Many2one( + comodel_name="mdfe.30.infviagens", + string="Informações do total", + xsd_required=True, + help=( + "Informações do total de viagens acobertadas pelo Evento " + "“pagamento do frete”" + ), + ) + + mdfe30_infPag = fields.One2many( + "mdfe.30.evpagtoopermdfe_infpag", + "mdfe30_infPag_evPagtoOperMDFe_id", + string="Informações do Pagamento do Frete", + ) + + +class InfViagens(models.AbstractModel): + """Informações do total de viagens acobertadas pelo Evento “pagamento do + frete”""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infviagens" + _inherit = "spec.mixin.mdfe" + _binding_type = "EvPagtoOperMdfe.InfViagens" + + mdfe30_qtdViagens = fields.Char( + string="Quantidade total", + xsd_required=True, + help=("Quantidade total de viagens realizadas com o pagamento do Frete"), + ) + + mdfe30_nroViagem = fields.Char( + string="Número de referência da viagem", + xsd_required=True, + help="Número de referência da viagem do MDFe referenciado.", + ) + + +class EvPagtoOperMdfeInfPag(models.AbstractModel): + "Informações do Pagamento do Frete" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.evpagtoopermdfe_infpag" + _inherit = "spec.mixin.mdfe" + _binding_type = "EvPagtoOperMdfe.InfPag" + + mdfe30_infPag_evPagtoOperMDFe_id = fields.Many2one( + comodel_name="mdfe.30.evpagtoopermdfe", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_xNome = fields.Char( + string="Razão social ou Nome do responsavel", + help="Razão social ou Nome do responsavel pelo pagamento", + ) + + mdfe30_CPF = fields.Char( + string="Número do CPF do responsável pelo pgto", + choice="infpag", + xsd_choice_required=True, + xsd_type="TCpf", + help=( + "Número do CPF do responsável pelo pgto\nInformar os zeros não " + "significativos." + ), + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ do responsável pelo pgto", + choice="infpag", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ do responsável pelo pgto\nInformar os zeros não " + "significativos." + ), + ) + + mdfe30_idEstrangeiro = fields.Char( + string="Identificador do responsável pelo pgto", + choice="infpag", + xsd_choice_required=True, + help=("Identificador do responsável pelo pgto em caso de ser estrangeiro"), + ) + + mdfe30_comp = fields.One2many( + "mdfe.30.evpagtoopermdfe_comp", + "mdfe30_Comp_infPag_id", + string="Componentes do Pagamentoi do Frete", + ) + + mdfe30_vContrato = fields.Monetary( + string="Valor Total do Contrato", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + ) + + mdfe30_indPag = fields.Selection( + INFPAG_INDPAG, + string="Indicador da Forma", + xsd_required=True, + help=( + "Indicador da Forma de Pagamento:0-Pagamento à Vista;1-Pagamento à" + " Prazo;" + ), + ) + + mdfe30_vAdiant = fields.Monetary( + string="Valor do Adiantamento", + xsd_type="TDec_1302", + currency_field="brl_currency_id", + help="Valor do Adiantamento (usar apenas em pagamento à Prazo", + ) + + mdfe30_infPrazo = fields.One2many( + "mdfe.30.evpagtoopermdfe_infprazo", + "mdfe30_infPrazo_infPag_id", + string="Informações do pagamento a prazo", + help=( + "Informações do pagamento a prazo.\nInformar somente se indPag for" + " à Prazo" + ), + ) + + mdfe30_infBanc = fields.Many2one( + comodel_name="mdfe.30.evpagtoopermdfe_infbanc", + string="Informações bancárias", + xsd_required=True, + ) + + +class EvPagtoOperMdfeComp(models.AbstractModel): + "Componentes do Pagamentoi do Frete" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.evpagtoopermdfe_comp" + _inherit = "spec.mixin.mdfe" + _binding_type = "EvPagtoOperMdfe.InfPag.Comp" + + mdfe30_Comp_infPag_id = fields.Many2one( + comodel_name="mdfe.30.evpagtoopermdfe_infpag", + xsd_implicit=True, + ondelete="cascade", + ) + mdfe30_tpComp = fields.Selection( + COMP_TPCOMP, + string="Tipo do Componente", + xsd_required=True, + help=( + "Tipo do Componente\n01 - Vale Pedágio; \n02 - Impostos, taxas e " + "contribuições; \n03 - Despesas (bancárias, meios de pagamento, " + "outras)\n; 99 - Outros" + ), + ) + + mdfe30_vComp = fields.Monetary( + string="Valor do componente", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + ) + + mdfe30_xComp = fields.Char(string="Descrição do componente do tipo Outros") + + +class EvPagtoOperMdfeInfPrazo(models.AbstractModel): + """Informações do pagamento a prazo. + Informar somente se indPag for à Prazo""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.evpagtoopermdfe_infprazo" + _inherit = "spec.mixin.mdfe" + _binding_type = "EvPagtoOperMdfe.InfPag.InfPrazo" + + mdfe30_infPrazo_infPag_id = fields.Many2one( + comodel_name="mdfe.30.evpagtoopermdfe_infpag", + xsd_implicit=True, + ondelete="cascade", + ) + mdfe30_nParcela = fields.Char(string="Número da Parcela", xsd_required=True) + + mdfe30_dVenc = fields.Date( + string="Data de vencimento da Parcela", + xsd_required=True, + xsd_type="TData", + help="Data de vencimento da Parcela (AAAA-MM-DD)", + ) + + mdfe30_vParcela = fields.Monetary( + string="Valor da Parcela", + xsd_required=True, + xsd_type="TDec_1302Opc", + currency_field="brl_currency_id", + ) + + +class EvPagtoOperMdfeInfBanc(models.AbstractModel): + "Informações bancárias" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.evpagtoopermdfe_infbanc" + _inherit = "spec.mixin.mdfe" + _binding_type = "EvPagtoOperMdfe.InfPag.InfBanc" + + mdfe30_codBanco = fields.Char( + string="Número do banco", choice="infbanc", xsd_choice_required=True + ) + + mdfe30_codAgencia = fields.Char( + string="Número da agência bancária", choice="infbanc", xsd_choice_required=True + ) + + mdfe30_CNPJIPEF = fields.Char( + string="Número do CNPJ da Instituição", + choice="infbanc", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ da Instituição de Pagamento Eletrônico do " + "Frete\nInformar os zeros não significativos." + ), + ) + + mdfe30_PIX = fields.Char( + string="Chave PIX", + choice="infbanc", + xsd_choice_required=True, + help=( + "Chave PIX\nInformar a chave PIX para recebimento do frete. \nPode" + " ser email, CPF/ CNPJ (somente numeros), Telefone com a seguinte " + "formatação (+5599999999999) ou a chave aleatória gerada pela " + "instituição." + ), + ) diff --git a/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aereo_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aereo_v3_00.py new file mode 100644 index 000000000000..b9f01d4f644f --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aereo_v3_00.py @@ -0,0 +1,61 @@ +# Copyright 2023 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + + +class Aereo(models.AbstractModel): + "Informações do modal Aéreo" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.aereo" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aereo" + + mdfe30_nac = fields.Char( + string="Marca da Nacionalidade da aeronave", xsd_required=True + ) + + mdfe30_matr = fields.Char( + string="Marca de Matrícula da aeronave", xsd_required=True + ) + + mdfe30_nVoo = fields.Char( + string="Número do Voo", + xsd_required=True, + help=( + "Número do Voo\nFormato = AB1234, sendo AB a designação da empresa" + " e 1234 o número do voo. Quando não for possível incluir as " + "marcas de nacionalidade e matrícula sem hífen." + ), + ) + + mdfe30_cAerEmb = fields.Char( + string="Aeródromo de Embarque", + xsd_required=True, + help=( + "Aeródromo de Embarque\nO código de três letras IATA do aeroporto " + "de partida deverá ser incluído como primeira anotação. Quando não" + " for possível, utilizar a sigla OACI." + ), + ) + + mdfe30_cAerDes = fields.Char( + string="Aeródromo de Destino", + xsd_required=True, + help=( + "Aeródromo de Destino\nO código de três letras IATA do aeroporto " + "de destino deverá ser incluído como primeira anotação. Quando não" + " for possível, utilizar a sigla OACI." + ), + ) + + mdfe30_dVoo = fields.Date( + string="Data do Voo", + xsd_required=True, + xsd_type="TData", + help="Data do Voo\nFormato AAAA-MM-DD", + ) diff --git a/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aquaviario_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aquaviario_v3_00.py new file mode 100644 index 000000000000..9d9285a5f605 --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_aquaviario_v3_00.py @@ -0,0 +1,244 @@ +# Copyright 2023 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + +"Tipo de Navegação" +AQUAV_TPNAV = [ + ("0", "Interior"), + ("1", "Cabotagem"), +] + +"Tipo da unidade de carga vazia" +INFUNIDCARGAVAZIA_TPUNIDCARGAVAZIA = [ + ("1", "Container"), + ("2", "ULD"), + ("3", "Pallet"), + ("4", "Outros"), +] + +"""Tipo da unidade de transporte vazia + Deve ser preenchido com “1” para Rodoviário Tração do tipo caminhão ou “2” para + Rodoviário reboque do tipo carreta""" +INFUNIDTRANSPVAZIA_TPUNIDTRANSPVAZIA = [ + ("1", "1"), + ("2", "2"), +] + + +class Aquav(models.AbstractModel): + "Informações do modal Aquaviário" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.aquav" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aquav" + + mdfe30_irin = fields.Char( + string="Irin do navio sempre deverá", + xsd_required=True, + help="Irin do navio sempre deverá ser informado", + ) + + mdfe30_tpEmb = fields.Char( + string="Código do tipo de embarcação", + xsd_required=True, + help=( + "Código do tipo de embarcação\nPreencher com código da Tabela de " + "Tipo de Embarcação definida no Ministério dos Transportes" + ), + ) + + mdfe30_cEmbar = fields.Char(string="Código da embarcação", xsd_required=True) + + mdfe30_xEmbar = fields.Char(string="Nome da embarcação", xsd_required=True) + + mdfe30_nViag = fields.Char(string="Número da Viagem", xsd_required=True) + + mdfe30_cPrtEmb = fields.Char( + string="Código do Porto de Embarque", + xsd_required=True, + help=( + "Código do Porto de Embarque\nPreencher de acordo com Tabela de " + "Portos definida no Ministério dos Transportes" + ), + ) + + mdfe30_cPrtDest = fields.Char( + string="Código do Porto de Destino", + xsd_required=True, + help=( + "Código do Porto de Destino\nPreencher de acordo com Tabela de " + "Portos definida no Ministério dos Transportes" + ), + ) + + mdfe30_prtTrans = fields.Char(string="Porto de Transbordo") + + mdfe30_tpNav = fields.Selection( + AQUAV_TPNAV, + string="Tipo de Navegação", + help=( + "Tipo de Navegação\nPreencher com: \n\t\t\t\t\t\t0 - " + "Interior;\n\t\t\t\t\t\t1 - Cabotagem" + ), + ) + + mdfe30_infTermCarreg = fields.One2many( + "mdfe.30.inftermcarreg", + "mdfe30_infTermCarreg_aquav_id", + string="Grupo de informações dos terminais", + help="Grupo de informações dos terminais de carregamento.", + ) + + mdfe30_infTermDescarreg = fields.One2many( + "mdfe.30.inftermdescarreg", + "mdfe30_infTermDescarreg_aquav_id", + string="infTermDescarreg", + help="Grupo de informações dos terminais de descarregamento.", + ) + + mdfe30_infEmbComb = fields.One2many( + "mdfe.30.infembcomb", + "mdfe30_infEmbComb_aquav_id", + string="Informações das Embarcações do Comboio", + ) + + mdfe30_infUnidCargaVazia = fields.One2many( + "mdfe.30.infunidcargavazia", + "mdfe30_infUnidCargaVazia_aquav_id", + string="Informações das Undades de Carga vazias", + ) + + mdfe30_infUnidTranspVazia = fields.One2many( + "mdfe.30.infunidtranspvazia", + "mdfe30_infUnidTranspVazia_aquav_id", + string="Informações das Undades", + help="Informações das Undades de Transporte vazias", + ) + + +class InfTermCarreg(models.AbstractModel): + "Grupo de informações dos terminais de carregamento." + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.inftermcarreg" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aquav.InfTermCarreg" + + mdfe30_infTermCarreg_aquav_id = fields.Many2one( + comodel_name="mdfe.30.aquav", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_cTermCarreg = fields.Char( + string="Código do Terminal de Carregamento", + xsd_required=True, + help=( + "Código do Terminal de Carregamento\nPreencher de acordo com a " + "Tabela de Terminais de Carregamento. O código de cada Porto está " + "definido no Ministério de Transportes." + ), + ) + + mdfe30_xTermCarreg = fields.Char( + string="Nome do Terminal de Carregamento", xsd_required=True + ) + + +class InfTermDescarreg(models.AbstractModel): + "Grupo de informações dos terminais de descarregamento." + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.inftermdescarreg" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aquav.InfTermDescarreg" + + mdfe30_infTermDescarreg_aquav_id = fields.Many2one( + comodel_name="mdfe.30.aquav", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_cTermDescarreg = fields.Char( + string="Código do Terminal de Descarregamento", + xsd_required=True, + help=( + "Código do Terminal de Descarregamento\nPreencher de acordo com a " + "Tabela de Terminais de Descarregamento. O código de cada Porto " + "está definido no Ministério de Transportes." + ), + ) + + mdfe30_xTermDescarreg = fields.Char( + string="Nome do Terminal de Descarregamento", xsd_required=True + ) + + +class InfEmbComb(models.AbstractModel): + "Informações das Embarcações do Comboio" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infembcomb" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aquav.InfEmbComb" + + mdfe30_infEmbComb_aquav_id = fields.Many2one( + comodel_name="mdfe.30.aquav", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_cEmbComb = fields.Char( + string="Código da embarcação do comboio", xsd_required=True + ) + + mdfe30_xBalsa = fields.Char(string="Identificador da Balsa", xsd_required=True) + + +class InfUnidCargaVazia(models.AbstractModel): + "Informações das Undades de Carga vazias" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infunidcargavazia" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aquav.InfUnidCargaVazia" + + mdfe30_infUnidCargaVazia_aquav_id = fields.Many2one( + comodel_name="mdfe.30.aquav", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_idUnidCargaVazia = fields.Char( + string="Identificação da unidades de carga vazia", + xsd_required=True, + xsd_type="TContainer", + ) + + mdfe30_tpUnidCargaVazia = fields.Selection( + INFUNIDCARGAVAZIA_TPUNIDCARGAVAZIA, + string="Tipo da unidade de carga vazia", + xsd_required=True, + help=( + "Tipo da unidade de carga vazia\n1 - Container; 2 - ULD;3 - " + "Pallet;4 - Outros;" + ), + ) + + +class InfUnidTranspVazia(models.AbstractModel): + "Informações das Undades de Transporte vazias" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infunidtranspvazia" + _inherit = "spec.mixin.mdfe" + _binding_type = "Aquav.InfUnidTranspVazia" + + mdfe30_infUnidTranspVazia_aquav_id = fields.Many2one( + comodel_name="mdfe.30.aquav", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_idUnidTranspVazia = fields.Char( + string="Identificação da unidades", + xsd_required=True, + xsd_type="TContainer", + help="Identificação da unidades de transporte vazia", + ) + + mdfe30_tpUnidTranspVazia = fields.Selection( + INFUNIDTRANSPVAZIA_TPUNIDTRANSPVAZIA, + string="Tipo da unidade de transporte vazia", + xsd_required=True, + help=( + "Tipo da unidade de transporte vazia\nDeve ser preenchido com “1” " + "para Rodoviário Tração do tipo caminhão ou “2” para Rodoviário " + "reboque do tipo carreta" + ), + ) diff --git a/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_ferroviario_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_ferroviario_v3_00.py new file mode 100644 index 000000000000..5c531c786fda --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_ferroviario_v3_00.py @@ -0,0 +1,111 @@ +# Copyright 2023 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + + +class Ferrov(models.AbstractModel): + "Informações do modal Ferroviário" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.ferrov" + _inherit = "spec.mixin.mdfe" + _binding_type = "Ferrov" + + mdfe30_trem = fields.Many2one( + comodel_name="mdfe.30.trem", + string="Informações da composição do trem", + xsd_required=True, + ) + + mdfe30_vag = fields.One2many( + "mdfe.30.vag", "mdfe30_vag_ferrov_id", string="informações dos Vagões" + ) + + +class Trem(models.AbstractModel): + "Informações da composição do trem" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.trem" + _inherit = "spec.mixin.mdfe" + _binding_type = "Ferrov.Trem" + + mdfe30_xPref = fields.Char(string="Prefixo do Trem", xsd_required=True) + + mdfe30_dhTrem = fields.Datetime( + string="Data e hora de liberação do trem", + xsd_type="TDateTimeUTC", + help="Data e hora de liberação do trem na origem", + ) + + mdfe30_xOri = fields.Char( + string="Origem do Trem", + xsd_required=True, + help="Origem do Trem\nSigla da estação de origem", + ) + + mdfe30_xDest = fields.Char( + string="Destino do Trem", + xsd_required=True, + help="Destino do Trem\nSigla da estação de destino", + ) + + mdfe30_qVag = fields.Char( + string="Quantidade de vagões carregados", xsd_required=True + ) + + +class Vag(models.AbstractModel): + "informações dos Vagões" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.vag" + _inherit = "spec.mixin.mdfe" + _binding_type = "Ferrov.Vag" + + mdfe30_vag_ferrov_id = fields.Many2one( + comodel_name="mdfe.30.ferrov", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_pesoBC = fields.Float( + string="Peso Base de Cálculo de Frete", + xsd_required=True, + xsd_type="TDec_0303", + digits=( + 3, + 3, + ), + help="Peso Base de Cálculo de Frete em Toneladas", + ) + + mdfe30_pesoR = fields.Float( + string="Peso Real em Toneladas", + xsd_required=True, + xsd_type="TDec_0303", + digits=( + 3, + 3, + ), + ) + + mdfe30_tpVag = fields.Char(string="Tipo de Vagão") + + mdfe30_serie = fields.Char( + string="Serie de Identificação do vagão", xsd_required=True + ) + + mdfe30_nVag = fields.Char( + string="Número de Identificação do vagão", xsd_required=True + ) + + mdfe30_nSeq = fields.Char(string="Sequencia do vagão na composição") + + mdfe30_TU = fields.Char( + string="Tonelada Útil", + xsd_required=True, + help=( + "Tonelada Útil\nUnidade de peso referente à carga útil (apenas o " + "peso da carga transportada), expressa em toneladas." + ), + ) diff --git a/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_rodoviario_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_rodoviario_v3_00.py new file mode 100644 index 000000000000..66d2df3d56b2 --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/mdfe_modal_rodoviario_v3_00.py @@ -0,0 +1,833 @@ +# Copyright 2023 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models +from .ev_pagto_oper_mdfe_v3_00 import ( + COMP_TPCOMP, + INFPAG_INDPAG, +) +from .tipos_geral_mdfe_v3_00 import TUF + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + +"Tipo do Vale Pedagio" +DISP_TPVALEPED = [ + ("01", "TAG"), + ("02", "Cupom"), + ("03", "Cartão"), +] + +"""Indicador de operação de transporte de alto desempenho + Operação de transporte com utilização de veículos de frotas dedicadas ou + fidelizadas. + Preencher com “1” para indicar operação de transporte de alto desempenho, + demais casos não informar a tag""" +INFPAG_INDALTODESEMP = [ + ("1", "1"), +] + +"Tipo Proprietário ou possuidor" +PROP_TPPROP = [ + ("0", "TAC Agregado"), + ("1", "TAC Independente"), + ("2", "Outros."), +] + +"""Categoria de Combinação Veicular + Preencher com: + 02 Veículo Comercial 2 eixos;0 + 4 Veículo Comercial 3 eixos; + 06 Veículo Comercial 4 eixos;0 + 7 Veículo Comercial 5 eixos; 0 + 8 Veículo Comercial 6 eixos; + 10 Veículo Comercial 7 eixos; + 11 Veículo Comercial 8 eixos; + 12 Veículo Comercial 9 eixos; + 13 Veículo Comercial 10 eixos; + 14 Veículo Comercial Acima de 10 eixos;""" +VALEPED_CATEGCOMBVEIC = [ + ("02", "02"), + ("04", "04"), + ("06", "06"), + ("07", "07"), + ("08", "08"), + ("10", "10"), + ("11", "11"), + ("12", "12"), + ("13", "13"), + ("14", "14"), +] + +"Tipo de Carroceria" +VEICREBOQUE_TPCAR = [ + ("00", "não aplicável"), + ("01", "Aberta"), + ("02", "Fechada/Baú"), + ("03", "Granelera"), + ("04", "Porta Container"), + ("05", "Sider"), +] + +"Tipo de Carroceria" +VEICTRACAO_TPCAR = [ + ("00", "não aplicável"), + ("01", "Aberta"), + ("02", "Fechada/Baú"), + ("03", "Granelera"), + ("04", "Porta Container"), + ("05", "Sider"), +] + +"Tipo de Rodado" +VEICTRACAO_TPROD = [ + ("01", "Truck"), + ("02", "Toco"), + ("03", "Cavalo Mecânico"), + ("04", "VAN"), + ("05", "Utilitário"), + ("06", "Outros."), +] + + +class Rodo(models.AbstractModel): + "Informações do modal Rodoviário" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.rodo" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo" + + mdfe30_infANTT = fields.Many2one( + comodel_name="mdfe.30.infantt", + string="Grupo de informações", + help="Grupo de informações para Agência Reguladora", + ) + + mdfe30_veicTracao = fields.Many2one( + comodel_name="mdfe.30.veictracao", + string="Dados do Veículo com a Tração", + xsd_required=True, + ) + + mdfe30_veicReboque = fields.One2many( + "mdfe.30.veicreboque", "mdfe30_veicReboque_rodo_id", string="Dados dos reboques" + ) + + mdfe30_codAgPorto = fields.Char(string="Código de Agendamento no porto") + + mdfe30_lacRodo = fields.One2many( + "mdfe.30.lacrodo", "mdfe30_lacRodo_rodo_id", string="Lacres" + ) + + +class InfAntt(models.AbstractModel): + "Grupo de informações para Agência Reguladora" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infantt" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt" + + mdfe30_RNTRC = fields.Char( + string="Registro Nacional", + xsd_type="TRNTRC", + help=( + "Registro Nacional de Transportadores Rodoviários de " + "Carga\nRegistro obrigatório do emitente do MDF-e junto à ANTT " + "para exercer a atividade de transportador rodoviário de cargas " + "por conta de terceiros e mediante remuneração." + ), + ) + + mdfe30_infCIOT = fields.One2many( + "mdfe.30.infciot", "mdfe30_infCIOT_infANTT_id", string="Dados do CIOT" + ) + + mdfe30_valePed = fields.Many2one( + comodel_name="mdfe.30.valeped", + string="Informações de Vale Pedágio", + help=( + "Informações de Vale Pedágio\nOutras informações sobre Vale-" + "Pedágio obrigatório que não tenham campos específicos devem ser " + "informadas no campo de observações gerais de uso livre pelo " + "contribuinte, visando atender as determinações legais vigentes." + ), + ) + + mdfe30_infContratante = fields.One2many( + "mdfe.30.infcontratante", + "mdfe30_infContratante_infANTT_id", + string="Grupo de informações dos contratantes", + help=("Grupo de informações dos contratantes do serviço de transporte"), + ) + + mdfe30_infPag = fields.One2many( + "mdfe.30.rodo_infpag", + "mdfe30_infPag_infANTT_id", + string="Informações do Pagamento do Frete", + ) + + +class InfCiot(models.AbstractModel): + "Dados do CIOT" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infciot" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.InfCiot" + + mdfe30_infCIOT_infANTT_id = fields.Many2one( + comodel_name="mdfe.30.infantt", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_CIOT = fields.Char( + string="Código Identificador da Operação", + xsd_required=True, + help=( + "Código Identificador da Operação de Transporte\nTambém Conhecido " + "como conta frete" + ), + ) + + mdfe30_CPF = fields.Char( + string="Número do CPF responsável pela geração", + choice="infciot", + xsd_choice_required=True, + xsd_type="TCpf", + help=( + "Número do CPF responsável pela geração do CIOT\nInformar os zeros" + " não significativos." + ), + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ responsável pela geração", + choice="infciot", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ responsável pela geração do CIOT\nInformar os " + "zeros não significativos." + ), + ) + + +class ValePed(models.AbstractModel): + """Informações de Vale Pedágio + Outras informações sobre Vale-Pedágio obrigatório que não tenham campos + específicos devem ser informadas no campo de observações gerais de uso + livre pelo contribuinte, visando atender as determinações legais + vigentes.""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.valeped" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.ValePed" + + mdfe30_disp = fields.One2many( + "mdfe.30.disp", + "mdfe30_disp_valePed_id", + string="Informações dos dispositivos", + help="Informações dos dispositivos do Vale Pedágio", + ) + + mdfe30_categCombVeic = fields.Selection( + VALEPED_CATEGCOMBVEIC, + string="Categoria de Combinação Veicular", + help=( + "Categoria de Combinação Veicular\nPreencher com:\n\n02 Veículo " + "Comercial 2 eixos;0\n4 Veículo Comercial 3 eixos;\n06 Veículo " + "Comercial 4 eixos;0\n7 Veículo Comercial 5 eixos; 0\n8 Veículo " + "Comercial 6 eixos;\n10 Veículo Comercial 7 eixos;\n11 Veículo " + "Comercial 8 eixos;\n12 Veículo Comercial 9 eixos;\n13 Veículo " + "Comercial 10 eixos;\n14 Veículo Comercial Acima de 10 eixos;" + ), + ) + + +class Disp(models.AbstractModel): + "Informações dos dispositivos do Vale Pedágio" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.disp" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.ValePed.Disp" + + mdfe30_disp_valePed_id = fields.Many2one( + comodel_name="mdfe.30.valeped", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_CNPJForn = fields.Char( + string="CNPJ da empresa fornecedora", + xsd_required=True, + help=( + "CNPJ da empresa fornecedora do Vale-Pedágio\n- CNPJ da Empresa " + "Fornecedora do Vale-Pedágio, ou seja, empresa que fornece ao " + "Responsável pelo Pagamento do Vale-Pedágio os dispositivos do " + "Vale-Pedágio.\n\t\t\t\t\t\t\t\t\t- Informar os zeros não " + "significativos." + ), + ) + + mdfe30_CNPJPg = fields.Char( + string="CNPJ do responsável pelo pagamento", + choice="disp", + xsd_type="TCnpjOpc", + help=( + "CNPJ do responsável pelo pagamento do Vale-Pedágio\n- responsável" + " pelo pagamento do Vale Pedágio. Informar somente quando o " + "responsável não for o emitente do MDF-e.\n\t\t\t\t\t\t\t\t\t- " + "Informar os zeros não significativos." + ), + ) + + mdfe30_CPFPg = fields.Char( + string="CPFPg", + choice="disp", + xsd_type="TCpf", + help=( + "CNPJ do responsável pelo pagamento do Vale-Pedágio\nInformar os " + "zeros não significativos." + ), + ) + + mdfe30_nCompra = fields.Char( + string="Número do comprovante de compra", + help=( + "Número do comprovante de compra\nNúmero de ordem do comprovante " + "de compra do Vale-Pedágio fornecido para cada veículo ou " + "combinação veicular, por viagem." + ), + ) + + mdfe30_vValePed = fields.Monetary( + string="Valor do Vale-Pedagio", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + help=( + "Valor do Vale-Pedagio\nValor do Vale-Pedágio obrigatório " + "necessário à livre circulação, desde a origem da operação de " + "transporte até o destino, do transportador contratado." + ), + ) + + mdfe30_tpValePed = fields.Selection( + DISP_TPVALEPED, + string="Tipo do Vale Pedagio", + help="Tipo do Vale Pedagio\n01 - TAG; 02 - Cupom; 03 - Cartão", + ) + + +class InfContratante(models.AbstractModel): + "Grupo de informações dos contratantes do serviço de transporte" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infcontratante" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.InfContratante" + + mdfe30_infContratante_infANTT_id = fields.Many2one( + comodel_name="mdfe.30.infantt", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_xNome = fields.Char(string="Razão social ou Nome do contratante") + + mdfe30_CPF = fields.Char( + string="Número do CPF do contratante do serviço", + choice="infcontratante", + xsd_choice_required=True, + xsd_type="TCpf", + help=( + "Número do CPF do contratante do serviço\nInformar os zeros não " + "significativos." + ), + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ do contratante do serviço", + choice="infcontratante", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ do contratante do serviço\nInformar os zeros não " + "significativos." + ), + ) + + mdfe30_idEstrangeiro = fields.Char( + string="Identificador do contratante em caso", + choice="infcontratante", + xsd_choice_required=True, + help=("Identificador do contratante em caso de contratante estrangeiro"), + ) + + +class RodoInfPag(models.AbstractModel): + "Informações do Pagamento do Frete" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.rodo_infpag" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.InfPag" + + mdfe30_infPag_infANTT_id = fields.Many2one( + comodel_name="mdfe.30.infantt", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_xNome = fields.Char( + string="Razão social ou Nome do respnsável", + help="Razão social ou Nome do respnsável pelo pagamento", + ) + + mdfe30_CPF = fields.Char( + string="Número do CPF do responsável pelo pgto", + choice="infpag", + xsd_choice_required=True, + xsd_type="TCpf", + help=( + "Número do CPF do responsável pelo pgto\nInformar os zeros não " + "significativos." + ), + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ do responsável pelo pgto", + choice="infpag", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ do responsável pelo pgto\nInformar os zeros não " + "significativos." + ), + ) + + mdfe30_idEstrangeiro = fields.Char( + string="Identificador do responsável pelo pgto", + choice="infpag", + xsd_choice_required=True, + help=("Identificador do responsável pelo pgto em caso de ser estrangeiro"), + ) + + mdfe30_comp = fields.One2many( + "mdfe.30.rodo_comp", + "mdfe30_Comp_infPag_id", + string="Componentes do Pagamentoi do Frete", + ) + + mdfe30_vContrato = fields.Monetary( + string="Valor Total do Contrato", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + ) + + mdfe30_indAltoDesemp = fields.Selection( + INFPAG_INDALTODESEMP, + string="Indicador de operação de transporte", + help=( + "Indicador de operação de transporte de alto desempenho\nOperação " + "de transporte com utilização de veículos de frotas dedicadas ou " + "fidelizadas.\nPreencher com “1” para indicar operação de " + "transporte de alto desempenho, demais casos não informar a tag" + ), + ) + + mdfe30_indPag = fields.Selection( + INFPAG_INDPAG, + string="Indicador da Forma", + xsd_required=True, + help=( + "Indicador da Forma de Pagamento:0-Pagamento à Vista;1-Pagamento à" + " Prazo;" + ), + ) + + mdfe30_vAdiant = fields.Monetary( + string="Valor do Adiantamento", + xsd_type="TDec_1302", + currency_field="brl_currency_id", + help="Valor do Adiantamento (usar apenas em pagamento à Prazo", + ) + + mdfe30_infPrazo = fields.One2many( + "mdfe.30.rodo_infprazo", + "mdfe30_infPrazo_infPag_id", + string="Informações do pagamento a prazo", + help=( + "Informações do pagamento a prazo.\nInformar somente se indPag for" + " à Prazo" + ), + ) + + mdfe30_infBanc = fields.Many2one( + comodel_name="mdfe.30.rodo_infbanc", + string="Informações bancárias", + xsd_required=True, + ) + + +class RodoComp(models.AbstractModel): + "Componentes do Pagamentoi do Frete" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.rodo_comp" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.InfPag.Comp" + + mdfe30_Comp_infPag_id = fields.Many2one( + comodel_name="mdfe.30.rodo_infpag", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_tpComp = fields.Selection( + COMP_TPCOMP, + string="Tipo do Componente", + xsd_required=True, + help=( + "Tipo do Componente\nPreencher com: 01 - Vale Pedágio; \n02 - " + "Impostos, taxas e contribuições; \n03 - Despesas (bancárias, " + "meios de pagamento, outras)\n; 99 - Outros" + ), + ) + + mdfe30_vComp = fields.Monetary( + string="Valor do componente", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + ) + + mdfe30_xComp = fields.Char(string="Descrição do componente do tipo Outros") + + +class RodoInfPrazo(models.AbstractModel): + """Informações do pagamento a prazo. + Informar somente se indPag for à Prazo""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.rodo_infprazo" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.InfPag.InfPrazo" + + mdfe30_infPrazo_infPag_id = fields.Many2one( + comodel_name="mdfe.30.rodo_infpag", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nParcela = fields.Char(string="Número da Parcela", xsd_required=True) + + mdfe30_dVenc = fields.Date( + string="Data de vencimento da Parcela", + xsd_required=True, + xsd_type="TData", + help="Data de vencimento da Parcela (AAAA-MM-DD)", + ) + + mdfe30_vParcela = fields.Monetary( + string="Valor da Parcela", + xsd_required=True, + xsd_type="TDec_1302Opc", + currency_field="brl_currency_id", + ) + + +class RodoInfBanc(models.AbstractModel): + "Informações bancárias" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.rodo_infbanc" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.InfAntt.InfPag.InfBanc" + + mdfe30_codBanco = fields.Char( + string="Número do banco", choice="infbanc", xsd_choice_required=True + ) + + mdfe30_codAgencia = fields.Char( + string="Número da agência bancária", choice="infbanc", xsd_choice_required=True + ) + + mdfe30_CNPJIPEF = fields.Char( + string="Número do CNPJ da Instituição", + choice="infbanc", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ da Instituição de Pagamento Eletrônico do " + "Frete\nInformar os zeros não significativos." + ), + ) + + mdfe30_PIX = fields.Char( + string="Chave PIX", + choice="infbanc", + xsd_choice_required=True, + help=( + "Chave PIX\nInformar a chave PIX para recebimento do frete. \nPode" + " ser email, CPF/ CNPJ (somente numeros), Telefone com a seguinte " + "formatação (+5599999999999) ou a chave aleatória gerada pela " + "instituição." + ), + ) + + +class VeicTracao(models.AbstractModel): + "Dados do Veículo com a Tração" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.veictracao" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.VeicTracao" + + mdfe30_cInt = fields.Char(string="Código interno do veículo") + + mdfe30_placa = fields.Char(string="Placa do veículo", xsd_required=True) + + mdfe30_RENAVAM = fields.Char(string="RENAVAM do veículo") + + mdfe30_tara = fields.Char(string="Tara em KG", xsd_required=True) + + mdfe30_capKG = fields.Char(string="Capacidade em KG") + + mdfe30_capM3 = fields.Char(string="Capacidade em M3") + + mdfe30_prop = fields.Many2one( + comodel_name="mdfe.30.veictracao_prop", + string="Proprietário ou possuidor do Veículo", + help=( + "Proprietário ou possuidor do Veículo.\nSó preenchido quando o " + "veículo não pertencer à empresa emitente do MDF-e" + ), + ) + + mdfe30_condutor = fields.One2many( + "mdfe.30.rodo_condutor", + "mdfe30_condutor_veicTracao_id", + string="Informações do(s) Condutor(es)", + help="Informações do(s) Condutor(es) do veículo", + ) + + mdfe30_tpRod = fields.Selection( + VEICTRACAO_TPROD, + string="Tipo de Rodado", + xsd_required=True, + help=( + "Tipo de Rodado\nPreencher com:\n\t\t\t\t\t\t\t\t\t01 - " + "Truck;\n\t\t\t\t\t\t\t\t\t02 - Toco;\n\t\t\t\t\t\t\t\t\t03 - " + "Cavalo Mecânico;\n\t\t\t\t\t\t\t\t\t04 - " + "VAN;\n\t\t\t\t\t\t\t\t\t05 - Utilitário;\n\t\t\t\t\t\t\t\t\t06 - " + "Outros." + ), + ) + + mdfe30_tpCar = fields.Selection( + VEICTRACAO_TPCAR, + string="Tipo de Carroceria", + xsd_required=True, + help=( + "Tipo de Carroceria\nPreencher com:\n\t\t\t\t\t\t\t\t\t00 - não " + "aplicável;\n\t\t\t\t\t\t\t\t\t01 - Aberta;\n\t\t\t\t\t\t\t\t\t02 " + "- Fechada/Baú;\n\t\t\t\t\t\t\t\t\t03 - " + "Granelera;\n\t\t\t\t\t\t\t\t\t04 - Porta " + "Container;\n\t\t\t\t\t\t\t\t\t05 - Sider" + ), + ) + + mdfe30_UF = fields.Selection( + TUF, + string="UF em que veículo está licenciado", + xsd_type="TUf", + help=( + "UF em que veículo está licenciado\nSigla da UF de licenciamento " + "do veículo." + ), + ) + + +class VeicTracaoProp(models.AbstractModel): + """Proprietário ou possuidor do Veículo. + Só preenchido quando o veículo não pertencer à empresa emitente do MDF-e""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.veictracao_prop" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.VeicTracao.Prop" + + mdfe30_CPF = fields.Char( + string="Número do CPF", + choice="prop", + xsd_choice_required=True, + xsd_type="TCpf", + help="Número do CPF\nInformar os zeros não significativos.", + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ", + choice="prop", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help="Número do CNPJ\nInformar os zeros não significativos.", + ) + + mdfe30_RNTRC = fields.Char( + string="Registro Nacional", + xsd_required=True, + xsd_type="TRNTRC", + help=( + "Registro Nacional dos Transportadores Rodoviários de " + "Carga\nRegistro obrigatório do proprietário, co-proprietário ou " + "arrendatário do veículo junto à ANTT para exercer a atividade de " + "transportador rodoviário de cargas por conta de terceiros e " + "mediante remuneração." + ), + ) + + mdfe30_xNome = fields.Char( + string="Razão Social ou Nome do proprietário", xsd_required=True + ) + + mdfe30_IE = fields.Char(string="Inscrição Estadual") + + mdfe30_UF = fields.Selection(TUF, string="UF", xsd_type="TUf") + + mdfe30_tpProp = fields.Selection( + PROP_TPPROP, + string="Tipo Proprietário ou possuidor", + xsd_required=True, + help=( + "Tipo Proprietário ou possuidor\nPreencher " + "com:\n\t\t\t\t\t\t\t\t\t\t\t\t0-TAC " + "Agregado;\n\t\t\t\t\t\t\t\t\t\t\t\t1-TAC Independente; " + "\n\t\t\t\t\t\t\t\t\t\t\t\t2 – Outros." + ), + ) + + +class RodoCondutor(models.AbstractModel): + "Informações do(s) Condutor(es) do veículo" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.rodo_condutor" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.VeicTracao.Condutor" + + mdfe30_condutor_veicTracao_id = fields.Many2one( + comodel_name="mdfe.30.veictracao", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_xNome = fields.Char(string="Nome do Condutor", xsd_required=True) + + mdfe30_CPF = fields.Char( + string="CPF do Condutor", xsd_required=True, xsd_type="TCpf" + ) + + +class VeicReboque(models.AbstractModel): + "Dados dos reboques" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.veicreboque" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.VeicReboque" + + mdfe30_veicReboque_rodo_id = fields.Many2one( + comodel_name="mdfe.30.rodo", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_cInt = fields.Char(string="Código interno do veículo") + + mdfe30_placa = fields.Char(string="Placa do veículo", xsd_required=True) + + mdfe30_RENAVAM = fields.Char(string="RENAVAM do veículo") + + mdfe30_tara = fields.Char(string="Tara em KG", xsd_required=True) + + mdfe30_capKG = fields.Char(string="Capacidade em KG", xsd_required=True) + + mdfe30_capM3 = fields.Char(string="Capacidade em M3") + + mdfe30_prop = fields.Many2one( + comodel_name="mdfe.30.veicreboque_prop", + string="Proprietários ou possuidor do Veículo", + help=( + "Proprietários ou possuidor do Veículo.\nSó preenchido quando o " + "veículo não pertencer à empresa emitente do MDF-e" + ), + ) + + mdfe30_tpCar = fields.Selection( + VEICREBOQUE_TPCAR, + string="Tipo de Carroceria", + xsd_required=True, + help=( + "Tipo de Carroceria\nPreencher com:\n\t\t\t\t\t\t\t\t\t00 - não " + "aplicável;\n\t\t\t\t\t\t\t\t\t01 - Aberta;\n\t\t\t\t\t\t\t\t\t02 " + "- Fechada/Baú;\n\t\t\t\t\t\t\t\t\t03 - " + "Granelera;\n\t\t\t\t\t\t\t\t\t04 - Porta " + "Container;\n\t\t\t\t\t\t\t\t\t05 - Sider" + ), + ) + + mdfe30_UF = fields.Selection( + TUF, + string="UF em que veículo está licenciado", + xsd_type="TUf", + help=( + "UF em que veículo está licenciado\nSigla da UF de licenciamento " + "do veículo." + ), + ) + + +class VeicReboqueProp(models.AbstractModel): + """Proprietário ou possuidor do Veículo. + Só preenchido quando o veículo não pertencer à empresa emitente do MDF-e""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.veicreboque_prop" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.VeicReboque.Prop" + + mdfe30_CPF = fields.Char( + string="Número do CPF", + choice="prop", + xsd_choice_required=True, + xsd_type="TCpf", + help="Número do CPF\nInformar os zeros não significativos.", + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ", + choice="prop", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help="Número do CNPJ\nInformar os zeros não significativos.", + ) + + mdfe30_RNTRC = fields.Char( + string="Registro Nacional", + xsd_required=True, + xsd_type="TRNTRC", + help=( + "Registro Nacional dos Transportadores Rodoviários de " + "Carga\nRegistro obrigatório do proprietário, co-proprietário ou " + "arrendatário do veículo junto à ANTT para exercer a atividade de " + "transportador rodoviário de cargas por conta de terceiros e " + "mediante remuneração." + ), + ) + + mdfe30_xNome = fields.Char( + string="Razão Social ou Nome do proprietário", xsd_required=True + ) + + mdfe30_IE = fields.Char(string="Inscrição Estadual") + + mdfe30_UF = fields.Selection(TUF, string="UF", xsd_type="TUf") + + mdfe30_tpProp = fields.Selection( + PROP_TPPROP, + string="Tipo Proprietário ou possuidor", + xsd_required=True, + help=( + "Tipo Proprietário ou possuidor\nPreencher " + "com:\n\t\t\t\t\t\t\t\t\t\t\t\t0-TAC " + "Agregado;\n\t\t\t\t\t\t\t\t\t\t\t\t1-TAC Independente; " + "\n\t\t\t\t\t\t\t\t\t\t\t\t2 – Outros." + ), + ) + + +class LacRodo(models.AbstractModel): + "Lacres" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.lacrodo" + _inherit = "spec.mixin.mdfe" + _binding_type = "Rodo.LacRodo" + + mdfe30_lacRodo_rodo_id = fields.Many2one( + comodel_name="mdfe.30.rodo", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nLacre = fields.Char(string="Número do Lacre", xsd_required=True) diff --git a/l10n_br_mdfe_spec/models/v3_0/mdfe_tipos_basico_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/mdfe_tipos_basico_v3_00.py new file mode 100644 index 000000000000..839457d23bd7 --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/mdfe_tipos_basico_v3_00.py @@ -0,0 +1,2236 @@ +# Copyright 2023 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models +from .tipos_geral_mdfe_v3_00 import ( + TAMB, + TCODUFIBGE, + TEMIT, + TMODMD, + TTRANSP, + TUF, + TTIPOUNIDCARGA, + TTIPOUNIDTRANSP, +) + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + +"Tipo Modal Manifesto" +TMODALMD = [ + ("1", "1"), + ("2", "2"), + ("3", "3"), + ("4", "4"), +] + +"Tipo processo de emissão do MDF-e" +TPROCEMI = [ + ("0", "0"), +] + +"Indicador de participação do Canal Verde" +IDE_INDCANALVERDE = [ + ("1", "1"), +] + +"""Indicador de MDF-e com inclusão da Carga posterior a emissão por evento + de inclusão de DF-e""" +IDE_INDCARREGAPOSTERIOR = [ + ("1", "1"), +] + +"Forma de emissão do Manifesto" +IDE_TPEMIS = [ + ("1", "Normal"), + ("2", "Contingência"), + ("3", "Regime Especial NFF"), +] + +"Indicador de Reentrega" +INFCTE_INDREENTREGA = [ + ("1", "1"), +] + +"Indicador de Reentrega" +INFMDFETRANSP_INDREENTREGA = [ + ("1", "1"), +] + +"Indicador de Reentrega" +INFNFE_INDREENTREGA = [ + ("1", "1"), +] + +"Responsável pelo seguro" +INFRESP_RESPSEG = [ + ("1", " Emitente do MDF-e"), + ("2", "Responsável pela contratação do serviço de transporte (contratante) "), +] + +"Tipo de Carga" +PRODPRED_TPCARGA = [ + ("01", "Granel sólido"), + ("02", "Granel líquido"), + ("03", "Frigorificada"), + ("04", "Conteinerizada"), + ("05", "Carga Geral"), + ("06", "Neogranel"), + ("07", "Perigosa (granel sólido)"), + ("08", "Perigosa (granel líquido)"), + ("09", "Perigosa (carga frigorificada)"), + ("10", "Perigosa (conteinerizada)"), + ("11", "Perigosa (carga geral)."), +] + +"""Código da unidade de medida do Peso Bruto da Carga / Mercadorias + transportadas""" +TOT_CUNID = [ + ("01", "KG"), + ("02", "TON"), +] + + +class TrespTec(models.AbstractModel): + "Tipo Dados da Responsável Técnico" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tresptec" + _inherit = "spec.mixin.mdfe" + _binding_type = "TrespTec" + + mdfe30_CNPJ = fields.Char( + string="CNPJ", + xsd_required=True, + xsd_type="TCnpj", + help=( + "CNPJ da pessoa jurídica responsável técnica pelo sistema " + "utilizado na emissão do documento fiscal eletrônico\nInformar o " + "CNPJ da pessoa jurídica desenvolvedora do sistema utilizado na " + "emissão do documento fiscal eletrônico." + ), + ) + + mdfe30_xContato = fields.Char( + string="Nome da pessoa a ser contatada", + xsd_required=True, + help=( + "Nome da pessoa a ser contatada\nInformar o nome da pessoa a ser " + "contatada na empresa desenvolvedora do sistema utilizado na " + "emissão do documento fiscal eletrônico. No caso de pessoa física," + " informar o respectivo nome." + ), + ) + + mdfe30_email = fields.Char( + string="Email da pessoa jurídica a ser contatada", + xsd_required=True, + xsd_type="TEmail", + ) + + mdfe30_fone = fields.Char( + string="Telefone da pessoa jurídica", + xsd_required=True, + help=( + "Telefone da pessoa jurídica a ser contatada\nPreencher com o " + "Código DDD + número do telefone." + ), + ) + + mdfe30_idCSRT = fields.Char( + string="Identificador do código de segurança", + help=( + "Identificador do código de segurança do responsável " + "técnico\nIdentificador do CSRT utilizado para geração do hash" + ), + ) + + mdfe30_hashCSRT = fields.Char( + string="Hash do token do código de segurança", + help=( + "Hash do token do código de segurança do responsável técnico\nO " + "hashCSRT é o resultado das funções SHA-1 e base64 do token CSRT " + "fornecido pelo fisco + chave de acesso do DF-e. (Implementação em" + " futura NT)\n\nObservação: 28 caracteres são representados no " + "schema como 20 bytes do tipo base64Binary" + ), + ) + + +class TendOrg(models.AbstractModel): + "Tipo Dados do Endereço" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tendorg" + _inherit = "spec.mixin.mdfe" + _binding_type = "TendOrg" + + mdfe30_xLgr = fields.Char(string="Logradouro", xsd_required=True) + + mdfe30_nro = fields.Char(string="Número", xsd_required=True) + + mdfe30_xCpl = fields.Char(string="Complemento") + + mdfe30_xBairro = fields.Char(string="Bairro", xsd_required=True) + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help=( + "Código do município (utilizar a tabela do IBGE), informar 9999999" + " para operações com o exterior." + ), + ) + + mdfe30_xMun = fields.Char( + string="Nome do município, ", + xsd_required=True, + help=( + "Nome do município, , informar EXTERIOR para operações com o " "exterior." + ), + ) + + mdfe30_CEP = fields.Char(string="CEP") + + mdfe30_UF = fields.Selection( + TUF, + string="Sigla da UF, ", + xsd_required=True, + xsd_type="TUf", + help="Sigla da UF, , informar EX para operações com o exterior.", + ) + + mdfe30_cPais = fields.Char(string="Código do país") + + mdfe30_xPais = fields.Char(string="Nome do país") + + mdfe30_fone = fields.Char(string="Telefone") + + +class TendReEnt(models.AbstractModel): + "Tipo Dados do Local de Retirada ou Entrega" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tendreent" + _inherit = "spec.mixin.mdfe" + _binding_type = "TendReEnt" + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ", + choice="tendreent", + xsd_choice_required=True, + xsd_type="TCnpj", + ) + + mdfe30_CPF = fields.Char( + string="Número do CPF", + choice="tendreent", + xsd_choice_required=True, + xsd_type="TCpf", + ) + + mdfe30_xNome = fields.Char(string="Razão Social ou Nome", xsd_required=True) + + mdfe30_xLgr = fields.Char(string="Logradouro", xsd_required=True) + + mdfe30_nro = fields.Char(string="Número", xsd_required=True) + + mdfe30_xCpl = fields.Char(string="Complemento") + + mdfe30_xBairro = fields.Char(string="Bairro", xsd_required=True) + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help=( + "Código do município (utilizar a tabela do IBGE), informar 9999999" + " para operações com o exterior." + ), + ) + + mdfe30_xMun = fields.Char( + string="Nome do município, ", + xsd_required=True, + help=( + "Nome do município, , informar EXTERIOR para operações com o " "exterior." + ), + ) + + mdfe30_UF = fields.Selection( + TUF, + string="Sigla da UF, ", + xsd_required=True, + xsd_type="TUf", + help="Sigla da UF, , informar EX para operações com o exterior.", + ) + + +class TendeEmi(models.AbstractModel): + "Tipo Dados do Endereço" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tendeemi" + _inherit = "spec.mixin.mdfe" + _binding_type = "TendeEmi" + + mdfe30_xLgr = fields.Char(string="Logradouro", xsd_required=True) + + mdfe30_nro = fields.Char(string="Número", xsd_required=True) + + mdfe30_xCpl = fields.Char(string="Complemento") + + mdfe30_xBairro = fields.Char(string="Bairro", xsd_required=True) + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help=( + "Código do município (utilizar a tabela do IBGE), informar 9999999" + " para operações com o exterior." + ), + ) + + mdfe30_xMun = fields.Char( + string="Nome do município, ", + xsd_required=True, + help=( + "Nome do município, , informar EXTERIOR para operações com o " "exterior." + ), + ) + + mdfe30_CEP = fields.Char( + string="CEP", help="CEP\nInformar zeros não significativos" + ) + + mdfe30_UF = fields.Selection( + TUF, + string="Sigla da UF, ", + xsd_required=True, + xsd_type="TUf", + help="Sigla da UF, , informar EX para operações com o exterior.", + ) + + mdfe30_fone = fields.Char(string="Telefone") + + mdfe30_email = fields.Char(string="Endereço de E-mail", xsd_type="TEmail") + + +class TenderFer(models.AbstractModel): + "Tipo Dados do Endereço" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tenderfer" + _inherit = "spec.mixin.mdfe" + _binding_type = "TenderFer" + + mdfe30_xLgr = fields.Char(string="Logradouro", xsd_required=True) + + mdfe30_nro = fields.Char(string="Número") + + mdfe30_xCpl = fields.Char(string="Complemento") + + mdfe30_xBairro = fields.Char(string="Bairro") + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help=( + "Código do município (utilizar a tabela do IBGE), informar 9999999" + " para operações com o exterior." + ), + ) + + mdfe30_xMun = fields.Char( + string="Nome do município, ", + xsd_required=True, + help=( + "Nome do município, , informar EXTERIOR para operações com o " "exterior." + ), + ) + + mdfe30_CEP = fields.Char(string="CEP", xsd_required=True) + + mdfe30_UF = fields.Selection( + TUF, + string="Sigla da UF, ", + xsd_required=True, + xsd_type="TUf", + help="Sigla da UF, , informar EX para operações com o exterior.", + ) + + +class Tendereco(models.AbstractModel): + "Tipo Dados do Endereço" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tendereco" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tendereco" + + mdfe30_xLgr = fields.Char(string="Logradouro", xsd_required=True) + + mdfe30_nro = fields.Char(string="Número", xsd_required=True) + + mdfe30_xCpl = fields.Char(string="Complemento") + + mdfe30_xBairro = fields.Char(string="Bairro", xsd_required=True) + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help=( + "Código do município (utilizar a tabela do IBGE), informar 9999999" + " para operações com o exterior." + ), + ) + + mdfe30_xMun = fields.Char( + string="Nome do município", + xsd_required=True, + help=("Nome do município, informar EXTERIOR para operações com o " "exterior."), + ) + + mdfe30_CEP = fields.Char( + string="CEP", help="CEP\nInformar os zeros não significativos" + ) + + mdfe30_UF = fields.Selection( + TUF, + string="Sigla da UF", + xsd_required=True, + xsd_type="TUf", + help="Sigla da UF, informar EX para operações com o exterior.", + ) + + mdfe30_cPais = fields.Char( + string="Código do país", help="Código do país\nUtilizar a tabela do BACEN" + ) + + mdfe30_xPais = fields.Char(string="Nome do país") + + +class Tendernac(models.AbstractModel): + "Tipo Dados do Endereço" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tendernac" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tendernac" + + mdfe30_xLgr = fields.Char(string="Logradouro", xsd_required=True) + + mdfe30_nro = fields.Char(string="Número", xsd_required=True) + + mdfe30_xCpl = fields.Char(string="Complemento") + + mdfe30_xBairro = fields.Char(string="Bairro", xsd_required=True) + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help=( + "Código do município (utilizar a tabela do IBGE), informar 9999999" + " para operações com o exterior." + ), + ) + + mdfe30_xMun = fields.Char( + string="Nome do município, ", + xsd_required=True, + help=( + "Nome do município, , informar EXTERIOR para operações com o " "exterior." + ), + ) + + mdfe30_CEP = fields.Char(string="CEP") + + mdfe30_UF = fields.Selection( + TUF, + string="Sigla da UF, ", + xsd_required=True, + xsd_type="TUf", + help="Sigla da UF, , informar EX para operações com o exterior.", + ) + + +class Tlocal(models.AbstractModel): + "Tipo Dados do Local de Origem ou Destino" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tlocal" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tlocal" + + mdfe30_cMun = fields.Char( + string="Código do município", + xsd_required=True, + xsd_type="TCodMunIBGE", + help="Código do município (utilizar a tabela do IBGE)", + ) + + mdfe30_xMun = fields.Char(string="Nome do município", xsd_required=True) + + mdfe30_UF = fields.Selection( + TUF, string="Sigla da UF", xsd_required=True, xsd_type="TUf" + ) + + +class TnfeNf(models.AbstractModel): + "Tipo de Dados das Notas Fiscais Papel e Eletrônica" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tnfenf" + _inherit = "spec.mixin.mdfe" + _binding_type = "TnfeNf" + + mdfe30_infNFe = fields.Many2one( + comodel_name="mdfe.30.tnfenf_infnfe", + string="Informações da NF-e", + choice="tnfenf", + xsd_choice_required=True, + ) + + mdfe30_infNF = fields.Many2one( + comodel_name="mdfe.30.infnf", + string="Informações da NF mod 1 e 1A", + choice="tnfenf", + xsd_choice_required=True, + ) + + +class TnfeNfInfNfe(models.AbstractModel): + "Nota Fiscal Eletronica" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tnfenf_infnfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "TnfeNf.InfNfe" + + mdfe30_chNFe = fields.Char( + string="Chave de acesso da NF-e", xsd_required=True, xsd_type="TChNFe" + ) + + mdfe30_PIN = fields.Char( + string="PIN SUFRAMA", + xsd_type="TPIN", + help="PIN SUFRAMA\nPIN atribuído pela SUFRAMA para a operação.", + ) + + +class InfNf(models.AbstractModel): + "Informações da NF mod 1 e 1A" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infnf" + _inherit = "spec.mixin.mdfe" + _binding_type = "TnfeNf.InfNf" + + mdfe30_emi = fields.Many2one( + comodel_name="mdfe.30.emi", + string="Informações do Emitente da NF", + xsd_required=True, + ) + + mdfe30_dest = fields.Many2one( + comodel_name="mdfe.30.dest", + string="Informações do Destinatário da NF", + xsd_required=True, + ) + + mdfe30_serie = fields.Char(string="Série", xsd_required=True) + + mdfe30_nNF = fields.Char(string="Número", xsd_required=True) + + mdfe30_dEmi = fields.Date( + string="Data de Emissão", + xsd_required=True, + xsd_type="TData", + help="Data de Emissão\nFormato AAAA-MM-DD", + ) + + mdfe30_vNF = fields.Monetary( + string="Valor Total da NF", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + ) + + mdfe30_PIN = fields.Char( + string="PIN SUFRAMA", + xsd_type="TPIN", + help="PIN SUFRAMA\nPIN atribuído pela SUFRAMA para a operação.", + ) + + +class Emi(models.AbstractModel): + "Informações do Emitente da NF" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.emi" + _inherit = "spec.mixin.mdfe" + _binding_type = "TnfeNf.InfNf.Emi" + + mdfe30_CNPJ = fields.Char( + string="CNPJ do emitente", xsd_required=True, xsd_type="TCnpj" + ) + + mdfe30_xNome = fields.Char(string="Razão Social ou Nome", xsd_required=True) + + mdfe30_UF = fields.Selection( + TUF, + string="UF do Emitente", + xsd_required=True, + xsd_type="TUf", + help="UF do Emitente\nInformar 'EX' para operações com o exterior.", + ) + + +class Dest(models.AbstractModel): + "Informações do Destinatário da NF" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.dest" + _inherit = "spec.mixin.mdfe" + _binding_type = "TnfeNf.InfNf.Dest" + + mdfe30_CNPJ = fields.Char( + string="CNPJ do Destinatário", + choice="dest", + xsd_choice_required=True, + xsd_type="TCnpjOpc", + help=( + "CNPJ do Destinatário\nInformar o CNPJ ou o CPF do destinatário, " + "preenchendo os\nzeros não significativos.\nNão informar o " + "conteúdo da TAG se a operação for realizada com o Exterior." + ), + ) + + mdfe30_CPF = fields.Char( + string="CPF do Destinatário", + choice="dest", + xsd_choice_required=True, + xsd_type="TCpf", + help="CPF do Destinatário\nInformar os zeros não significativos.", + ) + + mdfe30_xNome = fields.Char(string="Razão Social ou Nome", xsd_required=True) + + mdfe30_UF = fields.Selection( + TUF, + string="UF do Destinatário", + xsd_required=True, + xsd_type="TUf", + help=("UF do Destinatário\nInformar 'EX' para operações com o exterior."), + ) + + +class TprotMdfe(models.AbstractModel): + "Tipo Protocolo de status resultado do processamento do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tprotmdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "TprotMdfe" + + mdfe30_infProt = fields.Many2one( + comodel_name="mdfe.30.infprot", + string="Dados do protocolo de status", + xsd_required=True, + ) + + mdfe30_infFisco = fields.Many2one( + comodel_name="mdfe.30.inffisco", string="Mensagem do Fisco" + ) + + mdfe30_versao = fields.Char(string="versao", xsd_required=True, xsd_type="TVerMDe") + + +class InfProt(models.AbstractModel): + "Dados do protocolo de status" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infprot" + _inherit = "spec.mixin.mdfe" + _binding_type = "TprotMdfe.InfProt" + + mdfe30_tpAmb = fields.Selection( + TAMB, + string="Identificação do Ambiente", + xsd_required=True, + xsd_type="TAmb", + help="Identificação do Ambiente:\n1 - Produção\n2 - Homologação", + ) + + mdfe30_verAplic = fields.Char( + string="Versão do Aplicativo que processou", + xsd_required=True, + xsd_type="TVerAplic", + help="Versão do Aplicativo que processou a NF-3e", + ) + + mdfe30_chMDFe = fields.Char( + string="Chave de acesso do MDF-e", xsd_required=True, xsd_type="TChMDFe" + ) + + mdfe30_dhRecbto = fields.Datetime( + string="Data e hora de processamento", + xsd_required=True, + xsd_type="TDateTimeUTC", + help=("Data e hora de processamento, no formato AAAA-MM-DDTHH:MM:SS TZD."), + ) + + mdfe30_nProt = fields.Char( + string="Número do Protocolo de Status do MDF-e", xsd_type="TProt" + ) + + mdfe30_digVal = fields.Char( + string="Digest Value do MDF-e processado", + xsd_type="ds:DigestValueType", + help=( + "Digest Value do MDF-e processado. Utilizado para conferir a " + "integridade do MDF-e original." + ), + ) + + mdfe30_cStat = fields.Char(string="Código do status do MDF-e", xsd_required=True) + + mdfe30_xMotivo = fields.Char( + string="Descrição literal do status do MDF-e", + xsd_required=True, + xsd_type="TMotivo", + ) + + mdfe30_Id = fields.Char(string="Id", xsd_type="xs:ID") + + +class InfFisco(models.AbstractModel): + "Mensagem do Fisco" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.inffisco" + _inherit = "spec.mixin.mdfe" + _binding_type = "TprotMdfe.InfFisco" + + mdfe30_cMsg = fields.Char( + string="Código do status da mensagem do fisco", xsd_required=True + ) + + mdfe30_xMsg = fields.Char( + string="Mensagem do Fisco", xsd_required=True, xsd_type="TMotivo" + ) + + +class TretEnviMdfe(models.AbstractModel): + "Tipo Retorno do Recibo do Pedido de Autorização do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tretenvimdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "TretEnviMdfe" + + mdfe30_cUF = fields.Selection( + TCODUFIBGE, + string="Identificação da UF", + xsd_required=True, + xsd_type="TCodUfIBGE", + ) + + mdfe30_verAplic = fields.Char( + string="Versão do Aplicativo que recebeu", + xsd_required=True, + xsd_type="TVerAplic", + help="Versão do Aplicativo que recebeu o Arquivo.", + ) + + mdfe30_cStat = fields.Char( + string="Código do status da mensagem enviada", + xsd_required=True, + xsd_type="TStat", + ) + + mdfe30_xMotivo = fields.Char( + string="Descrição literal do status", + xsd_required=True, + xsd_type="TMotivo", + help="Descrição literal do status do serviço solicitado.", + ) + + mdfe30_infRec = fields.Many2one( + comodel_name="mdfe.30.infrec", string="Dados do Recibo do Arquivo" + ) + + mdfe30_versao = fields.Char(string="versao", xsd_required=True, xsd_type="TVerMDe") + + +class InfRec(models.AbstractModel): + "Dados do Recibo do Arquivo" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infrec" + _inherit = "spec.mixin.mdfe" + _binding_type = "TretEnviMdfe.InfRec" + + mdfe30_nRec = fields.Char( + string="Número do Recibo", xsd_required=True, xsd_type="TRec" + ) + + mdfe30_dhRecbto = fields.Datetime( + string="Data e hora do recebimento", + xsd_required=True, + xsd_type="xs:dateTime", + help="Data e hora do recebimento, no formato AAAA-MM-DDTHH:MM:SS", + ) + + mdfe30_tMed = fields.Char( + string="Tempo médio de resposta do serviço", + xsd_required=True, + help=( + "Tempo médio de resposta do serviço (em segundos) dos últimos 5 " "minutos" + ), + ) + + +class TunidCarga(models.AbstractModel): + "Tipo Dados Unidade de Carga" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tunidcarga" + _inherit = "spec.mixin.mdfe" + _binding_type = "TunidCarga" + + mdfe30_infUnidCarga_TUnidadeTransp_id = fields.Many2one( + comodel_name="mdfe.30.tunidadetransp", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_tpUnidCarga = fields.Selection( + TTIPOUNIDCARGA, + string="Tipo da Unidade de Carga", + xsd_required=True, + xsd_type="TtipoUnidCarga", + help=( + "Tipo da Unidade de Carga\n1 - Container;\n\n2 - ULD;\n\n3 - " + "Pallet;\n\n4 - Outros;" + ), + ) + + mdfe30_idUnidCarga = fields.Char( + string="Identificação da Unidade de Carga", + xsd_required=True, + xsd_type="TContainer", + help=( + "Identificação da Unidade de Carga\nInformar a identificação da " + "unidade de carga, por exemplo: número do container." + ), + ) + + mdfe30_lacUnidCarga = fields.One2many( + "mdfe.30.lacunidcarga", + "mdfe30_lacUnidCarga_TUnidCarga_id", + string="Lacres das Unidades de Carga", + ) + + mdfe30_qtdRat = fields.Char(string="Quantidade rateada (Peso,Volume)") + + +class LacUnidCarga(models.AbstractModel): + "Lacres das Unidades de Carga" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.lacunidcarga" + _inherit = "spec.mixin.mdfe" + _binding_type = "TunidCarga.LacUnidCarga" + + mdfe30_lacUnidCarga_TUnidCarga_id = fields.Many2one( + comodel_name="mdfe.30.tunidcarga", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nLacre = fields.Char(string="Número do lacre", xsd_required=True) + + +class TretMdfe(models.AbstractModel): + "Tipo Retorno do Pedido de Autorização do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tretmdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "TretMdfe" + + mdfe30_cUF = fields.Selection( + TCODUFIBGE, + string="Identificação da UF", + xsd_required=True, + xsd_type="TCodUfIBGE", + ) + + mdfe30_verAplic = fields.Char( + string="Versão do Aplicativo que recebeu", + xsd_required=True, + xsd_type="TVerAplic", + help="Versão do Aplicativo que recebeu o Arquivo.", + ) + + mdfe30_cStat = fields.Char( + string="Código do status da mensagem enviada", + xsd_required=True, + xsd_type="TStat", + ) + + mdfe30_xMotivo = fields.Char( + string="Descrição literal do status", + xsd_required=True, + xsd_type="TMotivo", + help="Descrição literal do status do serviço solicitado.", + ) + + mdfe30_protMDFe = fields.Many2one( + comodel_name="mdfe.30.tprotmdfe", + string="Dados do Recibo do Arquivo", + xsd_type="TProtMDFe", + ) + + mdfe30_versao = fields.Char(string="versao", xsd_required=True, xsd_type="TVerMDe") + + +class TunidadeTransp(models.AbstractModel): + "Tipo Dados Unidade de Transporte" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tunidadetransp" + _inherit = "spec.mixin.mdfe" + _binding_type = "TunidadeTransp" + + mdfe30_infUnidTransp_infCTe_id = fields.Many2one( + comodel_name="mdfe.30.infcte", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_infUnidTransp_infNFe_id = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infnfe", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_infUnidTransp_infMDFeTransp_id = fields.Many2one( + comodel_name="mdfe.30.infmdfetransp", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_tpUnidTransp = fields.Selection( + TTIPOUNIDTRANSP, + string="Tipo da Unidade de Transporte", + xsd_required=True, + xsd_type="TtipoUnidTransp", + help=( + "Tipo da Unidade de Transporte\n1 - Rodoviário Tração;\n\n2 - " + "Rodoviário Reboque;\n\n3 - Navio;\n\n4 - Balsa;\n\n5 - " + "Aeronave;\n\n6 - Vagão;\n\n7 - Outros" + ), + ) + + mdfe30_idUnidTransp = fields.Char( + string="Identificação da Unidade de Transporte", + xsd_required=True, + xsd_type="TContainer", + help=( + "Identificação da Unidade de Transporte\nInformar a identificação " + "conforme o tipo de unidade de transporte.\nPor exemplo: para " + "rodoviário tração ou reboque deverá preencher com a placa do " + "veículo." + ), + ) + + mdfe30_lacUnidTransp = fields.One2many( + "mdfe.30.lacunidtransp", + "mdfe30_lacUnidTransp_TUnidadeTransp_id", + string="Lacres das Unidades de Transporte", + ) + + mdfe30_infUnidCarga = fields.One2many( + "mdfe.30.tunidcarga", + "mdfe30_infUnidCarga_TUnidadeTransp_id", + string="Informações das Unidades de Carga", + xsd_type="TUnidCarga", + help=( + "Informações das Unidades de Carga " + "(Containeres/ULD/Outros)\nDispositivo de carga utilizada (Unit " + "Load Device - ULD) significa todo tipo de contêiner de carga, " + "vagão, contêiner de avião, palete de aeronave com rede ou palete " + "de aeronave com rede sobre um iglu." + ), + ) + + mdfe30_qtdRat = fields.Monetary( + string="Quantidade rateada (Peso,Volume)", + xsd_type="TDec_0302_0303", + currency_field="brl_currency_id", + ) + + +class LacUnidTransp(models.AbstractModel): + "Lacres das Unidades de Transporte" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.lacunidtransp" + _inherit = "spec.mixin.mdfe" + _binding_type = "TunidadeTransp.LacUnidTransp" + + mdfe30_lacUnidTransp_TUnidadeTransp_id = fields.Many2one( + comodel_name="mdfe.30.tunidadetransp", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nLacre = fields.Char(string="Número do lacre", xsd_required=True) + + +class Tmdfe(models.AbstractModel): + "Tipo Manifesto de Documentos Fiscais Eletrônicos" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tmdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe" + + mdfe30_infMDFe = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infmdfe", + string="Informações do MDF-e", + xsd_required=True, + ) + + mdfe30_infMDFeSupl = fields.Many2one( + comodel_name="mdfe.30.infmdfesupl", string="Informações suplementares do MDF-e" + ) + + +class TmdfeInfMdfe(models.AbstractModel): + "Informações do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tmdfe_infmdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe" + + mdfe30_ide = fields.Many2one( + comodel_name="mdfe.30.ide", string="Identificação do MDF-e", xsd_required=True + ) + + mdfe30_emit = fields.Many2one( + comodel_name="mdfe.30.emit", + string="Identificação do Emitente do Manifesto", + xsd_required=True, + ) + + mdfe30_infModal = fields.Many2one( + comodel_name="mdfe.30.infmodal", + string="Informações do modal", + xsd_required=True, + ) + + mdfe30_infDoc = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infdoc", + string="Informações", + xsd_required=True, + help="Informações dos Documentos fiscais vinculados ao manifesto", + ) + + mdfe30_seg = fields.One2many( + "mdfe.30.seg", "mdfe30_seg_infMDFe_id", string="Informações de Seguro da Carga" + ) + + mdfe30_prodPred = fields.Many2one( + comodel_name="mdfe.30.prodpred", + string="Produto predominante", + help=("Produto predominante\nInformar a descrição do produto " "predominante"), + ) + + mdfe30_tot = fields.Many2one( + comodel_name="mdfe.30.tot", + string="Totalizadores da carga transportada", + xsd_required=True, + help=("Totalizadores da carga transportada e seus documentos fiscais"), + ) + + mdfe30_lacres = fields.One2many( + "mdfe.30.lacres", + "mdfe30_lacres_infMDFe_id", + string="Lacres do MDF-e", + help=( + "Lacres do MDF-e\nPreechimento opcional para os modais Rodoviário " + "e Ferroviário" + ), + ) + + mdfe30_autXML = fields.One2many( + "mdfe.30.autxml", + "mdfe30_autXML_infMDFe_id", + string="Autorizados para download do XML do DF-e", + help=( + "Autorizados para download do XML do DF-e\nInformar CNPJ ou CPF. " + "Preencher os zeros não significativos." + ), + ) + + mdfe30_infAdic = fields.Many2one( + comodel_name="mdfe.30.infadic", string="Informações Adicionais" + ) + + mdfe30_infRespTec = fields.Many2one( + comodel_name="mdfe.30.tresptec", + string="Informações do Responsável Técnico", + xsd_type="TRespTec", + help="Informações do Responsável Técnico pela emissão do DF-e", + ) + + mdfe30_infSolicNFF = fields.Many2one( + comodel_name="mdfe.30.infsolicnff", + string="Grupo de informações do pedido", + help=("Grupo de informações do pedido de emissão da Nota Fiscal Fácil"), + ) + + mdfe30_versao = fields.Char( + string="Versão do leiaute", + xsd_required=True, + xsd_type="TVerMDe", + help="Versão do leiaute\nEx: '3.00'", + ) + + mdfe30_Id = fields.Char( + string="Identificador da tag a ser assinada", + xsd_required=True, + help=( + "Identificador da tag a ser assinada\nInformar a chave de acesso " + "do MDF-e e precedida do literal 'MDFe'" + ), + ) + + +class Ide(models.AbstractModel): + "Identificação do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.ide" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Ide" + + mdfe30_cUF = fields.Selection( + TCODUFIBGE, + string="Código da UF do emitente do MDF-e", + xsd_required=True, + xsd_type="TCodUfIBGE", + help=( + "Código da UF do emitente do MDF-e\nCódigo da UF do emitente do " + "Documento Fiscal. Utilizar a\nTabela do IBGE de código de " + "unidades da federação." + ), + ) + + mdfe30_tpAmb = fields.Selection( + TAMB, + string="Tipo do Ambiente", + xsd_required=True, + xsd_type="TAmb", + help="Tipo do Ambiente\n1 - Produção\n2 - Homologação", + ) + + mdfe30_tpEmit = fields.Selection( + TEMIT, + string="Tipo do Emitente", + xsd_required=True, + xsd_type="TEmit", + help=( + "Tipo do Emitente\n1 - Prestador de serviço de transporte \n2 - " + "Transportador de Carga Própria 3 - Prestador de serviço de " + "transporte que emitirá CT-e Globalizado \n\nOBS: Deve ser " + "preenchido com 2 para emitentes de NF-e e pelas transportadoras " + "quando estiverem fazendo transporte de carga própria. Deve ser " + "preenchido com 3 para transportador de carga que emitirá à " + "posteriori CT-e Globalizado relacionando as NF-e." + ), + ) + + mdfe30_tpTransp = fields.Selection( + TTRANSP, + string="Tipo do Transportador", + xsd_type="TTransp", + help="Tipo do Transportador\n1 - ETC\n\n2 - TAC\n\n3 - CTC", + ) + + mdfe30_mod = fields.Selection( + TMODMD, + string="Modelo do Manifesto Eletrônico", + xsd_required=True, + xsd_type="TModMD", + help=( + "Modelo do Manifesto Eletrônico\nUtilizar o código 58 para " + "identificação do MDF-e" + ), + ) + + mdfe30_serie = fields.Char( + string="Série do Manifesto", + xsd_required=True, + xsd_type="TSerie", + help=( + "Série do Manifesto\nInformar a série do documento fiscal " + "(informar zero se inexistente).\nSérie na faixa [920-969]: " + "Reservada para emissão por contribuinte pessoa física com " + "inscrição estadual." + ), + ) + + mdfe30_nMDF = fields.Char( + string="Número do Manifesto", + xsd_required=True, + xsd_type="TNF", + help=( + "Número do Manifesto\nNúmero que identifica o Manifesto. 1 a " "999999999." + ), + ) + + mdfe30_cMDF = fields.Char( + string="Código numérico que compõe a Chave", + xsd_required=True, + help=( + "Código numérico que compõe a Chave de Acesso.\nCódigo aleatório " + "gerado pelo emitente, com o objetivo de evitar acessos indevidos " + "ao documento." + ), + ) + + mdfe30_cDV = fields.Char( + string="Digito verificador da chave de acesso", + xsd_required=True, + help=( + "Digito verificador da chave de acesso do Manifesto\nInformar o " + "dígito de controle da chave de acesso do MDF-e, que deve ser " + "calculado com a aplicação do algoritmo módulo 11 (base 2,9) da " + "chave de acesso." + ), + ) + + mdfe30_modal = fields.Selection( + TMODALMD, + string="Modalidade de transporte", + xsd_required=True, + xsd_type="TModalMD", + help=( + "Modalidade de transporte\n1 - Rodoviário;\n2 - Aéreo; 3 - " + "Aquaviário; 4 - Ferroviário." + ), + ) + + mdfe30_dhEmi = fields.Datetime( + string="Data e hora de emissão do Manifesto", + xsd_required=True, + xsd_type="TDateTimeUTC", + help=( + "Data e hora de emissão do Manifesto\nFormato AAAA-MM-DDTHH:MM:DD " "TZD" + ), + ) + + mdfe30_tpEmis = fields.Selection( + IDE_TPEMIS, + string="Forma de emissão do Manifesto", + xsd_required=True, + help=( + "Forma de emissão do Manifesto\n1 - Normal\n; 2 - Contingência; " + "3-Regime Especial NFF" + ), + ) + + mdfe30_procEmi = fields.Selection( + TPROCEMI, + string="Identificação do processo de emissão", + xsd_required=True, + help=( + "Identificação do processo de emissão do Manifesto\n0 - emissão de" + " MDF-e com aplicativo do contribuinte" + ), + ) + + mdfe30_verProc = fields.Char( + string="Versão do processo de emissão", + xsd_required=True, + help=( + "Versão do processo de emissão\nInformar a versão do aplicativo " + "emissor de MDF-e." + ), + ) + + mdfe30_UFIni = fields.Selection( + TUF, + string="Sigla da UF do Carregamento", + xsd_required=True, + xsd_type="TUf", + help=( + "Sigla da UF do Carregamento\nUtilizar a Tabela do IBGE de código " + "de unidades da federação.\nInformar 'EX' para operações com o " + "exterior." + ), + ) + + mdfe30_UFFim = fields.Selection( + TUF, + string="Sigla da UF do Descarregamento", + xsd_required=True, + xsd_type="TUf", + help=( + "Sigla da UF do Descarregamento\nUtilizar a Tabela do IBGE de " + "código de unidades da federação.\nInformar 'EX' para operações " + "com o exterior." + ), + ) + + mdfe30_infMunCarrega = fields.One2many( + "mdfe.30.infmuncarrega", + "mdfe30_infMunCarrega_ide_id", + string="Informações dos Municípios", + help="Informações dos Municípios de Carregamento", + ) + + mdfe30_infPercurso = fields.One2many( + "mdfe.30.infpercurso", + "mdfe30_infPercurso_ide_id", + string="Informações do Percurso do MDF-e", + ) + + mdfe30_dhIniViagem = fields.Datetime( + string="Data e hora previstos de inicio", + xsd_type="TDateTimeUTC", + help=( + "Data e hora previstos de inicio da viagem\nFormato AAAA-MM-" + "DDTHH:MM:DD TZD" + ), + ) + + mdfe30_indCanalVerde = fields.Selection( + IDE_INDCANALVERDE, string="Indicador de participação do Canal Verde" + ) + + mdfe30_indCarregaPosterior = fields.Selection( + IDE_INDCARREGAPOSTERIOR, + string="Indicador de MDF-e com inclusão", + help=( + "Indicador de MDF-e com inclusão da Carga posterior a emissão por " + "evento de inclusão de DF-e" + ), + ) + + +class InfMunCarrega(models.AbstractModel): + "Informações dos Municípios de Carregamento" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infmuncarrega" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Ide.InfMunCarrega" + + mdfe30_infMunCarrega_ide_id = fields.Many2one( + comodel_name="mdfe.30.ide", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_cMunCarrega = fields.Char( + string="Código do Município de Carregamento", + xsd_required=True, + xsd_type="TCodMunIBGE", + ) + + mdfe30_xMunCarrega = fields.Char( + string="Nome do Município de Carregamento", xsd_required=True + ) + + +class InfPercurso(models.AbstractModel): + "Informações do Percurso do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infpercurso" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Ide.InfPercurso" + + mdfe30_infPercurso_ide_id = fields.Many2one( + comodel_name="mdfe.30.ide", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_UFPer = fields.Selection( + TUF, + string="Sigla das Unidades da Federação", + xsd_required=True, + xsd_type="TUf", + help=( + "Sigla das Unidades da Federação do percurso do veículo.\nNão é " + "necessário repetir as UF de Início e Fim" + ), + ) + + +class Emit(models.AbstractModel): + "Identificação do Emitente do Manifesto" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.emit" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Emit" + + mdfe30_CNPJ = fields.Char( + string="CNPJ do emitente", + choice="emit", + xsd_choice_required=True, + xsd_type="TCnpj", + help="CNPJ do emitente\nInformar zeros não significativos", + ) + + mdfe30_CPF = fields.Char( + string="CPF do emitente", + choice="emit", + xsd_choice_required=True, + xsd_type="TCpf", + help=( + "CPF do emitente\nInformar zeros não significativos.\n\nUsar com " + "série específica 920-969 para emitente pessoa física com " + "inscrição estadual.\nPoderá ser usado também para emissão do " + "Regime Especial da Nota Fiscal Fácil" + ), + ) + + mdfe30_IE = fields.Char(string="Inscrição Estadual do emitemte") + + mdfe30_xNome = fields.Char( + string="Razão social ou Nome do emitente", xsd_required=True + ) + + mdfe30_xFant = fields.Char(string="Nome fantasia do emitente") + + mdfe30_enderEmit = fields.Many2one( + comodel_name="mdfe.30.tendeemi", + string="Endereço do emitente", + xsd_required=True, + xsd_type="TEndeEmi", + ) + + +class InfModal(models.AbstractModel): + "Informações do modal" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infmodal" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfModal" + + mdfe30_versaoModal = fields.Char( + string="Versão do leiaute específico", + xsd_required=True, + help="Versão do leiaute específico para o Modal", + ) + + +class TmdfeInfDoc(models.AbstractModel): + "Informações dos Documentos fiscais vinculados ao manifesto" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tmdfe_infdoc" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc" + + mdfe30_infMunDescarga = fields.One2many( + "mdfe.30.infmundescarga", + "mdfe30_infMunDescarga_infDoc_id", + string="Informações dos Municípios", + help="Informações dos Municípios de descarregamento", + ) + + +class InfMunDescarga(models.AbstractModel): + "Informações dos Municípios de descarregamento" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infmundescarga" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga" + + mdfe30_infMunDescarga_infDoc_id = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infdoc", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_cMunDescarga = fields.Char( + string="Código do Município de Descarregamento", + xsd_required=True, + xsd_type="TCodMunIBGE", + ) + + mdfe30_xMunDescarga = fields.Char( + string="Nome do Município de Descarregamento", xsd_required=True + ) + + mdfe30_infCTe = fields.One2many( + "mdfe.30.infcte", + "mdfe30_infCTe_infMunDescarga_id", + string="Conhecimentos de Tranporte", + help=( + "Conhecimentos de Tranporte - usar este grupo quando for prestador" + " de serviço de transporte" + ), + ) + + mdfe30_infNFe = fields.One2many( + "mdfe.30.tmdfe_infnfe", + "mdfe30_infNFe_infMunDescarga_id", + string="Nota Fiscal Eletronica", + ) + + mdfe30_infMDFeTransp = fields.One2many( + "mdfe.30.infmdfetransp", + "mdfe30_infMDFeTransp_infMunDescarga_id", + string="Manifesto Eletrônico", + help=( + "Manifesto Eletrônico de Documentos Fiscais. Somente para modal " + "Aquaviário (vide regras MOC)" + ), + ) + + +class InfCte(models.AbstractModel): + """Conhecimentos de Tranporte - usar este grupo quando for prestador de + serviço de transporte""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infcte" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfCte" + + mdfe30_infCTe_infMunDescarga_id = fields.Many2one( + comodel_name="mdfe.30.infmundescarga", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_chCTe = fields.Char( + string="Conhecimento Eletrônico", + xsd_required=True, + xsd_type="TChCTe", + help="Conhecimento Eletrônico - Chave de Acesso", + ) + + mdfe30_SegCodBarra = fields.Char( + string="Segundo código de barras", xsd_type="TSegCodBarra" + ) + + mdfe30_indReentrega = fields.Selection( + INFCTE_INDREENTREGA, string="Indicador de Reentrega" + ) + + mdfe30_infUnidTransp = fields.One2many( + "mdfe.30.tunidadetransp", + "mdfe30_infUnidTransp_infCTe_id", + string="Informações das Unidades de Transporte", + xsd_type="TUnidadeTransp", + help=( + "Informações das Unidades de Transporte " + "(Carreta/Reboque/Vagão)\nDeve ser preenchido com as informações " + "das unidades de transporte utilizadas." + ), + ) + + mdfe30_peri = fields.One2many( + "mdfe.30.infcte_peri", + "mdfe30_peri_infCTe_id", + string="Preenchido quando for transporte", + help=( + "Preenchido quando for transporte de produtos classificados pela " + "ONU como perigosos." + ), + ) + + mdfe30_infEntregaParcial = fields.Many2one( + comodel_name="mdfe.30.infentregaparcial", + string="Grupo de informações da Entrega Parcial", + help="Grupo de informações da Entrega Parcial (Corte de Voo)", + ) + + +class InfCtePeri(models.AbstractModel): + """Preenchido quando for transporte de produtos classificados pela ONU como + perigosos.""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infcte_peri" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfCte.Peri" + + mdfe30_peri_infCTe_id = fields.Many2one( + comodel_name="mdfe.30.infcte", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nONU = fields.Char( + string="Número ONU/UN", + xsd_required=True, + help=( + "Número ONU/UN\nVer a legislação de transporte de produtos " + "perigosos aplicadas ao modal" + ), + ) + + mdfe30_xNomeAE = fields.Char( + string="Nome apropriado para embarque do produto", + help=( + "Nome apropriado para embarque do produto\nVer a legislação de " + "transporte de produtos perigosos aplicada ao modo de transporte" + ), + ) + + mdfe30_xClaRisco = fields.Char( + string="Classe ou subclasse/divisão", + help=( + "Classe ou subclasse/divisão, e risco subsidiário/risco " + "secundário\nVer a legislação de transporte de produtos perigosos " + "aplicadas ao modal" + ), + ) + + mdfe30_grEmb = fields.Char( + string="Grupo de Embalagem", + help=( + "Grupo de Embalagem\nVer a legislação de transporte de produtos " + "perigosos aplicadas ao " + "modal\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPreenchimento obrigatório " + "para o modal aéreo.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tA legislação " + "para o modal rodoviário e ferroviário não atribui grupo de " + "embalagem para todos os produtos, portanto haverá casos de não " + "preenchimento desse campo." + ), + ) + + mdfe30_qTotProd = fields.Char( + string="Quantidade total por produto", + xsd_required=True, + help=( + "Quantidade total por produto\nPreencher conforme a legislação de " + "transporte de produtos perigosos aplicada ao modal" + ), + ) + + mdfe30_qVolTipo = fields.Char( + string="Quantidade e Tipo de volumes", + help=( + "Quantidade e Tipo de volumes\nPreencher conforme a legislação de " + "transporte de produtos perigosos aplicada ao modal" + ), + ) + + +class InfEntregaParcial(models.AbstractModel): + "Grupo de informações da Entrega Parcial (Corte de Voo)" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infentregaparcial" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfCte.InfEntregaParcial" + + mdfe30_qtdTotal = fields.Float( + string="Quantidade total de volumes", + xsd_required=True, + xsd_type="TDec_1104", + digits=( + 11, + 4, + ), + ) + + mdfe30_qtdParcial = fields.Float( + string="Quantidade de volumes enviados no MDF-e", + xsd_required=True, + xsd_type="TDec_1104", + digits=( + 11, + 4, + ), + ) + + +class TmdfeInfNfe(models.AbstractModel): + "Nota Fiscal Eletronica" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tmdfe_infnfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfNfe" + + mdfe30_infNFe_infMunDescarga_id = fields.Many2one( + comodel_name="mdfe.30.infmundescarga", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_chNFe = fields.Char( + string="Nota Fiscal Eletrônica", xsd_required=True, xsd_type="TChNFe" + ) + + mdfe30_SegCodBarra = fields.Char( + string="Segundo código de barras", xsd_type="TSegCodBarra" + ) + + mdfe30_indReentrega = fields.Selection( + INFNFE_INDREENTREGA, string="Indicador de Reentrega" + ) + + mdfe30_infUnidTransp = fields.One2many( + "mdfe.30.tunidadetransp", + "mdfe30_infUnidTransp_infNFe_id", + string="Informações das Unidades de Transporte", + xsd_type="TUnidadeTransp", + help=( + "Informações das Unidades de Transporte " + "(Carreta/Reboque/Vagão)\nDeve ser preenchido com as informações " + "das unidades de transporte utilizadas." + ), + ) + + mdfe30_peri = fields.One2many( + "mdfe.30.infnfe_peri", + "mdfe30_peri_infNFe_id", + string="Preenchido quando for transporte", + help=( + "Preenchido quando for transporte de produtos classificados pela " + "ONU como perigosos." + ), + ) + + +class InfNfePeri(models.AbstractModel): + """Preenchido quando for transporte de produtos classificados pela ONU como + perigosos.""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infnfe_peri" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfNfe.Peri" + + mdfe30_peri_infNFe_id = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infnfe", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nONU = fields.Char( + string="Número ONU/UN", + xsd_required=True, + help=( + "Número ONU/UN\nVer a legislação de transporte de produtos " + "perigosos aplicadas ao modal" + ), + ) + + mdfe30_xNomeAE = fields.Char( + string="Nome apropriado para embarque do produto", + help=( + "Nome apropriado para embarque do produto\nVer a legislação de " + "transporte de produtos perigosos aplicada ao modo de transporte" + ), + ) + + mdfe30_xClaRisco = fields.Char( + string="Classe ou subclasse/divisão", + help=( + "Classe ou subclasse/divisão, e risco subsidiário/risco " + "secundário\nVer a legislação de transporte de produtos perigosos " + "aplicadas ao modal" + ), + ) + + mdfe30_grEmb = fields.Char( + string="Grupo de Embalagem", + help=( + "Grupo de Embalagem\nVer a legislação de transporte de produtos " + "perigosos aplicadas ao " + "modal\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPreenchimento obrigatório " + "para o modal aéreo.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tA legislação " + "para o modal rodoviário e ferroviário não atribui grupo de " + "embalagem para todos os produtos, portanto haverá casos de não " + "preenchimento desse campo." + ), + ) + + mdfe30_qTotProd = fields.Char( + string="Quantidade total por produto", + xsd_required=True, + help=( + "Quantidade total por produto\nPreencher conforme a legislação de " + "transporte de produtos perigosos aplicada ao modal" + ), + ) + + mdfe30_qVolTipo = fields.Char( + string="Quantidade e Tipo de volumes", + help=( + "Quantidade e Tipo de volumes\nPreencher conforme a legislação de " + "transporte de produtos perigosos aplicada ao modal" + ), + ) + + +class InfMdfeTransp(models.AbstractModel): + """Manifesto Eletrônico de Documentos Fiscais. Somente para modal + Aquaviário (vide regras MOC)""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infmdfetransp" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfMdfeTransp" + + mdfe30_infMDFeTransp_infMunDescarga_id = fields.Many2one( + comodel_name="mdfe.30.infmundescarga", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_chMDFe = fields.Char( + string="Manifesto Eletrônico", + xsd_required=True, + xsd_type="TChNFe", + help="Manifesto Eletrônico de Documentos Fiscais", + ) + + mdfe30_indReentrega = fields.Selection( + INFMDFETRANSP_INDREENTREGA, string="Indicador de Reentrega" + ) + + mdfe30_infUnidTransp = fields.One2many( + "mdfe.30.tunidadetransp", + "mdfe30_infUnidTransp_infMDFeTransp_id", + string="Informações das Unidades de Transporte", + xsd_type="TUnidadeTransp", + help=( + "Informações das Unidades de Transporte " + "(Carreta/Reboque/Vagão)\nDispositivo de carga utilizada (Unit " + "Load Device - ULD) significa todo tipo de contêiner de carga, " + "vagão, contêiner de avião, palete de aeronave com rede ou palete " + "de aeronave com rede sobre um iglu." + ), + ) + + mdfe30_peri = fields.One2many( + "mdfe.30.infmdfetransp_peri", + "mdfe30_peri_infMDFeTransp_id", + string="Preenchido quando for transporte", + help=( + "Preenchido quando for transporte de produtos classificados pela " + "ONU como perigosos." + ), + ) + + +class InfMdfeTranspPeri(models.AbstractModel): + """Preenchido quando for transporte de produtos classificados pela ONU como + perigosos.""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infmdfetransp_peri" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfDoc.InfMunDescarga.InfMdfeTransp.Peri" + + mdfe30_peri_infMDFeTransp_id = fields.Many2one( + comodel_name="mdfe.30.infmdfetransp", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nONU = fields.Char( + string="Número ONU/UN", + xsd_required=True, + help=( + "Número ONU/UN\nVer a legislação de transporte de produtos " + "perigosos aplicadas ao modal" + ), + ) + + mdfe30_xNomeAE = fields.Char( + string="Nome apropriado para embarque do produto", + help=( + "Nome apropriado para embarque do produto\nVer a legislação de " + "transporte de produtos perigosos aplicada ao modo de transporte" + ), + ) + + mdfe30_xClaRisco = fields.Char( + string="Classe ou subclasse/divisão", + help=( + "Classe ou subclasse/divisão, e risco subsidiário/risco " + "secundário\nVer a legislação de transporte de produtos perigosos " + "aplicadas ao modal" + ), + ) + + mdfe30_grEmb = fields.Char( + string="Grupo de Embalagem", + help=( + "Grupo de Embalagem\nVer a legislação de transporte de produtos " + "perigosos aplicadas ao " + "modal\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPreenchimento obrigatório " + "para o modal aéreo.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tA legislação " + "para o modal rodoviário e ferroviário não atribui grupo de " + "embalagem para todos os produtos, portanto haverá casos de não " + "preenchimento desse campo." + ), + ) + + mdfe30_qTotProd = fields.Char( + string="Quantidade total por produto", + xsd_required=True, + help=( + "Quantidade total por produto\nPreencher conforme a legislação de " + "transporte de produtos perigosos aplicada ao modal" + ), + ) + + mdfe30_qVolTipo = fields.Char( + string="Quantidade e Tipo de volumes", + help=( + "Quantidade e Tipo de volumes\nPreencher conforme a legislação de " + "transporte de produtos perigosos aplicada ao modal" + ), + ) + + +class Seg(models.AbstractModel): + "Informações de Seguro da Carga" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.seg" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Seg" + + mdfe30_seg_infMDFe_id = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infmdfe", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_infResp = fields.Many2one( + comodel_name="mdfe.30.infresp", + string="Informações do responsável pelo seguro", + xsd_required=True, + help="Informações do responsável pelo seguro da carga", + ) + + mdfe30_infSeg = fields.Many2one( + comodel_name="mdfe.30.infseg", string="Informações da seguradora" + ) + + mdfe30_nApol = fields.Char( + string="Número da Apólice", + help="Número da Apólice\nObrigatório pela lei 11.442/07 (RCTRC)", + ) + + mdfe30_nAver = fields.Char( + string="Número da Averbação", + help="Número da Averbação\nInformar as averbações do seguro", + ) + + +class InfResp(models.AbstractModel): + "Informações do responsável pelo seguro da carga" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infresp" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Seg.InfResp" + + mdfe30_respSeg = fields.Selection( + INFRESP_RESPSEG, + string="Responsável pelo seguro", + xsd_required=True, + help=( + "Responsável pelo seguro\nPreencher " + "com:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t1- Emitente do MDF-e;\n\n22 -" + " Responsável pela contratação do serviço de transporte " + "(contratante)\t\n\n\nDados obrigatórios apenas no modal " + "Rodoviário, depois da lei 11.442/07. Para os demais modais esta " + "informação é opcional." + ), + ) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ do responsável", + choice="infresp", + xsd_type="TCnpj", + help=( + "Número do CNPJ do responsável pelo seguro\nObrigatório apenas se " + "responsável pelo seguro for (2) responsável pela contratação do " + "transporte - pessoa jurídica" + ), + ) + + mdfe30_CPF = fields.Char( + string="Número do CPF do responsável pelo seguro", + choice="infresp", + xsd_type="TCpf", + help=( + "Número do CPF do responsável pelo seguro\nObrigatório apenas se " + "responsável pelo seguro for (2) responsável pela contratação do " + "transporte - pessoa física" + ), + ) + + +class InfSeg(models.AbstractModel): + "Informações da seguradora" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infseg" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Seg.InfSeg" + + mdfe30_xSeg = fields.Char(string="Nome da Seguradora", xsd_required=True) + + mdfe30_CNPJ = fields.Char( + string="Número do CNPJ da seguradora", + xsd_required=True, + xsd_type="TCnpjOpc", + help=( + "Número do CNPJ da seguradora\nObrigatório apenas se responsável " + "pelo seguro for (2) responsável pela contratação do transporte - " + "pessoa jurídica" + ), + ) + + +class ProdPred(models.AbstractModel): + """Produto predominante + Informar a descrição do produto predominante""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.prodpred" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.ProdPred" + + mdfe30_tpCarga = fields.Selection( + PRODPRED_TPCARGA, + string="Tipo de Carga", + xsd_required=True, + help=( + "Tipo de Carga\nConforme Resolução ANTT nº. " + "5.849/2019.\n\n01-Granel sólido;\n02-Granel " + "líquido;\n03-Frigorificada;\n04-Conteinerizada;\n05-Carga " + "Geral;\n06-Neogranel;\n07-Perigosa (granel sólido);\n08-Perigosa " + "(granel líquido);\n09-Perigosa (carga " + "frigorificada);\n10-Perigosa (conteinerizada);\n11-Perigosa " + "(carga geral)." + ), + ) + + mdfe30_xProd = fields.Char(string="Descrição do produto", xsd_required=True) + + mdfe30_cEAN = fields.Char( + string="GTIN", + help=( + "GTIN (Global Trade Item Number) do produto, antigo código EAN ou " + "código de barras" + ), + ) + + mdfe30_NCM = fields.Char(string="Código NCM") + + mdfe30_infLotacao = fields.Many2one( + comodel_name="mdfe.30.inflotacao", + string="Informações da carga lotação", + help=( + "Informações da carga lotação. Informar somente quando MDF-e for " + "de carga lotação" + ), + ) + + +class InfLotacao(models.AbstractModel): + """Informações da carga lotação. Informar somente quando MDF-e for de carga + lotação""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.inflotacao" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.ProdPred.InfLotacao" + + mdfe30_infLocalCarrega = fields.Many2one( + comodel_name="mdfe.30.inflocalcarrega", + string="Informações da localização", + xsd_required=True, + help=( + "Informações da localização de carregamento do MDF-e de carga " "lotação" + ), + ) + + mdfe30_infLocalDescarrega = fields.Many2one( + comodel_name="mdfe.30.inflocaldescarrega", + string="infLocalDescarrega", + xsd_required=True, + help=( + "Informações da localização de descarregamento do MDF-e de carga " "lotação" + ), + ) + + +class InfLocalCarrega(models.AbstractModel): + """Informações da localização de carregamento do MDF-e de carga lotação""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.inflocalcarrega" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.ProdPred.InfLotacao.InfLocalCarrega" + + mdfe30_CEP = fields.Char( + string="CEP onde foi carregado o MDF-e", + choice="inflocalcarrega", + xsd_choice_required=True, + help=("CEP onde foi carregado o MDF-e\nInformar zeros não significativos"), + ) + + mdfe30_latitude = fields.Char( + string="Latitude do ponto geográfico onde", + choice="inflocalcarrega", + xsd_choice_required=True, + xsd_type="TLatitude", + help="Latitude do ponto geográfico onde foi carregado o MDF-e", + ) + + mdfe30_longitude = fields.Char( + string="longitude", + choice="inflocalcarrega", + xsd_choice_required=True, + xsd_type="TLongitude", + help="Latitude do ponto geográfico onde foi carregado o MDF-e", + ) + + +class InfLocalDescarrega(models.AbstractModel): + """Informações da localização de descarregamento do MDF-e de carga + lotação""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.inflocaldescarrega" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.ProdPred.InfLotacao.InfLocalDescarrega" + + mdfe30_CEP = fields.Char( + string="CEP onde foi descarregado o MDF-e", + choice="inflocaldescarrega", + xsd_choice_required=True, + help=( + "CEP onde foi descarregado o MDF-e\nInformar zeros não " "significativos" + ), + ) + + mdfe30_latitude = fields.Char( + string="Latitude do ponto geográfico onde", + choice="inflocaldescarrega", + xsd_choice_required=True, + xsd_type="TLatitude", + help="Latitude do ponto geográfico onde foi descarregado o MDF-e", + ) + + mdfe30_longitude = fields.Char( + string="longitude", + choice="inflocaldescarrega", + xsd_choice_required=True, + xsd_type="TLongitude", + help="Latitude do ponto geográfico onde foi descarregado o MDF-e", + ) + + +class Tot(models.AbstractModel): + "Totalizadores da carga transportada e seus documentos fiscais" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tot" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Tot" + + mdfe30_qCTe = fields.Char( + string="Quantidade total de CT-e relacionados", + help="Quantidade total de CT-e relacionados no Manifesto", + ) + + mdfe30_qNFe = fields.Char( + string="Quantidade total de NF-e relacionadas", + help="Quantidade total de NF-e relacionadas no Manifesto", + ) + + mdfe30_qMDFe = fields.Char( + string="Quantidade total de MDF-e relacionados", + help=("Quantidade total de MDF-e relacionados no Manifesto Aquaviário"), + ) + + mdfe30_vCarga = fields.Monetary( + string="Valor total", + xsd_required=True, + xsd_type="TDec_1302", + currency_field="brl_currency_id", + help="Valor total da carga / mercadorias transportadas", + ) + + mdfe30_cUnid = fields.Selection( + TOT_CUNID, + string="Código da unidade de medida", + xsd_required=True, + help=( + "Código da unidade de medida do Peso Bruto da Carga / Mercadorias " + "transportadas\n01 – KG; 02 - TON" + ), + ) + + mdfe30_qCarga = fields.Float( + string="Peso Bruto Total", + xsd_required=True, + xsd_type="TDec_1104", + digits=( + 11, + 4, + ), + help="Peso Bruto Total da Carga / Mercadorias transportadas", + ) + + +class Lacres(models.AbstractModel): + """Lacres do MDF-e + Preechimento opcional para os modais Rodoviário e Ferroviário""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.lacres" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.Lacres" + + mdfe30_lacres_infMDFe_id = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infmdfe", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_nLacre = fields.Char(string="número do lacre", xsd_required=True) + + +class AutXml(models.AbstractModel): + """Autorizados para download do XML do DF-e + Informar CNPJ ou CPF. Preencher os zeros não significativos.""" + + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.autxml" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.AutXml" + + mdfe30_autXML_infMDFe_id = fields.Many2one( + comodel_name="mdfe.30.tmdfe_infmdfe", xsd_implicit=True, ondelete="cascade" + ) + mdfe30_CNPJ = fields.Char( + string="CNPJ do autorizado", + choice="autxml", + xsd_choice_required=True, + xsd_type="TCnpj", + help="CNPJ do autorizado\nInformar zeros não significativos", + ) + + mdfe30_CPF = fields.Char( + string="CPF do autorizado", + choice="autxml", + xsd_choice_required=True, + xsd_type="TCpf", + help="CPF do autorizado\nInformar zeros não significativos", + ) + + +class InfAdic(models.AbstractModel): + "Informações Adicionais" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infadic" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfAdic" + + mdfe30_infAdFisco = fields.Char( + string="Informações adicionais de interesse", + help=( + "Informações adicionais de interesse do Fisco\nNorma referenciada," + " informações complementares, etc" + ), + ) + + mdfe30_infCpl = fields.Char( + string="Informações complementares de interesse", + help="Informações complementares de interesse do Contribuinte", + ) + + +class InfSolicNff(models.AbstractModel): + "Grupo de informações do pedido de emissão da Nota Fiscal Fácil" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infsolicnff" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfe.InfSolicNff" + + mdfe30_xSolic = fields.Char( + string="Solicitação do pedido de emissão da NFF", + xsd_required=True, + help=( + "Solicitação do pedido de emissão da NFF.\nSerá preenchido com a " + "totalidade de campos informados no aplicativo emissor " + "serializado." + ), + ) + + +class InfMdfeSupl(models.AbstractModel): + "Informações suplementares do MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.infmdfesupl" + _inherit = "spec.mixin.mdfe" + _binding_type = "Tmdfe.InfMdfeSupl" + + mdfe30_qrCodMDFe = fields.Char( + string="Texto com o QR-Code para consulta", + xsd_required=True, + help="Texto com o QR-Code para consulta do MDF-e", + ) + + +class TenviMdfe(models.AbstractModel): + "Tipo Pedido de Autorização Assíncrona de MDF-e" + _description = textwrap.dedent(" %s" % (__doc__,)) + _name = "mdfe.30.tenvimdfe" + _inherit = "spec.mixin.mdfe" + _binding_type = "TenviMdfe" + + mdfe30_idLote = fields.Char(string="idLote", xsd_required=True, xsd_type="TIdLote") + + mdfe30_MDFe = fields.Many2one( + comodel_name="mdfe.30.tmdfe", string="MDFe", xsd_required=True, xsd_type="TMDFe" + ) + + mdfe30_versao = fields.Char(string="versao", xsd_required=True, xsd_type="TVerMDe") diff --git a/l10n_br_mdfe_spec/models/v3_0/tipos_geral_mdfe_v3_00.py b/l10n_br_mdfe_spec/models/v3_0/tipos_geral_mdfe_v3_00.py new file mode 100644 index 000000000000..fd12789d3472 --- /dev/null +++ b/l10n_br_mdfe_spec/models/v3_0/tipos_geral_mdfe_v3_00.py @@ -0,0 +1,183 @@ +# Copyright 2022 Akretion - Raphaël Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). +# Generated by https://github.com/akretion/xsdata-odoo +# +import textwrap +from odoo import fields, models + +__NAMESPACE__ = "http://www.portalfiscal.inf.br/mdfe" + +"Tipo Ambiente" +TAMB = [ + ("1", "1"), + ("2", "2"), +] + +"""Tipo Código de orgão (UF da tabela do IBGE + 90 SUFRAMA + 91 RFB + 92 + BRId)""" +TCORGAOIBGE = [ + ("11", "11"), + ("12", "12"), + ("13", "13"), + ("14", "14"), + ("15", "15"), + ("16", "16"), + ("17", "17"), + ("21", "21"), + ("22", "22"), + ("23", "23"), + ("24", "24"), + ("25", "25"), + ("26", "26"), + ("27", "27"), + ("28", "28"), + ("29", "29"), + ("31", "31"), + ("32", "32"), + ("33", "33"), + ("35", "35"), + ("41", "41"), + ("42", "42"), + ("43", "43"), + ("50", "50"), + ("51", "51"), + ("52", "52"), + ("53", "53"), + ("90", "90"), + ("91", "91"), + ("92", "92"), + ("93", "93"), +] + +"Tipo Código da UF da tabela do IBGE" +TCODUFIBGE = [ + ("11", "11"), + ("12", "12"), + ("13", "13"), + ("14", "14"), + ("15", "15"), + ("16", "16"), + ("17", "17"), + ("21", "21"), + ("22", "22"), + ("23", "23"), + ("24", "24"), + ("25", "25"), + ("26", "26"), + ("27", "27"), + ("28", "28"), + ("29", "29"), + ("31", "31"), + ("32", "32"), + ("33", "33"), + ("35", "35"), + ("41", "41"), + ("42", "42"), + ("43", "43"), + ("50", "50"), + ("51", "51"), + ("52", "52"), + ("53", "53"), +] + +"Tipo Código da UF da tabela do IBGE + 99 para Exterior" +TCODUFIBGE_EX = [ + ("11", "11"), + ("12", "12"), + ("13", "13"), + ("14", "14"), + ("15", "15"), + ("16", "16"), + ("17", "17"), + ("21", "21"), + ("22", "22"), + ("23", "23"), + ("24", "24"), + ("25", "25"), + ("26", "26"), + ("27", "27"), + ("28", "28"), + ("29", "29"), + ("31", "31"), + ("32", "32"), + ("33", "33"), + ("35", "35"), + ("41", "41"), + ("42", "42"), + ("43", "43"), + ("50", "50"), + ("51", "51"), + ("52", "52"), + ("53", "53"), + ("99", "99"), +] + +"Tipo Emitente" +TEMIT = [ + ("1", "1"), + ("2", "2"), + ("3", "3"), +] + +"Tipo Modelo Manifesto de Documento Fiscal Eletrônico" +TMODMD = [ + ("58", "58"), +] + +"Tipo Transportador" +TTRANSP = [ + ("1", "1"), + ("2", "2"), + ("3", "3"), +] + +"Tipo Sigla da UF" +TUF = [ + ("AC", "AC"), + ("AL", "AL"), + ("AM", "AM"), + ("AP", "AP"), + ("BA", "BA"), + ("CE", "CE"), + ("DF", "DF"), + ("ES", "ES"), + ("GO", "GO"), + ("MA", "MA"), + ("MG", "MG"), + ("MS", "MS"), + ("MT", "MT"), + ("PA", "PA"), + ("PB", "PB"), + ("PE", "PE"), + ("PI", "PI"), + ("PR", "PR"), + ("RJ", "RJ"), + ("RN", "RN"), + ("RO", "RO"), + ("RR", "RR"), + ("RS", "RS"), + ("SC", "SC"), + ("SE", "SE"), + ("SP", "SP"), + ("TO", "TO"), + ("EX", "EX"), +] + +"Tipo da Unidade de Carga" +TTIPOUNIDCARGA = [ + ("1", "1"), + ("2", "2"), + ("3", "3"), + ("4", "4"), +] + +"Tipo da Unidade de Transporte" +TTIPOUNIDTRANSP = [ + ("1", "1"), + ("2", "2"), + ("3", "3"), + ("4", "4"), + ("5", "5"), + ("6", "6"), + ("7", "7"), +] diff --git a/l10n_br_mdfe_spec/readme/CONTRIBUTORS.rst b/l10n_br_mdfe_spec/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..af528869caee --- /dev/null +++ b/l10n_br_mdfe_spec/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Raphaël Valyi diff --git a/l10n_br_mdfe_spec/readme/DESCRIPTION.rst b/l10n_br_mdfe_spec/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..2d39303fa404 --- /dev/null +++ b/l10n_br_mdfe_spec/readme/DESCRIPTION.rst @@ -0,0 +1,26 @@ +Este módulo contem a estrutura de dados do ​Manifesto Eletrônico de Documentos Fiscais (CT-e). +Este módulo não faz nada sozinho, ele precisaria de um modulo `l10n_br_mdfe` que mapearia esses mixins +nos documentos fiscais Odoo de forma semlhante a forma como o módulo `l10n_br_nfe` faz como o módulo `l10n_br_nfe_spec`. + +Este módulo inclui os leiautes persistantes dos modos de transporte do MDF-e: + +* modo aéreo +* modo aquaviário +* modo ferroviário +* modo rodoviário + + + +Geração +~~~~~~~ + +O código dos mixins Odoo desse módulo é 100% gerado a partir dos últimos esquemas xsd da Fazenda usando xsdata e essa extensão dele: + +https://github.com/akretion/xsdata-odoo + + +O comando usado foi: + +export XSDATA_SCHEMA=mdfe; export XSDATA_VERSION=30; export XSDATA_LANG="portuguese" + +xsdata generate nfelib/mdfe/schemas/v3_0 --package nfelib.mdfe.odoo.v3_0 --output=odoo diff --git a/l10n_br_mdfe_spec/static/description/icon.png b/l10n_br_mdfe_spec/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/l10n_br_mdfe_spec/static/description/index.html b/l10n_br_mdfe_spec/static/description/index.html new file mode 100644 index 000000000000..06d6bead51de --- /dev/null +++ b/l10n_br_mdfe_spec/static/description/index.html @@ -0,0 +1,446 @@ + + + + + + +nfe spec + + + +
+

nfe spec

+ + +

Production/Stable License: LGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runbot

+

Este módulo contem a estrutura de dados da Nota Fiscal Electrônica (NF-e). +Um módulo que usa ele é o módulo l10n_br_nfe que permite transmitir as NF-e’s.

+
+

Geração

+

O código dos mixins Odoo desse módulo é 100% gerado a partir dos últimos esquemas XSD da Fazenda usando generateDS e essa extensão dele:

+

https://github.com/akretion/generateds-odoo

+

Depois de baixar os esquemas na pasta /tmp/generated/schemas/nfe/v4_00 basta fazer o comando:

+
+python gends_run_gen_odoo.py -f -l nfe -x 4_00 -e '^ICMS\d+|^ICMSSN\d+' -d . -v /tmp/generated/schemas/nfe/v4_00/leiauteNFe_v4.00.xsd
+
+
+
+

Prefixo dos campos e versão

+

Com até uns 800 campos fiscais apenas na NF-e, com uma meia dúzia de documentos fiscais complexos, +com 3000 módulos OCA, existiria um risco real de conflito com os nomes de campos vindo dos esquemas. +Além disso, temos várias versões da NFe, a 3.1, a 4.0 etc…

+

Nisso foi decidido que cada campo tem um prefixo composto do nome do schema +e de alguns dígitos da versão do esquema. No caso nfe40_. A escolha de 2 dígitos permite +que uma atualização menor do esquema use os mesmos campos (e dados no banco então) e que um simples +update Odoo (–update=…) consiga resolver a migração. Enquanto que para uma mudança maior +como de 3.1 para 4.0, seria assumido de usar novos campos e novas tabelas (para os objetos não Odoo) +e que a lib nfelib iria trabalhar com os campos da versão maior do documento fiscal considerado.

+
+
+

Casos das tags de ICMS e ICMSSN

+

Para facilitar a validação das tags de ICMS e ICMSSN, o esquema contem tags especificas para cada tipo desses impostos. +Porem, Depois no Odoo o modelo é diferente com uma class apenas. Se a gente injectasse todos esses mixins de ICMS e ICMSSN na mesma class Odoo +a gente teria colisão de campos, com campos com o mesmo nome e seleções diferentes… Para evitar esses problemas, filtramos as classes +desses tags (opção -x no generateds-odoo). De qualquer forma, ja que o Odoo e o módulo l10n_br_fiscal tem modelos proprios para os impostos +temos que assumir que o mapping das tags de impostos nao pode ser tão automatizada.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+ +
+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

rvalyi

+

This module is part of the OCA/l10n-brazil project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+ + diff --git a/l10n_br_mdfe_spec/tests/__init__.py b/l10n_br_mdfe_spec/tests/__init__.py new file mode 100644 index 000000000000..491458bdf37f --- /dev/null +++ b/l10n_br_mdfe_spec/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mdfe_import diff --git a/l10n_br_mdfe_spec/tests/test_mdfe_import.py b/l10n_br_mdfe_spec/tests/test_mdfe_import.py new file mode 100644 index 000000000000..fd324dde943a --- /dev/null +++ b/l10n_br_mdfe_spec/tests/test_mdfe_import.py @@ -0,0 +1,154 @@ +# Copyright 2020 Akretion - Raphael Valyi +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html). + +import re +from datetime import datetime + +import nfelib +import pkg_resources +from nfelib.mdfe.bindings.v3_0.mdfe_v3_00 import Mdfe +from xsdata.formats.dataclass.parsers import XmlParser + +from odoo import api +from odoo.tests import TransactionCase + +from ..models import spec_models + +tz_datetime = re.compile(r".*[-+]0[0-9]:00$") + + +@api.model +def build_fake(self, node, create=False): + attrs = self.build_attrs_fake(node, create_m2o=True) + return self.new(attrs) + + +# flake8: noqa: C901 +@api.model +def build_attrs_fake(self, node, create_m2o=False): + """ + Similar to build_attrs from spec_driven_model but simpler: assuming + generated abstract mixins are not injected into concrete Odoo models. + """ + fields = self.fields_get() + vals = self.default_get(fields.keys()) + for fname, fspec in node.__dataclass_fields__.items(): + if fname == "any_element": + continue + value = getattr(node, fname) + if value is None: + continue + key = "%s%s" % ( + self._field_prefix, + fspec.metadata.get("name", fname), + ) + if ( + fspec.type == str or not any(["." in str(i) for i in fspec.type.__args__]) + ) and not str(fspec.type).startswith("typing.List"): + # SimpleType + if fields[key]["type"] == "datetime": + if "T" in value: + if tz_datetime.match(value): + old_value = value + value = old_value[:19] + # TODO see python3/pysped/xml_sped/base.py#L692 + value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S") + vals[key] = value + + else: + if hasattr(fspec.type.__args__[0], "__name__"): + binding_type = fspec.type.__args__[0].__name__ + else: + binding_type = fspec.type.__args__[0].__forward_arg__ + + # ComplexType + if fields.get(key) and fields[key].get("related"): + key = fields[key]["related"][0] + comodel_name = fields[key]["relation"] + else: + clean_type = binding_type.lower() # TODO double check + comodel_name = "%s.%s.%s" % ( + self._schema_name, + self._schema_version.replace(".", "")[0:2], + clean_type.split(".")[-1], + ) + comodel = self.env.get(comodel_name) + if comodel is None: # example skip ICMS100 class + continue + + if not str(fspec.type).startswith("typing.List"): + # m2o + new_value = comodel.build_attrs_fake( + value, + create_m2o=create_m2o, + ) + if new_value is None: + continue + if comodel._name == self._name: # stacked m2o + vals.update(new_value) + else: + vals[key] = self.match_or_create_m2o_fake( + comodel, new_value, create_m2o + ) + else: # if attr.get_container() == 1: + # o2m + lines = [] + for line in [li for li in value if li]: + line_vals = comodel.build_attrs_fake(line, create_m2o=create_m2o) + lines.append((0, 0, line_vals)) + vals[key] = lines + + for k, v in fields.items(): + if ( + v.get("related") is not None + and len(v["related"]) == 1 + and vals.get(k) is not None + ): + vals[v["related"][0]] = vals.get(k) + + return vals + + +@api.model +def match_or_create_m2o_fake(self, comodel, new_value, create_m2o=False): + return comodel.new(new_value).id + + +# spec_models.CteSpecMixin._update_cache = _update_cache +spec_models.MdfeSpecMixin.build_fake = build_fake +spec_models.MdfeSpecMixin.build_attrs_fake = build_attrs_fake +spec_models.MdfeSpecMixin.match_or_create_m2o_fake = match_or_create_m2o_fake + + +class MdfeImportTest(TransactionCase): + def test_import_mdfe(self): + res_items = ( + "mdfe", + "samples", + "v3_0", + "41190876676436000167580010000500001000437558-mdfe.xml", + ) + resource_path = "/".join(res_items) + nfe_stream = pkg_resources.resource_stream(nfelib.__name__, resource_path) + parser = XmlParser() + binding = parser.from_string(nfe_stream.read().decode(), Mdfe) + inf_mdfe = self.env["mdfe.30.tmdfe_infmdfe"].build_fake( + binding.infMDFe, create=False + ) + self.assertEqual(inf_mdfe.mdfe30_emit.mdfe30_CNPJ, "76676436000167") + + def test_import_mdfe2(self): + res_items = ( + "mdfe", + "samples", + "v3_0", + "50170876063965000276580010000011311421039568-mdfe.xml", + ) + resource_path = "/".join(res_items) + nfe_stream = pkg_resources.resource_stream(nfelib.__name__, resource_path) + parser = XmlParser() + binding = parser.from_string(nfe_stream.read().decode(), Mdfe) + inf_mdfe = self.env["mdfe.30.tmdfe_infmdfe"].build_fake( + binding.infMDFe, create=False + ) + self.assertEqual(inf_mdfe.mdfe30_emit.mdfe30_xNome, "TESTE") diff --git a/setup/l10n_br_mdfe_spec/odoo/addons/l10n_br_mdfe_spec b/setup/l10n_br_mdfe_spec/odoo/addons/l10n_br_mdfe_spec new file mode 120000 index 000000000000..1665a667102f --- /dev/null +++ b/setup/l10n_br_mdfe_spec/odoo/addons/l10n_br_mdfe_spec @@ -0,0 +1 @@ +../../../../l10n_br_mdfe_spec \ No newline at end of file diff --git a/setup/l10n_br_mdfe_spec/setup.py b/setup/l10n_br_mdfe_spec/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/l10n_br_mdfe_spec/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)