diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 740db8b1d060a7679504b532b81e72b421132f43..d2eb54a281f0e49890598bda0d9b87c96bc63a22 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,35 +1,86 @@
 variables:
-  BUILDOUT: tools/buildout.cfg
+  BUILDOUT: buildout.cfg
+  DB_NAME: $CI_PROJECT_NAME-$CI_JOB_ID
+  DB_USER: openerp
+  NAME_PRO: $CI_PROJECT_NAME
 
 cache:
-  key: "$CI_BUILD_NAME"
+  key: one-key-to-rule-them-all
   paths:
   - buildout-cache/
 
-before_script:
-  - git clone --depth=1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.openpyme.mx/pyerp/test.git tools
-  - virtualenv --quiet --python=python2.7 .
-  - source bin/activate
-  - pip install -r tools/requirements.txt
-
 stages:
   - build
-  - test
-  - deploy
+  - unit test
+  - code style
+
+make:
+  tags:
+    - base
+  stage: build
+  script:
+    - git clone --depth=1 --branch feat_bench_odoo_15 http://gitlab.openpyme.mx/pyerp/bench.git
+    - cd bench
+    - cp -f $CI_PROJECT_DIR/buildout.cfg buildout.cfg
+    - ln -s profiles/ci.cfg local.cfg
+    - virtualenv . --python=python3.10
+    - source bin/activate
+    - bin/pip3.10 install -r requirements.txt
+    - bin/buildout
+    - cp -LR $CI_PROJECT_DIR/$NAME_PRO local_modules/
+  artifacts:
+    paths:
+      - bench
+    expire_in: 1 week
+
+test:
+  tags:
+    - base
+  stage: unit test
+  script:
+    - cd bench
+    - source bin/activate
+    - createdb $DB_NAME
+    - start_openerp -d $DB_NAME -i $NAME_PRO --stop-after-init
+    - start_openerp -d $DB_NAME -i l10n_generic_coa --stop-after-init
+    - start_openerp -d $DB_NAME -i account_payment --stop-after-init
+    - start_openerp -d $DB_NAME -i $NAME_PRO --test-enable --stop-after-init
+  dependencies:
+    - make
 
 code-analysis:
-  stage: test
+  tags:
+    - base
+  stage: code style
+  allow_failure: true
   script:
-    - buildout -qc $BUILDOUT buildout:directory=$CI_PROJECT_DIR install node code-analysis
+    - cd bench
+    - source bin/activate
     - code-analysis
+  dependencies:
+    - make
 
 lint-analysis:
-  stage: test
+  tags:
+    - base
+  stage: code style
+  allow_failure: true
   script:
-    - buildout -qc $BUILDOUT buildout:directory=$CI_PROJECT_DIR install pylint-bin pylint
+    - cd bench
+    - source bin/activate
+    - python-pylint scripts/run_pylint --path local_modules/ -c config/pylint.cfg
+
+  dependencies:
+    - make
 
 mccabe:
-  stage: test
+  tags:
+    - base
+  stage: code style
+  allow_failure: true
   script:
-    - buildout -qc $BUILDOUT buildout:directory=$CI_PROJECT_DIR install xenon
-    - xenon -bC -mB -aB -i bin,eggs,old-eggs,downloads,lib .
+    - cd bench
+    - source bin/activate
+    - xenon -bC -mB -aB -i bin,eggs,downloads,lib,parts .
+  dependencies:
+    - make
diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst
index 579857ee15feb39a8acec2199aa5505cb99e79b6..e3344df941991b59bc926f4cf8373a61ef9f084e 100644
--- a/CONTRIBUTORS.rst
+++ b/CONTRIBUTORS.rst
@@ -2,3 +2,4 @@
 * Moisés López
 * Federico Cruz <federico.cruz@openpyme.mx>
 * Agustín Cruz <agustin.cruz@openpyme.mx>
+* Noé Fernando <noe.izquierdo@openpyme.mx>
\ No newline at end of file
diff --git a/buildout.cfg b/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..d190c7defea46de47e9ee6a693eeda0d92965532
--- /dev/null
+++ b/buildout.cfg
@@ -0,0 +1,27 @@
+[buildout]
+extends =
+    local.cfg
+    config/account.cfg
+    config/mexico.cfg
+
+# The project name, base for paths
+site = pyerp
+domain = subdomain.openpyme.mx
+
+# Adjust to directory-setup of server. (Usually don't needed)
+# Relative paths:
+filestore = ${buildout:directory}/data_dir
+
+# The PyERP options
+[options]
+admin_passwd = 11235813
+xmlrpc_port = 8069
+longpolling_port = 8072
+db_maxconn = 64
+dbfilter = .*
+workers = 3
+limit_time_cpu = 86400
+limit_time_real = 86400
+limit_memory_soft = 2684354560
+limit_memory_hard = 3221225472
+sentry_dns = http://a49ee0cdb261441aa28990a5b909fc55:c079095e7aa84bebbd2027157de826a6@sentry.openpyme.mx/7
diff --git a/l10n_mx_facturae/__init__.py b/l10n_mx_facturae/__init__.py
index 35e7c9600c556ac0a37452da226bd559cf1e5a03..084335270d09e1c36da8db121e7fde6f39222269 100644
--- a/l10n_mx_facturae/__init__.py
+++ b/l10n_mx_facturae/__init__.py
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
 
 from . import models
-from . import wizard
+from . import report
+#from . import wizard
diff --git a/l10n_mx_facturae/__manifest__.py b/l10n_mx_facturae/__manifest__.py
new file mode 100644
index 0000000000000000000000000000000000000000..040c9ffb87c5a22357f130bf6d331ddd9e8d358a
--- /dev/null
+++ b/l10n_mx_facturae/__manifest__.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+{
+    "name": "Factura Electronica CFDI",
+    "version": "15.0.3.7.0",
+    "author": "OpenPyme",
+    "category": "Localization/Mexico",
+    "website": "http://www.openpyme.mx/",
+    "license": "AGPL-3",
+    "depends": [
+        "account_global_discount",
+        "account_invoice_change_currency",
+        "l10n_mx_base",
+    ],
+    "data": [
+        # Security
+        "security/res_groups.xml",
+
+        # Datas
+        "data/account_move.xml",
+        "data/account_payment.xml",
+        #"data/email_template.xml",
+        "data/facturae_data.xml",
+        "data/ir_attachment_facturae_config.xml",
+        "data/res_partner.xml",
+        #"data/ir_cron.xml",
+
+        # Views
+        "views/account_move.xml",
+        "views/account_payment.xml",
+        "views/res_company.xml",
+        "views/res_partner.xml",
+
+        # templates
+        "templates/account_move.xml",
+        "templates/account_payment.xml",
+
+        #Views Wizards
+        #"wizard/account_invoice_refund.xml",
+    ],
+    "demo": [
+        "demo/demo_res_partner.xml",
+        "demo/demo_product.xml",
+    ],
+    "installable": True,
+}
diff --git a/l10n_mx_facturae/__openerp__.py b/l10n_mx_facturae/__openerp__.py
deleted file mode 100644
index ab41196dd2c3f36b72f74a9de5b013232425023a..0000000000000000000000000000000000000000
--- a/l10n_mx_facturae/__openerp__.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-
-{
-    "name": "Factura Electronica CFDI",
-    "version": "8.0.3.7.0",
-    "author": "OpenPyme",
-    "category": "Localization/Mexico",
-    "website": "http://www.openpyme.mx/",
-    "license": "AGPL-3",
-    "depends": [
-        "account_cancel",
-        "account_invoice_discount",
-        "base_vat",
-        "base_iso3166",
-        "l10n_mx_account_tax_category",
-        "l10n_mx_ir_attachment_facturae",
-        "l10n_mx_res_partner_bank",
-    ],
-    "demo": [],
-    "data": [
-        "security/res_groups.xml",
-        "views/account_invoice.xml",
-        "views/account_voucher.xml",
-        "views/res_partner.xml",
-        "wizard/account_invoice_refund.xml",
-        "data/account_invoice.xml",
-        "data/account_voucher.xml",
-        "data/ir_cron.xml",
-        "data/email_template.xml",
-        "data/ir_attachment_facturae_config.xml",
-        "data/facturae_data.xml",
-    ],
-    "installable": True,
-}
diff --git a/l10n_mx_facturae/data/account_invoice.xml b/l10n_mx_facturae/data/account_invoice.xml
deleted file mode 100644
index d59cdf073035f071afaeb3a09e5b20519e35e311..0000000000000000000000000000000000000000
--- a/l10n_mx_facturae/data/account_invoice.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
-<data>
-
-    <!-- XML invoice report definition -->
-    <record id="report_templates_aeroo_account_invoice_cfdi"
-        model="report.templates.aeroo">
-        <field name="name">Account Invoice CFDI XML</field>
-        <field name="model">account.invoice</field>
-        <field name="report_name">account.invoice.cfdi.xml</field>
-        <field
-            name="report_rml">l10n_mx_facturae/templates/account_invoice.txt</field>
-    </record>
-
-    <record id="ir_actions_report_xml_account_invioice_cfdi"
-        model="ir.actions.report.xml">
-        <field name="name">Account Invoice CFDI XML</field>
-        <field name="type">ir.actions.report.xml</field>
-        <field name="model">account.invoice</field>
-        <field name="report_name">account.invoice.cfdi.xml</field>
-        <field name="report_type">aeroo</field>
-        <field name="in_format">genshi-raw</field>
-        <field name="out_format" ref="report_aeroo.report_mimetypes_raw" />
-        <field name="aeroo_templates_ids"
-            eval="[(6, 0, [report_templates_aeroo_account_invoice_cfdi])]" />
-        <field name="parser_state">default</field>
-    </record>
-
-</data>
-
-<data noupdate="1">
-
-    <!-- PDF invoice report definition -->
-    <record id="report_templates_aeroo_pdf_account_invoice_cfdi"
-        model="report.templates.aeroo">
-        <field name="name">Default Invoice Report PDF</field>
-        <field name="model">account.invoice</field>
-        <field name="report_name">invoice.report.aaero.pdf</field>
-        <field name="report_rml">l10n_mx_facturae/report/account_invoice.odt</field>
-    </record>
-
-    <record id="ir_actions_report_pdf_account_invioice_cfdi"
-        model="ir.actions.report.xml">
-        <field name="name">Account Invoice CFDI PDF</field>
-        <field name="type">ir.actions.report.xml</field>
-        <field name="model">account.invoice</field>
-        <field name="report_name">invoice.report.aaero.pdf</field>
-        <field name="report_type">aeroo</field>
-        <field name="in_format">oo-odt</field>
-        <field name="out_format" ref="report_aeroo.report_mimetypes_pdf_odt" />
-        <field name="aeroo_templates_ids"
-            eval="[(6, 0, [report_templates_aeroo_pdf_account_invoice_cfdi])]" />
-        <field name="parser_loc">l10n_mx_ir_attachment_facturae/report/generate_qr.py</field>
-        <field name="parser_state">loc</field>
-    </record>
-
-</data>
-</openerp>
diff --git a/l10n_mx_facturae/data/account_move.xml b/l10n_mx_facturae/data/account_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4b2fd495bf7b1fb8392416cc66e77c84e4c80107
--- /dev/null
+++ b/l10n_mx_facturae/data/account_move.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+    <!-- XML move report definition -->
+    <record id="ir_actions_report_xml_account_move_cfdi" model="ir.actions.report">
+        <field name="name">Account Move CFDI XML</field>
+        <field name="model">account.move</field>
+        <field name="report_type">qweb-xml</field>
+        <field name="report_name">l10n_mx_facturae.account_move</field>
+        <field name="xml_declaration">true</field>
+        <field name="xsd_schema">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjx4czpzY2hlbWEgeG1sbnM6Y2ZkaT0iaHR0cDovL3d3dy5zYXQuZ29iLm14L2NmZC80IiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOmNhdENGREk9Imh0dHA6Ly93d3cuc2F0LmdvYi5teC9zaXRpb19pbnRlcm5ldC9jZmQvY2F0YWxvZ29zIiB4bWxuczp0ZENGREk9Imh0dHA6Ly93d3cuc2F0LmdvYi5teC9zaXRpb19pbnRlcm5ldC9jZmQvdGlwb0RhdG9zL3RkQ0ZESSIgdGFyZ2V0TmFtZXNwYWNlPSJodHRwOi8vd3d3LnNhdC5nb2IubXgvY2ZkLzQiIGVsZW1lbnRGb3JtRGVmYXVsdD0icXVhbGlmaWVkIiBhdHRyaWJ1dGVGb3JtRGVmYXVsdD0idW5xdWFsaWZpZWQiPg0KCTx4czppbXBvcnQgbmFtZXNwYWNlPSJodHRwOi8vd3d3LnNhdC5nb2IubXgvc2l0aW9faW50ZXJuZXQvY2ZkL2NhdGFsb2dvcyIgc2NoZW1hTG9jYXRpb249Imh0dHA6Ly93d3cuc2F0LmdvYi5teC9zaXRpb19pbnRlcm5ldC9jZmQvY2F0YWxvZ29zL2NhdENGREkueHNkIi8+DQoJPHhzOmltcG9ydCBuYW1lc3BhY2U9Imh0dHA6Ly93d3cuc2F0LmdvYi5teC9zaXRpb19pbnRlcm5ldC9jZmQvdGlwb0RhdG9zL3RkQ0ZESSIgc2NoZW1hTG9jYXRpb249Imh0dHA6Ly93d3cuc2F0LmdvYi5teC9zaXRpb19pbnRlcm5ldC9jZmQvdGlwb0RhdG9zL3RkQ0ZESS90ZENGREkueHNkIi8+DQoJPHhzOmVsZW1lbnQgbmFtZT0iQ29tcHJvYmFudGUiPg0KCQk8eHM6YW5ub3RhdGlvbj4NCgkJCTx4czpkb2N1bWVudGF0aW9uPkVzdMOhbmRhciBkZSBDb21wcm9iYW50ZSBGaXNjYWwgRGlnaXRhbCBwb3IgSW50ZXJuZXQuPC94czpkb2N1bWVudGF0aW9uPg0KCQk8L3hzOmFubm90YXRpb24+DQoJCTx4czpjb21wbGV4VHlwZT4NCgkJCTx4czpzZXF1ZW5jZT4NCgkJCQk8eHM6ZWxlbWVudCBuYW1lPSJJbmZvcm1hY2lvbkdsb2JhbCIgbWluT2NjdXJzPSIwIj4NCgkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIGNvbmRpY2lvbmFsIHBhcmEgcHJlY2lzYXIgbGEgaW5mb3JtYWNpw7NuIHJlbGFjaW9uYWRhIGNvbiBlbCBjb21wcm9iYW50ZSBnbG9iYWwuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iUGVyaW9kaWNpZGFkIiB0eXBlPSJjYXRDRkRJOmNfUGVyaW9kaWNpZGFkIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgZXhwcmVzYXIgZWwgcGVyw61vZG8gYWwgcXVlIGNvcnJlc3BvbmRlIGxhIGluZm9ybWFjacOzbiBkZWwgY29tcHJvYmFudGUgZ2xvYmFsLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iTWVzZXMiIHR5cGU9ImNhdENGREk6Y19NZXNlcyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGV4cHJlc2FyIGVsIG1lcyBvIGxvcyBtZXNlcyBhbCBxdWUgY29ycmVzcG9uZGUgbGEgaW5mb3JtYWNpw7NuIGRlbCBjb21wcm9iYW50ZSBnbG9iYWwuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJBw7FvIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgZXhwcmVzYXIgZWwgYcOxbyBhbCBxdWUgY29ycmVzcG9uZGUgbGEgaW5mb3JtYWNpw7NuIGRlbCBjb21wcm9iYW50ZSBnbG9iYWwuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOnNob3J0Ij4NCgkJCQkJCQkJCTx4czptaW5JbmNsdXNpdmUgdmFsdWU9IjIwMjEiLz4NCgkJCQkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCTwveHM6ZWxlbWVudD4NCgkJCQk8eHM6ZWxlbWVudCBuYW1lPSJDZmRpUmVsYWNpb25hZG9zIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIj4NCgkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIHBhcmEgcHJlY2lzYXIgbGEgaW5mb3JtYWNpw7NuIGRlIGxvcyBjb21wcm9iYW50ZXMgcmVsYWNpb25hZG9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6Y29tcGxleFR5cGU+DQoJCQkJCQk8eHM6c2VxdWVuY2U+DQoJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iQ2ZkaVJlbGFjaW9uYWRvIiBtYXhPY2N1cnM9InVuYm91bmRlZCI+DQoJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+Tm9kbyByZXF1ZXJpZG8gcGFyYSBwcmVjaXNhciBsYSBpbmZvcm1hY2nDs24gZGUgbG9zIGNvbXByb2JhbnRlcyByZWxhY2lvbmFkb3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iVVVJRCIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHJlZ2lzdHJhciBlbCBmb2xpbyBmaXNjYWwgKFVVSUQpIGRlIHVuIENGREkgcmVsYWNpb25hZG8gY29uIGVsIHByZXNlbnRlIGNvbXByb2JhbnRlLCBwb3IgZWplbXBsbzogU2kgZWwgQ0ZESSByZWxhY2lvbmFkbyBlcyB1biBjb21wcm9iYW50ZSBkZSB0cmFzbGFkbyBxdWUgc2lydmUgcGFyYSByZWdpc3RyYXIgZWwgbW92aW1pZW50byBkZSBsYSBtZXJjYW5jw61hLiBTaSBlc3RlIGNvbXByb2JhbnRlIHNlIHVzYSBjb21vIG5vdGEgZGUgY3LDqWRpdG8gbyBub3RhIGRlIGTDqWJpdG8gZGVsIGNvbXByb2JhbnRlIHJlbGFjaW9uYWRvLiBTaSBlc3RlIGNvbXByb2JhbnRlIGVzIHVuYSBkZXZvbHVjacOzbiBzb2JyZSBlbCBjb21wcm9iYW50ZSByZWxhY2lvbmFkby4gU2kgw6lzdGUgc3VzdGl0dXllIGEgdW5hIGZhY3R1cmEgY2FuY2VsYWRhLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJPHhzOmxlbmd0aCB2YWx1ZT0iMzYiLz4NCgkJCQkJCQkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJCQkJCQkJPHhzOnBhdHRlcm4gdmFsdWU9IlthLWYwLTlBLUZdezh9LVthLWYwLTlBLUZdezR9LVthLWYwLTlBLUZdezR9LVthLWYwLTlBLUZdezR9LVthLWYwLTlBLUZdezEyfSIvPg0KCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCTwveHM6ZWxlbWVudD4NCgkJCQkJCTwveHM6c2VxdWVuY2U+DQoJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlRpcG9SZWxhY2lvbiIgdHlwZT0iY2F0Q0ZESTpjX1RpcG9SZWxhY2lvbiIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGluZGljYXIgbGEgY2xhdmUgZGUgbGEgcmVsYWNpw7NuIHF1ZSBleGlzdGUgZW50cmUgw6lzdGUgcXVlIHNlIGVzdMOhIGdlbmVyYW5kbyB5IGVsIG8gbG9zIENGREkgcHJldmlvcy48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCTwveHM6Y29tcGxleFR5cGU+DQoJCQkJPC94czplbGVtZW50Pg0KCQkJCTx4czplbGVtZW50IG5hbWU9IkVtaXNvciI+DQoJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+Tm9kbyByZXF1ZXJpZG8gcGFyYSBleHByZXNhciBsYSBpbmZvcm1hY2nDs24gZGVsIGNvbnRyaWJ1eWVudGUgZW1pc29yIGRlbCBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJSZmMiIHR5cGU9InRkQ0ZESTp0X1JGQyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHJlZ2lzdHJhciBsYSBDbGF2ZSBkZWwgUmVnaXN0cm8gRmVkZXJhbCBkZSBDb250cmlidXllbnRlcyBjb3JyZXNwb25kaWVudGUgYWwgY29udHJpYnV5ZW50ZSBlbWlzb3IgZGVsIGNvbXByb2JhbnRlLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iTm9tYnJlIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgcmVnaXN0cmFyIGVsIG5vbWJyZSwgZGVub21pbmFjacOzbiBvIHJhesOzbiBzb2NpYWwgZGVsIGNvbnRyaWJ1eWVudGUgaW5zY3JpdG8gZW4gZWwgUkZDLCBkZWwgZW1pc29yIGRlbCBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjMwMCIvPg0KCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iW158XXsxLDMwMH0iLz4NCgkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iUmVnaW1lbkZpc2NhbCIgdHlwZT0iY2F0Q0ZESTpjX1JlZ2ltZW5GaXNjYWwiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBpbmNvcnBvcmFyIGxhIGNsYXZlIGRlbCByw6lnaW1lbiBkZWwgY29udHJpYnV5ZW50ZSBlbWlzb3IgYWwgcXVlIGFwbGljYXLDoSBlbCBlZmVjdG8gZmlzY2FsIGRlIGVzdGUgY29tcHJvYmFudGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJGYWNBdHJBZHF1aXJlbnRlIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSBleHByZXNhciBlbCBuw7ptZXJvIGRlIG9wZXJhY2nDs24gcHJvcG9yY2lvbmFkbyBwb3IgZWwgU0FUIGN1YW5kbyBzZSB0cmF0ZSBkZSB1biBjb21wcm9iYW50ZSBhIHRyYXbDqXMgZGUgdW4gUENFQ0ZESSBvIHVuIFBDR0NGRElTUC48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJCQkJPHhzOmxlbmd0aCB2YWx1ZT0iMTAiLz4NCgkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbMC05XXsxMH0iLz4NCgkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJPHhzOmVsZW1lbnQgbmFtZT0iUmVjZXB0b3IiPg0KCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gcmVxdWVyaWRvIHBhcmEgcHJlY2lzYXIgbGEgaW5mb3JtYWNpw7NuIGRlbCBjb250cmlidXllbnRlIHJlY2VwdG9yIGRlbCBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJSZmMiIHR5cGU9InRkQ0ZESTp0X1JGQyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHJlZ2lzdHJhciBsYSBDbGF2ZSBkZWwgUmVnaXN0cm8gRmVkZXJhbCBkZSBDb250cmlidXllbnRlcyBjb3JyZXNwb25kaWVudGUgYWwgY29udHJpYnV5ZW50ZSByZWNlcHRvciBkZWwgY29tcHJvYmFudGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJOb21icmUiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSByZWdpc3RyYXIgZWwgbm9tYnJlKHMpLCBwcmltZXIgYXBlbGxpZG8sIHNlZ3VuZG8gYXBlbGxpZG8sIHNlZ8O6biBjb3JyZXNwb25kYSwgZGVub21pbmFjacOzbiBvIHJhesOzbiBzb2NpYWwgZGVsIGNvbnRyaWJ1eWVudGUsIGluc2NyaXRvIGVuIGVsIFJGQywgZGVsIHJlY2VwdG9yIGRlbCBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjMwMCIvPg0KCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iW158XXsxLDMwMH0iLz4NCgkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iRG9taWNpbGlvRmlzY2FsUmVjZXB0b3IiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSByZWdpc3RyYXIgZWwgY8OzZGlnbyBwb3N0YWwgZGVsIGRvbWljaWxpbyBmaXNjYWwgZGVsIHJlY2VwdG9yIGRlbCBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCTx4czpsZW5ndGggdmFsdWU9IjUiLz4NCgkJCQkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJCQkJPHhzOnBhdHRlcm4gdmFsdWU9IlswLTldezV9Ii8+DQoJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlJlc2lkZW5jaWFGaXNjYWwiIHR5cGU9ImNhdENGREk6Y19QYWlzIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSByZWdpc3RyYXIgbGEgY2xhdmUgZGVsIHBhw61zIGRlIHJlc2lkZW5jaWEgcGFyYSBlZmVjdG9zIGZpc2NhbGVzIGRlbCByZWNlcHRvciBkZWwgY29tcHJvYmFudGUsIGN1YW5kbyBzZSB0cmF0ZSBkZSB1biBleHRyYW5qZXJvLCB5IHF1ZSBlcyBjb25mb3JtZSBjb24gbGEgZXNwZWNpZmljYWNpw7NuIElTTyAzMTY2LTEgYWxwaGEtMy4gRXMgcmVxdWVyaWRvIGN1YW5kbyBzZSBpbmNsdXlhIGVsIGNvbXBsZW1lbnRvIGRlIGNvbWVyY2lvIGV4dGVyaW9yIG8gc2UgcmVnaXN0cmUgZWwgYXRyaWJ1dG8gTnVtUmVnSWRUcmliLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iTnVtUmVnSWRUcmliIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSBleHByZXNhciBlbCBuw7ptZXJvIGRlIHJlZ2lzdHJvIGRlIGlkZW50aWRhZCBmaXNjYWwgZGVsIHJlY2VwdG9yIGN1YW5kbyBzZWEgcmVzaWRlbnRlIGVuIGVsIGV4dHJhbmplcm8uIEVzIHJlcXVlcmlkbyBjdWFuZG8gc2UgaW5jbHV5YSBlbCBjb21wbGVtZW50byBkZSBjb21lcmNpbyBleHRlcmlvci48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjQwIi8+DQoJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iUmVnaW1lbkZpc2NhbFJlY2VwdG9yIiB0eXBlPSJjYXRDRkRJOmNfUmVnaW1lbkZpc2NhbCIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGluY29ycG9yYXIgbGEgY2xhdmUgZGVsIHLDqWdpbWVuIGZpc2NhbCBkZWwgY29udHJpYnV5ZW50ZSByZWNlcHRvciBhbCBxdWUgYXBsaWNhcsOhIGVsIGVmZWN0byBmaXNjYWwgZGUgZXN0ZSBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlVzb0NGREkiIHR5cGU9ImNhdENGREk6Y19Vc29DRkRJIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgZXhwcmVzYXIgbGEgY2xhdmUgZGVsIHVzbyBxdWUgZGFyw6EgYSBlc3RhIGZhY3R1cmEgZWwgcmVjZXB0b3IgZGVsIENGREkuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCTwveHM6ZWxlbWVudD4NCgkJCQk8eHM6ZWxlbWVudCBuYW1lPSJDb25jZXB0b3MiPg0KCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gcmVxdWVyaWRvIHBhcmEgbGlzdGFyIGxvcyBjb25jZXB0b3MgY3ViaWVydG9zIHBvciBlbCBjb21wcm9iYW50ZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJPHhzOnNlcXVlbmNlPg0KCQkJCQkJCTx4czplbGVtZW50IG5hbWU9IkNvbmNlcHRvIiBtYXhPY2N1cnM9InVuYm91bmRlZCI+DQoJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+Tm9kbyByZXF1ZXJpZG8gcGFyYSByZWdpc3RyYXIgbGEgaW5mb3JtYWNpw7NuIGRldGFsbGFkYSBkZSB1biBiaWVuIG8gc2VydmljaW8gYW1wYXJhZG8gZW4gZWwgY29tcHJvYmFudGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCTx4czpzZXF1ZW5jZT4NCgkJCQkJCQkJCQk8eHM6ZWxlbWVudCBuYW1lPSJJbXB1ZXN0b3MiIG1pbk9jY3Vycz0iMCI+DQoJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+Tm9kbyBjb25kaWNpb25hbCBwYXJhIGNhcHR1cmFyIGxvcyBpbXB1ZXN0b3MgYXBsaWNhYmxlcyBhbCBwcmVzZW50ZSBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJPHhzOnNlcXVlbmNlPg0KCQkJCQkJCQkJCQkJCTx4czplbGVtZW50IG5hbWU9IlRyYXNsYWRvcyIgbWluT2NjdXJzPSIwIj4NCgkJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIHBhcmEgYXNlbnRhciBsb3MgaW1wdWVzdG9zIHRyYXNsYWRhZG9zIGFwbGljYWJsZXMgYWwgcHJlc2VudGUgY29uY2VwdG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCQkJCTx4czpzZXF1ZW5jZT4NCgkJCQkJCQkJCQkJCQkJCQk8eHM6ZWxlbWVudCBuYW1lPSJUcmFzbGFkbyIgbWF4T2NjdXJzPSJ1bmJvdW5kZWQiPg0KCQkJCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gcmVxdWVyaWRvIHBhcmEgYXNlbnRhciBsYSBpbmZvcm1hY2nDs24gZGV0YWxsYWRhIGRlIHVuIHRyYXNsYWRvIGRlIGltcHVlc3RvcyBhcGxpY2FibGUgYWwgcHJlc2VudGUgY29uY2VwdG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iQmFzZSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGxhIGJhc2UgcGFyYSBlbCBjw6FsY3VsbyBkZWwgaW1wdWVzdG8sIGxhIGRldGVybWluYWNpw7NuIGRlIGxhIGJhc2Ugc2UgcmVhbGl6YSBkZSBhY3VlcmRvIGNvbiBsYXMgZGlzcG9zaWNpb25lcyBmaXNjYWxlcyB2aWdlbnRlcy4gTm8gc2UgcGVybWl0ZW4gdmFsb3JlcyBuZWdhdGl2b3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOmRlY2ltYWwiPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmZyYWN0aW9uRGlnaXRzIHZhbHVlPSI2Ii8+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6bWluSW5jbHVzaXZlIHZhbHVlPSIwLjAwMDAwMSIvPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkltcHVlc3RvIiB0eXBlPSJjYXRDRkRJOmNfSW1wdWVzdG8iIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBzZcOxYWxhciBsYSBjbGF2ZSBkZWwgdGlwbyBkZSBpbXB1ZXN0byB0cmFzbGFkYWRvIGFwbGljYWJsZSBhbCBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlRpcG9GYWN0b3IiIHR5cGU9ImNhdENGREk6Y19UaXBvRmFjdG9yIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgc2XDsWFsYXIgbGEgY2xhdmUgZGVsIHRpcG8gZGUgZmFjdG9yIHF1ZSBzZSBhcGxpY2EgYSBsYSBiYXNlIGRlbCBpbXB1ZXN0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlRhc2FPQ3VvdGEiIHVzZT0ib3B0aW9uYWwiPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBjb25kaWNpb25hbCBwYXJhIHNlw7FhbGFyIGVsIHZhbG9yIGRlIGxhIHRhc2EgbyBjdW90YSBkZWwgaW1wdWVzdG8gcXVlIHNlIHRyYXNsYWRhIHBhcmEgZWwgcHJlc2VudGUgY29uY2VwdG8uIEVzIHJlcXVlcmlkbyBjdWFuZG8gZWwgYXRyaWJ1dG8gVGlwb0ZhY3RvciB0ZW5nYSB1bmEgY2xhdmUgcXVlIGNvcnJlc3BvbmRhIGEgVGFzYSBvIEN1b3RhLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpkZWNpbWFsIj4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpmcmFjdGlvbkRpZ2l0cyB2YWx1ZT0iNiIvPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOm1pbkluY2x1c2l2ZSB2YWx1ZT0iMC4wMDAwMDAiLz4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJJbXBvcnRlIiB0eXBlPSJ0ZENGREk6dF9JbXBvcnRlIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSBzZcOxYWxhciBlbCBpbXBvcnRlIGRlbCBpbXB1ZXN0byB0cmFzbGFkYWRvIHF1ZSBhcGxpY2EgYWwgY29uY2VwdG8uIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLiBFcyByZXF1ZXJpZG8gY3VhbmRvIFRpcG9GYWN0b3Igc2VhIFRhc2EgbyBDdW90YS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQkJCQkJCTwveHM6Y29tcGxleFR5cGU+DQoJCQkJCQkJCQkJCQkJCQkJPC94czplbGVtZW50Pg0KCQkJCQkJCQkJCQkJCQkJPC94czpzZXF1ZW5jZT4NCgkJCQkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iUmV0ZW5jaW9uZXMiIG1pbk9jY3Vycz0iMCI+DQoJCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+Tm9kbyBvcGNpb25hbCBwYXJhIGFzZW50YXIgbG9zIGltcHVlc3RvcyByZXRlbmlkb3MgYXBsaWNhYmxlcyBhbCBwcmVzZW50ZSBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJCQkJPHhzOnNlcXVlbmNlPg0KCQkJCQkJCQkJCQkJCQkJCTx4czplbGVtZW50IG5hbWU9IlJldGVuY2lvbiIgbWF4T2NjdXJzPSJ1bmJvdW5kZWQiPg0KCQkJCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gcmVxdWVyaWRvIHBhcmEgYXNlbnRhciBsYSBpbmZvcm1hY2nDs24gZGV0YWxsYWRhIGRlIHVuYSByZXRlbmNpw7NuIGRlIGltcHVlc3RvcyBhcGxpY2FibGUgYWwgcHJlc2VudGUgY29uY2VwdG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iQmFzZSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGxhIGJhc2UgcGFyYSBlbCBjw6FsY3VsbyBkZSBsYSByZXRlbmNpw7NuLCBsYSBkZXRlcm1pbmFjacOzbiBkZSBsYSBiYXNlIHNlIHJlYWxpemEgZGUgYWN1ZXJkbyBjb24gbGFzIGRpc3Bvc2ljaW9uZXMgZmlzY2FsZXMgdmlnZW50ZXMuIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpkZWNpbWFsIj4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpmcmFjdGlvbkRpZ2l0cyB2YWx1ZT0iNiIvPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOm1pbkluY2x1c2l2ZSB2YWx1ZT0iMC4wMDAwMDEiLz4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJJbXB1ZXN0byIgdHlwZT0iY2F0Q0ZESTpjX0ltcHVlc3RvIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgc2XDsWFsYXIgbGEgY2xhdmUgZGVsIHRpcG8gZGUgaW1wdWVzdG8gcmV0ZW5pZG8gYXBsaWNhYmxlIGFsIGNvbmNlcHRvLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iVGlwb0ZhY3RvciIgdHlwZT0iY2F0Q0ZESTpjX1RpcG9GYWN0b3IiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBzZcOxYWxhciBsYSBjbGF2ZSBkZWwgdGlwbyBkZSBmYWN0b3IgcXVlIHNlIGFwbGljYSBhIGxhIGJhc2UgZGVsIGltcHVlc3RvLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iVGFzYU9DdW90YSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGxhIHRhc2EgbyBjdW90YSBkZWwgaW1wdWVzdG8gcXVlIHNlIHJldGllbmUgcGFyYSBlbCBwcmVzZW50ZSBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6ZGVjaW1hbCI+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czptaW5JbmNsdXNpdmUgdmFsdWU9IjAuMDAwMDAwIi8+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCQk8eHM6ZnJhY3Rpb25EaWdpdHMgdmFsdWU9IjYiLz4NCgkJCQkJCQkJCQkJCQkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iSW1wb3J0ZSIgdHlwZT0idGRDRkRJOnRfSW1wb3J0ZSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGVsIGltcG9ydGUgZGVsIGltcHVlc3RvIHJldGVuaWRvIHF1ZSBhcGxpY2EgYWwgY29uY2VwdG8uIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQkJCQkJCQk8L3hzOnNlcXVlbmNlPg0KCQkJCQkJCQkJCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJCTwveHM6ZWxlbWVudD4NCgkJCQkJCQkJCQkJCTwveHM6c2VxdWVuY2U+DQoJCQkJCQkJCQkJCTwveHM6Y29tcGxleFR5cGU+DQoJCQkJCQkJCQkJPC94czplbGVtZW50Pg0KCQkJCQkJCQkJCTx4czplbGVtZW50IG5hbWU9IkFDdWVudGFUZXJjZXJvcyIgbWluT2NjdXJzPSIwIj4NCgkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIHBhcmEgcmVnaXN0cmFyIGluZm9ybWFjacOzbiBkZWwgY29udHJpYnV5ZW50ZSBUZXJjZXJvLCBhIGN1ZW50YSBkZWwgcXVlIHNlIHJlYWxpemEgbGEgb3BlcmFjacOzbi48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJSZmNBQ3VlbnRhVGVyY2Vyb3MiIHR5cGU9InRkQ0ZESTp0X1JGQyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHJlZ2lzdHJhciBsYSBDbGF2ZSBkZWwgUmVnaXN0cm8gRmVkZXJhbCBkZSBDb250cmlidXllbnRlcyBkZWwgY29udHJpYnV5ZW50ZSBUZXJjZXJvLCBhIGN1ZW50YSBkZWwgcXVlIHNlIHJlYWxpemEgbGEgb3BlcmFjacOzbi48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9Ik5vbWJyZUFDdWVudGFUZXJjZXJvcyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHJlZ2lzdHJhciBlbCBub21icmUsIGRlbm9taW5hY2nDs24gbyByYXrDs24gc29jaWFsIGRlbCBjb250cmlidXllbnRlIFRlcmNlcm8gY29ycmVzcG9uZGllbnRlIGNvbiBlbCBSZmMsIGEgY3VlbnRhIGRlbCBxdWUgc2UgcmVhbGl6YSBsYSBvcGVyYWNpw7NuLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJCQkJPHhzOm1pbkxlbmd0aCB2YWx1ZT0iMSIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOm1heExlbmd0aCB2YWx1ZT0iMzAwIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbXnxdezEsMzAwfSIvPg0KCQkJCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJSZWdpbWVuRmlzY2FsQUN1ZW50YVRlcmNlcm9zIiB0eXBlPSJjYXRDRkRJOmNfUmVnaW1lbkZpc2NhbCIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGluY29ycG9yYXIgbGEgY2xhdmUgZGVsIHLDqWdpbWVuIGRlbCBjb250cmlidXllbnRlIFRlcmNlcm8sIGEgY3VlbnRhIGRlbCBxdWUgc2UgcmVhbGl6YSBsYSBvcGVyYWNpw7NuLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iRG9taWNpbGlvRmlzY2FsQUN1ZW50YVRlcmNlcm9zIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgaW5jb3Jwb3JhciBlbCBjw7NkaWdvIHBvc3RhbCBkZWwgZG9taWNpbGlvIGZpc2NhbCBkZWwgVGVyY2VybywgYSBjdWVudGEgZGVsIHF1ZSBzZSByZWFsaXphIGxhIG9wZXJhY2nDs24uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOnN0cmluZyI+DQoJCQkJCQkJCQkJCQkJCQk8eHM6bGVuZ3RoIHZhbHVlPSI1Ii8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbMC05XXs1fSIvPg0KCQkJCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCTwveHM6ZWxlbWVudD4NCgkJCQkJCQkJCQk8eHM6ZWxlbWVudCBuYW1lPSJJbmZvcm1hY2lvbkFkdWFuZXJhIiBtaW5PY2N1cnM9IjAiIG1heE9jY3Vycz0idW5ib3VuZGVkIj4NCgkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIHBhcmEgaW50cm9kdWNpciBsYSBpbmZvcm1hY2nDs24gYWR1YW5lcmEgYXBsaWNhYmxlIGN1YW5kbyBzZSB0cmF0ZSBkZSB2ZW50YXMgZGUgcHJpbWVyYSBtYW5vIGRlIG1lcmNhbmPDrWFzIGltcG9ydGFkYXMgbyBzZSB0cmF0ZSBkZSBvcGVyYWNpb25lcyBkZSBjb21lcmNpbyBleHRlcmlvciBjb24gYmllbmVzIG8gc2VydmljaW9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQk8eHM6Y29tcGxleFR5cGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9Ik51bWVyb1BlZGltZW50byIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGV4cHJlc2FyIGVsIG7Dum1lcm8gZGVsIHBlZGltZW50byBxdWUgYW1wYXJhIGxhIGltcG9ydGFjacOzbiBkZWwgYmllbiBxdWUgc2UgZXhwcmVzYSBlbiBlbCBzaWd1aWVudGUgZm9ybWF0bzogw7psdGltb3MgMiBkw61naXRvcyBkZWwgYcOxbyBkZSB2YWxpZGFjacOzbiBzZWd1aWRvcyBwb3IgZG9zIGVzcGFjaW9zLCAyIGTDrWdpdG9zIGRlIGxhIGFkdWFuYSBkZSBkZXNwYWNobyBzZWd1aWRvcyBwb3IgZG9zIGVzcGFjaW9zLCA0IGTDrWdpdG9zIGRlbCBuw7ptZXJvIGRlIGxhIHBhdGVudGUgc2VndWlkb3MgcG9yIGRvcyBlc3BhY2lvcywgMSBkw61naXRvIHF1ZSBjb3JyZXNwb25kZSBhbCDDumx0aW1vIGTDrWdpdG8gZGVsIGHDsW8gZW4gY3Vyc28sIHNhbHZvIHF1ZSBzZSB0cmF0ZSBkZSB1biBwZWRpbWVudG8gY29uc29saWRhZG8gaW5pY2lhZG8gZW4gZWwgYcOxbyBpbm1lZGlhdG8gYW50ZXJpb3IgbyBkZWwgcGVkaW1lbnRvIG9yaWdpbmFsIGRlIHVuYSByZWN0aWZpY2FjacOzbiwgc2VndWlkbyBkZSA2IGTDrWdpdG9zIGRlIGxhIG51bWVyYWNpw7NuIHByb2dyZXNpdmEgcG9yIGFkdWFuYS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCQkJCQkJCTx4czpsZW5ndGggdmFsdWU9IjIxIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iWzAtOV17Mn0gIFswLTldezJ9ICBbMC05XXs0fSAgWzAtOV17N30iLz4NCgkJCQkJCQkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iQ3VlbnRhUHJlZGlhbCIgbWluT2NjdXJzPSIwIiBtYXhPY2N1cnM9InVuYm91bmRlZCI+DQoJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+Tm9kbyBvcGNpb25hbCBwYXJhIGFzZW50YXIgZWwgbsO6bWVybyBkZSBjdWVudGEgcHJlZGlhbCBjb24gZWwgcXVlIGZ1ZSByZWdpc3RyYWRvIGVsIGlubXVlYmxlLCBlbiBlbCBzaXN0ZW1hIGNhdGFzdHJhbCBkZSBsYSBlbnRpZGFkIGZlZGVyYXRpdmEgZGUgcXVlIHRyYXRlLCBvIGJpZW4gcGFyYSBpbmNvcnBvcmFyIGxvcyBkYXRvcyBkZSBpZGVudGlmaWNhY2nDs24gZGVsIGNlcnRpZmljYWRvIGRlIHBhcnRpY2lwYWNpw7NuIGlubW9iaWxpYXJpYSBubyBhbW9ydGl6YWJsZS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJOdW1lcm8iIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBwcmVjaXNhciBlbCBuw7ptZXJvIGRlIGxhIGN1ZW50YSBwcmVkaWFsIGRlbCBpbm11ZWJsZSBjdWJpZXJ0byBwb3IgZWwgcHJlc2VudGUgY29uY2VwdG8sIG8gYmllbiBwYXJhIGluY29ycG9yYXIgbG9zIGRhdG9zIGRlIGlkZW50aWZpY2FjacOzbiBkZWwgY2VydGlmaWNhZG8gZGUgcGFydGljaXBhY2nDs24gaW5tb2JpbGlhcmlhIG5vIGFtb3J0aXphYmxlLCB0cmF0w6FuZG9zZSBkZSBhcnJlbmRhbWllbnRvLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJCQkJPHhzOm1pbkxlbmd0aCB2YWx1ZT0iMSIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOm1heExlbmd0aCB2YWx1ZT0iMTUwIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbMC05YS16QS1aXXsxLDE1MH0iLz4NCgkJCQkJCQkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iQ29tcGxlbWVudG9Db25jZXB0byIgbWluT2NjdXJzPSIwIj4NCgkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIGRvbmRlIHNlIGluY2x1eWVuIGxvcyBub2RvcyBjb21wbGVtZW50YXJpb3MgZGUgZXh0ZW5zacOzbiBhbCBjb25jZXB0byBkZWZpbmlkb3MgcG9yIGVsIFNBVCwgZGUgYWN1ZXJkbyBjb24gbGFzIGRpc3Bvc2ljaW9uZXMgcGFydGljdWxhcmVzIHBhcmEgdW4gc2VjdG9yIG8gYWN0aXZpZGFkIGVzcGVjw61maWNhLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQk8eHM6Y29tcGxleFR5cGU+DQoJCQkJCQkJCQkJCQk8eHM6c2VxdWVuY2U+DQoJCQkJCQkJCQkJCQkJPHhzOmFueSBtYXhPY2N1cnM9InVuYm91bmRlZCIvPg0KCQkJCQkJCQkJCQkJPC94czpzZXF1ZW5jZT4NCgkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iUGFydGUiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1bmJvdW5kZWQiPg0KCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gb3BjaW9uYWwgcGFyYSBleHByZXNhciBsYXMgcGFydGVzIG8gY29tcG9uZW50ZXMgcXVlIGludGVncmFuIGxhIHRvdGFsaWRhZCBkZWwgY29uY2VwdG8gZXhwcmVzYWRvIGVuIGVsIGNvbXByb2JhbnRlIGZpc2NhbCBkaWdpdGFsIHBvciBJbnRlcm5ldC48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJPHhzOnNlcXVlbmNlPg0KCQkJCQkJCQkJCQkJCTx4czplbGVtZW50IG5hbWU9IkluZm9ybWFjaW9uQWR1YW5lcmEiIG1pbk9jY3Vycz0iMCIgbWF4T2NjdXJzPSJ1bmJvdW5kZWQiPg0KCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gb3BjaW9uYWwgcGFyYSBpbnRyb2R1Y2lyIGxhIGluZm9ybWFjacOzbiBhZHVhbmVyYSBhcGxpY2FibGUgY3VhbmRvIHNlIHRyYXRlIGRlIHZlbnRhcyBkZSBwcmltZXJhIG1hbm8gZGUgbWVyY2FuY8OtYXMgaW1wb3J0YWRhcyBvIHNlIHRyYXRlIGRlIG9wZXJhY2lvbmVzIGRlIGNvbWVyY2lvIGV4dGVyaW9yIGNvbiBiaWVuZXMgbyBzZXJ2aWNpb3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iTnVtZXJvUGVkaW1lbnRvIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgZXhwcmVzYXIgZWwgbsO6bWVybyBkZWwgcGVkaW1lbnRvIHF1ZSBhbXBhcmEgbGEgaW1wb3J0YWNpw7NuIGRlbCBiaWVuIHF1ZSBzZSBleHByZXNhIGVuIGVsIHNpZ3VpZW50ZSBmb3JtYXRvOiDDumx0aW1vcyAyIGTDrWdpdG9zIGRlbCBhw7FvIGRlIHZhbGlkYWNpw7NuIHNlZ3VpZG9zIHBvciBkb3MgZXNwYWNpb3MsIDIgZMOtZ2l0b3MgZGUgbGEgYWR1YW5hIGRlIGRlc3BhY2hvIHNlZ3VpZG9zIHBvciBkb3MgZXNwYWNpb3MsIDQgZMOtZ2l0b3MgZGVsIG7Dum1lcm8gZGUgbGEgcGF0ZW50ZSBzZWd1aWRvcyBwb3IgZG9zIGVzcGFjaW9zLCAxIGTDrWdpdG8gcXVlIGNvcnJlc3BvbmRlIGFsIMO6bHRpbW8gZMOtZ2l0byBkZWwgYcOxbyBlbiBjdXJzbywgc2Fsdm8gcXVlIHNlIHRyYXRlIGRlIHVuIHBlZGltZW50byBjb25zb2xpZGFkbyBpbmljaWFkbyBlbiBlbCBhw7FvIGlubWVkaWF0byBhbnRlcmlvciBvIGRlbCBwZWRpbWVudG8gb3JpZ2luYWwgZGUgdW5hIHJlY3RpZmljYWNpw7NuLCBzZWd1aWRvIGRlIDYgZMOtZ2l0b3MgZGUgbGEgbnVtZXJhY2nDs24gcHJvZ3Jlc2l2YSBwb3IgYWR1YW5hLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJCQkJCQkJPHhzOmxlbmd0aCB2YWx1ZT0iMjEiLz4NCgkJCQkJCQkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbMC05XXsyfSAgWzAtOV17Mn0gIFswLTldezR9ICBbMC05XXs3fSIvPg0KCQkJCQkJCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJCTwveHM6ZWxlbWVudD4NCgkJCQkJCQkJCQkJCTwveHM6c2VxdWVuY2U+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkNsYXZlUHJvZFNlcnYiIHR5cGU9ImNhdENGREk6Y19DbGF2ZVByb2RTZXJ2IiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgZXhwcmVzYXIgbGEgY2xhdmUgZGVsIHByb2R1Y3RvIG8gZGVsIHNlcnZpY2lvIGFtcGFyYWRvIHBvciBsYSBwcmVzZW50ZSBwYXJ0ZS4gRXMgcmVxdWVyaWRvIHkgZGViZW4gdXRpbGl6YXIgbGFzIGNsYXZlcyBkZWwgY2F0w6Fsb2dvIGRlIHByb2R1Y3RvcyB5IHNlcnZpY2lvcywgY3VhbmRvIGxvcyBjb25jZXB0b3MgcXVlIHJlZ2lzdHJlbiBwb3Igc3VzIGFjdGl2aWRhZGVzIGNvcnJlc3BvbmRhbiBjb24gZGljaG9zIGNvbmNlcHRvcy48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9Ik5vSWRlbnRpZmljYWNpb24iIHVzZT0ib3B0aW9uYWwiPg0KCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBvcGNpb25hbCBwYXJhIGV4cHJlc2FyIGVsIG7Dum1lcm8gZGUgc2VyaWUsIG7Dum1lcm8gZGUgcGFydGUgZGVsIGJpZW4gbyBpZGVudGlmaWNhZG9yIGRlbCBwcm9kdWN0byBvIGRlbCBzZXJ2aWNpbyBhbXBhcmFkbyBwb3IgbGEgcHJlc2VudGUgcGFydGUuIE9wY2lvbmFsbWVudGUgc2UgcHVlZGUgdXRpbGl6YXIgY2xhdmVzIGRlbCBlc3TDoW5kYXIgR1RJTi48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCQkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCQkJCQkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjEwMCIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iW158XXsxLDEwMH0iLz4NCgkJCQkJCQkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iQ2FudGlkYWQiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBwcmVjaXNhciBsYSBjYW50aWRhZCBkZSBiaWVuZXMgbyBzZXJ2aWNpb3MgZGVsIHRpcG8gcGFydGljdWxhciBkZWZpbmlkbyBwb3IgbGEgcHJlc2VudGUgcGFydGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOmRlY2ltYWwiPg0KCQkJCQkJCQkJCQkJCQkJPHhzOmZyYWN0aW9uRGlnaXRzIHZhbHVlPSI2Ii8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6bWluSW5jbHVzaXZlIHZhbHVlPSIwLjAwMDAwMSIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlVuaWRhZCIgdXNlPSJvcHRpb25hbCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIG9wY2lvbmFsIHBhcmEgcHJlY2lzYXIgbGEgdW5pZGFkIGRlIG1lZGlkYSBwcm9waWEgZGUgbGEgb3BlcmFjacOzbiBkZWwgZW1pc29yLCBhcGxpY2FibGUgcGFyYSBsYSBjYW50aWRhZCBleHByZXNhZGEgZW4gbGEgcGFydGUuIExhIHVuaWRhZCBkZWJlIGNvcnJlc3BvbmRlciBjb24gbGEgZGVzY3JpcGNpw7NuIGRlIGxhIHBhcnRlLiA8L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCQkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCQkJCQkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjIwIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbXnxdezEsMjB9Ii8+DQoJCQkJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkRlc2NyaXBjaW9uIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgcHJlY2lzYXIgbGEgZGVzY3JpcGNpw7NuIGRlbCBiaWVuIG8gc2VydmljaW8gY3ViaWVydG8gcG9yIGxhIHByZXNlbnRlIHBhcnRlLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJCQkJPHhzOm1pbkxlbmd0aCB2YWx1ZT0iMSIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOm1heExlbmd0aCB2YWx1ZT0iMTAwMCIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iW158XXsxLDEwMDB9Ii8+DQoJCQkJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlZhbG9yVW5pdGFyaW8iIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0ib3B0aW9uYWwiPg0KCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBvcGNpb25hbCBwYXJhIHByZWNpc2FyIGVsIHZhbG9yIG8gcHJlY2lvIHVuaXRhcmlvIGRlbCBiaWVuIG8gc2VydmljaW8gY3ViaWVydG8gcG9yIGxhIHByZXNlbnRlIHBhcnRlLiBObyBzZSBwZXJtaXRlbiB2YWxvcmVzIG5lZ2F0aXZvcy48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkltcG9ydGUiIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0ib3B0aW9uYWwiPg0KCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBvcGNpb25hbCBwYXJhIHByZWNpc2FyIGVsIGltcG9ydGUgdG90YWwgZGUgbG9zIGJpZW5lcyBvIHNlcnZpY2lvcyBkZSBsYSBwcmVzZW50ZSBwYXJ0ZS4gRGViZSBzZXIgZXF1aXZhbGVudGUgYWwgcmVzdWx0YWRvIGRlIG11bHRpcGxpY2FyIGxhIGNhbnRpZGFkIHBvciBlbCB2YWxvciB1bml0YXJpbyBleHByZXNhZG8gZW4gbGEgcGFydGUuIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQk8L3hzOnNlcXVlbmNlPg0KCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJDbGF2ZVByb2RTZXJ2IiB0eXBlPSJjYXRDRkRJOmNfQ2xhdmVQcm9kU2VydiIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGV4cHJlc2FyIGxhIGNsYXZlIGRlbCBwcm9kdWN0byBvIGRlbCBzZXJ2aWNpbyBhbXBhcmFkbyBwb3IgZWwgcHJlc2VudGUgY29uY2VwdG8uIEVzIHJlcXVlcmlkbyB5IGRlYmVuIHV0aWxpemFyIGxhcyBjbGF2ZXMgZGVsIGNhdMOhbG9nbyBkZSBwcm9kdWN0b3MgeSBzZXJ2aWNpb3MsIGN1YW5kbyBsb3MgY29uY2VwdG9zIHF1ZSByZWdpc3RyZW4gcG9yIHN1cyBhY3RpdmlkYWRlcyBjb3JyZXNwb25kYW4gY29uIGRpY2hvcyBjb25jZXB0b3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJOb0lkZW50aWZpY2FjaW9uIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gb3BjaW9uYWwgcGFyYSBleHByZXNhciBlbCBuw7ptZXJvIGRlIHBhcnRlLCBpZGVudGlmaWNhZG9yIGRlbCBwcm9kdWN0byBvIGRlbCBzZXJ2aWNpbywgbGEgY2xhdmUgZGUgcHJvZHVjdG8gbyBzZXJ2aWNpbywgU0tVIG8gZXF1aXZhbGVudGUsIHByb3BpYSBkZSBsYSBvcGVyYWNpw7NuIGRlbCBlbWlzb3IsIGFtcGFyYWRvIHBvciBlbCBwcmVzZW50ZSBjb25jZXB0by4gT3BjaW9uYWxtZW50ZSBzZSBwdWVkZSB1dGlsaXphciBjbGF2ZXMgZGVsIGVzdMOhbmRhciBHVElOLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQk8eHM6bWluTGVuZ3RoIHZhbHVlPSIxIi8+DQoJCQkJCQkJCQkJCQk8eHM6bWF4TGVuZ3RoIHZhbHVlPSIxMDAiLz4NCgkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbXnxdezEsMTAwfSIvPg0KCQkJCQkJCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCQkJCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJDYW50aWRhZCIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHByZWNpc2FyIGxhIGNhbnRpZGFkIGRlIGJpZW5lcyBvIHNlcnZpY2lvcyBkZWwgdGlwbyBwYXJ0aWN1bGFyIGRlZmluaWRvIHBvciBlbCBwcmVzZW50ZSBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6ZGVjaW1hbCI+DQoJCQkJCQkJCQkJCQk8eHM6ZnJhY3Rpb25EaWdpdHMgdmFsdWU9IjYiLz4NCgkJCQkJCQkJCQkJCTx4czptaW5JbmNsdXNpdmUgdmFsdWU9IjAuMDAwMDAxIi8+DQoJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQkJCQkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iQ2xhdmVVbmlkYWQiIHR5cGU9ImNhdENGREk6Y19DbGF2ZVVuaWRhZCIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHByZWNpc2FyIGxhIGNsYXZlIGRlIHVuaWRhZCBkZSBtZWRpZGEgZXN0YW5kYXJpemFkYSBhcGxpY2FibGUgcGFyYSBsYSBjYW50aWRhZCBleHByZXNhZGEgZW4gZWwgY29uY2VwdG8uIExhIHVuaWRhZCBkZWJlIGNvcnJlc3BvbmRlciBjb24gbGEgZGVzY3JpcGNpw7NuIGRlbCBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlVuaWRhZCIgdXNlPSJvcHRpb25hbCI+DQoJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIG9wY2lvbmFsIHBhcmEgcHJlY2lzYXIgbGEgdW5pZGFkIGRlIG1lZGlkYSBwcm9waWEgZGUgbGEgb3BlcmFjacOzbiBkZWwgZW1pc29yLCBhcGxpY2FibGUgcGFyYSBsYSBjYW50aWRhZCBleHByZXNhZGEgZW4gZWwgY29uY2VwdG8uIExhIHVuaWRhZCBkZWJlIGNvcnJlc3BvbmRlciBjb24gbGEgZGVzY3JpcGNpw7NuIGRlbCBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCQkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCQkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjIwIi8+DQoJCQkJCQkJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCQkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbXnxdezEsMjB9Ii8+DQoJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkRlc2NyaXBjaW9uIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgcHJlY2lzYXIgbGEgZGVzY3JpcGNpw7NuIGRlbCBiaWVuIG8gc2VydmljaW8gY3ViaWVydG8gcG9yIGVsIHByZXNlbnRlIGNvbmNlcHRvLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCQkJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJCQkJCQkJPHhzOm1pbkxlbmd0aCB2YWx1ZT0iMSIvPg0KCQkJCQkJCQkJCQkJPHhzOm1heExlbmd0aCB2YWx1ZT0iMTAwMCIvPg0KCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iW158XXsxLDEwMDB9Ii8+DQoJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlZhbG9yVW5pdGFyaW8iIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBwcmVjaXNhciBlbCB2YWxvciBvIHByZWNpbyB1bml0YXJpbyBkZWwgYmllbiBvIHNlcnZpY2lvIGN1YmllcnRvIHBvciBlbCBwcmVzZW50ZSBjb25jZXB0by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkltcG9ydGUiIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0icmVxdWlyZWQiPg0KCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBwcmVjaXNhciBlbCBpbXBvcnRlIHRvdGFsIGRlIGxvcyBiaWVuZXMgbyBzZXJ2aWNpb3MgZGVsIHByZXNlbnRlIGNvbmNlcHRvLiBEZWJlIHNlciBlcXVpdmFsZW50ZSBhbCByZXN1bHRhZG8gZGUgbXVsdGlwbGljYXIgbGEgY2FudGlkYWQgcG9yIGVsIHZhbG9yIHVuaXRhcmlvIGV4cHJlc2FkbyBlbiBlbCBjb25jZXB0by4gTm8gc2UgcGVybWl0ZW4gdmFsb3JlcyBuZWdhdGl2b3MuIDwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iRGVzY3VlbnRvIiB0eXBlPSJ0ZENGREk6dF9JbXBvcnRlIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gb3BjaW9uYWwgcGFyYSByZXByZXNlbnRhciBlbCBpbXBvcnRlIGRlIGxvcyBkZXNjdWVudG9zIGFwbGljYWJsZXMgYWwgY29uY2VwdG8uIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iT2JqZXRvSW1wIiB0eXBlPSJjYXRDRkRJOmNfT2JqZXRvSW1wIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgZXhwcmVzYXIgc2kgbGEgb3BlcmFjacOzbiBjb21lcmNpYWwgZXMgb2JqZXRvIG8gbm8gZGUgaW1wdWVzdG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCTwveHM6ZWxlbWVudD4NCgkJCQkJCTwveHM6c2VxdWVuY2U+DQoJCQkJCTwveHM6Y29tcGxleFR5cGU+DQoJCQkJPC94czplbGVtZW50Pg0KCQkJCTx4czplbGVtZW50IG5hbWU9IkltcHVlc3RvcyIgbWluT2NjdXJzPSIwIj4NCgkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIGNvbmRpY2lvbmFsIHBhcmEgZXhwcmVzYXIgZWwgcmVzdW1lbiBkZSBsb3MgaW1wdWVzdG9zIGFwbGljYWJsZXMuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCTx4czpzZXF1ZW5jZT4NCgkJCQkJCQk8eHM6ZWxlbWVudCBuYW1lPSJSZXRlbmNpb25lcyIgbWluT2NjdXJzPSIwIj4NCgkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIGNvbmRpY2lvbmFsIHBhcmEgY2FwdHVyYXIgbG9zIGltcHVlc3RvcyByZXRlbmlkb3MgYXBsaWNhYmxlcy4gRXMgcmVxdWVyaWRvIGN1YW5kbyBlbiBsb3MgY29uY2VwdG9zIHNlIHJlZ2lzdHJlIGFsZ8O6biBpbXB1ZXN0byByZXRlbmlkby48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJPHhzOnNlcXVlbmNlPg0KCQkJCQkJCQkJCTx4czplbGVtZW50IG5hbWU9IlJldGVuY2lvbiIgbWF4T2NjdXJzPSJ1bmJvdW5kZWQiPg0KCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gcmVxdWVyaWRvIHBhcmEgbGEgaW5mb3JtYWNpw7NuIGRldGFsbGFkYSBkZSB1bmEgcmV0ZW5jacOzbiBkZSBpbXB1ZXN0byBlc3BlY8OtZmljby48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJJbXB1ZXN0byIgdHlwZT0iY2F0Q0ZESTpjX0ltcHVlc3RvIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgc2XDsWFsYXIgbGEgY2xhdmUgZGVsIHRpcG8gZGUgaW1wdWVzdG8gcmV0ZW5pZG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJJbXBvcnRlIiB0eXBlPSJ0ZENGREk6dF9JbXBvcnRlIiB1c2U9InJlcXVpcmVkIj4NCgkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgc2XDsWFsYXIgZWwgbW9udG8gZGVsIGltcHVlc3RvIHJldGVuaWRvLiBObyBzZSBwZXJtaXRlbiB2YWxvcmVzIG5lZ2F0aXZvcy48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCQkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCTwveHM6Y29tcGxleFR5cGU+DQoJCQkJCQkJCQkJPC94czplbGVtZW50Pg0KCQkJCQkJCQkJPC94czpzZXF1ZW5jZT4NCgkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iVHJhc2xhZG9zIiBtaW5PY2N1cnM9IjAiPg0KCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPk5vZG8gY29uZGljaW9uYWwgcGFyYSBjYXB0dXJhciBsb3MgaW1wdWVzdG9zIHRyYXNsYWRhZG9zIGFwbGljYWJsZXMuIEVzIHJlcXVlcmlkbyBjdWFuZG8gZW4gbG9zIGNvbmNlcHRvcyBzZSByZWdpc3RyZSB1biBpbXB1ZXN0byB0cmFzbGFkYWRvLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQkJCQk8eHM6Y29tcGxleFR5cGU+DQoJCQkJCQkJCQk8eHM6c2VxdWVuY2U+DQoJCQkJCQkJCQkJPHhzOmVsZW1lbnQgbmFtZT0iVHJhc2xhZG8iIG1heE9jY3Vycz0idW5ib3VuZGVkIj4NCgkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIHJlcXVlcmlkbyBwYXJhIGxhIGluZm9ybWFjacOzbiBkZXRhbGxhZGEgZGUgdW4gdHJhc2xhZG8gZGUgaW1wdWVzdG8gZXNwZWPDrWZpY28uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCTx4czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iQmFzZSIgdHlwZT0idGRDRkRJOnRfSW1wb3J0ZSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGxhIHN1bWEgZGUgbG9zIGF0cmlidXRvcyBCYXNlIGRlIGxvcyBjb25jZXB0b3MgZGVsIGltcHVlc3RvIHRyYXNsYWRhZG8uIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iSW1wdWVzdG8iIHR5cGU9ImNhdENGREk6Y19JbXB1ZXN0byIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGxhIGNsYXZlIGRlbCB0aXBvIGRlIGltcHVlc3RvIHRyYXNsYWRhZG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJUaXBvRmFjdG9yIiB0eXBlPSJjYXRDRkRJOmNfVGlwb0ZhY3RvciIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJCQkJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIHNlw7FhbGFyIGxhIGNsYXZlIGRlbCB0aXBvIGRlIGZhY3RvciBxdWUgc2UgYXBsaWNhIGEgbGEgYmFzZSBkZWwgaW1wdWVzdG8uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQkJCQkJCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJUYXNhT0N1b3RhIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSBzZcOxYWxhciBlbCB2YWxvciBkZSBsYSB0YXNhIG8gY3VvdGEgZGVsIGltcHVlc3RvIHF1ZSBzZSB0cmFzbGFkYSBwb3IgbG9zIGNvbmNlcHRvcyBhbXBhcmFkb3MgZW4gZWwgY29tcHJvYmFudGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJCQkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJCQkJCQkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOmRlY2ltYWwiPg0KCQkJCQkJCQkJCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQkJCQkJCQkJCQk8eHM6bWluSW5jbHVzaXZlIHZhbHVlPSIwLjAwMDAwMCIvPg0KCQkJCQkJCQkJCQkJCQkJPHhzOmZyYWN0aW9uRGlnaXRzIHZhbHVlPSI2Ii8+DQoJCQkJCQkJCQkJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJCQkJCQkJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJCQkJCQkJCQkJPC94czphdHRyaWJ1dGU+DQoJCQkJCQkJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkltcG9ydGUiIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0ib3B0aW9uYWwiPg0KCQkJCQkJCQkJCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQkJCQkJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBjb25kaWNpb25hbCBwYXJhIHNlw7FhbGFyIGxhIHN1bWEgZGVsIGltcG9ydGUgZGVsIGltcHVlc3RvIHRyYXNsYWRhZG8sIGFncnVwYWRvIHBvciBpbXB1ZXN0bywgVGlwb0ZhY3RvciB5IFRhc2FPQ3VvdGEuIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQkJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCQkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQkJCQkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJCQkJCQk8L3hzOnNlcXVlbmNlPg0KCQkJCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCQkJCTwveHM6ZWxlbWVudD4NCgkJCQkJCTwveHM6c2VxdWVuY2U+DQoJCQkJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlRvdGFsSW1wdWVzdG9zUmV0ZW5pZG9zIiB0eXBlPSJ0ZENGREk6dF9JbXBvcnRlIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSBleHByZXNhciBlbCB0b3RhbCBkZSBsb3MgaW1wdWVzdG9zIHJldGVuaWRvcyBxdWUgc2UgZGVzcHJlbmRlbiBkZSBsb3MgY29uY2VwdG9zIGV4cHJlc2Fkb3MgZW4gZWwgY29tcHJvYmFudGUgZmlzY2FsIGRpZ2l0YWwgcG9yIEludGVybmV0LiBObyBzZSBwZXJtaXRlbiB2YWxvcmVzIG5lZ2F0aXZvcy4gRXMgcmVxdWVyaWRvIGN1YW5kbyBlbiBsb3MgY29uY2VwdG9zIHNlIHJlZ2lzdHJlbiBpbXB1ZXN0b3MgcmV0ZW5pZG9zLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCQkJCTx4czphdHRyaWJ1dGUgbmFtZT0iVG90YWxJbXB1ZXN0b3NUcmFzbGFkYWRvcyIgdHlwZT0idGRDRkRJOnRfSW1wb3J0ZSIgdXNlPSJvcHRpb25hbCI+DQoJCQkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIGNvbmRpY2lvbmFsIHBhcmEgZXhwcmVzYXIgZWwgdG90YWwgZGUgbG9zIGltcHVlc3RvcyB0cmFzbGFkYWRvcyBxdWUgc2UgZGVzcHJlbmRlbiBkZSBsb3MgY29uY2VwdG9zIGV4cHJlc2Fkb3MgZW4gZWwgY29tcHJvYmFudGUgZmlzY2FsIGRpZ2l0YWwgcG9yIEludGVybmV0LiBObyBzZSBwZXJtaXRlbiB2YWxvcmVzIG5lZ2F0aXZvcy4gRXMgcmVxdWVyaWRvIGN1YW5kbyBlbiBsb3MgY29uY2VwdG9zIHNlIHJlZ2lzdHJlbiBpbXB1ZXN0b3MgdHJhc2xhZGFkb3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJCTwveHM6YXR0cmlidXRlPg0KCQkJCQk8L3hzOmNvbXBsZXhUeXBlPg0KCQkJCTwveHM6ZWxlbWVudD4NCgkJCQk8eHM6ZWxlbWVudCBuYW1lPSJDb21wbGVtZW50byIgbWluT2NjdXJzPSIwIj4NCgkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIGRvbmRlIHNlIGluY2x1eWUgZWwgY29tcGxlbWVudG8gVGltYnJlIEZpc2NhbCBEaWdpdGFsIGRlIG1hbmVyYSBvYmxpZ2F0b3JpYSB5IGxvcyBub2RvcyBjb21wbGVtZW50YXJpb3MgZGV0ZXJtaW5hZG9zIHBvciBlbCBTQVQsIGRlIGFjdWVyZG8gY29uIGxhcyBkaXNwb3NpY2lvbmVzIHBhcnRpY3VsYXJlcyBwYXJhIHVuIHNlY3RvciBvIGFjdGl2aWRhZCBlc3BlY8OtZmljYS48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmNvbXBsZXhUeXBlPg0KCQkJCQkJPHhzOnNlcXVlbmNlPg0KCQkJCQkJCTx4czphbnkgbWluT2NjdXJzPSIwIiBtYXhPY2N1cnM9InVuYm91bmRlZCIvPg0KCQkJCQkJPC94czpzZXF1ZW5jZT4NCgkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQk8L3hzOmVsZW1lbnQ+DQoJCQkJPHhzOmVsZW1lbnQgbmFtZT0iQWRkZW5kYSIgbWluT2NjdXJzPSIwIj4NCgkJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5Ob2RvIG9wY2lvbmFsIHBhcmEgcmVjaWJpciBsYXMgZXh0ZW5zaW9uZXMgYWwgcHJlc2VudGUgZm9ybWF0byBxdWUgc2VhbiBkZSB1dGlsaWRhZCBhbCBjb250cmlidXllbnRlLiBQYXJhIGxhcyByZWdsYXMgZGUgdXNvIGRlbCBtaXNtbywgcmVmZXJpcnNlIGFsIGZvcm1hdG8gb3JpZ2VuLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6Y29tcGxleFR5cGU+DQoJCQkJCQk8eHM6c2VxdWVuY2U+DQoJCQkJCQkJPHhzOmFueSBtYXhPY2N1cnM9InVuYm91bmRlZCIvPg0KCQkJCQkJPC94czpzZXF1ZW5jZT4NCgkJCQkJPC94czpjb21wbGV4VHlwZT4NCgkJCQk8L3hzOmVsZW1lbnQ+DQoJCQk8L3hzOnNlcXVlbmNlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJWZXJzaW9uIiB1c2U9InJlcXVpcmVkIiBmaXhlZD0iNC4wIj4NCgkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIGNvbiB2YWxvciBwcmVmaWphZG8gYSA0LjAgcXVlIGluZGljYSBsYSB2ZXJzacOzbiBkZWwgZXN0w6FuZGFyIGJham8gZWwgcXVlIHNlIGVuY3VlbnRyYSBleHByZXNhZG8gZWwgY29tcHJvYmFudGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOnN0cmluZyI+DQoJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iU2VyaWUiIHVzZT0ib3B0aW9uYWwiPg0KCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBvcGNpb25hbCBwYXJhIHByZWNpc2FyIGxhIHNlcmllIHBhcmEgY29udHJvbCBpbnRlcm5vIGRlbCBjb250cmlidXllbnRlLiBFc3RlIGF0cmlidXRvIGFjZXB0YSB1bmEgY2FkZW5hIGRlIGNhcmFjdGVyZXMuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOnN0cmluZyI+DQoJCQkJCQk8eHM6bWluTGVuZ3RoIHZhbHVlPSIxIi8+DQoJCQkJCQk8eHM6bWF4TGVuZ3RoIHZhbHVlPSIyNSIvPg0KCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCQk8eHM6cGF0dGVybiB2YWx1ZT0iW158XXsxLDI1fSIvPg0KCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJGb2xpbyIgdXNlPSJvcHRpb25hbCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIG9wY2lvbmFsIHBhcmEgY29udHJvbCBpbnRlcm5vIGRlbCBjb250cmlidXllbnRlIHF1ZSBleHByZXNhIGVsIGZvbGlvIGRlbCBjb21wcm9iYW50ZSwgYWNlcHRhIHVuYSBjYWRlbmEgZGUgY2FyYWN0ZXJlcy48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjQwIi8+DQoJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbXnxdezEsNDB9Ii8+DQoJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJPC94czphdHRyaWJ1dGU+DQoJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkZlY2hhIiB0eXBlPSJ0ZENGREk6dF9GZWNoYUgiIHVzZT0icmVxdWlyZWQiPg0KCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSBsYSBleHByZXNpw7NuIGRlIGxhIGZlY2hhIHkgaG9yYSBkZSBleHBlZGljacOzbiBkZWwgQ29tcHJvYmFudGUgRmlzY2FsIERpZ2l0YWwgcG9yIEludGVybmV0LiBTZSBleHByZXNhIGVuIGxhIGZvcm1hIEFBQUEtTU0tRERUaGg6bW06c3MgeSBkZWJlIGNvcnJlc3BvbmRlciBjb24gbGEgaG9yYSBsb2NhbCBkb25kZSBzZSBleHBpZGUgZWwgY29tcHJvYmFudGUuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJTZWxsbyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGNvbnRlbmVyIGVsIHNlbGxvIGRpZ2l0YWwgZGVsIGNvbXByb2JhbnRlIGZpc2NhbCwgYWwgcXVlIGhhY2VuIHJlZmVyZW5jaWEgbGFzIHJlZ2xhcyBkZSByZXNvbHVjacOzbiBtaXNjZWzDoW5lYSB2aWdlbnRlLiBFbCBzZWxsbyBkZWJlIHNlciBleHByZXNhZG8gY29tbyB1bmEgY2FkZW5hIGRlIHRleHRvIGVuIGZvcm1hdG8gQmFzZSA2NC48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJGb3JtYVBhZ28iIHR5cGU9ImNhdENGREk6Y19Gb3JtYVBhZ28iIHVzZT0ib3B0aW9uYWwiPg0KCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBjb25kaWNpb25hbCBwYXJhIGV4cHJlc2FyIGxhIGNsYXZlIGRlIGxhIGZvcm1hIGRlIHBhZ28gZGUgbG9zIGJpZW5lcyBvIHNlcnZpY2lvcyBhbXBhcmFkb3MgcG9yIGVsIGNvbXByb2JhbnRlLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQk8L3hzOmFubm90YXRpb24+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iTm9DZXJ0aWZpY2FkbyIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGV4cHJlc2FyIGVsIG7Dum1lcm8gZGUgc2VyaWUgZGVsIGNlcnRpZmljYWRvIGRlIHNlbGxvIGRpZ2l0YWwgcXVlIGFtcGFyYSBhbCBjb21wcm9iYW50ZSwgZGUgYWN1ZXJkbyBjb24gZWwgYWN1c2UgY29ycmVzcG9uZGllbnRlIGEgMjAgcG9zaWNpb25lcyBvdG9yZ2FkbyBwb3IgZWwgc2lzdGVtYSBkZWwgU0FULjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQk8L3hzOmFubm90YXRpb24+DQoJCQkJPHhzOnNpbXBsZVR5cGU+DQoJCQkJCTx4czpyZXN0cmljdGlvbiBiYXNlPSJ4czpzdHJpbmciPg0KCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJPC94czphdHRyaWJ1dGU+DQoJCQk8eHM6YXR0cmlidXRlIG5hbWU9IkNlcnRpZmljYWRvIiB1c2U9InJlcXVpcmVkIj4NCgkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHF1ZSBzaXJ2ZSBwYXJhIGluY29ycG9yYXIgZWwgY2VydGlmaWNhZG8gZGUgc2VsbG8gZGlnaXRhbCBxdWUgYW1wYXJhIGFsIGNvbXByb2JhbnRlLCBjb21vIHRleHRvIGVuIGZvcm1hdG8gYmFzZSA2NC48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQk8L3hzOnJlc3RyaWN0aW9uPg0KCQkJCTwveHM6c2ltcGxlVHlwZT4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJDb25kaWNpb25lc0RlUGFnbyIgdXNlPSJvcHRpb25hbCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIGNvbmRpY2lvbmFsIHBhcmEgZXhwcmVzYXIgbGFzIGNvbmRpY2lvbmVzIGNvbWVyY2lhbGVzIGFwbGljYWJsZXMgcGFyYSBlbCBwYWdvIGRlbCBjb21wcm9iYW50ZSBmaXNjYWwgZGlnaXRhbCBwb3IgSW50ZXJuZXQuIEVzdGUgYXRyaWJ1dG8gcHVlZGUgc2VyIGNvbmRpY2lvbmFkbyBtZWRpYW50ZSBhdHJpYnV0b3MgbyBjb21wbGVtZW50b3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOnN0cmluZyI+DQoJCQkJCQk8eHM6d2hpdGVTcGFjZSB2YWx1ZT0iY29sbGFwc2UiLz4NCgkJCQkJCTx4czptaW5MZW5ndGggdmFsdWU9IjEiLz4NCgkJCQkJCTx4czptYXhMZW5ndGggdmFsdWU9IjEwMDAiLz4NCgkJCQkJCTx4czpwYXR0ZXJuIHZhbHVlPSJbXnxdezEsMTAwMH0iLz4NCgkJCQkJPC94czpyZXN0cmljdGlvbj4NCgkJCQk8L3hzOnNpbXBsZVR5cGU+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iU3ViVG90YWwiIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0icmVxdWlyZWQiPg0KCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byByZXF1ZXJpZG8gcGFyYSByZXByZXNlbnRhciBsYSBzdW1hIGRlIGxvcyBpbXBvcnRlcyBkZSBsb3MgY29uY2VwdG9zIGFudGVzIGRlIGRlc2N1ZW50b3MgZSBpbXB1ZXN0by4gTm8gc2UgcGVybWl0ZW4gdmFsb3JlcyBuZWdhdGl2b3MuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJEZXNjdWVudG8iIHR5cGU9InRkQ0ZESTp0X0ltcG9ydGUiIHVzZT0ib3B0aW9uYWwiPg0KCQkJCTx4czphbm5vdGF0aW9uPg0KCQkJCQk8eHM6ZG9jdW1lbnRhdGlvbj5BdHJpYnV0byBjb25kaWNpb25hbCBwYXJhIHJlcHJlc2VudGFyIGVsIGltcG9ydGUgdG90YWwgZGUgbG9zIGRlc2N1ZW50b3MgYXBsaWNhYmxlcyBhbnRlcyBkZSBpbXB1ZXN0b3MuIE5vIHNlIHBlcm1pdGVuIHZhbG9yZXMgbmVnYXRpdm9zLiBTZSBkZWJlIHJlZ2lzdHJhciBjdWFuZG8gZXhpc3RhbiBjb25jZXB0b3MgY29uIGRlc2N1ZW50by48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJPC94czphdHRyaWJ1dGU+DQoJCQk8eHM6YXR0cmlidXRlIG5hbWU9Ik1vbmVkYSIgdHlwZT0iY2F0Q0ZESTpjX01vbmVkYSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGlkZW50aWZpY2FyIGxhIGNsYXZlIGRlIGxhIG1vbmVkYSB1dGlsaXphZGEgcGFyYSBleHByZXNhciBsb3MgbW9udG9zLCBjdWFuZG8gc2UgdXNhIG1vbmVkYSBuYWNpb25hbCBzZSByZWdpc3RyYSBNWE4uIENvbmZvcm1lIGNvbiBsYSBlc3BlY2lmaWNhY2nDs24gSVNPIDQyMTcuPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJUaXBvQ2FtYmlvIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSByZXByZXNlbnRhciBlbCB0aXBvIGRlIGNhbWJpbyBGSVggY29uZm9ybWUgY29uIGxhIG1vbmVkYSB1c2FkYS4gRXMgcmVxdWVyaWRvIGN1YW5kbyBsYSBjbGF2ZSBkZSBtb25lZGEgZXMgZGlzdGludGEgZGUgTVhOIHkgZGUgWFhYLiBFbCB2YWxvciBkZWJlIHJlZmxlamFyIGVsIG7Dum1lcm8gZGUgcGVzb3MgbWV4aWNhbm9zIHF1ZSBlcXVpdmFsZW4gYSB1bmEgdW5pZGFkIGRlIGxhIGRpdmlzYSBzZcOxYWxhZGEgZW4gZWwgYXRyaWJ1dG8gbW9uZWRhLiBTaSBlbCB2YWxvciBlc3TDoSBmdWVyYSBkZWwgcG9yY2VudGFqZSBhcGxpY2FibGUgYSBsYSBtb25lZGEgdG9tYWRvIGRlbCBjYXTDoWxvZ28gY19Nb25lZGEsIGVsIGVtaXNvciBkZWJlIG9idGVuZXIgZGVsIFBBQyBxdWUgdmF5YSBhIHRpbWJyYXIgZWwgQ0ZESSwgZGUgbWFuZXJhIG5vIGF1dG9tw6F0aWNhLCB1bmEgY2xhdmUgZGUgY29uZmlybWFjacOzbiBwYXJhIHJhdGlmaWNhciBxdWUgZWwgdmFsb3IgZXMgY29ycmVjdG8gZSBpbnRlZ3JhciBkaWNoYSBjbGF2ZSBlbiBlbCBhdHJpYnV0byBDb25maXJtYWNpb24uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCQk8eHM6c2ltcGxlVHlwZT4NCgkJCQkJPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOmRlY2ltYWwiPg0KCQkJCQkJPHhzOmZyYWN0aW9uRGlnaXRzIHZhbHVlPSI2Ii8+DQoJCQkJCQk8eHM6bWluSW5jbHVzaXZlIHZhbHVlPSIwLjAwMDAwMSIvPg0KCQkJCQkJPHhzOndoaXRlU3BhY2UgdmFsdWU9ImNvbGxhcHNlIi8+DQoJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJPC94czphdHRyaWJ1dGU+DQoJCQk8eHM6YXR0cmlidXRlIG5hbWU9IlRvdGFsIiB0eXBlPSJ0ZENGREk6dF9JbXBvcnRlIiB1c2U9InJlcXVpcmVkIj4NCgkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgcmVwcmVzZW50YXIgbGEgc3VtYSBkZWwgc3VidG90YWwsIG1lbm9zIGxvcyBkZXNjdWVudG9zIGFwbGljYWJsZXMsIG3DoXMgbGFzIGNvbnRyaWJ1Y2lvbmVzIHJlY2liaWRhcyAoaW1wdWVzdG9zIHRyYXNsYWRhZG9zIC0gZmVkZXJhbGVzIHkvbyBsb2NhbGVzLCBkZXJlY2hvcywgcHJvZHVjdG9zLCBhcHJvdmVjaGFtaWVudG9zLCBhcG9ydGFjaW9uZXMgZGUgc2VndXJpZGFkIHNvY2lhbCwgY29udHJpYnVjaW9uZXMgZGUgbWVqb3JhcykgbWVub3MgbG9zIGltcHVlc3RvcyByZXRlbmlkb3MgZmVkZXJhbGVzIHkvbyBsb2NhbGVzLiBTaSBlbCB2YWxvciBlcyBzdXBlcmlvciBhbCBsw61taXRlIHF1ZSBlc3RhYmxlemNhIGVsIFNBVCBlbiBsYSBSZXNvbHVjacOzbiBNaXNjZWzDoW5lYSBGaXNjYWwgdmlnZW50ZSwgZWwgZW1pc29yIGRlYmUgb2J0ZW5lciBkZWwgUEFDIHF1ZSB2YXlhIGEgdGltYnJhciBlbCBDRkRJLCBkZSBtYW5lcmEgbm8gYXV0b23DoXRpY2EsIHVuYSBjbGF2ZSBkZSBjb25maXJtYWNpw7NuIHBhcmEgcmF0aWZpY2FyIHF1ZSBlbCB2YWxvciBlcyBjb3JyZWN0byBlIGludGVncmFyIGRpY2hhIGNsYXZlIGVuIGVsIGF0cmlidXRvIENvbmZpcm1hY2lvbi4gTm8gc2UgcGVybWl0ZW4gdmFsb3JlcyBuZWdhdGl2b3MuIDwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQk8L3hzOmFubm90YXRpb24+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iVGlwb0RlQ29tcHJvYmFudGUiIHR5cGU9ImNhdENGREk6Y19UaXBvRGVDb21wcm9iYW50ZSIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGV4cHJlc2FyIGxhIGNsYXZlIGRlbCBlZmVjdG8gZGVsIGNvbXByb2JhbnRlIGZpc2NhbCBwYXJhIGVsIGNvbnRyaWJ1eWVudGUgZW1pc29yLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQk8L3hzOmFubm90YXRpb24+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iRXhwb3J0YWNpb24iIHR5cGU9ImNhdENGREk6Y19FeHBvcnRhY2lvbiIgdXNlPSJyZXF1aXJlZCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIHJlcXVlcmlkbyBwYXJhIGV4cHJlc2FyIHNpIGVsIGNvbXByb2JhbnRlIGFtcGFyYSB1bmEgb3BlcmFjacOzbiBkZSBleHBvcnRhY2nDs24uPC94czpkb2N1bWVudGF0aW9uPg0KCQkJCTwveHM6YW5ub3RhdGlvbj4NCgkJCTwveHM6YXR0cmlidXRlPg0KCQkJPHhzOmF0dHJpYnV0ZSBuYW1lPSJNZXRvZG9QYWdvIiB0eXBlPSJjYXRDRkRJOmNfTWV0b2RvUGFnbyIgdXNlPSJvcHRpb25hbCI+DQoJCQkJPHhzOmFubm90YXRpb24+DQoJCQkJCTx4czpkb2N1bWVudGF0aW9uPkF0cmlidXRvIGNvbmRpY2lvbmFsIHBhcmEgcHJlY2lzYXIgbGEgY2xhdmUgZGVsIG3DqXRvZG8gZGUgcGFnbyBxdWUgYXBsaWNhIHBhcmEgZXN0ZSBjb21wcm9iYW50ZSBmaXNjYWwgZGlnaXRhbCBwb3IgSW50ZXJuZXQsIGNvbmZvcm1lIGFsIEFydMOtY3VsbyAyOS1BIGZyYWNjacOzbiBWSUkgaW5jaXNvcyBhIHkgYiBkZWwgQ0ZGLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQk8L3hzOmFubm90YXRpb24+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iTHVnYXJFeHBlZGljaW9uIiB0eXBlPSJjYXRDRkRJOmNfQ29kaWdvUG9zdGFsIiB1c2U9InJlcXVpcmVkIj4NCgkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gcmVxdWVyaWRvIHBhcmEgaW5jb3Jwb3JhciBlbCBjw7NkaWdvIHBvc3RhbCBkZWwgbHVnYXIgZGUgZXhwZWRpY2nDs24gZGVsIGNvbXByb2JhbnRlIChkb21pY2lsaW8gZGUgbGEgbWF0cml6IG8gZGUgbGEgc3VjdXJzYWwpLjwveHM6ZG9jdW1lbnRhdGlvbj4NCgkJCQk8L3hzOmFubm90YXRpb24+DQoJCQk8L3hzOmF0dHJpYnV0ZT4NCgkJCTx4czphdHRyaWJ1dGUgbmFtZT0iQ29uZmlybWFjaW9uIiB1c2U9Im9wdGlvbmFsIj4NCgkJCQk8eHM6YW5ub3RhdGlvbj4NCgkJCQkJPHhzOmRvY3VtZW50YXRpb24+QXRyaWJ1dG8gY29uZGljaW9uYWwgcGFyYSByZWdpc3RyYXIgbGEgY2xhdmUgZGUgY29uZmlybWFjacOzbiBxdWUgZW50cmVndWUgZWwgUEFDIHBhcmEgZXhwZWRpciBlbCBjb21wcm9iYW50ZSBjb24gaW1wb3J0ZXMgZ3JhbmRlcywgY29uIHVuIHRpcG8gZGUgY2FtYmlvIGZ1ZXJhIGRlbCByYW5nbyBlc3RhYmxlY2lkbyBvIGNvbiBhbWJvcyBjYXNvcy4gRXMgcmVxdWVyaWRvIGN1YW5kbyBzZSByZWdpc3RyYSB1biB0aXBvIGRlIGNhbWJpbyBvIHVuIHRvdGFsIGZ1ZXJhIGRlbCByYW5nbyBlc3RhYmxlY2lkby48L3hzOmRvY3VtZW50YXRpb24+DQoJCQkJPC94czphbm5vdGF0aW9uPg0KCQkJCTx4czpzaW1wbGVUeXBlPg0KCQkJCQk8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCgkJCQkJCTx4czp3aGl0ZVNwYWNlIHZhbHVlPSJjb2xsYXBzZSIvPg0KCQkJCQkJPHhzOmxlbmd0aCB2YWx1ZT0iNSIvPg0KCQkJCQkJPHhzOnBhdHRlcm4gdmFsdWU9IlswLTlhLXpBLVpdezV9Ii8+DQoJCQkJCTwveHM6cmVzdHJpY3Rpb24+DQoJCQkJPC94czpzaW1wbGVUeXBlPg0KCQkJPC94czphdHRyaWJ1dGU+DQoJCTwveHM6Y29tcGxleFR5cGU+DQoJPC94czplbGVtZW50Pg0KPC94czpzY2hlbWE+DQo=</field>
+    </record>
+
+    <!-- PDF move report definition -->
+    <record id="ir_actions_report_pdf_account_move_cfdi" model="ir.actions.report">
+        <field name="name">Account Move CFDI PDF</field>
+        <field name="model">account.move</field>
+        <field name="report_type">aeroo</field>
+        <field name="report_name">l10n_mx_facturae.account_move_template_cfdi_pdf</field>
+        <field name="tml_source">file</field>
+        <field name="report_file">l10n_mx_facturae/report/account_move.odt</field>
+        <field name="in_format">oo-odt</field>
+        <field name="out_format" ref="report_aeroo.report_mimetypes_pdf_odt"/>
+        <field name="parser_model">report.l10n_mx_facturae.account_move</field>
+        <field name="styles_mode">default</field>
+        <field name="preload_mode">static</field>
+        <field name="deferred">off</field>
+    </record>
+</odoo>
diff --git a/l10n_mx_facturae/data/account_payment.xml b/l10n_mx_facturae/data/account_payment.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f2d4733197eb5ed90bcf2bd5c21a5c9e37d5ad60
--- /dev/null
+++ b/l10n_mx_facturae/data/account_payment.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+    <!-- XML payment report definition -->
+    <record id="ir_actions_report_xml_account_payment_cfdi" model="ir.actions.report">
+        <field name="name">Account Payment CFDI XML</field>
+        <field name="model">account.payment</field>
+        <field name="report_type">qweb-xml</field>
+        <field name="report_name">l10n_mx_facturae.account_payment</field>
+        <field name="xml_declaration">true</field>
+        <field name="xsd_schema"></field>
+    </record>
+
+    <!-- PDF payment report definition -->
+    <record id="ir_actions_report_pdf_account_payment_cfdi" model="ir.actions.report">
+        <field name="name">Account Payment CFDI PDF</field>
+        <field name="model">account.payment</field>
+        <field name="report_type">aeroo</field>
+        <field name="report_name">l10n_mx_facturae.account_payment_template_cfdi_pdf</field>
+        <field name="tml_source">file</field>
+        <field name="report_file">l10n_mx_facturae/report/account_payment.odt</field>
+        <field name="in_format">oo-odt</field>
+        <field name="out_format" ref="report_aeroo.report_mimetypes_pdf_odt"/>
+        <field name="parser_model">report.l10n_mx_facturae.account_payment</field>
+        <field name="styles_mode">default</field>
+        <field name="preload_mode">static</field>
+        <field name="deferred">off</field>
+    </record>
+
+</odoo>
diff --git a/l10n_mx_facturae/data/account_voucher.xml b/l10n_mx_facturae/data/account_voucher.xml
deleted file mode 100644
index 0ac23e61480099dbd0e104e9af5679e42f5dc6ac..0000000000000000000000000000000000000000
--- a/l10n_mx_facturae/data/account_voucher.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
-<data>
-
-    <!-- XML voucher report definition -->
-    <record id="report_templates_aeroo_account_voucher_cfdi"
-        model="report.templates.aeroo">
-        <field name="name">Account Voucher CFDI XML</field>
-        <field name="model">account.voucher</field>
-        <field name="report_name">account.voucher.cfdi.xml</field>
-        <field
-            name="report_rml">l10n_mx_facturae/templates/account_voucher.txt</field>
-    </record>
-
-    <record id="ir_actions_report_xml_account_voucher_cfdi"
-        model="ir.actions.report.xml">
-        <field name="name">Account Voucher CFDI XML</field>
-        <field name="type">ir.actions.report.xml</field>
-        <field name="model">account.voucher</field>
-        <field name="report_name">account.voucher.cfdi.xml</field>
-        <field name="report_type">aeroo</field>
-        <field name="in_format">genshi-raw</field>
-        <field name="out_format" ref="report_aeroo.report_mimetypes_raw" />
-        <field name="aeroo_templates_ids"
-            eval="[(6, 0, [report_templates_aeroo_account_voucher_cfdi])]" />
-        <field name="parser_state">default</field>
-    </record>
-
-</data>
-
-<data noupdate="1">
-
-    <!-- PDF voucher report definition -->
-    <record id="report_templates_aeroo_account_voucher_pdf_cfdi"
-        model="report.templates.aeroo">
-        <field name="name">Default Voucher CFDI PDF</field>
-        <field name="model">account.voucher</field>
-        <field name="report_name">account.voucher.cfdi.pdf</field>
-        <field name="report_rml">l10n_mx_facturae/report/account_voucher.odt</field>
-    </record>
-
-    <record id="ir_actions_report_pdf_account_voucher_cfdi"
-        model="ir.actions.report.xml">
-        <field name="name">Account Voucher CFDI PDF</field>
-        <field name="type">ir.actions.report.xml</field>
-        <field name="model">account.voucher</field>
-        <field name="report_name">account.voucher.cfdi.pdf</field>
-        <field name="report_type">aeroo</field>
-        <field name="in_format">oo-odt</field>
-        <field name="out_format" ref="report_aeroo.report_mimetypes_pdf_odt" />
-        <field name="aeroo_templates_ids"
-            eval="[(6, 0, [report_templates_aeroo_account_voucher_pdf_cfdi])]" />
-        <field name="parser_loc">l10n_mx_ir_attachment_facturae/report/generate_qr.py</field>
-        <field name="parser_state">loc</field>
-    </record>
-
-</data>
-</openerp>
diff --git a/l10n_mx_facturae/data/email_template.xml b/l10n_mx_facturae/data/email_template.xml
index 3d534e910ddc5b7ef05ffc4561afcbe3142517fe..64aad2a1ae48f7f2c2052d186df328ea1c6a7633 100644
--- a/l10n_mx_facturae/data/email_template.xml
+++ b/l10n_mx_facturae/data/email_template.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" ?>
-<openerp>
+<odoo>
     <!-- Mail template are declared in a NOUPDATE block
          so users can freely customize/delete them -->
     <data noupdate="1">
         <!--Email template -->
-        <record id="account_voucher_cfdi_email_template" model="email.template">
+        <record id="account_payment_cfdi_email_template" model="email.template">
             <field name="name">Electronic Payment Receipt</field>
             <field name="subject">${object.company_id.name|safe} Payment (Ref ${object.number or 'n/a'})</field>
             <field name="partner_to">${object.partner_id.id}</field>
-            <field name="model_id" ref="account_voucher.model_account_voucher"/>
+            <field name="model_id" ref="account_payment.model_account_payment"/>
             <field name="auto_delete" eval="True"/>
             <field name="lang">${object.partner_id.lang}</field>
             <field name="body_html"><![CDATA[
@@ -65,4 +65,4 @@
             ]]></field>
         </record>
     </data>
-</openerp>
+</odoo>
diff --git a/l10n_mx_facturae/data/facturae_data.xml b/l10n_mx_facturae/data/facturae_data.xml
index 2f0a3e6c000656d4a45af5b1cd4445856ef04fe7..c64076bb004fde29392768f9167479bf2d6ea3b7 100644
--- a/l10n_mx_facturae/data/facturae_data.xml
+++ b/l10n_mx_facturae/data/facturae_data.xml
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<openerp>
-<data noupdate="0">
+<odoo>
 
     <record id="group_cfdi_custom_number" model="res.groups">
         <field name="name">CFDI Custom Number</field>
         <field name="category_id" ref="base.module_category_accounting_and_finance"/>
     </record>
 
-</data>
-</openerp>
+
+</odoo>
diff --git a/l10n_mx_facturae/data/ir_attachment_facturae_config.xml b/l10n_mx_facturae/data/ir_attachment_facturae_config.xml
index bbde0be4411965c51a65df1359f7af05e1fe3e58..45397483037e90a0ce92c1a8e8a1f0464bc9de83 100644
--- a/l10n_mx_facturae/data/ir_attachment_facturae_config.xml
+++ b/l10n_mx_facturae/data/ir_attachment_facturae_config.xml
@@ -1,28 +1,26 @@
 <?xml version="1.0"?>
-<openerp>
-<data noupdate="1">
+<odoo>
 
-    <record id="ir_attachment_facturae_mx_config_account_invoice"
+    <record id="ir_attachment_facturae_mx_config_account_move"
         model="ir.attachment.facturae.mx.config">
-        <field name="model">account.invoice</field>
+        <field name="model">account.move</field>
         <field name="version">4.0</field>
-        <field name="template_xml_sign">account.invoice.cfdi.xml</field>
+        <field name="template_xml_sign">l10n_mx_facturae.account_move</field>
         <field name="template_xml_cancel">Aun.no.hay.uno</field>
-        <field name="template_pdf_sign">invoice.report.aaero.pdf</field>
-        <field name="template_pdf_cancel">invoice.report.aaero.pdf</field>
-        <field name="email_template_id" ref="account.email_template_edi_invoice"/>
+        <field name="template_pdf_sign">l10n_mx_facturae.account_move_template_cfdi_pdf</field>
+        <field name="template_pdf_cancel">l10n_mx_facturae.account_move_template_cfdi_pdf</field>
+        <!--<field name="mail_template_id" ref="account.email_template_edi_invoice"/>-->
     </record>
 
-    <record id="ir_attachment_facturae_mx_config_account_voucher"
+    <record id="ir_attachment_facturae_mx_config_account_payment"
         model="ir.attachment.facturae.mx.config">
-        <field name="model">account.voucher</field>
+        <field name="model">account.payment</field>
         <field name="version">4.0</field>
-        <field name="template_xml_sign">account.voucher.cfdi.xml</field>
+        <field name="template_xml_sign">l10n_mx_facturae.account_payment</field>
         <field name="template_xml_cancel">Aun.no.hay.uno</field>
-        <field name="template_pdf_sign">account.voucher.cfdi.pdf</field>
-        <field name="template_pdf_cancel">account.voucher.cfdi.pdf</field>
-        <field name="email_template_id" ref="account_voucher_cfdi_email_template"/>
+        <field name="template_pdf_sign">l10n_mx_facturae.account_payment_template_cfdi_pdf</field>
+        <field name="template_pdf_cancel"><!--l10n_mx_facturae.account_payment_template_cfdi_pdf--></field>
+        <!--<field name="mail_template_id" ref="account_payment_cfdi_email_template"/>-->
     </record>
 
-</data>
-</openerp>
+</odoo>
diff --git a/l10n_mx_facturae/data/ir_cron.xml b/l10n_mx_facturae/data/ir_cron.xml
index 976b588bbdd2c35b877b443728b3b76f18123d19..ccda338b1d467bdc0776dc9e184895c14e71a6fe 100644
--- a/l10n_mx_facturae/data/ir_cron.xml
+++ b/l10n_mx_facturae/data/ir_cron.xml
@@ -1,16 +1,12 @@
 <?xml version="1.0" encoding='UTF-8'?>
-<openerp>
-    <data noupdate="1">
-        <record model="ir.cron" id="ir_cron_invoices_pending_to_cancel">
-           <field name="name">Invoices pending to cancel</field>
-           <field name="interval_number">2</field>
-           <field name="interval_type">hours</field>
-           <field name="numbercall">-1</field>
-           <field name="model" eval="'account.invoice'"/>
-           <field name="function" eval="'cron_invoices_pending_to_cancel'"/>
-           <field name="args" eval="'()'"/>
-           <field name="active" eval="True" />
-        </record>
-    </data>
-</openerp>
-
+<odoo noupdate="1">
+    <record model="ir.cron" id="ir_cron_invoices_pending_to_cancel">
+        <field name="name">Invoices pending to cancel</field>
+        <field name="interval_number">2</field>
+        <field name="interval_type">hours</field>
+        <field name="numbercall">-1</field>
+        <field name="model_name">l10n_mx_base.model_account_move</field>
+        <!--<field name="function" eval="cron_invoices_pending_to_cancel"/>-->
+        <field name="active" eval="True" />
+    </record>
+</odoo>
diff --git a/l10n_mx_facturae/data/res_partner.xml b/l10n_mx_facturae/data/res_partner.xml
new file mode 100644
index 0000000000000000000000000000000000000000..547f322a97ffdab30f8e5cb0d7aced3b79389f64
--- /dev/null
+++ b/l10n_mx_facturae/data/res_partner.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+    <record id="res_partner_public_general" model="res.partner">
+        <field name="name">Publico en general</field>
+        <field name="is_company">1</field>
+        <field name="street">45 10 oriente</field>
+        <field name="city">Culiacán</field>
+        <field name="state_id" ref="base.state_mx_sin"/>
+        <field name="zip">80290</field>
+        <field name="vat">MXXAXX010101000</field>
+        <field name="phone">(870)-931-0505</field>
+        <field name="country_id" ref="base.mx"/>
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_616"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+        <field name="payment_method_id" ref="l10n_mx_base.cfdi_payment_method_1"/>
+    </record>
+
+</odoo>
diff --git a/l10n_mx_facturae/demo/demo_product.xml b/l10n_mx_facturae/demo/demo_product.xml
new file mode 100644
index 0000000000000000000000000000000000000000..839b077907094b6804600303f0f048098f0aad22
--- /dev/null
+++ b/l10n_mx_facturae/demo/demo_product.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+
+    <record id="product.product_product_7" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_27" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_16" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_3" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_9" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_20" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_5" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_8" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.consu_delivery_03" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_13" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_10" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_6" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.consu_delivery_02" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_24" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_delivery_02" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_25" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_delivery_01" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_12" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_order_01" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.consu_delivery_01" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+
+    <record id="product.product_product_22" model="product.product">
+        <field name="cfdi_product_service_id" ref="l10n_mx_base.56101700"/>
+    </record>
+</data>
+</odoo>
diff --git a/l10n_mx_facturae/demo/demo_res_partner.xml b/l10n_mx_facturae/demo/demo_res_partner.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2313354b9c8e92946527bf99f5ae98403b6b5185
--- /dev/null
+++ b/l10n_mx_facturae/demo/demo_res_partner.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+    <record id="res_partner_2023" model="res.partner">
+        <field name="name">Felix Manuel Andrade Ballado</field>
+        <field name="is_company">1</field>
+        <field name="street">4557 10 oriente</field>
+        <field name="city">Huimanguillo</field>
+        <field name="state_id" ref="base.state_mx_tab"/>
+        <field name="zip">86400</field>
+        <field name="vat">MXAABF800614HI0</field>
+        <field name="phone">(870)-931-0505</field>
+        <field name="country_id" ref="base.mx"/>
+        <field name="email">felix.andrade@example.com</field>
+        <field name="company_id" ref="l10n_mx.demo_company_mx"/>
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_616"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+        <field name="payment_method_id" ref="l10n_mx_base.cfdi_payment_method_1"/>
+    </record>
+
+    <record id="l10n_mx_ir_attachment_facturae.demo_partner_company_mx_frontier" model="res.partner">
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_601"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+    </record>
+
+    <function name="write" model="ir.model.data">
+        <function name="search" model="ir.model.data">
+            <value
+                eval="[
+                    ('module', '=', 'l10n_mx'), ('name', '=', 'partner_demo_company_mx'),
+                    ('module', '=', 'l10n_mx'), ('name', '=', 'demo_company_mx')
+                ]"
+            />
+        </function>
+        <value eval="{'noupdate': False}" />
+    </function>
+
+    <record id="l10n_mx.partner_demo_company_mx" model="res.partner">
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_601"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+    </record>
+
+    <record id="l10n_mx.demo_company_mx" model="res.company">
+        <field name="city">Jesus Maria</field>
+        <field name="state_id" ref="base.state_mx_ags"/>
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_601"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+    </record>
+
+    <record id="l10n_mx_ir_attachment_facturae.res_company_mx_frontier" model="res.company">
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_601"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+    </record>
+
+    <record id="res_partner_2024" model="res.partner">
+        <field name="name">Maria Olivia Martinez Sagaz</field>
+        <field name="is_company">1</field>
+        <field name="street">45 10 oriente</field>
+        <field name="city">Culiacán</field>
+        <field name="state_id" ref="base.state_mx_sin"/>
+        <field name="zip">80290</field>
+        <field name="vat">MXMASO451221PM4</field>
+        <field name="phone">(870)-931-0505</field>
+        <field name="country_id" ref="base.mx"/>
+        <field name="email">maria.martinez@example.com</field>
+        <field name="company_id" ref="l10n_mx_ir_attachment_facturae.res_company_mx_frontier"/>
+        <field name="cfdi_fiscal_regime_id" ref="l10n_mx_base.regime_fiscal_616"/>
+        <field name="cfdi_use_id" ref="l10n_mx_base.cfdi_use_S01"/>
+        <field name="payment_method_id" ref="l10n_mx_base.cfdi_payment_method_1"/>
+    </record>
+</data>
+</odoo>
diff --git a/l10n_mx_facturae/i18n/es_MX.po b/l10n_mx_facturae/i18n/es_MX.po
new file mode 100644
index 0000000000000000000000000000000000000000..460e0b6d950aea6a7598e0716cd5d12cffb8111f
--- /dev/null
+++ b/l10n_mx_facturae/i18n/es_MX.po
@@ -0,0 +1,628 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# 	* l10n_mx_facturae
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 15.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-04-25 23:00+0000\n"
+"PO-Revision-Date: 2024-04-25 18:02-0600\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: es_MX\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: \n"
+"X-Generator: Poedit 3.2.2\n"
+
+#. module: l10n_mx_facturae
+#: model:ir.actions.report,name:l10n_mx_facturae.ir_actions_report_pdf_account_move_cfdi
+msgid "Account Move CFDI PDF"
+msgstr "Traslado de cuenta CFDI PDF"
+
+#. module: l10n_mx_facturae
+#: model:ir.actions.report,name:l10n_mx_facturae.ir_actions_report_xml_account_move_cfdi
+msgid "Account Move CFDI XML"
+msgstr "Traslado de cuenta CFDI XML"
+
+#. module: l10n_mx_facturae
+#: model:ir.actions.report,name:l10n_mx_facturae.ir_actions_report_pdf_account_payment_cfdi
+msgid "Account Payment CFDI PDF"
+msgstr "Pago de cuenta CFDI PDF"
+
+#. module: l10n_mx_facturae
+#: model:ir.actions.report,name:l10n_mx_facturae.ir_actions_report_xml_account_payment_cfdi
+msgid "Account Payment CFDI XML"
+msgstr "Pago de cuenta CFDI XML"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.l10n_mx_facturae_res_partner_view_form
+msgid ""
+"Addends are used to add additional content to the invoice that  the SAT.\n"
+"                    An addendum contains information of a commercial, "
+"logistic and  operation,\n"
+"                    often required by the receiving company (client).\n"
+"                    <br/><br/>\n"
+"                    Once you have selected the addendum, you must add the "
+"necessary information\n"
+"                    in all or some of the following sections: Customers, "
+"suppliers, company,\n"
+"                    products, services, invoices or delivery notes\n"
+"                    <br/><br/>\n"
+"                    Done the necessary configurations, you will be able to "
+"stamp your invoices\n"
+"                    with the selected complement."
+msgstr ""
+"Los sumandos se utilizan para agregar contenido adicional a la factura que "
+"emite el SAT.\n"
+"                     Una adenda contiene información de carácter comercial, "
+"logístico y de operación,\n"
+"                     a menudo requerido por la empresa receptora "
+"(cliente).\n"
+"                     <br/>><br/>\n"
+"                     Una vez que hayas seleccionado la adenda, deberás "
+"agregar la información necesaria\n"
+"                     en todos o algunos de los siguientes apartados: "
+"Clientes, proveedores, empresa,\n"
+"                     productos, servicios, facturas o albaranes\n"
+"                     <br/>><br/>\n"
+"                     Realizadas las configuraciones necesarias, podrás "
+"sellar tus facturas\n"
+"                     con el complemento seleccionado."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_adenda_ids
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_adenda_ids
+msgid "Addendum"
+msgstr "Adenda"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__address_issued_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__address_issued_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__address_issued_id
+msgid "Address Issued Invoice"
+msgstr "Dirección Factura Emitida"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.l10n_mx_facturae_res_partner_view_form
+msgid "Adendas"
+msgstr "Adendas"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields.selection,name:l10n_mx_facturae.selection__account_move__cfdi_periodicity__03
+msgid "Biweekly"
+msgstr "Cada dos semanas"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_folio_fiscal
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_folio_fiscal
+msgid "CFD-I Folio Fiscal"
+msgstr "CFD-I Folio Fiscal"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_id
+msgid "CFDI"
+msgstr "CFDI"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__cfdi_adenda_ids
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__cfdi_adenda_ids
+msgid "CFDI Adendas"
+msgstr "CFDI Adendas"
+
+#. module: l10n_mx_facturae
+#: model:res.groups,name:l10n_mx_facturae.group_cfdi_custom_number
+msgid "CFDI Custom Number"
+msgstr "Número de Pedimento"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__cfdi_relation_type
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_relation_type
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_relation_type
+msgid "CFDI Relation type"
+msgstr "CFDI Tipo de relación"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__cfdi_id
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__cfdi_id
+msgid "CFDI related to the selected record"
+msgstr "CFDI relacionado con el registro seleccionado"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__cfdi_use
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_use
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_use
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__cfdi_use_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__cfdi_use_id
+msgid "CFDI use"
+msgstr "Uso de CFDI"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid ""
+"Can't post the entry %s, the related invoice is waiting for a request to "
+"cancel."
+msgstr ""
+"No se puede asentar la póliza %s, porque la factura relacionada esta "
+"esperando el resultado de una solicitud de cancelación."
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "Cancellation request sent"
+msgstr "Solicitud de cancelación enviada"
+
+#. module: l10n_mx_facturae
+#: model:res.groups,name:l10n_mx_facturae.cfdi_cuentapredial
+msgid "Cfdi Cuenta Predial"
+msgstr "Cuenta Predial"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_datetime
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_datetime
+msgid "Cfdi Datetime"
+msgstr "CFDI Fecha/hora"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__cfdi_periodicity
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_periodicity
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_periodicity
+msgid "Cfdi Periodicity"
+msgstr "CFDI Periodicidad"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_partner__cfdi_use_id
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_users__cfdi_use_id
+msgid ""
+"Cfdi usage that will be used by default on this customer invoices and "
+"credit notes"
+msgstr ""
+"Uso de CFDI que se utilizará por defecto en las facturas y notas de crédito "
+"de este cliente"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_res_company
+msgid "Companies"
+msgstr "Compañías"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_res_partner
+msgid "Contact"
+msgstr "Contacto"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "Could not check SAT invoice status due to the following error: %s."
+msgstr ""
+"No se ha podido comprobar el estado de la factura SAT debido al siguiente "
+"error: %s."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move_line__cfdi_cuentapredial
+msgid "Cuenta Predial"
+msgstr "Cuenta Predial"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_partner__gln_number
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_users__gln_number
+msgid "Customer or Delivery branch"
+msgstr "Cliente o sucursal de entrega"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields.selection,name:l10n_mx_facturae.selection__account_move__cfdi_periodicity__01
+msgid "Daily"
+msgstr "Diario"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__date_invoice_cancel
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__date_invoice_cancel
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__date_invoice_cancel
+msgid "Date Invoice Cancelled"
+msgstr "Fecha de cancelación de la factura"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__datetime
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__datetime
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__datetime
+msgid "Datetime"
+msgstr "Fecha y hora"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_form_customer
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_tree
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_payment_cfdi_view_form
+msgid "Fiscal Number"
+msgstr "Número Fiscal"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__cfdi_folio_fiscal
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__cfdi_folio_fiscal
+msgid "Folio used in the electronic invoice"
+msgstr "Folio utilizado en la factura electrónica"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__gln_number
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__gln_number
+msgid "GLN Number"
+msgstr "Número GLN"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__is_cfdi_candidate
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__is_cfdi_candidate
+msgid ""
+"Helper field to determine if document is CFDI candidate to show send PAC "
+"button on form view."
+msgstr ""
+"Campo auxiliar para determinar si el documento es candidato a CFDI para "
+"mostrar el botón enviar PAC en la vista del formulario."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__show_unreconcile
+msgid "Helper field to hide unreconcile button"
+msgstr "Campo de ayuda para ocultar el botón de irreconciliar"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move_line__cfdi_numero_identificacion
+msgid "Identification Number"
+msgstr "Número de identificación"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_bank_statement_line__date_invoice_cancel
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__date_invoice_cancel
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__date_invoice_cancel
+msgid "If the invoice is cancelled, save the date when was cancel"
+msgstr "Si la factura es cancelada, guarde la fecha cuando se canceló"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid ""
+"Incorrect tax sequence configuration, check this data in Account >> Tax >> "
+"Sequence"
+msgstr ""
+"Configuración incorrecta de la secuencia de impuestos, compruebe estos "
+"datos en Cuenta >> Impuestos >> Secuencia"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_search
+msgid "Invoices that being substituted and must be cancelled"
+msgstr "Facturas que se sustituyen y deben cancelarse"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_search
+msgid "Invoices to be signed"
+msgstr "Facturas por firmar"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__is_cfdi_candidate
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__is_cfdi_candidate
+msgid "Is Cfdi Candidate"
+msgstr "Es Candidato Cfdi"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_account_move
+msgid "Journal Entry"
+msgstr "Asiento de diario"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_account_move_line
+msgid "Journal Item"
+msgstr "Apunte contable"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__l10n_mx_edi_error
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__l10n_mx_edi_error
+msgid "L10N Mx Edi Error"
+msgstr "L10N Mx Edi Error"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__l10n_mx_edi_original_invoice
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__l10n_mx_edi_original_invoice
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__l10n_mx_edi_original_invoice
+msgid "L10N Mx Edi Original Invoice"
+msgstr "L10N Mx Edi Factura original"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__l10n_mx_edi_to_cancel
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__l10n_mx_edi_to_cancel
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__l10n_mx_edi_to_cancel
+msgid "L10N Mx Edi To Cancel"
+msgstr "L10N Mx Edi Para Cancelar"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__l10n_mx_export
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__l10n_mx_export
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__l10n_mx_export
+msgid "Merchandise export"
+msgstr "Exportación de mercancías"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "Missing SAT code for product: {product}"
+msgstr "Falta el código SAT para el producto: {producto}"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields.selection,name:l10n_mx_facturae.selection__account_move__cfdi_periodicity__04
+msgid "Monthly"
+msgstr "Mensualmente"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "No status update found on SAT"
+msgstr "No se ha encontrado ninguna actualización de estado en SAT"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_partner__supplier_number
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_users__supplier_number
+msgid "Number or reference that the Client assigned to our company."
+msgstr "Número o referencia que el Cliente asignó a nuestra empresa."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move_line__cfdi_custom_number
+msgid "N° Pediment"
+msgstr "N° Pedimento"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "Operation not supported"
+msgstr "Operación no admitida"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__related_cfdi_ids
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__related_cfdi_ids
+msgid "Original CFDI to which this CFDI is referred to"
+msgstr "CFDI original al que se refiere este CFDI"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_form_customer
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_payment_cfdi_view_form
+msgid "PAC State"
+msgstr "Estado PAC"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_bank_statement_line__payment_method_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__payment_method_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__payment_method_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__payment_method_id
+msgid "Payment Method"
+msgstr "Forma de pago"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_partner__payment_method_id
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_users__payment_method_id
+msgid ""
+"Payment method associated with this partner accordingto CFDI 4.0 catalog."
+msgstr "Forma de pago asociada a este socio de acuerdo al catálogo CFDI 4.0."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_bank_statement_line__payment_method_id
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__payment_method_id
+msgid "Payment method associated with this payment term according"
+msgstr "Método de pago asociado a este plazo de pago según"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_account_payment
+msgid "Payments"
+msgstr "Pagos"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid ""
+"Predial Account must be only numbers.\n"
+"All letters must be replaced by '0'"
+msgstr ""
+"La cuenta de premarcado debe ser solo numérica.\n"
+"Todas las letras deben sustituirse por \"0\"."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move_line__cfdi_cuentapredial
+msgid "Predial number for real state lease invoices"
+msgstr "Número predial para facturas de arrendamiento de inmuebles"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "Product {p} must have at least one tax selected."
+msgstr "El producto {p} debe tener al menos un impuesto seleccionado."
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_form_customer
+msgid "Related"
+msgstr "Relacionado"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__related_cfdi_ids
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__related_cfdi_ids
+msgid "Related Cfdi"
+msgstr "CFDI relacionado"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_form_customer
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_payment_cfdi_view_form
+msgid "Retry"
+msgstr "Reintentar"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__cfdi_adenda_ids
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__cfdi_adenda_ids
+msgid "Select addendum node to use on this CFDI."
+msgstr "Seleccione el nodo de adenda a utilizar en este CFDI."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__sequence_id
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__sequence_id
+msgid "Sequence"
+msgstr "Secuencia"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__show_edi
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__show_edi
+msgid "Show Edi"
+msgstr "Mostrar edición"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__show_glnnumber
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__show_glnnumber
+msgid "Show Glnnumber"
+msgstr "Mostrar número de registro"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__show_suppliernumber
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__show_suppliernumber
+msgid "Show Suppliernumber"
+msgstr "Mostrar número de proveedor"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__show_unreconcile
+msgid "Show Unreconcile"
+msgstr "Mostrar irreconciliar"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_payment_cfdi_view_form
+msgid "Sign"
+msgstr "Firma"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_payment.py:0
+#, python-format
+msgid ""
+"Some of the invoices that will be paid with this record are not signed, and "
+"the UUID is required to indicate the invoices that are paid with this CFDI "
+msgstr ""
+"Algunas de las facturas que se pagarán con este registro no están firmadas, "
+"y se requiere el UUID para indicar las facturas que se pagan con este CFDI"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__cfdi_state
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__cfdi_state
+msgid "State"
+msgstr "Estado"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__cfdi_state
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__cfdi_state
+msgid "State of attachments"
+msgstr "Estado de los archivos adjuntos"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_move__state
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_account_payment__state
+msgid "Status"
+msgstr "Estado"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__supplier_number
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__supplier_number
+msgid "Supplier Number"
+msgstr "Número de proveedor"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_bank_statement_line__l10n_mx_edi_to_cancel
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__l10n_mx_edi_to_cancel
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__l10n_mx_edi_to_cancel
+msgid ""
+"Technical field to display a warning when an invoice must be canceled "
+"because have being replaced by a new one."
+msgstr ""
+"Campo técnico para mostrar un aviso cuando una factura debe cancelarse "
+"porque ha sido sustituida por una nueva."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_bank_statement_line__l10n_mx_edi_original_invoice
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__l10n_mx_edi_original_invoice
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__l10n_mx_edi_original_invoice
+msgid "Technical field to relate origin invoice with substitute"
+msgstr "Campo técnico para relacionar la factura de origen con la sustituta"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid "The invoice could not be canceled"
+msgstr "La factura no se ha podido cancelar"
+
+#. module: l10n_mx_facturae
+#: model:res.groups,comment:l10n_mx_facturae.cfdi_cuentapredial
+msgid ""
+"The user will have access to add Cuenta Predial information to invoice "
+"lines."
+msgstr ""
+"El usuario tendrá acceso al campo para la Cuenta Predial en las líneas de "
+"las facturas."
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_bank_statement_line__address_issued_id
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move__address_issued_id
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_payment__address_issued_id
+msgid ""
+"This address will be used as address that issued for electronic invoice"
+msgstr ""
+"Esta dirección se utilizará como dirección emitida para la factura "
+"electrónica"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_partner__cfdi_adenda_ids
+#: model:ir.model.fields,help:l10n_mx_facturae.field_res_users__cfdi_adenda_ids
+msgid "This field allows adding a node or addendum to the invoice"
+msgstr "Este campo permite agregar un nodo o adenda a la factura"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#, python-format
+msgid ""
+"This invoice must be cancelled because have being replaced with invoice: "
+msgstr ""
+"Esta factura debe cancelarse porque ha sido reemplazada por una factura: "
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,help:l10n_mx_facturae.field_account_move_line__cfdi_numero_identificacion
+msgid "This number is the identification number for invoice line in cfdi"
+msgstr ""
+"Este número es el número de identificación de la línea de factura en CFDI"
+
+#. module: l10n_mx_facturae
+#: code:addons/l10n_mx_facturae/models/account_move.py:0
+#: model:ir.model.fields.selection,name:l10n_mx_facturae.selection__account_move__state__waiting
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_search
+#, python-format
+msgid "To cancel"
+msgstr "A cancelar"
+
+#. module: l10n_mx_facturae
+#: model_terms:ir.ui.view,arch_db:l10n_mx_facturae.account_move_view_search
+msgid "To sign"
+msgstr "A firmar"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_company__cfdi_use_id
+msgid "Use CFDI"
+msgstr "Uso de CFDI"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_partner__edi
+#: model:ir.model.fields,field_description:l10n_mx_facturae.field_res_users__edi
+msgid "User EDI"
+msgstr "Usuario EDI"
+
+#. module: l10n_mx_facturae
+#: model:ir.model.fields.selection,name:l10n_mx_facturae.selection__account_move__cfdi_periodicity__02
+msgid "Weekly"
+msgstr "Semanal"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_report_l10n_mx_facturae_account_move
+msgid "report.l10n_mx_facturae.account_move"
+msgstr "report.l10n_mx_facturae.account_move"
+
+#. module: l10n_mx_facturae
+#: model:ir.model,name:l10n_mx_facturae.model_report_l10n_mx_facturae_account_payment
+msgid "report.l10n_mx_facturae.account_payment"
+msgstr "report.l10n_mx_facturae.account_payment"
diff --git a/l10n_mx_facturae/models/__init__.py b/l10n_mx_facturae/models/__init__.py
index cbde404e0d2ea99dc6b467faa78fd70566f1a74b..8d64c35b0c1a3a9b78dcf0f716b9296d67b58200 100644
--- a/l10n_mx_facturae/models/__init__.py
+++ b/l10n_mx_facturae/models/__init__.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 
-from . import account_invoice
 from . import account_move
-from . import account_voucher
-from . import email_template
+from . import account_payment
+#from . import email_template
+from . import res_company
 from . import res_partner
diff --git a/l10n_mx_facturae/models/account_invoice.py b/l10n_mx_facturae/models/account_invoice.py
deleted file mode 100644
index 294f08df6aaedeba15a29d3b9d09db892c182d08..0000000000000000000000000000000000000000
--- a/l10n_mx_facturae/models/account_invoice.py
+++ /dev/null
@@ -1,671 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import logging
-import pytz
-from datetime import datetime, timedelta
-
-from openerp import api, fields, models
-from openerp.exceptions import ValidationError, Warning as UserError
-from openerp.tools.float_utils import float_round
-from openerp.tools.translate import _
-
-
-_logger = logging.getLogger(__name__)
-
-
-class AccountInvoice(models.Model):
-    _name = "account.invoice"
-    _inherit = ["account.invoice", "base.cfdi"]
-
-    @property
-    def formapago(self):
-        """Return payment type for display on CFDI"""
-        self.ensure_one()
-        try:
-            code = self.payment_type_ids[0].code
-        except IndexError:
-            code = "99"
-        return code
-
-    @property
-    def descuento(self):
-        self.ensure_one()
-        discount = 0.0
-        for line in self.invoice_line:
-            discount += line.descuento
-        return discount
-
-    @property
-    def subtotal(self):
-        self.ensure_one()
-        subtotal = 0.0
-        for line in self.invoice_line:
-            subtotal += line.importe
-        return subtotal
-
-    @property
-    def total(self):
-        self.ensure_one()
-        return (
-            self.subtotal
-            - self.descuento
-            + self.impuestos["total_traslados"]
-            + self.impuestos["total_retenciones"]
-            + self.impuestos["total_locales"]
-        )
-
-    @property
-    def impuestos(self):
-        """Return computed taxes for display on CFDI"""
-        self.ensure_one()
-        tax_grouped = {}
-        taxes = {
-            "traslados": [],
-            "retenciones": [],
-            "locales": [],
-            "total_traslados": 0.0,
-            "total_retenciones": 0.0,
-            "total_locales": 0.0,
-        }
-
-        for line in self.invoice_line:
-            for tax in line.export_invoice_line_for_xml().taxes:
-                # Mimic logic from compute function in account.invoice.tax
-                # object to group taxes from invoice lines and be able to get
-                # the same result for display on CFDI
-                if self.type in ("out_invoice", "in_invoice"):
-                    tax.account_id = tax.account_collected_id or line.account_id.id
-                    tax.analytic_id = tax.account_analytic_collected_id
-                else:
-                    tax.account_id = tax.account_paid_id or line.account_id.id
-                    tax.analytic_id = tax.account_analytic_paid_id
-
-                key = (tax.id, tax.account_id, tax.analytic_id)
-                if key not in tax_grouped:
-                    tax_grouped[key] = tax
-                else:
-                    tax_grouped[key].amount += tax.amount
-                    tax_grouped[key].base += tax.base
-
-        # Classify taxes for CFDI
-        for dummy, tax in tax_grouped.items():
-            if tax.group in ["IVA", "IEPS", "ISR"]:
-                if tax.amount >= 0:
-                    taxes["traslados"].append(tax)
-                    taxes["total_traslados"] += tax.amount
-                else:
-                    taxes["retenciones"].append(tax)
-                    taxes["total_retenciones"] += tax.amount
-            else:
-                taxes["locales"].append(tax)
-                taxes["total_locales"] += tax.amount
-        return taxes
-
-    # pylint: disable=W0212
-    address_issued_id = fields.Many2one(
-        "res.partner",
-        "Address Issued Invoice",
-        readonly=True,
-        states={"draft": [("readonly", False)]},
-        help="This address will be used as address that issued "
-        "for electronic invoice",
-        compute="_compute_address_issued",
-    )
-    datetime = fields.Datetime(compute="_compute_datetime")
-    date_invoice_cancel = fields.Datetime(
-        "Date Invoice Cancelled",
-        readonly=True,
-        copy=False,
-        help="If the invoice is cancelled, save the date" " when was cancel",
-    )
-    payment_method_id = fields.Many2one(
-        "cfdi.payment.method",
-        string="Payment Method",
-        readonly=True,
-        states={"draft": [("readonly", False)]},
-        help="Payment method associated with this payment term according",
-    )
-    cfdi_use = fields.Many2one(
-        "cfdi.use", "CFDI use", readonly=True, states={"draft": [("readonly", False)]}
-    )
-    cfdi_relation_type = fields.Many2one("cfdi.relation.type", "CFDI Relation type")
-    state = fields.Selection(selection_add=[("waiting", _("To cancel"))])
-    l10n_mx_edi_to_cancel = fields.Char(
-        compute="_compute_l10n_mx_edi_to_cancel",
-        search="_search_l10n_mx_edi_to_cancel",
-        help="Technical field to display a warning when an invoice must be canceled "
-        "because have being replaced by a new one.",
-    )
-    l10n_mx_edi_original_invoice = fields.Many2one(
-        "account.invoice",
-        compute="_compute_l10n_mx_edi_to_cancel",
-        help="Technical field to relate origin invoice with substitute",
-    )
-    cfdi_periodicity = fields.Selection(
-        [
-            ("01", "Daily"),
-            ("02", "Weekly"),
-            ("03", "Biweekly"),
-            ("04", "Monthly"),
-        ],
-        default="04",
-    )
-
-    l10n_mx_export = fields.Boolean(
-        compute="_compute_export",
-        string="Merchandise export"
-    )
-
-    @api.multi
-    @api.depends("company_id")
-    def _compute_is_cfdi_candidate(self):
-        mexico = self.env.ref("base.mx")
-        for record in self:
-            record.is_cfdi_candidate = bool(record.company_id.country_id == mexico)
-
-    @api.multi
-    def _get_cfdi_datetime(self):
-        """This base function inherits the creation of the cfdi datetime
-        what it basically does is respect the date_invoice from invoice form
-        """
-        self.ensure_one()
-        date_invoice = fields.Datetime.from_string(self.date_invoice)
-        time_now = fields.Datetime.context_timestamp(self, datetime.now())
-        # If we are singing an invoice in the past we need to move forward 1 minute the
-        # computed time to be in the 72 hours range defined by SAT
-        # On the opposite if we are singing an invoice for today we move back 1 minute
-        # the computed time to prevent false errors about being out of 72 hours range
-        if date_invoice.date() < time_now.date():
-            time_now += timedelta(minutes=1)
-        else:
-            time_now -= timedelta(minutes=1)
-        date_create = datetime.combine(date_invoice, time_now.timetz())
-        # Needed to save date into the database as until now we are using user timezone
-        # to express the datetime that will cause double timezone conversion if kept
-        date_create = date_create.astimezone(tz=pytz.utc)
-        return fields.Datetime.to_string(date_create)
-
-    @api.multi
-    @api.depends("journal_id")
-    def _compute_address_issued(self):
-        for invoice in self:
-            if invoice.journal_id.address_issued_id:
-                invoice.address_issued_id = invoice.journal_id.address_issued_id
-            else:
-                invoice.address_issued_id = invoice.company_id.partner_id
-
-    @api.multi
-    def _compute_sequence_id(self):
-        for record in self:
-            record.sequence_id = record.journal_id.sequence_id
-
-    @api.multi
-    def _compute_l10n_mx_edi_to_cancel(self):
-        """Computes legend to display when an invoice needs to be cancelled because
-        have being substituted by a new one.
-        """
-        # Get substitution relation to compare
-        substitution = self.env.ref("l10n_mx.cfdi_relation_type_04")
-        invoices_to_cancel = self.filtered(
-            lambda i: i.type == "out_invoice" and i.state in ("open", "paid")
-        )
-        for inv in invoices_to_cancel:
-            message = ""
-            origin_documents = inv.refund_invoice_ids.filtered(
-                lambda i:
-                    i.state in ("open", "paid") and i.type == "out_invoice"
-            )
-            is_substitue = any(
-                [o.cfdi_relation_type == substitution for o in origin_documents]
-            )
-            if origin_documents and is_substitue:
-                message = _("This invoice must be cancelled because have being "
-                            "replaced with invoice: ")
-                inv.l10n_mx_edi_original_invoice = origin_documents[0]
-
-            inv.l10n_mx_edi_to_cancel = message
-
-    @api.model
-    def _search_l10n_mx_edi_to_cancel(self, operator, value):
-        """Allows to get ids for invoices that must be cancelled"""
-        substitution = self.env.ref("l10n_mx.cfdi_relation_type_04")
-
-        if operator not in ["=", "!="] or not isinstance(value, bool):
-            raise UserError(_("Operation not supported"))
-
-        if operator != "=":
-            value = not value
-
-        self._cr.execute(
-            """
-            SELECT id FROM account_invoice ai
-            WHERE EXISTS (
-                SELECT * FROM account_invoice_refunds_rel airr
-                INNER JOIN account_invoice air on airr.refund_invoice_id = air.id
-                WHERE airr.original_invoice_id = ai.id
-                AND air.cfdi_relation_type = %s
-                LIMIT 1
-            )
-            AND ai.state IN ('open', 'paid')
-            """,
-            (substitution.id,)
-        )
-        return [
-            ("id", "in" if value else "not in", [r[0] for r in self._cr.fetchall()])
-        ]
-
-    @api.model
-    def cron_invoices_pending_to_cancel(self):
-        invoices = self.env["account.invoice"].search([("state", "in", ["waiting"])])
-        for invoice in invoices:
-            invoice.action_consult_cancellation_status()
-
-    @api.one
-    def _compute_datetime(self):
-        self.datetime = self.cfdi_datetime
-
-    @api.multi
-    @api.onchange("partner_id")
-    def onchange_partner_id(self):
-        """Copy fields cfdi_use, payment_method_id and cfdi_adenda_id
-        from selected partner
-        """
-        res = super(AccountInvoice, self).onchange_partner_id()
-        for invoice in self.filtered(lambda i: i.type in ("out_invoice", "out_refund")):
-            partner = invoice.partner_id
-            if partner:
-                if partner.cfdi_fiscal_regime_id.id:
-                    invoice.cfdi_fiscal_regime_id = partner.cfdi_fiscal_regime_id.id
-                if partner.cfdi_use.id:
-                    invoice.cfdi_use = partner.cfdi_use.id
-                invoice.payment_method_id = partner.payment_method_id.id
-                invoice.cfdi_adenda_ids = [(6, 0, partner.cfdi_adenda_ids._ids)]
-        return res
-
-    @api.model
-    def _prepare_refund(
-        self, invoice, date=None, period_id=None, description=None, journal_id=None
-    ):
-        """Overrides the prepare refund function to set field UsoCFDI"""
-        values = super(AccountInvoice, self)._prepare_refund(
-            invoice,
-            date=date,
-            period_id=period_id,
-            description=description,
-            journal_id=journal_id,
-        )
-        # We set field UsoCFDI to Descuentos y devoluciones for all refunds
-        usocfdi = self.env.ref("l10n_mx.cfdi_use_G02")
-        values["cfdi_use"] = usocfdi.id
-        values["cfdi_relation_type"] = self._context.get("cfdi_relation_type")
-        payment_type = self.env.ref("l10n_mx.pay_method_condonacion")
-        values["payment_type_ids"] = [(4, payment_type.id, None)]
-        payment_method = self.env.ref("l10n_mx.cfdi_payment_method_1")
-        values["payment_method_id"] = payment_method.id
-
-        return values
-
-    @api.multi
-    def action_invoice_validate(self):
-        res = super(AccountInvoice, self).action_invoice_validate()
-        for account_invoice in self:
-            if account_invoice.journal_id.sign_sat:
-                # Create new CFDI object for this invoice
-                account_invoice.create_cfdi()
-        return res
-
-    @api.multi
-    def action_cancel(self):
-        """Extend `AccountInvoice.action_cancel()`; Cancels the CFDI related to the
-        invoice
-        """
-        # Get only invoices with related cfdi to cancel cfdi before cancel invoice
-        cfdis = self.filtered(
-            lambda i:
-                i.journal_id.sign_sat
-                and i.cfdi_id
-                and i.cfdi_id.state not in ["draft", "cancel"]
-        )
-        for invoice in cfdis:
-            # Ensure we can cancel this invoice
-            invoice.check_if_can_cancel()
-            # If l10n_mx_edi_original_invoice is set save uuid to send info to PAC
-            # while cancel invoice
-            invoice.cfdi_id.substitute_cfdi_uuid = (
-                invoice.l10n_mx_edi_original_invoice.cfdi_id.uuid
-            )
-            cancelacion = invoice.cancel_cfdi()[0]
-            if cancelacion:
-                # CFDI cancelled (cancelacion == True) must cancel invoice too
-                super(AccountInvoice, invoice).action_cancel()
-            elif cancelacion is None:
-                # CFDI set to approval (cancelacion == None) must set invoice
-                # to waiting too
-                invoice.write({"state": "waiting"})
-            elif cancelacion is False:
-                # CFDI cancel denied (cancelacion == False) must get back invoice
-                # to open state
-                self.undo_waiting_state()
-
-        # Call super only with invoices without CFDI
-        invoices = self - cfdis
-        return super(AccountInvoice, invoices).action_cancel()
-
-    @api.multi
-    def undo_waiting_state(self):
-        """When cancel is negate revert invoice to open and post account_move"""
-        to_update = self.filtered(lambda i: i.state == "waiting")
-        to_update.write({"state": "open"})
-        to_update.mapped("move_id").post()
-
-    @api.multi
-    def action_consult_cancellation_status(self):
-        """Verify cancellation status"""
-        # TODO: Is this really needed? Maybe we can reuse the action_cancel
-        for invoice in self:
-            try:
-                with self.env.cr.savepoint():
-                    status_cancelacion = invoice.consult_cfdi_cancellation_status()
-                    if status_cancelacion is None:
-                        invoice.message_post(
-                            body=_("No status update found on SAT")
-                        )
-                    elif status_cancelacion is False:
-                        self.undo_waiting_state()
-                    else:
-                        try:
-                            invoice.action_cancel()
-                        except Exception as e:
-                            invoice.message_post(
-                                body=_("The invoice could not be canceled")
-                            )
-            except Exception as e:
-                invoice.message_post(
-                    body=_(
-                        "Could not check SAT invoice status "
-                        "due to the following error: %s."
-                    ) % (e)
-                )
-
-    @api.multi
-    def _validate_cfdi_data(self):
-        self._validate_account_invoice_fields()
-        self._validate_account_invoice_partners()
-
-    @api.multi
-    def _validate_account_invoice_fields(self):
-        """ This function is to validate that the invoice has an
-            issue address, partner and company"""
-        for record in self:
-            self._cfdi_validate_required_fields(
-                record,
-                [
-                    "cfdi_use",
-                    "partner_id",
-                    "cfdi_fiscal_regime_id",
-                    "payment_type_ids",
-                    "address_issued_id",
-                    "journal_id",
-                    "account_id"
-                ],
-            )
-
-    @api.multi
-    def _validate_account_invoice_partners(self):
-        """ This function is to validate that the vat of the
-            commercial partner and company"""
-
-        required = [
-            "vat",
-            "zip",
-            "cfdi_fiscal_regime_id",
-        ]
-
-        for record in self:
-            self._cfdi_validate_required_fields(
-                record.address_issued_id,
-                required,
-            )
-
-            self._cfdi_validate_required_fields(
-                record.company_id.partner_id,
-                required,
-            )
-
-            self._cfdi_validate_required_fields(
-                record.commercial_partner_id,
-                required,
-            )
-
-            if record.partner_id.country_id.code_alpha3 == "MEX":
-                self._cfdi_validate_required_fields(
-                    record.partner_id,
-                    required,
-                )
-
-    @api.multi
-    def _compute_export(self):
-        for record in self:
-            if record.cfdi_adenda_ids.filtered(
-                lambda i: i.code == "02"
-            ) and record.commercial_partner_id.country_id.code_alpha3 != "MEX":
-                record.l10n_mx_export = True
-
-
-class AccountInvoiceLine(models.Model):
-    _inherit = "account.invoice.line"
-
-    cfdi_numero_identificacion = fields.Char(
-        string="Identification Number",
-        help="This number is the identification number for invoice line in cfdi",
-        compute="_compute_cfdi_ident_number",
-    )
-    cfdi_cuentapredial = fields.Char(
-        string="Cuenta Predial",
-        help="Predial number for real state lease invoices",
-    )
-    cfdi_custom_number = fields.Many2many(
-        "import.pediment.number",
-        "invoice_pediment_rel",
-        "invoice_line_id",
-        "cfdi_custom_number_id",
-        "N° Pediment",
-    )
-
-    @api.multi
-    @api.constrains("cfdi_cuentapredial")
-    def _constraint_cfdi_cuentapredial(self):
-        for record in self:
-            if record.cfdi_cuentapredial and not record.cfdi_cuentapredial.isdigit():
-                raise ValidationError(
-                    _(
-                        "Predial Account must be only numbers.\n"
-                        "All letters must be replaced by '0'"
-                    )
-                )
-
-    @api.multi
-    @api.depends("product_id")
-    def _compute_cfdi_ident_number(self):
-        """Update cfdi_numero_identificacion only for invoice lines that are not signed
-        yet and that are customer's documents.
-        """
-        to_update = self.filtered(
-            lambda line: line.invoice_id.cfdi_state == "draft"
-            and line.invoice_id.type in ("out_invoice", "out_refund")
-        )
-        for record in to_update:
-            record.cfdi_numero_identificacion = record.product_id.default_code
-
-    @property
-    def cfdi_product_code(self):
-        """Return computed cfdi code for current line based on code selected
-        for product or product category.
-        Raise a validation error if no code found"""
-        self.ensure_one()
-        if self.product_id.cfdi_product_service_id.exists():
-            return self.product_id.cfdi_product_service_id.code
-        # Traverse product category to find cfdi product code
-        category = self.product_id.categ_id
-        while category:
-            if category.cfdi_product_service_id:
-                return category.cfdi_product_service_id.code
-            else:
-                category = category.parent_id
-        # If not have return for this point raise an error
-        raise ValidationError(
-            _("Missing SAT code for product: {product}").format(
-                product=self.product_id.name
-            )
-        )
-
-    @property
-    def importe(self):
-        """Return computed total line for display on CFDI"""
-        self.ensure_one()
-        return self.export_invoice_line_for_xml().importe
-
-    @property
-    def descuento(self):
-        """Property that computes the discount amount in currency for CFDI XML
-        invoice view
-        """
-        self.ensure_one()
-        return self.export_invoice_line_for_xml().descuento
-
-    @property
-    def impuestos(self):
-        """Return computed taxes for display on CFDI"""
-        self.ensure_one()
-        taxes = {"traslados": [], "retenciones": [], "locales": []}
-        for tax in self.export_invoice_line_for_xml().taxes:
-            if tax.group in ["IVA", "IEPS", "ISR"]:
-                if tax.amount >= 0:
-                    taxes["traslados"].append(tax)
-                else:
-                    taxes["retenciones"].append(tax)
-            else:
-                taxes["locales"].append(tax)
-        return taxes
-
-    @property
-    def valorunitario(self):
-        """Return computed price unit for display on CFDI"""
-        self.ensure_one()
-        return self.export_invoice_line_for_xml().price_unit
-
-    def export_invoice_line_for_xml(self):
-        # pylint: disable=R1710
-        """Computes all values needed for export account.invoice.line as CFDI"""
-
-        class Dict2obj(object):
-            """Convert dictionary to object
-            @source http://stackoverflow.com/a/1305561/383912
-            """
-
-            def __init__(self, d):
-                self.__dict__["d"] = d
-
-            def __getattr__(self, key):
-                value = self.__dict__["d"][key]
-                return value
-
-        def process_tax(tax):
-            """Helper function to populate extra values needed for display
-            taxes on CFDI representation from account.invoice
-            @param tax: tax values computed from original compute_all function
-                on account.invoice.tax object
-            @type tax: dictionary
-            @return: dictionary populated with all values needed for tax
-                excluding IEPS tax if partner is not IEPS subjected
-            @rtype: dictionary or None
-            """
-            tax_record = self.env["account.tax"].browse(tax["id"])
-            tax_group = tax_record.tax_category_id
-            # IEPS tax only must be included when partner is IEPS subjected
-            if tax_group.name == "IEPS" and not partner.ieps_subjected:
-                return
-            # TODO: Delete on version 3.0.0
-            if "base" not in tax:
-                tax["base"] = currency.cfdi_round(tax["price_unit"] * self.quantity)
-            tax["group"] = tax_group.name
-            tax["type"] = tax_record.type
-            tax["TasaOCuota"] = abs(tax_record.amount)
-            return tax
-
-        currency = self.invoice_id.currency_id
-        precision = self.env["decimal.precision"].precision_get("Product Price")
-        total_discount = 1 - self.discount / 100.0
-        # Include global discount
-        total_discount *= 1 - self.invoice_id.global_discount / 100
-        price = float_round(self.price_unit * total_discount, precision)
-        partner = self.invoice_id.partner_id
-        # Check if IEPS is on taxes, this will be used later to know if need price
-        # to be recalculated because IEPS must be price included as partner is not
-        # IEPS subjected and product include IEPS taxes
-        ieps_group = self.env.ref("l10n_mx.tax_category_ieps")
-        is_ieps_tax_subjected = any(
-            tax.tax_category_id == ieps_group for tax in self.invoice_line_tax_id
-        )
-        is_price_included = any(
-            tax.price_include for tax in self.invoice_line_tax_id
-        )
-        # Compute taxes using original compute_all function from
-        # account.invoice.tax to get same result for CFDI display
-        res = self.invoice_line_tax_id.compute_all(
-            price,
-            self.quantity,
-            product=self.product_id,
-            partner=partner,
-            currency=self.invoice_id.currency_id,
-        )
-        # pylint: disable=C1801
-        if len(res["taxes"]) == 0:
-            raise ValidationError(
-                _("Product {p} must have at least one tax selected.").format(
-                    p=self.product_id.name
-                )
-            )
-        taxes = []
-        taxes_list = iter(res["taxes"])
-        tax = next(taxes_list)
-        # Iterate taxes and append to the new tax list as needed
-        while True:
-            tax = process_tax(tax)
-            if tax:
-                taxes.append(tax)
-            try:
-                tax = next(taxes_list)
-            except StopIteration:
-                if tax is None:
-                    raise ValidationError(
-                        _(
-                            "Incorrect tax sequence configuration, check "
-                            "this data in Account >> Tax >> Sequence"
-                        )
-                    )
-                break
-        res["price_unit"] = self.price_unit
-        # Recompute price_unit is needed when any tax is setup to price included or
-        # when product is IEPS subjected but not partner
-        if is_price_included or (not partner.ieps_subjected and is_ieps_tax_subjected):
-            # Send round=False in context to avoid rounding to wrong value when working
-            # with high Product Price precision (6 digits)
-            res["price_unit"] = self.invoice_line_tax_id.with_context(
-                round=False
-            ).compute_all(
-                res["price_unit"], 1.0, product=self.product_id, partner=partner
-            )[
-                "base"
-            ]
-            # Round price_unit to Product Price precision after computing taxes
-            res["price_unit"] = float_round(
-                res["price_unit"],
-                self.env["decimal.precision"].precision_get("Product Price"),
-            )
-
-        res["importe"] = currency.round(res["price_unit"] * self.quantity)
-        res["descuento"] = currency.round(res["importe"] * (1 - total_discount))
-        # Overrides original taxes with the list computed by us
-        res["taxes"] = [Dict2obj(t) for t in taxes]
-        return Dict2obj(res)
diff --git a/l10n_mx_facturae/models/account_move.py b/l10n_mx_facturae/models/account_move.py
index 06a0050e1ee453b3adf35fb9b9c1e33ac323a6f6..e4265bd6c7d73bf938cc00a16b498243ced01706 100644
--- a/l10n_mx_facturae/models/account_move.py
+++ b/l10n_mx_facturae/models/account_move.py
@@ -1,19 +1,159 @@
 # -*- coding: utf-8 -*-
 
 import logging
+import pytz
+from datetime import datetime, timedelta
 
-from openerp import api, models
-from openerp.exceptions import Warning as UserError
-from openerp.tools.translate import _
+from odoo import api, fields, models
+from odoo.exceptions import ValidationError, Warning as UserError
+from odoo.tools.float_utils import float_round
+from odoo.tools.translate import _
 
 
 _logger = logging.getLogger(__name__)
 
 
 class AccountMove(models.Model):
-    _inherit = "account.move"
+    _name = "account.move"
+    _inherit = ["account.move", "base.cfdi"]
+
+    @property
+    def formapago(self):
+        """Return payment type for display on CFDI"""
+        self.ensure_one()
+        try:
+            code = self.payment_type_ids[0].code
+        except IndexError:
+            code = "99"
+        return code
+
+    @property
+    def descuento(self):
+        self.ensure_one()
+        discount = 0.0
+        for line in self.invoice_line_ids:
+            discount += line.descuento
+        return discount
+
+    @property
+    def subtotal(self):
+        self.ensure_one()
+        subtotal = 0.0
+        for line in self.invoice_line_ids:
+            subtotal += line.importe
+        return subtotal
+
+    @property
+    def total(self):
+        self.ensure_one()
+        return (
+            self.subtotal
+            - self.descuento
+            + self.impuestos["total_traslados"]
+            + self.impuestos["total_retenciones"]
+            + self.impuestos["total_locales"]
+        )
+
+    @property
+    def impuestos(self):
+        """Return computed taxes for display on CFDI"""
+        self.ensure_one()
+        tax_grouped = {}
+        taxes = {
+            "traslados": [],
+            "retenciones": [],
+            "locales": [],
+            "total_traslados": 0.0,
+            "total_retenciones": 0.0,
+            "total_locales": 0.0,
+        }
+
+        for line in self.invoice_line_ids:
+            for tax in line.export_invoice_line_for_xml().taxes:
+                # Mimic logic from compute function in account.invoice.tax
+                # object to group taxes from invoice lines and be able to get
+                # the same result for display on CFDI
+                grouping_dict = self._get_tax_grouping_key_from_tax_line(line)
+                grouping_key = "-".join(str(v) for v in grouping_dict.values())
+                if grouping_key not in tax_grouped:
+                    tax_grouped[grouping_key] = tax
+                else:
+                    tax_grouped[grouping_key].amount += tax.amount
+                    tax_grouped[grouping_key].base += tax.base
+
+        # Classify taxes for CFDI
+        for dummy, tax in tax_grouped.items():
+            if tax.group in ["IVA", "IEPS", "ISR"]:
+                tax.xml_amount = "{0:.2f}".format(tax.amount)
+                if tax.amount >= 0:
+                    taxes["traslados"].append(tax)
+                    taxes["total_traslados"] += tax.amount
+                else:
+                    taxes["retenciones"].append(tax)
+                    taxes["total_retenciones"] += tax.amount
+            else:
+                taxes["locales"].append(tax)
+                taxes["total_locales"] += tax.amount
+        return taxes
+
+    # pylint: disable=W0212
+    address_issued_id = fields.Many2one(
+        "res.partner",
+        "Address Issued Invoice",
+        readonly=True,
+        states={"draft": [("readonly", False)]},
+        help="This address will be used as address that issued "
+        "for electronic invoice",
+        compute="_compute_address_issued",
+    )
+    datetime = fields.Datetime(compute="_compute_datetime")
+    date_invoice_cancel = fields.Datetime(
+        "Date Invoice Cancelled",
+        readonly=True,
+        copy=False,
+        help="If the invoice is cancelled, save the date" " when was cancel",
+    )
+    payment_method_id = fields.Many2one(
+        "cfdi.payment.method",
+        string="Payment Method",
+        readonly=True,
+        states={"draft": [("readonly", False)]},
+        help="Payment method associated with this payment term according",
+    )
+    cfdi_use = fields.Many2one(
+        "cfdi.use", "CFDI use", readonly=True, states={"draft": [("readonly", False)]}
+    )
+    cfdi_relation_type = fields.Many2one("cfdi.relation.type", "CFDI Relation type")
+    l10n_mx_edi_to_cancel = fields.Char(
+        #compute="_compute_l10n_mx_edi_to_cancel",
+        #search="_search_l10n_mx_edi_to_cancel",
+        help="Technical field to display a warning when an invoice must be canceled "
+        "because have being replaced by a new one.",
+    )
+    l10n_mx_edi_original_invoice = fields.Many2one(
+        "account.move",
+        #compute="_compute_l10n_mx_edi_to_cancel",
+        help="Technical field to relate origin invoice with substitute",
+    )
+    invoice_global = fields.Boolean(
+        compute="_compute_invoice_global",
+        string="Is Invoice global?",
+    )
+    cfdi_periodicity = fields.Selection(
+        [
+            ("01", "Daily"),
+            ("02", "Weekly"),
+            ("03", "Biweekly"),
+            ("04", "Monthly"),
+        ],
+        default="04",
+    )
+
+    l10n_mx_export = fields.Boolean(
+        compute="_compute_export",
+        string="Merchandise export",
+    )
 
-    @api.multi
     def button_validate(self):
         """
             Extend `AccountMove.button_validate`: prevents  to manipulate the
@@ -28,3 +168,626 @@ class AccountMove(models.Model):
                       "for a request to cancel.") % account_move.name
                 )
         return super(AccountMove, self).button_validate()
+
+    def _get_cfdi_datetime(self):
+        """This base function inherits the creation of the cfdi datetime
+        what it basically does is respect the date_invoice from invoice form
+        """
+        self.ensure_one()
+        date_invoice = fields.Datetime.from_string(self.invoice_date)
+        time_now = fields.Datetime.context_timestamp(self, datetime.now())
+        # If we are singing an invoice in the past we need to move forward 1 minute the
+        # computed time to be in the 72 hours range defined by SAT
+        # On the opposite if we are singing an invoice for today we move back 1 minute
+        # the computed time to prevent false errors about being out of 72 hours range
+        if date_invoice.date() < time_now.date():
+            time_now += timedelta(minutes=1)
+        else:
+            time_now -= timedelta(minutes=1)
+        date_create = datetime.combine(date_invoice, time_now.timetz())
+        # Needed to save date into the database as until now we are using user timezone
+        # to express the datetime that will cause double timezone conversion if kept
+        date_create = date_create.astimezone(tz=pytz.utc)
+        return fields.Datetime.to_string(date_create)
+
+    @api.depends("journal_id")
+    def _compute_address_issued(self):
+        for invoice in self:
+            if invoice.journal_id.address_issued_id:
+                invoice.address_issued_id = invoice.journal_id.address_issued_id
+            else:
+                invoice.address_issued_id = invoice.company_id.partner_id
+
+    def _compute_sequence_id(self):
+        for record in self:
+            record.sequence_id = record.journal_id.secure_sequence_id
+
+    def _compute_l10n_mx_edi_to_cancel(self):
+        """Computes legend to display when an invoice needs to be cancelled because
+        have being substituted by a new one.
+        """
+        # Get substitution relation to compare
+        substitution = self.env.ref("l10n_mx_ir_attachment_facturae.cfdi_relation_type_04")
+        invoices_to_cancel = self.filtered(
+            lambda i: i.move_type == "out_invoice" and i.state in ("posted",)
+        )
+        for inv in invoices_to_cancel:
+            message = ""
+            origin_documents = inv.refund_invoice_ids.filtered(
+                lambda i:
+                    i.state in ("posted",) and i.move_type == "out_invoice"
+            )
+            is_substitue = any(
+                [o.cfdi_relation_type == substitution for o in origin_documents]
+            )
+            if origin_documents and is_substitue:
+                message00 = _("This invoice must be cancelled because have being "
+                            "replaced with invoice: ")
+                inv.l10n_mx_edi_original_invoice = origin_documents[0]
+
+            inv.l10n_mx_edi_to_cancel = message
+
+    @api.model
+    def _search_l10n_mx_edi_to_cancel(self, operator, value):
+        """Allows to get ids for invoices that must be cancelled"""
+        substitution = self.env.ref("l10n_mx_ir_attachment_facturae.cfdi_relation_type_04")
+
+        if operator not in ["=", "!="] or not isinstance(value, bool):
+            raise UserError(_("Operation not supported"))
+
+        if operator != "=":
+            value = not value
+
+        self._cr.execute(
+            """
+            SELECT id FROM account_move am
+            WHERE EXISTS (
+                SELECT * FROM account_invoice_refunds_rel airr
+                INNER JOIN account_move air on airr.refund_invoice_id = air.id
+                WHERE airr.original_invoice_id = am.id
+                AND air.cfdi_relation_type = %s
+                LIMIT 1
+            )
+            AND am.move_state IN ('posted',)
+            """,
+            (substitution.id,)
+        )
+        return [
+            ("id", "in" if value else "not in", [r[0] for r in self._cr.fetchall()])
+        ]
+
+    @api.model
+    def cron_invoices_pending_to_cancel(self):
+        invoices = self.env["account.move"].search([("state", "in", ["waiting"])])
+        for invoice in invoices:
+            invoice.action_consult_cancellation_status()
+
+    def _compute_datetime(self):
+        for record in self:
+            record.datetime = record.cfdi_datetime
+
+    @api.onchange("partner_id")
+    def onchange_partner_id(self):
+        """Copy fields cfdi_use, payment_method_id and cfdi_adenda_id
+        from selected partner
+        """
+        res = super(AccountMove, self).onchange_partner_id()
+        for invoice in self.filtered(lambda i: i.move_type in ("out_invoice", "out_refund")):
+            partner = invoice.partner_id
+            if partner:
+                if partner.cfdi_use_id:
+                    invoice.cfdi_use = partner.cfdi_use_id.id
+                invoice.payment_method_id = partner.payment_method_id.id
+                invoice.cfdi_adenda_ids = [(6, 0, partner.cfdi_adenda_ids._ids)]
+        return res
+
+    @api.model
+    def _prepare_refund(
+        self, invoice, date=None, period_id=None, description=None, journal_id=None
+    ):
+        """Overrides the prepare refund function to set field UsoCFDI"""
+        values = super(AccountMove, self)._prepare_refund(
+            invoice,
+            date=date,
+            period_id=period_id,
+            description=description,
+            journal_id=journal_id,
+        )
+        # We set field UsoCFDI to Descuentos y devoluciones for all refunds
+        usocfdi = self.env.ref("l10n_mx_base.cfdi_use_G02")
+        values["cfdi_use"] = usocfdi.id
+        values["cfdi_relation_type"] = self._context.get("cfdi_relation_type")
+        payment_type = self.env.ref("l10n_mx_base.pay_method_condonacion")
+        values["payment_type_ids"] = [(4, payment_type.id, None)]
+        payment_method = self.env.ref("l10n_mx_base.cfdi_payment_method_1")
+        values["payment_method_id"] = payment_method.id
+
+        return values
+
+    def action_post(self):
+        res = super(AccountMove, self).action_post()
+        for record in self:
+            record.action_invoice_validate()
+        return res
+
+    def action_invoice_validate(self):
+        for account_invoice in self:
+            if account_invoice.journal_id.sign_sat:
+                # Create new CFDI object for this invoice
+                account_invoice.create_cfdi()
+
+    def l10n_mx_action_cancel(self):
+        """Cancels the CFDI related to the invoice"""
+
+        # Get only invoices with related cfdi to cancel cfdi before cancel invoice
+        cfdis = self.filtered(
+            lambda i:
+                i.journal_id.sign_sat
+                and i.cfdi_id
+                and i.cfdi_id.state not in ["draft", "cancel"]
+        )
+
+        for invoice in cfdis:
+            invoice.message_post(
+                body=_("Cancellation request sent")
+            )
+            cancelacion = invoice.cancel_cfdi()
+            if cancelacion:
+                # CFDI cancelled (cancelacion == True) must cancel invoice too
+                invoice.button_draft()
+                invoice.button_cancel()
+            elif cancelacion is None:
+                # CFDI set to approval (cancelacion == None) must set invoice
+                # to waiting too
+                invoice.write({"state": "posted"})
+                invoice.message_post(
+                    body=_("Awaiting cancellation")
+                )
+            elif cancelacion is False:
+                # CFDI cancel denied (cancelacion == False) must get back invoice
+                # to open state
+                self.undo_waiting_state()
+                invoice.message_post(
+                    body=_("Denied cancellation")
+                )
+
+    def undo_waiting_state(self):
+        """When cancel is negate revert invoice to open and post account_move"""
+        for record in self:
+            to_update = record.filtered(lambda i: i.cfdi_state == "waiting")
+            to_update.write({"state": "posted"})
+            to_update.mapped("move_id").post()
+
+    @api.depends("state", "cfdi_state")
+    def _compute_show_reset_to_draft_button(self):
+        super()._compute_show_reset_to_draft_button()
+
+        for move in self:
+            if move.state in ("posted", "cancel") and move.cfdi_state in ("signed", "done", "waiting", "cancel"):
+                move.show_reset_to_draft_button = False
+
+    def action_consult_cancellation_status(self):
+        """Verify cancellation status"""
+        # TODO: Is this really needed? Maybe we can reuse the action_cancel
+        for invoice in self:
+            try:
+                with self.env.cr.savepoint():
+                    status_cancelacion = invoice.consult_cfdi_cancellation_status()
+                    if status_cancelacion is None:
+                        invoice.message_post(
+                            body=_("No status update found on SAT")
+                        )
+                    elif status_cancelacion is False:
+                        self.undo_waiting_state()
+                    else:
+                        try:
+                            invoice.action_cancel()
+                        except Exception as e:
+                            invoice.message_post(
+                                body=_("The invoice could not be canceled")
+                            )
+            except Exception as e:
+                invoice.message_post(
+                    body=_(
+                        "Could not check SAT invoice status "
+                        "due to the following error: %s."
+                    ) % (e)
+                )
+
+    def _compute_export(self):
+        for record in self:
+            record.l10n_mx_export = bool(
+                record.cfdi_adenda_ids.filtered(
+                    lambda i: i.code == "02"
+                ) and record.commercial_partner_id.country_id.code_alpha3 != "MEX"
+            )
+
+    def _compute_invoice_global(self):
+        for record in self:
+            record.invoice_global = bool(
+                record.commercial_partner_id.name == "Publico en general" and
+                record.commercial_partner_id.vat_split == "XAXX010101000"
+            )
+
+    ############################################################
+    # This section compute function of decision for xml CFDI 4.0
+    ############################################################
+
+    def l10n_mx_facturae_compute_fecha(self):
+        tz = pytz.timezone(self.env.user.tz or pytz.utc.zone)
+        date = pytz.UTC.localize(self.cfdi_datetime).astimezone(tz)
+        return date.strftime("%Y-%m-%dT%H:%M:%S")
+
+    def l10n_mx_facturae_compute_fecha_global_year(self):
+        tz = pytz.timezone(self.env.user.tz or pytz.utc.zone)
+        date = pytz.UTC.localize(self.cfdi_datetime).astimezone(tz)
+        return date.strftime("%Y")
+
+    def l10n_mx_facturae_compute_fecha_global_month(self):
+        tz = pytz.timezone(self.env.user.tz or pytz.utc.zone)
+        date = pytz.UTC.localize(self.cfdi_datetime).astimezone(tz)
+        return date.strftime("%m")
+
+    def l10n_mx_facturae_compute_serie(self):
+        if self.journal_id.secure_sequence_id.prefix:
+            return self.serie
+
+    def l10n_mx_facturae_compute_export(self):
+        if self.l10n_mx_export:
+            return "02"
+
+        return "01"
+
+    def l10n_mx_facturae_compute_subtotal(self):
+        return "{0:.2f}".format(self.subtotal)
+
+    def l10n_mx_facturae_compute_total(self):
+        return "{0:.2f}".format(self.total)
+
+    def l10n_mx_facturae_compute_payment_terms(self):
+        paymentterms = self.invoice_payment_term_id.name
+        return paymentterms
+
+    def l10n_mx_facturae_compute_tipocambio(self):
+        tipocambio = False
+        if self.currency_id.name != "MXN":
+            date = self.invoice_date
+            from_currency = self.currency_id
+            to_currency = self.company_id.currency_id
+            tipocambio = from_currency._get_conversion_rate(
+                from_currency,
+                to_currency,
+                self.company_id,
+                date,
+            )
+        return tipocambio
+
+    def l10n_mx_facturae_compute_type_document(self):
+        if self.move_type == "out_invoice":
+            return "I"
+        elif self.move_type == "out_refund":
+            return "E"
+
+    def l10n_mx_facturae_compute_payment_method(self):
+        if self.payment_method_id.code:
+            return self.payment_method_id.code
+        else:
+            return "PUE"
+
+    def l10n_mx_facturae_compute_rfc(self):
+        if self.commercial_partner_id.country_id.code_alpha3 != "MEX":
+            return "XEXX010101000"
+        else:
+            return self.commercial_partner_id.vat_split
+
+    def l10n_mx_facturae_compute_use_cfdi(self):
+        if self.commercial_partner_id.country_id.code_alpha3 != "MEX":
+            return "S01"
+        else:
+            return self.cfdi_use.code
+
+    def l10n_mx_facturae_compute_domicilio_fiscal(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        vat = self.commercial_partner_id.vat_split
+        domiciliofiscal = self.commercial_partner_id.zip
+        if code_country == "MEX" and vat == "XAXX010101000" or code_country != "MEX":
+            domiciliofiscal = self.address_issued_id.zip
+
+        return domiciliofiscal
+
+    def l10n_mx_facturae_compute_regimen_fiscal_receptor(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        regimenfiscal = self.commercial_partner_id.cfdi_fiscal_regime_id.code
+        if code_country != "MEX":
+            regimenfiscal = "616"
+
+        return regimenfiscal
+
+    def l10n_mx_facturae_compute_residencia_fiscal(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        residenciafiscal = False
+        if code_country != "MEX":
+            residenciafiscal = code_country
+
+        return residenciafiscal
+
+    def l10n_mx_facturae_compute_regimen_tributario(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        regimentribut = False
+        if code_country != "MEX":
+            regimentribut = self.commercial_partner_id.vat_split
+
+        return regimentribut
+
+    def l10n_mx_facturae_compute_product(self):
+        for line in self.invoice_line_ids:
+            product = line.cfdi_product_code
+            if not line.product_id.name:
+                product = "01010101"
+
+            return product
+
+    def l10n_mx_facturae_compute_unit(self):
+        for line in self.invoice_line_ids:
+            if len(line.product_uom_id.name) > 20:
+                unit = line.product_uom_id.name[:17].upper() + "..."
+            else:
+                unit = line.product_uom_id.name.upper()
+
+            return unit
+
+    def l10n_mx_facturae_compute_total_traslados(self, taxes):
+        res = False
+        if any(tax.type != "Excento" for tax in taxes["traslados"]):
+            res = taxes["total_traslados"]
+
+        return '{0:.2f}'.format(res)
+
+    def l10n_mx_facturae_compute_total_retenciones(self, taxes):
+        res = False
+        if taxes["total_retenciones"]:
+            res = taxes["total_retenciones"]
+            '{0:.2f}'.format(res)
+
+        return res
+
+class AccountMoveLine(models.Model):
+    _inherit = "account.move.line"
+
+    cfdi_numero_identificacion = fields.Char(
+        string="Identification Number",
+        help="This number is the identification number for invoice line in cfdi",
+        compute="_compute_cfdi_ident_number",
+    )
+    cfdi_cuentapredial = fields.Char(
+        string="Cuenta Predial",
+        help="Predial number for real state lease invoices",
+    )
+    cfdi_custom_number = fields.Many2many(
+        "cfdi.import.pediment.number",
+        "invoice_pediment_rel",
+        "invoice_line_id",
+        "cfdi_custom_number_id",
+        "N° Pediment",
+    )
+
+    @api.constrains("cfdi_cuentapredial")
+    def _constraint_cfdi_cuentapredial(self):
+        for record in self:
+            if record.cfdi_cuentapredial and not record.cfdi_cuentapredial.isdigit():
+                raise ValidationError(
+                    _(
+                        "Predial Account must be only numbers.\n"
+                        "All letters must be replaced by '0'"
+                    )
+                )
+
+    @api.depends("product_id")
+    def _compute_cfdi_ident_number(self):
+        """Update cfdi_numero_identificacion only for invoice lines that are not signed
+        yet and that are customer's documents.
+        """
+        to_update = self.filtered(
+            lambda line: line.move_id.cfdi_state == "draft"
+            and line.move_id.move_type in ("out_invoice", "out_refund")
+        )
+        for record in to_update:
+            record.cfdi_numero_identificacion = record.product_id.default_code
+
+    @property
+    def cfdi_product_code(self):
+        """Return computed cfdi code for current line based on code selected
+        for product or product category.
+        Raise a validation error if no code found"""
+        self.ensure_one()
+        if self.product_id.cfdi_product_service_id.exists():
+            return self.product_id.cfdi_product_service_id.code
+        # Traverse product category to find cfdi product code
+        category = self.product_id.categ_id
+        while category:
+            if category.cfdi_product_service_id:
+                return category.cfdi_product_service_id.code
+            else:
+                category = category.parent_id
+        # If not have return for this point raise an error
+        raise ValidationError(
+            _("Missing SAT code for product: {product}").format(
+                product=self.product_id.name
+            )
+        )
+
+    def l10n_mx_facturae_compute_objeto_impuesto(self):
+        objimp = "01"
+
+        # Process taxes for this line
+        impuestos = self.impuestos
+
+        # Check if there is a maningfull tax
+        summ = sum([float(o.base) for o in impuestos["traslados"]])
+        summ += sum([float(o.base) for o in impuestos["retenciones"]])
+
+        if summ:
+            objimp = "02"
+
+        return objimp
+
+    @property
+    def importe(self):
+        """Return computed total line for display on CFDI"""
+        self.ensure_one()
+        return self.export_invoice_line_for_xml().importe
+
+    @property
+    def descuento(self):
+        """Property that computes the discount amount in currency for CFDI XML
+        invoice view
+        """
+        self.ensure_one()
+        return self.export_invoice_line_for_xml().descuento
+
+    @property
+    def impuestos(self):
+        """Return computed taxes for display on CFDI"""
+        self.ensure_one()
+        taxes = {"traslados": [], "retenciones": [], "locales": []}
+        for tax in self.export_invoice_line_for_xml().taxes:
+            if tax.group in ["IVA", "IEPS", "ISR"]:
+                if tax.amount >= 0:
+                    taxes["traslados"].append(tax)
+                else:
+                    taxes["retenciones"].append(tax)
+            else:
+                taxes["locales"].append(tax)
+        return taxes
+
+    @property
+    def valorunitario(self):
+        """Return computed price unit for display on CFDI"""
+        self.ensure_one()
+        return self.export_invoice_line_for_xml().price_unit
+
+    def export_invoice_line_for_xml(self):
+        """Computes all values needed for export account.move.line as CFDI"""
+
+        class Dict2obj(object):
+            """Convert dictionary to object
+            @source http://stackoverflow.com/a/1305561/383912
+            """
+
+            def __init__(self, d):
+                self.__dict__["d"] = d
+
+            def __getattr__(self, key):
+                value = self.__dict__["d"][key]
+                return value
+
+        def process_tax(tax):
+            """Helper function to populate extra values needed for display
+            taxes on CFDI representation from account.move
+            @param tax: tax values computed from original compute_all function
+                on account.move.tax object
+            @type tax: dictionary
+            @return: dictionary populated with all values needed for tax
+                excluding IEPS tax if partner is not IEPS subjected
+            @rtype: dictionary or None
+            """
+            tax_record = self.env["account.tax"].browse(tax["id"])
+            tax_rep_lines = tax_record.refund_repartition_line_ids._origin.filtered(
+                lambda x: x.repartition_type == "tax"
+            )
+            # TODO: What happen when more than one tag is found?
+            tax_group = tax_rep_lines.mapped("tag_ids")[0]
+            # IEPS tax only must be included when partner is IEPS subjected
+            if tax_group.name == "IEPS" and not partner.ieps_subjected:
+                return
+            tax["group"] = tax_group.name
+            tax["xml_name"] = (
+                "001" if tax_group.name == "ISR" else
+                "002" if tax_group.name == "IVA" else "003"
+            )
+            tax["type"] = tax_record.l10n_mx_tax_type
+            tax["xml_amount"] = "{0:.2f}".format(tax["amount"])
+            tax["TasaOCuota"] = "{0:.6f}".format(abs(tax_record.amount)/100)
+            return tax
+
+        currency = self.move_id.currency_id
+        precision = self.env["decimal.precision"].precision_get("Product Price")
+        total_discount = 1 - self.discount / 100.0
+        # Include global discount
+        total_discount *= 1 - self.move_id.amount_global_discount / 100
+        price = float_round(self.price_unit * total_discount, precision)
+        partner = self.move_id.partner_id
+        # Check if IEPS is on taxes, this will be used later to know if need price
+        # to be recalculated because IEPS must be price included as partner is not
+        # IEPS subjected and product include IEPS taxes
+        ieps_group = self.env.ref("l10n_mx_base.tax_group_ieps")
+        is_ieps_tax_subjected = any(
+            tax.tax_group_id == ieps_group for tax in self.tax_ids
+        )
+        is_price_included = any(
+            tax.price_include for tax in self.tax_line_id
+        )
+        # Compute taxes using original compute_all function from
+        # account.move.tax to get same result for CFDI display
+        res = self.tax_ids.compute_all(
+            price,
+            quantity=self.quantity,
+            product=self.product_id,
+            partner=partner,
+            currency=self.move_id.currency_id,
+        )
+        # pylint: disable=C1801
+        if len(res["taxes"]) == 0:
+            raise ValidationError(
+                _("Product {p} must have at least one tax selected.").format(
+                    p=self.product_id.name
+                )
+            )
+        taxes = []
+        taxes_list = iter(res["taxes"])
+        tax = next(taxes_list)
+        # Iterate taxes and append to the new tax list as needed
+        while True:
+            tax = process_tax(tax)
+            if tax:
+                taxes.append(tax)
+            try:
+                tax = next(taxes_list)
+            except StopIteration:
+                if tax is None:
+                    raise ValidationError(
+                        _(
+                            "Incorrect tax sequence configuration, check "
+                            "this data in Account >> Tax >> Sequence"
+                        )
+                    )
+                break
+        res["price_unit"] = self.price_unit
+        # Recompute price_unit is needed when any tax is setup to price included or
+        # when product is IEPS subjected but not partner
+        if is_price_included or (not partner.ieps_subjected and is_ieps_tax_subjected):
+            # Send round=False in context to avoid rounding to wrong value when working
+            # with high Product Price precision (6 digits)
+            res["price_unit"] = self.tax_line_id.with_context(
+                round=False
+            ).compute_all(
+                res["price_unit"], 1.0, product=self.product_id, partner=partner
+            )[
+                "base"
+            ]
+            # Round price_unit to Product Price precision after computing taxes
+            res["price_unit"] = float_round(
+                res["price_unit"],
+                self.env["decimal.precision"].precision_get("Product Price"),
+            )
+
+        res["importe"] = currency.round(res["price_unit"] * self.quantity)
+        res["descuento"] = currency.round(res["importe"] * (1 - total_discount))
+        # Overrides original taxes with the list computed by us
+        res["taxes"] = [Dict2obj(t) for t in taxes]
+        return Dict2obj(res)
+
+    # ====================
+
+    def l10n_mx_facturae_importe(self):
+        return "{0:.2f}".format(self.importe)
diff --git a/l10n_mx_facturae/models/account_payment.py b/l10n_mx_facturae/models/account_payment.py
new file mode 100644
index 0000000000000000000000000000000000000000..e4406af49d74fa856d272e77973c9c7a529f676e
--- /dev/null
+++ b/l10n_mx_facturae/models/account_payment.py
@@ -0,0 +1,435 @@
+# -*- coding: utf-8 -*-
+
+import pytz
+from datetime import datetime, timedelta
+
+from odoo import api, fields, models
+from odoo.exceptions import ValidationError
+from odoo.tools import float_round
+from odoo.tools.translate import _
+
+
+class AccountPayment(models.Model):
+    _name = "account.payment"
+    _inherit = ["account.payment", "base.cfdi"]
+
+    show_unreconcile = fields.Boolean(
+        #compute="_compute_show_unreconcile",
+        help="Helper field to hide unreconcile button",
+    )
+
+    ############################################################
+    # This section compute function of decision for xml CFDI 4.0
+    ############################################################
+
+    def l10n_mx_facturae_payment_compute_serie(self):
+        if self.journal_id.secure_sequence_id.prefix:
+            return self.serie
+
+    def l10n_mx_facturae_payment_compute_fecha(self):
+        tz = pytz.timezone(self.env.user.tz or pytz.utc.zone)
+        date = pytz.UTC.localize(self.cfdi_datetime).astimezone(tz)
+        return date.strftime("%Y-%m-%dT%H:%M:%S")
+
+    def l10n_mx_facturae_payment_compute_rfc(self):
+        if self.commercial_partner_id.country_id.code_alpha3 != "MEX":
+            return "XEXX010101000"
+        else:
+            return self.commercial_partner_id.vat_split
+
+    def l10n_mx_facturae_payment_compute_domicilio_fiscal(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        vat = self.commercial_partner_id.vat_split
+        domiciliofiscal = self.commercial_partner_id.zip
+        if code_country == "MEX" and vat == "XAXX010101000" or code_country != "MEX":
+            domiciliofiscal = self.address_issued_id.zip
+
+        return domiciliofiscal
+
+    def l10n_mx_facturae_payment_compute_regimen_fiscal_receptor(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        regimenfiscal = self.commercial_partner_id.cfdi_fiscal_regime_id.code
+        if code_country != "MEX":
+            regimenfiscal = "616"
+
+        return regimenfiscal
+
+    def l10n_mx_facturae_payment_compute_residencia_fiscal(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        residenciafiscal = False
+        if code_country != "MEX":
+            residenciafiscal = code_country
+
+        return residenciafiscal
+
+    def l10n_mx_facturae_payment_compute_regimen_tributario(self):
+        code_country = self.commercial_partner_id.country_id.code_alpha3
+        regimentribut = False
+        if code_country != "MEX":
+            regimentribut = self.commercial_partner_id.vat_split
+
+        return regimentribut
+
+    def l10n_mx_facturae_payment_montototalpagos(self):
+        monto = self.amount
+        if self.currency_id.name != 'MXN':
+            monto = self.currency_id.round(self.currency_rate() * self.amount)
+        return monto
+
+    def l10n_mx_facturae_payment_compute_pago_fecha(self):
+        return self.date.strftime("%Y-%m-%dT%H:%M:%S")
+
+    def l10n_mx_facturae_payment_compute_tipocambio(self):
+        tipocambio = "1"
+        if self.currency_id.name != "MXN":
+            tipocambio = self.custom_rate
+
+        return tipocambio
+
+
+    ############################################################
+    # This section calculate for xml CFDI 4.0
+    ############################################################
+
+    @api.depends("state", "cfdi_state")
+    def _compute_show_unreconcile(self):
+        for payment in self:
+            if payment.cfdi_state in ["signed", "done"]:
+                payment.show_unreconcile = False
+            elif payment.state in ["draft", "cancel"]:
+                payment.show_unreconcile = False
+            else:
+                payment.show_unreconcile = True
+
+    def _compute_sequence_id(self):
+        for record in self:
+            record.sequence_id = record.journal_id.secure_sequence_id
+
+    def sign_payment(self):
+        """Create CFDI for selected vouchers"""
+        # Only vouchers to sign are the receipts
+        receipts = self.filtered(lambda r: r.payment_type == "inbound")
+        # Get only receipts that doesn't have a CFDI yet and create it
+        for receipt in receipts.filtered(lambda r: not r.cfdi_id.exists()):
+            receipt.create_cfdi()
+
+    def cancel_voucher(self):
+        """Cancel CFDI for selected vouchers"""
+        res = super(AccountPayment, self).cancel_voucher()
+        for record in self:
+            record.cancel_cfdi()
+            # Delete relation from voucher and CFDI
+            record.cfdi_id = False
+        return res
+
+    def substitute_voucher(self):
+        """Create new voucher for substitute this one"""
+        for record in self:
+            record._cancel_cfdi()
+            # After cancel voucher we must re open it
+            record.action_cancel_draft()
+
+    def _cancel_cfdi_related_document(self):
+        for record in self:
+            self.cancel_voucher()
+
+    def _l10n_mx_get_payments_to_invoice(self, invoice):
+        # Get all payments done to given invoice
+        self.ensure_one()
+        payments = self.env["account.move.line"]
+        for line in invoice._get_reconciled_invoices_partials():
+            payments |= line[2]
+
+        return payments
+
+    def replace_cfdi(self):
+        """Cancel voucher cfdi by replacing with 1 MXN voucher"""
+        for record in self:
+            record.cancel_cfdi()
+            record.action_draft()
+            record.action_cancel()
+
+    def currency_rate(self):
+        """Compute currency rate used for current voucher to display on XML
+        This calls currency.compute() with the right context,
+        so that it will take either the rate on the voucher if it is relevant
+        or will use the default behavior"""
+        self.ensure_one()
+        # We need to give the date in the context to get proper rate
+        voucher_currency = self.journal_id.currency_id or self.company_id.currency_id
+        voucher_currency = voucher_currency.with_context(date=self.date)
+
+        res = float_round(
+            voucher_currency.compute(1.0, self.company_id.currency_id, round=False),
+            precision_digits=6,
+        )
+        return res
+
+    @property
+    def doctos_relacionados(self):
+        """Return a list with all related invoices to this payment"""
+        self.ensure_one()
+
+        # Validate that all related invoices have an uuid
+        tofix = self.reconciled_invoice_ids.filtered(lambda i: not i.cfdi_folio_fiscal)
+        if tofix:
+            raise ValidationError(
+                 _("Some of the invoices that will be paid with this record are not "
+                   "signed, and the UUID is required to indicate the invoices that "
+                   "are paid with this CFDI ")
+            )
+        return self.reconciled_invoice_ids
+
+    def numparcialidad(self, invoice):
+        """Computes payment number based on all payments done to invoice"""
+        for record in self:
+            payments = self._l10n_mx_get_payments_to_invoice(invoice)
+            payments -= record.line_ids
+            # Leave only payments done in cash or bank older than current
+            payments = payments.filtered(
+                lambda r:
+                    r.date >= invoice.invoice_date
+                    and r.journal_id.type in ("cash", "bank")
+            )
+            return len(payments) + 1
+
+    def impsaldoant(self, invoice, to_xml=False):
+        """Computes amount_residual for invoice before current voucher"""
+        self.ensure_one()
+        # It is verified that the invoice is in another currency
+        is_multi_currency = (
+            invoice.currency_id != self.company_id.currency_id
+        )
+        # Search the lines of the policy where the account is receivable or payable
+        move_line_ids = invoice.line_ids.filtered(
+            lambda x: x.account_internal_type in ("receivable", "payable")
+        )
+        if is_multi_currency:
+            amount_residual = sum(
+                move_line.amount_currency for move_line in move_line_ids
+            )
+        else:
+            amount_residual = sum(
+                move_line.balance for move_line in move_line_ids
+            )
+        # Get all payments done to given invoice
+        payments = self._l10n_mx_get_payments_to_invoice(invoice)
+        payments -= self.line_ids
+        # Leave only payments done before (older than) the current one:
+        # 1.  Payments with document date before current voucher date
+        # 2.  Payments with same date but created before that current voucher
+        payments = payments.filtered(
+            lambda r:
+                r.date < self.date
+                or (r.date == self.date and r.create_date < self.create_date)
+        )
+
+        for payment in payments:
+            amount_currency = abs(payment.amount_currency) or 0.0
+            # If amount_currency exists it means we are dealing with a multi
+            # currency payment, and thus we need to sum amount_currency to
+            # amount_paid instead of normal debit - credit
+            if payment.currency_id:
+                amount_residual -= amount_currency
+            else:
+                amount_residual -= abs(payment.debit - payment.credit)
+
+        amount_residual = self.currency_id.round(amount_residual)
+        if to_xml:
+            amount_residual = "{0:.2f}".format(amount_residual)
+        return amount_residual
+
+    def imppagado(self, invoice, to_xml=False):
+        """Computes total amount payment on this voucher for given invoice"""
+        self.ensure_one()
+
+        amount_paid = 0.0
+        # Get payments done in this voucher for given invoice
+        payments = self._l10n_mx_get_payments_to_invoice(invoice)
+        payments &= self.line_ids
+
+        for payment in payments:
+            # If currency_id exists it means we are dealing with a multi
+            # currency payment, and thus we need to sum amount_currency to
+            # amount_paid instead of normal debit - credit
+            # TODO: Relay on currency_id could result in wrong results when
+            # transactions done in three different currencies or more
+            is_multi_currency = (
+                payment.currency_id
+                and invoice.currency_id != self.company_id.currency_id
+            )
+            if is_multi_currency:
+                amount_paid += payment.amount_currency * -1
+            else:
+                amount_paid += (payment.debit - payment.credit) * -1
+
+        amount_paid = self.currency_id.round(amount_paid)
+
+        # Ensure amount paid is always equal or less than amount residual
+        amount_residual = self.impsaldoant(invoice)
+        amount_paid = min(amount_paid, amount_residual)
+        if to_xml:
+            amount_paid = "{0:.2f}".format(amount_paid)
+        return amount_paid
+
+    def impsaldoinsoluto(self, invoice, to_xml=False):
+        self.ensure_one()
+        amount_residual = self.impsaldoant(invoice) - self.imppagado(invoice)
+        if to_xml:
+            amount_residual = "{0:.2f}".format(amount_residual)
+        return amount_residual
+
+    def tipocambiodr(self, invoice):
+        """Compute currency rate used for given invoice to display on XML
+        This calls curreny.compute() with the right context,
+        so that it will take either the rate on the voucher if it is relevant
+        or will use the default behavior"""
+        self.ensure_one()
+        company_currency = self.company_id.currency_id
+        voucher_currency = self.currency_id.with_context(date=self.date)
+
+        value = 1
+        if invoice.currency_id != voucher_currency:
+            value = float_round(
+                voucher_currency._convert(
+                    1.0,
+                    invoice.currency_id,
+                    self.company_id,
+                    self.date,
+                    round=False,
+                ),
+                precision_digits=6
+            )
+
+        return value
+
+    def impuestos_dr(self, invoice, tax_type="traslados"):
+        """Computes move lines for on payment taxes related to given invoice"""
+        self.ensure_one()
+
+        # Get payments done in this voucher for given invoice
+        payments = self._l10n_mx_get_payments_to_invoice(invoice)
+        payments &= self.line_ids
+
+        tax_reconciles = invoice.tax_cash_basis_created_move_ids.mapped(
+            "tax_cash_basis_rec_id"
+        ).filtered(
+            lambda rec: rec.credit_move_id in payments
+        )
+
+        # Get tax moves done for this payment and this invoice
+        domain = [("move_id.tax_cash_basis_rec_id", "in", tax_reconciles._ids)]
+        # Exclude IEPS if partner not IEPS subjected
+        if not self.partner_id.ieps_subjected:
+            domain.append(
+                ("tax_ids.invoice_repartition_line_ids.tag_ids.name", "!=", "IEPS")
+            )
+
+        if tax_type == "traslados":
+            domain.append(("tax_ids.amount", ">=", 0))
+            domain.append(("tax_ids.amount_type", "=", "percent"))
+
+        else:
+            domain.append(("tax_ids.amount", "<", 0))
+            domain.append(("tax_ids.amount_type", "=", "percent"))
+
+        tax_moves = self.env["account.move.line"].search(domain)
+        return tax_moves
+
+    def totales_p(self, tax_type="traslados"):
+        """Computes move lines for on payment taxes related to given invoice"""
+        self.ensure_one()
+        tax_totals = {}
+
+        impuestos = self.impuestos_p(tax_type=tax_type)
+        # Load tax record for being able to use on template to fill XML
+        for line in impuestos:
+            tax = line["tax"]
+            tax_rep_lines = tax.invoice_repartition_line_ids._origin.filtered(
+                lambda x: x.repartition_type == "tax"
+            )
+            tax_group = tax_rep_lines.mapped("tag_ids")
+            key = tax_group.name + str(tax.amount)
+
+            tax_totals["importe" + key] = line["importe"]
+            tax_totals["base" + key] = line["tax_base"]
+
+        return tax_totals
+
+    def impuestos_p(self, tax_type="traslados"):
+        """Computes move lines for on payment taxes related to given invoice"""
+        self.ensure_one()
+
+        tax_totals = dict()
+
+        for invoice in self.doctos_relacionados:
+            for base_line in self.impuestos_dr(invoice, tax_type=tax_type):
+                for tax in base_line.tax_ids:
+                    if tax.id not in tax_totals:
+                        tax_totals[tax.id] = dict(
+                            tax=tax,
+                            tax_base=0.0,
+                            importe=0.0,
+                        )
+
+                    tax_base = self._l10n_mx_tax_base_p(invoice, base_line)
+                    importe = self._l10n_mx_tax_importe_p(invoice, base_line)
+
+                    tax_totals[tax.id]["tax_base"] += tax_base
+                    tax_totals[tax.id]["importe"] += importe
+
+        return [line for line in tax_totals.values()]
+
+    def _l10n_mx_tax_base_dr(self, invoice, base_line):
+        amount = base_line.balance
+
+        if invoice.currency_id != self.company_id.currency_id:
+            amount = base_line.amount_currency
+
+        return -1 * amount
+
+    def _l10n_mx_tax_importe_dr(self, invoice, base_line):
+        tax_line = base_line.move_id.line_ids.filtered(
+            lambda l:
+                l.tax_line_id in base_line.tax_ids
+        )
+        amount = tax_line.balance
+
+        if invoice.currency_id != self.company_id.currency_id:
+            amount = tax_line.amount_currency
+
+        return -1 * amount
+
+    def _l10n_mx_tax_base_p(self, invoice, base_line):
+        amount = base_line.balance
+
+        if self.currency_id != self.company_id.currency_id:
+            amount = base_line.amount_currency
+            if invoice.currency_id == self.company_id.currency_id:
+                amount = invoice.currency_id._convert(
+                    amount,
+                    self.currency_id,
+                    self.company_id,
+                    self.date,
+                )
+
+        return -1 * amount
+
+    def _l10n_mx_tax_importe_p(self, invoice, base_line):
+        tax_line = base_line.move_id.line_ids.filtered(
+            lambda l:
+                l.tax_line_id in base_line.tax_ids
+        )
+        amount = tax_line.balance
+
+        if self.currency_id != self.company_id.currency_id:
+            amount = tax_line.amount_currency
+            if invoice.currency_id == self.company_id.currency_id:
+                amount = invoice.currency_id._convert(
+                    amount,
+                    self.currency_id,
+                    self.company_id,
+                    self.date,
+                )
+
+        return -1 * amount
diff --git a/l10n_mx_facturae/models/account_voucher.py b/l10n_mx_facturae/models/account_voucher.py
deleted file mode 100644
index 6258e9bfbf5ea35f39e9af818488cb6811e90646..0000000000000000000000000000000000000000
--- a/l10n_mx_facturae/models/account_voucher.py
+++ /dev/null
@@ -1,415 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from openerp import api, fields, models
-from openerp.exceptions import ValidationError
-from openerp.tools import float_round
-from openerp.tools.translate import _
-
-
-class AccountVoucher(models.Model):
-    _name = "account.voucher"
-    _inherit = ["account.voucher", "base.cfdi"]
-
-    show_unreconcile = fields.Boolean(
-        compute="_compute_show_unreconcile",
-        help="Helper field to hide unreconcile button",
-    )
-
-    @api.multi
-    @api.depends("state", "cfdi_state")
-    def _compute_show_unreconcile(self):
-        for voucher in self:
-            if voucher.cfdi_state in ["signed", "done"]:
-                voucher.show_unreconcile = False
-            elif voucher.state in ["draft", "cancel"]:
-                voucher.show_unreconcile = False
-            else:
-                voucher.show_unreconcile = True
-
-    @api.multi
-    def _compute_sequence_id(self):
-        for record in self:
-            record.sequence_id = record.journal_id.sequence_id
-
-    @api.multi
-    def sign_voucher(self):
-        """Create CFDI for selected vouchers"""
-        # Only vouchers to sign are the receipts
-        receipts = self.filtered(lambda r: r.type == "receipt")
-        # Get only receipts that doesn't have a CFDI yet and create it
-        for receipt in receipts.filtered(lambda r: not r.cfdi_id.exists()):
-            receipt.create_cfdi()
-
-    @api.multi
-    def cancel_voucher(self):
-        """Cancel CFDI for selected vouchers"""
-        res = super(AccountVoucher, self).cancel_voucher()
-        self.cancel_cfdi()
-        # Delete relation from voucher and CFDI
-        self.cfdi_id = False
-        return res
-
-    @api.multi
-    def substitute_voucher(self):
-        """Create new voucher for substitute this one"""
-        self._cancel_cfdi()
-        # After cancel voucher we must re open it
-        self.action_cancel_draft()
-
-    @api.multi
-    def _cancel_cfdi_related_document(self):
-        self.cancel_voucher()
-
-    @api.multi
-    def replace_cfdi(self):
-        """Cancel voucher cfdi by replacing with 1 MXN voucher"""
-        self._cancel_cfdi()
-
-    @api.multi
-    def currency_rate(self):
-        """Compute currency rate used for current voucher to display on XML
-        This calls currency.compute() with the right context,
-        so that it will take either the rate on the voucher if it is relevant
-        or will use the default behavior"""
-        self.ensure_one()
-        # We need to give the date in the context to get proper rate
-        voucher_currency = self.journal_id.currency or self.company_id.currency_id
-        voucher_currency = voucher_currency.with_context(date=self.date)
-        voucher_currency = voucher_currency.with_context(
-            special_currency_rate=(
-                voucher_currency.rate * self.payment_rate
-            ),
-            special_currency=(
-                self.payment_rate_currency_id
-                and self.payment_rate_currency_id.id
-                or False
-            ),
-        )
-        res = float_round(
-            voucher_currency.compute(1.0, self.company_id.currency_id, round=False),
-            precision_digits=6,
-        )
-        return res
-
-    @property
-    def doctos_relacionados(self):
-        """Return a list with all related invoices to this payment"""
-        self.ensure_one()
-
-        # Get all records from account.move.line related to this voucher but
-        # affecting an account different than the selected for this voucher
-        move_lines = self.move_ids.filtered(lambda x: x.account_id != self.account_id)
-        # Get all lines form partial and full reconciliations
-        temp_lines = move_lines.mapped("reconcile_partial_id.line_partial_ids")
-        temp_lines |= move_lines.mapped("reconcile_id.line_id")
-
-        # Get only invoices related to this voucher
-        invoices = (temp_lines - move_lines).mapped("invoice")
-        invoices = invoices.filtered(lambda i: i.type == "out_invoice")
-
-        # Validate that all related invoices have an uuid
-        tofix = invoices.filtered(lambda i: not i.cfdi_folio_fiscal)
-        if tofix:
-            raise ValidationError(
-                _("Some of the invoices that will be paid with this record are not "
-                  "signed, and the UUID is required to indicate the invoices that "
-                  "are paid with this CFDI ")
-            )
-        return invoices
-
-    @api.multi
-    def numparcialidad(self, invoice):
-        """Computes payment number based on all payments done to invoice"""
-        # Get all payments done to given invoice
-        payments = invoice.mapped("payment_ids") - self.move_ids
-        # Leave only payments done in cash or bank older than current
-        payments = payments.filtered(
-            lambda r: r.date >= invoice.date_invoice
-            and r.journal_id.type in ("cash", "bank")
-        )
-        return len(payments) + 1
-
-    @api.multi
-    def impsaldoant(self, invoice):
-        """Computes amount_residual for invoice before current voucher"""
-        self.ensure_one()
-        # It is verified that the invoice is in another currency
-        is_multi_currency = (
-            invoice.currency_id != self.company_id.currency_id
-        )
-        # Search the lines of the policy where the account is receivable or payable
-        move_line_ids = invoice.move_id.line_id.filtered(
-            lambda x: x.account_id.user_type.type in ("receivable", "payable")
-        )
-        if is_multi_currency:
-            amount_residual = sum(
-                move_line.amount_currency for move_line in move_line_ids
-            )
-        else:
-            amount_residual = sum(
-                move_line.balance for move_line in move_line_ids
-            )
-        # Get all payments done to given invoice
-        payments = invoice.mapped("payment_ids") - self.move_ids
-        payment_date = self.move_ids[0].create_date
-        # Leave only payments done before (older than) the current one:
-        # 1.  Payments with document date before current voucher date
-        # 2.  Payments with same date but created before that current voucher
-        payments = payments.filtered(
-            lambda r:
-                r.date < self.date
-                or (r.date == self.date and r.create_date < payment_date)
-        )
-
-        for payment in payments:
-            amount_currency = abs(payment.amount_currency) or 0.0
-            # If amount_currency exists it means we are dealing with a multi
-            # currency payment, and thus we need to sum amount_currency to
-            # amount_paid instead of normal debit - credit
-            if payment.currency_id:
-                amount_residual -= amount_currency
-            else:
-                amount_residual -= abs(payment.debit - payment.credit)
-        return self.currency_id.cfdi_round(amount_residual)
-
-    @api.multi
-    def imppagado(self, invoice):
-        """Computes total amount payment on this voucher for given invoice"""
-        self.ensure_one()
-
-        amount_paid = 0.0
-        # Get payments done in this voucher for given invoice
-        payments = invoice.mapped("payment_ids") & self.move_ids
-
-        for payment in payments:
-            # If currency_id exists it means we are dealing with a multi
-            # currency payment, and thus we need to sum amount_currency to
-            # amount_paid instead of normal debit - credit
-            # TODO: Relay on currency_id could result in wrong results when
-            # transactions done in three different currencies or more
-            is_multi_currency = (
-                payment.currency_id
-                and invoice.currency_id != self.company_id.currency_id
-            )
-            if is_multi_currency:
-                amount_paid += payment.amount_currency * -1
-            else:
-                amount_paid += (payment.debit - payment.credit) * -1
-
-        # Compute amount of writeoff to adjust amount payment to this invoice
-        if self.currency_id == invoice.currency_id and self.writeoff_amount < 0.0:
-            amount_paid += self.writeoff_amount / len(self.doctos_relacionados)
-        amount_paid = self.currency_id.cfdi_round(amount_paid)
-
-        # Ensure amount paid is always equal or less than amount residual
-        amount_residual = self.impsaldoant(invoice)
-        amount_paid = min(amount_paid, amount_residual)
-        return amount_paid
-
-    @api.multi
-    def tipocambiodr(self, invoice):
-        """Compute currency rate used for given invoice to display on XML
-        This calls curreny.compute() with the right context,
-        so that it will take either the rate on the voucher if it is relevant
-        or will use the default behavior"""
-        self.ensure_one()
-        company_currency = self.company_id.currency_id
-        voucher_currency = self.currency_id.with_context(date=self.date)
-
-        if invoice.currency_id == company_currency:
-            # When invoice is in company currency we are going to use payment rate
-            voucher_currency = voucher_currency.with_context(
-                special_currency_rate=(1 / self.payment_rate),
-                special_currency=voucher_currency.id,
-            )
-        else:
-            voucher_currency = voucher_currency.with_context(
-                special_currency_rate=(1 / invoice.currency_rate),
-                special_currency=invoice.currency_id.id,
-            )
-
-        value = float_round(
-            voucher_currency.compute(1.0, invoice.currency_id, round=False),
-            precision_digits=6
-        )
-
-        if (
-            voucher_currency == company_currency
-            and invoice.currency_id != company_currency
-        ):
-            # Hack to bypass PAC validation, suggested by PAC
-            value += 0.000001
-
-        return value
-
-    @api.multi
-    def impuestos_dr(self, invoice, tax_type="traslados"):
-        """Computes move lines for on payment taxes related to given invoice"""
-        self.ensure_one()
-        # Get payments done in this voucher for given invoice
-        payments = invoice.mapped("payment_ids") & self.move_ids
-        tax_reconciles = payments.mapped("tax_reconcile_id")
-        domain = self._l10n_mx_get_taxes_domain(tax_reconciles, tax_type=tax_type)
-        tax_moves = self.env["account.move.line"].search(domain)
-        return tax_moves
-
-    @api.multi
-    def totales_p(self, tax_type="traslados"):
-        """Computes move lines for on payment taxes related to given invoice"""
-        self.ensure_one()
-        tax_totals = []
-        company_currency = self.company_id.currency_id
-        voucher_currency = self.currency_id.with_context(date=self.date)
-        impuestos = self.impuestos_p(tax_type=tax_type)
-        # Load tax record for being able to use on template to fill XML
-        for line in impuestos:
-            if company_currency != voucher_currency:
-                company_currency = company_currency.with_context(
-                    special_currency_rate=self.currency_rate(),
-                    special_currency=voucher_currency.id,
-                )
-                line["importe"] = company_currency.compute(
-                    line["importe"], voucher_currency,
-                )
-                line["tax2_base"] = company_currency.compute(
-                    line["tax2_base"], voucher_currency,
-                )
-            else:
-                line["importe"] = float_round(
-                    line["importe"], precision_digits=2,
-                )
-                line["tax2_base"] = float_round(
-                    line["tax2_base"], precision_digits=2,
-                )
-
-            tax_totals.append(line)
-
-        return tax_totals
-
-    @api.multi
-    def impuestos_p(self, tax_type="traslados"):
-        """Computes move lines for on payment taxes related to given invoice"""
-        self.ensure_one()
-        company_currency = self.company_id.currency_id
-        voucher_currency = self.currency_id.with_context(date=self.date)
-        tax_totals = dict()
-
-        for invoice in self.doctos_relacionados:
-            for tax_move in self.impuestos_dr(invoice, tax_type=tax_type):
-                if tax_move.tax2_id.id not in tax_totals:
-                    tax_totals[tax_move.tax2_id.id] = dict(
-                        tax2_id=tax_move.tax2_id,
-                        tax2_base=0.0,
-                        importe=0.0,
-                    )
-
-                if tax_move.currency_id != voucher_currency:
-                    invoice_currency = (
-                        tax_move.currency_id
-                        if tax_move.currency_id else company_currency
-                    )
-                    invoice_currency = invoice_currency.with_context(date=self.date)
-                    if invoice_currency != company_currency:
-                        invoice_currency = invoice_currency.with_context(
-                            special_currency_rate=self.tipocambiodr(invoice),
-                            special_currency=invoice_currency.id,
-                        )
-                    else:
-                        invoice_currency = invoice_currency.with_context(
-                            special_currency_rate=(1 / self.tipocambiodr(invoice)),
-                            special_currency=voucher_currency.id,
-                        )
-                    tax2_base = invoice_currency.compute(
-                        tax_move.tax2_base, voucher_currency, round=False,
-                    )
-                    # Force rounding 6 decimals to use as many decimal as possible and
-                    # avoid rounding errors when validating XML
-                    tax2_base = float_round(
-                        tax2_base, precision_digits=6, rounding_method="DOWN",
-                    )
-                else:
-                    tax2_base = tax_move.tax2_base
-
-                tax_totals[tax_move.tax2_id.id]["tax2_base"] += tax2_base
-                tax_totals[tax_move.tax2_id.id]["importe"] += float_round(
-                    tax2_base * tax_move.tax2_id.amount,
-                    precision_digits=6,
-                    rounding_method="DOWN",
-                )
-
-        return [line for line in tax_totals.values()]
-
-    @api.multi
-    def _l10n_mx_get_taxes_domain(self, tax_reconciles, tax_type="traslados"):
-        self.ensure_one()
-        # Get tax moves done for this payment and this invoice
-        domain = [("tax_reconcile_id", "in", tax_reconciles._ids)]
-        # Exclude IEPS if partner not IEPS subjected
-        if not self.partner_id.ieps_subjected:
-            domain.append(
-                ("tax2_id.tax_category_id.code", "!=", "IEPS")
-            )
-
-        if tax_type == "traslados":
-            domain.append("|")
-            domain.append(("tax2_id.type", "=", "none"))
-            domain.append("&")
-            domain.append(("tax2_id.amount", ">=", 0))
-            domain.append(("tax2_id.type", "=", "percent"))
-
-        else:
-            domain.append(("tax2_id.amount", "<", 0))
-            domain.append(("tax2_id.type", "=", "percent"))
-
-        return domain
-
-    @api.multi
-    def _validate_cfdi_data(self):
-        self._validate_account_voucher_vat()
-        self._validate_account_voucher_payment_type()
-
-    @api.multi
-    def _validate_account_voucher_vat(self):
-        """ This is function is to validate that the
-        partner has a vat, name and property account position """
-
-        required = [
-            "vat",
-            "name",
-            "cfdi_fiscal_regime_id"
-        ]
-
-        for record in self:
-            # Validate required fields on document
-            self._cfdi_validate_required_fields(
-                record,
-                [
-                    "partner_id",
-                    "amount",
-                    "journal_id",
-                    "payment_type_id",
-                    "company_id"
-                ],
-            )
-
-            self._cfdi_validate_required_fields(
-                record.company_id.partner_id,
-                required,
-            )
-
-            self._cfdi_validate_required_fields(
-                record.partner_id,
-                required,
-            )
-
-    @api.multi
-    def _validate_account_voucher_payment_type(self):
-        for record in self:
-
-            # It is validated that there is a payment method or that the
-            # selected payment method has code 99
-
-            if not record.payment_type_id or record.payment_type_id.code == "99":
-                raise ValidationError(
-                    _("The payment method is missing or the payment method has code 99")
-                )
diff --git a/l10n_mx_facturae/models/email_template.py b/l10n_mx_facturae/models/email_template.py
index bfdcf7410b4024b9e39f33599768f7ef1ef5e4e7..c24134b6e2b3eb292504a482f66aa3135d3f1a8e 100644
--- a/l10n_mx_facturae/models/email_template.py
+++ b/l10n_mx_facturae/models/email_template.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-from openerp import api, models
+from odoo import api, models
 
 
 class EmailTemplate(models.Model):
diff --git a/l10n_mx_facturae/models/res_company.py b/l10n_mx_facturae/models/res_company.py
new file mode 100644
index 0000000000000000000000000000000000000000..4332c84e3137943ee66af144c8f94a5b3498794e
--- /dev/null
+++ b/l10n_mx_facturae/models/res_company.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+from odoo import api, fields, models
+
+
+class ResCompany(models.Model):
+    _inherit = "res.company"
+
+    cfdi_use_id = fields.Many2one(
+        "cfdi.use",
+        string="Use CFDI",
+        compute="_compute_use_cfdi",
+        inverse="_inverse_use_cfdi",
+    )
+
+    def _compute_use_cfdi(self):
+        for company in self:
+            use_cfdi = company.partner_id.cfdi_use_id
+            company.cfdi_use_id = use_cfdi.id
+
+    def _inverse_use_cfdi(self):
+        for company in self:
+            partner = company.partner_id
+            partner.cfdi_use_id = company.cfdi_use_id
diff --git a/l10n_mx_facturae/models/res_partner.py b/l10n_mx_facturae/models/res_partner.py
index 95bc6a89f076676639a836e2b121295ca17a3139..9ea8f093e4b44791e72b6f2d00bb9b35a1b6ed33 100644
--- a/l10n_mx_facturae/models/res_partner.py
+++ b/l10n_mx_facturae/models/res_partner.py
@@ -1,38 +1,54 @@
 # -*- coding: utf-8 -*-
 
-from openerp import api, fields, models
+from odoo import api, fields, models
 
 
 class ResPartner(models.Model):
     _inherit = "res.partner"
 
-    cfdi_use = fields.Many2one(
+    cfdi_use_id = fields.Many2one(
         "cfdi.use",
         "CFDI use",
         help="Cfdi usage that will be used by default on this customer "
         "invoices and credit notes",
     )
+
     cfdi_adenda_ids = fields.Many2many(
         "cfdi.adenda",
         string="CFDI Adendas",
         help="This field allows adding a node or addendum to the invoice",
     )
+
     payment_method_id = fields.Many2one(
         "cfdi.payment.method",
         string="Payment Method",
         help="Payment method associated with this partner according"
-        "to CFDI 3.3 catalog.",
+        "to CFDI 4.0 catalog.",
     )
+
     supplier_number = fields.Char(
         help="Number or reference that the Client assigned to our company."
     )
-    gln_number = fields.Char("GLN Number", help="Customer or Delivery branch")
+
+    gln_number = fields.Char(
+        "GLN Number",
+        help="Customer or Delivery branch"
+    )
+
     edi = fields.Char("User EDI")
-    show_glnnumber = fields.Boolean(compute="_compute_show_number")
-    show_suppliernumber = fields.Boolean(compute="_compute_show_number")
-    show_edi = fields.Boolean(compute="_compute_show_number")
 
-    @api.multi
+    show_glnnumber = fields.Boolean(
+        compute="_compute_show_number"
+    )
+
+    show_suppliernumber = fields.Boolean(
+        compute="_compute_show_number"
+    )
+
+    show_edi = fields.Boolean(
+        compute="_compute_show_number"
+    )
+
     @api.depends("cfdi_adenda_ids")
     def _compute_show_number(self):
         for record in self:
diff --git a/l10n_mx_facturae/report/__init__.py b/l10n_mx_facturae/report/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..dd3fb58358d6362b7384006875e04733600719d5
--- /dev/null
+++ b/l10n_mx_facturae/report/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+from . import account_move
+from . import account_payment
diff --git a/l10n_mx_facturae/report/account_invoice.odt b/l10n_mx_facturae/report/account_invoice.odt
deleted file mode 100644
index 7fd53ab3112f6263b1541abf65b06af66cd8c284..0000000000000000000000000000000000000000
Binary files a/l10n_mx_facturae/report/account_invoice.odt and /dev/null differ
diff --git a/l10n_mx_facturae/report/account_move.odt b/l10n_mx_facturae/report/account_move.odt
new file mode 100644
index 0000000000000000000000000000000000000000..75f9031ef26c464fc0cd0e355588980a1be7dd2f
Binary files /dev/null and b/l10n_mx_facturae/report/account_move.odt differ
diff --git a/l10n_mx_facturae/report/account_move.py b/l10n_mx_facturae/report/account_move.py
new file mode 100644
index 0000000000000000000000000000000000000000..91e1bf36d52cb2c255d8006cd94ad3fbad4d6739
--- /dev/null
+++ b/l10n_mx_facturae/report/account_move.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+from odoo import api, models
+
+
+class Parser(models.AbstractModel):
+    _inherit = "report.l10n_mx_cfdi"
+    _description = "report.l10n_mx_facturae.account_move"
+    _name = "report.l10n_mx_facturae.account_move"
+
+    def _get_report_values(self, docids, data=None):
+        res = super()._get_report_values(docids, data=data)
+        docs = self.env["account.move"].browse(docids)
+        # return a custom rendering context
+        res.update(
+            {
+                "doc_ids": docids,
+                "doc_model": "account.move",
+                "docs": docs,
+            }
+        )
+        return res
diff --git a/l10n_mx_facturae/report/account_payment.odt b/l10n_mx_facturae/report/account_payment.odt
new file mode 100644
index 0000000000000000000000000000000000000000..248f346134694e2fa203e3993d099b899bc95dba
Binary files /dev/null and b/l10n_mx_facturae/report/account_payment.odt differ
diff --git a/l10n_mx_facturae/report/account_payment.py b/l10n_mx_facturae/report/account_payment.py
new file mode 100644
index 0000000000000000000000000000000000000000..1cd16ae961618a584178506178e2da3a41465830
--- /dev/null
+++ b/l10n_mx_facturae/report/account_payment.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+from odoo import api, models
+
+
+class Parser(models.AbstractModel):
+    _inherit = "report.l10n_mx_cfdi"
+    _description = "report.l10n_mx_facturae.account_payment"
+    _name = "report.l10n_mx_facturae.account_payment"
+
+    @api.model
+    def aeroo_report(self, docids, data):
+        self = self.with_context(
+            format_impuesto=self._format_impuesto,
+            format_tasaocuota=self._format_tasaocuota,
+        )
+        return super(Parser, self).aeroo_report(docids, data)
+
+    def _get_report_values(self, docids, data=None):
+        res = super()._get_report_values(docids, data=data)
+        docs = self.env["account.payment"].browse(docids)
+        # return a custom rendering context
+        res.update(
+            {
+                "doc_ids": docids,
+                "doc_model": "account.payment",
+                "docs": docs,
+                "format_impuesto": self._format_impuesto,
+                "format_tasaocuota": self._format_tasaocuota,
+            }
+        )
+        return res
+
+    def _format_impuesto(self, tax):
+        tax_types = {
+            "ISR": "001",
+            "IVA": "002",
+            "IEPS": "003",
+        }
+        tax_rep_lines = tax.invoice_repartition_line_ids._origin.filtered(
+            lambda x: x.repartition_type == "tax"
+        )
+        tax_group = tax_rep_lines.mapped("tag_ids")
+        return tax_types[tax_group.name]
+
+    def _format_tasaocuota(self, tax):
+        """Format tasa o cuota"""
+        return "{0:.6f}".format(abs(tax.amount) / 100)
diff --git a/l10n_mx_facturae/report/account_voucher.odt b/l10n_mx_facturae/report/account_voucher.odt
deleted file mode 100644
index 04b4379a894f1b130eb544315004ca4c1b1cd335..0000000000000000000000000000000000000000
Binary files a/l10n_mx_facturae/report/account_voucher.odt and /dev/null differ
diff --git a/l10n_mx_facturae/security/res_groups.xml b/l10n_mx_facturae/security/res_groups.xml
index 9cc098cef4094321eaf3b8c18a3f13ff95903ee0..66505f1597a09d93c3741b89a46656f37f5e5369 100644
--- a/l10n_mx_facturae/security/res_groups.xml
+++ b/l10n_mx_facturae/security/res_groups.xml
@@ -4,7 +4,7 @@
 
     <record id="cfdi_cuentapredial" model="res.groups">
         <field name="name">Cfdi Cuenta Predial</field>
-        <field name="category_id" ref="l10n_mx.module_category_l10n_mx"/>
+        <field name="category_id" ref="l10n_mx_base.module_category_l10n_mx"/>
         <field name="comment">The user will have access to add Cuenta Predial information to invoice lines.</field>
     </record>
 
diff --git a/l10n_mx_facturae/templates/account_invoice.txt b/l10n_mx_facturae/templates/account_move.txt
similarity index 100%
rename from l10n_mx_facturae/templates/account_invoice.txt
rename to l10n_mx_facturae/templates/account_move.txt
diff --git a/l10n_mx_facturae/templates/account_move.xml b/l10n_mx_facturae/templates/account_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cc81104eb45719e289dc1d70c9946357d356bb8d
--- /dev/null
+++ b/l10n_mx_facturae/templates/account_move.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+    <template id="account_move">
+        <t t-set="move" t-value="docs[0]" />
+        <t t-set="taxes" t-value="move.impuestos" />
+        <t t-set="total_traslados" t-value="move.l10n_mx_facturae_compute_total_traslados(taxes)" />
+        <t t-set="total_retenciones" t-value="move.l10n_mx_facturae_compute_total_retenciones(taxes)" />
+        <t t-set="tipoCambio" t-value="move.l10n_mx_facturae_compute_tipocambio()"/>
+        <t t-set="residenciaFiscal" t-value="move.l10n_mx_facturae_compute_residencia_fiscal()"/>
+        <t t-set="regimenTrib" t-value="move.l10n_mx_facturae_compute_regimen_tributario()"/>
+        <cfdi:Comprobante t-foreach="docs" t-as="o"
+            xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd"
+            xmlns:cfdi="http://www.sat.gob.mx/cfd/4"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            t-attf-Version="4.0"
+            t-attf-Exportacion="{{ o.l10n_mx_facturae_compute_export() }}"
+            t-attf-Folio="{{ o.folio }}"
+            t-attf-Fecha="{{ o.l10n_mx_facturae_compute_fecha() }}"
+            t-attf-Sello="@"
+            t-attf-NoCertificado="@"
+            t-attf-Certificado="@"
+            t-attf-FormaPago="{{ o.formapago }}"
+            t-attf-CondicionesDePago="{{ o.l10n_mx_facturae_compute_payment_terms() }}"
+            t-attf-SubTotal="{{ o.l10n_mx_facturae_compute_subtotal()}}"
+            t-attf-Descuento="{{ o.descuento }}"
+            t-attf-Moneda="{{ o.currency_id.name }}"
+            t-att-TipoCambio="tipoCambio"
+            t-attf-Total="{{ o.l10n_mx_facturae_compute_total() }}"
+            t-attf-TipoDeComprobante="{{ o.l10n_mx_facturae_compute_type_document() }}"
+            t-attf-MetodoPago="{{ o.l10n_mx_facturae_compute_payment_method() }}"
+            t-attf-LugarExpedicion="{{ o.address_issued_id.zip }}">
+            <cfdi:CfdiRelacionados t-attf-TipoRelacion="o.cfdi_relation_type.code" t-if="o.reversed_entry_id">
+                <cfdi:CfdiRelacionado  t-foreach="o.reversed_entry_id" t-as="cfdi" t-attf-UUID="cfdi.cfdi_folio_fiscal"/>
+            </cfdi:CfdiRelacionados>
+            <cfdi:CfdiRelacionados t-attf-TipoRelacion="o.cfdi_relation_type.code" t-if="o.related_cfdi_ids">
+                <cfdi:CfdiRelacionado  t-foreach="o.related_cfdi_ids" t-as="cfdi" t-attf-UUID="cfdi.uuid"/>
+            </cfdi:CfdiRelacionados>
+            <cfdi:InformacionGlobal
+                t-if="o.invoice_global"
+                t-attf-Año="{{ o.l10n_mx_facturae_compute_fecha_global_year() }}"
+                t-attf-Meses="{{ o.l10n_mx_facturae_compute_fecha_global_month() }}"
+                t-attf-Periodicidad="{{ o.cfdi_periodicity }}" />
+            <cfdi:Emisor
+                t-attf-Rfc="{{ o.company_id.partner_id.vat_split }}"
+                t-attf-Nombre="{{ o.company_id.partner_id.name.upper() }}"
+                t-attf-RegimenFiscal="{{ o.company_id.partner_id.cfdi_fiscal_regime_id.code }}"/>
+            <cfdi:Receptor
+                t-attf-Nombre="{{ o.commercial_partner_id.name.upper() }}"
+                t-attf-Rfc="{{ o.l10n_mx_facturae_compute_rfc() }}"
+                t-attf-UsoCFDI="{{ o.l10n_mx_facturae_compute_use_cfdi() }}"
+                t-attf-DomicilioFiscalReceptor="{{ o.l10n_mx_facturae_compute_domicilio_fiscal() }}"
+                t-attf-RegimenFiscalReceptor="{{ o.l10n_mx_facturae_compute_regimen_fiscal_receptor() }}"
+                t-att-ResidenciaFiscal="residenciaFiscal"
+                t-att-NumRegIdTrib="regimenTrib" />
+            <cfdi:Conceptos>
+                <cfdi:Concepto t-foreach="o.invoice_line_ids" t-as="line"
+                    t-attf-ClaveProdServ="{{ o.l10n_mx_facturae_compute_product() }}"
+                    t-attf-NoIdentificacion="{{ line.cfdi_numero_identificacion }}"
+                    t-attf-Cantidad="{{ line.quantity }}"
+                    t-attf-ClaveUnidad="{{ line.product_uom_id.cfdi_unit_measure_id.code }}"
+                    t-attf-Unidad="{{ o.l10n_mx_facturae_compute_unit() }}"
+                    t-attf-Descripcion="{{ line.name }}"
+                    t-attf-ValorUnitario="{{ line.valorunitario }}"
+                    t-attf-Importe="{{ line.l10n_mx_facturae_importe() }}"
+                    t-attf-Descuento="{{ line.descuento }}"
+                    t-attf-ObjetoImp="{{ line.l10n_mx_facturae_compute_objeto_impuesto() }}">
+				    <cfdi:Impuestos t-if="line.l10n_mx_facturae_compute_objeto_impuesto() == '02' ">
+				        <cfdi:Traslados t-if="line.impuestos['traslados']">
+                            <t t-set="impuestos" t-value="line.impuestos"/>
+				            <cfdi:Traslado t-foreach="impuestos['traslados']" t-as="tax"
+				                t-att-Base="format_float(tax.base, o.currency_id.decimal_places)"
+                                t-attf-Impuesto="{{ tax.xml_name }}"
+                                t-attf-TipoFactor="{{ tax.type }}"
+				                t-attf-TasaOCuota="{{ tax.TasaOCuota }}"
+				                t-attf-Importe="{{ tax.xml_amount }}" />
+				        </cfdi:Traslados>
+				        <cfdi:Retenciones t-if="impuestos['retenciones']">
+				            <cfdi:Retencion t-foreach="impuestos['retenciones']" t-as="tax"
+				                t-att-Base="format_float(tax.base, o.currency_id.decimal_places)"
+                                t-attf-Impuesto="{{ tax.xml_name }}"
+                                t-attf-TipoFactor="{{ tax.type }}"
+				                t-attf-TasaOCuota="{{ tax.TasaOCuota }}"
+				                t-attf-Importe="{{ tax.xml_amount }}" />
+				        </cfdi:Retenciones>
+				    </cfdi:Impuestos>
+                    <cfdi:CuentaPredial t-if="line.cfdi_cuentapredial"
+                        t-attf-Numero="line.cfdi_cuentapredial" />
+                    <cfdi:InformacionAduanera
+                        t-if="line.cfdi_custom_number"
+                        t-foreach="line.cfdi_custom_number" t-as="cfdi_custom_number"
+                        t-attf-NumeroPedimento="{{ cfdi_custom_number.name }}" />
+                </cfdi:Concepto>
+            </cfdi:Conceptos>
+            <cfdi:Impuestos
+                t-att-TotalImpuestosTrasladados="total_traslados"
+                t-att-TotalImpuestosRetenidos="total_retenciones" >
+                <cfdi:Retenciones t-if="taxes['retenciones']">
+                    <cfdi:Retencion t-foreach="taxes['retenciones']" t-as="tax"
+                        t-attf-Impuesto="{{ tax.xml_name }}"
+                        t-attf-Importe="{{ tax.xml_amount }}" />
+                </cfdi:Retenciones>
+                <cfdi:Traslados t-if="taxes['traslados']">
+                    <cfdi:Traslado t-foreach="taxes['traslados']" t-as="tax"
+                        t-att-Base="format_float(tax.base, o.currency_id.decimal_places)"
+                        t-attf-Impuesto="{{ tax.xml_name }}"
+                        t-attf-TipoFactor="{{ tax.type }}"
+                        t-attf-TasaOCuota="{{ tax.TasaOCuota }}"
+                        t-attf-Importe="{{ tax.xml_amount }}" />
+                </cfdi:Traslados>
+            </cfdi:Impuestos>
+            <!--
+            <cfdi:Complemento t-if="is_local_taxes">
+                <implocal:ImpuestosLocales
+                    t-attf-version="1.0"
+                    t-attf-TotaldeTraslados="${ '{0:.2f}'.format(sumif(taxes.locales, 'amount', [('amount', '>', 0)])) }"
+                    t-attf-TotaldeRetenciones="${ '{0:.2f}'.format(abs(sumif(taxes.locales, 'amount', [('amount', '<', 0)]))) }">
+                    <implocal:TrasladosLocales
+                        t-foreach="taxes.locales" t-as="tax_line"
+                        t-if="tax_line.amount > 0"
+                        t-attf-ImpLocTrasladado="html_escape(tax_line.name)"
+                        t-attf-TasadeTraslado="${ '{0:.2f}'.format(tax_line.TasaOCuota * 100) }"
+                        t-attf-Importe="tax_line.amount" />
+                    <implocal:RetencionesLocales
+                        t-foreach="taxes.locales" t-as="tax_line"
+                        t-if="tax_line.amount < 0"
+                        t-attf-ImpLocRetenido="html_escape(tax_line.name)"
+                        t-attf-TasadeRetencion="tax_line.TasaOCuota * 100 }"
+                        t-attf-Importe="tax_line.amount" />
+                </implocal:ImpuestosLocales>
+            </cfdi:Complemento>
+            -->
+        </cfdi:Comprobante>
+
+    </template>
+
+</odoo>
diff --git a/l10n_mx_facturae/templates/account_payment.xml b/l10n_mx_facturae/templates/account_payment.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93989a084828268e39dd325b3dbeafde876ed96e
--- /dev/null
+++ b/l10n_mx_facturae/templates/account_payment.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+    <template id="account_payment">
+        <t t-set="payment" t-value="docs[0]" />
+        <t t-set="residenciaFiscal" t-value="payment.l10n_mx_facturae_payment_compute_residencia_fiscal()"/>
+        <t t-set="regimenTrib" t-value="payment.l10n_mx_facturae_payment_compute_regimen_tributario()"/>
+        <t t-set="tipoCambio" t-value="payment.l10n_mx_facturae_payment_compute_tipocambio()"/>
+        <t t-set="traslados" t-value="payment.totales_p()" />
+        <t t-set="retenciones" t-value="payment.totales_p(tax_type='retenciones')" />
+        <cfdi:Comprobante t-foreach="docs" t-as="o"
+            xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd http://www.sat.gob.mx/Pagos20 http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos20.xsd"
+            xmlns:cfdi="http://www.sat.gob.mx/cfd/4"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns:pago20="http://www.sat.gob.mx/Pagos20"
+            t-attf-Version="4.0"
+            t-attf-Exportacion="01"
+            t-attf-Folio="{{ o.folio }}"
+            t-attf-Fecha="{{ o.l10n_mx_facturae_payment_compute_fecha() }}"
+            t-attf-Sello="@"
+            t-attf-NoCertificado="@"
+            t-attf-Certificado="@"
+            t-attf-SubTotal="0"
+            t-attf-Moneda="XXX"
+            t-attf-Total="0"
+            t-attf-TipoDeComprobante="P"
+            t-attf-LugarExpedicion="{{ o.company_id.zip }}">
+            <cfdi:CfdiRelacionados t-attf-TipoRelacion="o.cfdi_relation_type.code" t-if="o.related_cfdi_ids">
+                <cfdi:CfdiRelacionado t-foreach="o.related_cfdi_ids" t-as="cfdi" t-attf-UUID="cfdi.uuid"/>
+            </cfdi:CfdiRelacionados>
+            <cfdi:Emisor
+                t-attf-Rfc="{{ o.company_id.partner_id.vat_split }}"
+                t-attf-Nombre="{{ o.company_id.partner_id.name.upper() }}"
+                t-attf-RegimenFiscal="{{ o.company_id.partner_id.cfdi_fiscal_regime_id.code }}"/>
+            <cfdi:Receptor
+                t-attf-Nombre="{{ o.commercial_partner_id.name.upper() }}"
+                t-attf-Rfc="{{ o.l10n_mx_facturae_payment_compute_rfc() }}"
+                t-attf-UsoCFDI="CP01"
+                t-attf-DomicilioFiscalReceptor="{{ o.l10n_mx_facturae_payment_compute_domicilio_fiscal() }}"
+                t-attf-RegimenFiscalReceptor="{{ o.l10n_mx_facturae_payment_compute_regimen_fiscal_receptor() }}"
+                t-att-ResidenciaFiscal="residenciaFiscal"
+                t-att-NumRegIdTrib="regimenTrib" />
+            <cfdi:Conceptos>
+                <cfdi:Concepto
+                    t-attf-Cantidad="1"
+                    t-attf-ClaveProdServ="84111506"
+                    t-attf-ClaveUnidad="ACT"
+                    t-attf-Descripcion="Pago"
+                    t-attf-Importe="0"
+                    t-attf-ObjetoImp="01"
+                    t-attf-ValorUnitario="0" />
+            </cfdi:Conceptos>
+            <cfdi:Complemento>
+                <pago20:Pagos t-attf-Version="2.0">
+                    <pago20:Totales
+                        t-attf-MontoTotalPagos="{{ o.l10n_mx_facturae_payment_montototalpagos() }}"
+                        t-att-TotalTrasladosBaseIVAExento="traslados.get('baseIVAExento', False)"
+                        t-att-TotalTrasladosBaseIVA16="format_float(traslados.get('baseIVA16.0'), o.currency_id.decimal_places) if traslados.get('baseIVA16.0', False) else False"
+                        t-att-TotalTrasladosImpuestoIVA16="format_float(traslados.get('importeIVA16.0'), o.currency_id.decimal_places) if traslados.get('importeIVA16.0', False) else False"
+                        t-att-TotalTrasladosBaseIVA8="format_float(traslados.get('baseIVA8.0'), o.currency_id.decimal_places) if traslados.get('baseIVA8.0', False) else False"
+                        t-att-TotalTrasladosImpuestoIVA8="format_float(traslados.get('importeIVA8.0'), o.currency_id.decimal_places) if traslados.get('importeIVA8.0', False) else False"
+                        t-att-TotalTrasladosBaseIVA0="format_float(traslados.get('baseIVA0.0'), o.currency_id.decimal_places) if traslados.get('baseIVA0.0', False) else False"
+                        t-att-TotalTrasladosImpuestoIVA0="format_float(traslados.get('importeIVA0.0'), o.currency_id.decimal_places) if traslados.get('baseIVA0.0', False) else False"
+                        t-att-TotalRetencionesIVA="retenciones.get('importeIVA', False)"
+                        t-att-TotalRetencionesISR="retenciones.get('importeISR', False)"
+                        t-att-TotalRetencionesIEPS="retenciones.get('importeIEPS', False)" />
+                    <pago20:Pago
+                        t-attf-FechaPago="{{ o.l10n_mx_facturae_payment_compute_pago_fecha() }}"
+                        t-attf-FormaDePagoP="{{ o.payment_type_id.code }}"
+                        t-attf-MonedaP="{{ o.currency_id.name }}"
+                        t-att-TipoCambioP="tipoCambio"
+                        t-attf-Monto="{{ o.amount }}"
+                        t-attf-NumOperacion="{{ o.name }}" >
+                        <pago20:DoctoRelacionado t-foreach="o.doctos_relacionados" t-as="invoice"
+                            t-attf-Folio="{{ invoice.folio }}"
+                            t-attf-IdDocumento="{{ invoice.cfdi_folio_fiscal }}"
+                            t-attf-MonedaDR="{{ invoice.currency_id.name }}"
+                            t-attf-EquivalenciaDR="{{ o.tipocambiodr(invoice) }}"
+                            t-attf-NumParcialidad="{{ o.numparcialidad(invoice) }}"
+                            t-attf-ImpSaldoAnt="{{ o.impsaldoant(invoice, to_xml=True) }}"
+                            t-attf-ImpSaldoInsoluto="{{ o.impsaldoinsoluto(invoice, to_xml=True) }}"
+                            t-attf-ImpPagado="{{ o.imppagado(invoice, to_xml=True) }}"
+                            t-attf-ObjetoImpDR="02" >
+                            <pago20:ImpuestosDR>
+                                <t t-set="retenciones" t-value="o.impuestos_dr(invoice, tax_type='retenciones')"/>
+                                <pago20:RetencionesDR t-if="retenciones">
+                                    <pago20:RetencionDR t-foreach="retenciones" t-as="tax_move"
+                                        t-att-BaseDR="format_float(tax_move.tax_base_amount, invoice.currency_id.decimal_places)"
+                                        t-att-ImpuestoDR="format_impuesto(tax_move.tax_line_id)"
+                                        t-att-ImporteDR="format_float(abs(tax_move.balance), invoice.currency_id.decimal_places)"
+                                        t-att-TasaOCuotaDR="format_tasaocuota(tax_move.tax_line_id)"
+                                        t-att-TipoFactorDR="tax_move.tax_line_id.l10n_mx_tax_type" />
+                                </pago20:RetencionesDR>
+                                <pago20:TrasladosDR>
+                                    <pago20:TrasladoDR
+                                            t-foreach="o.impuestos_dr(invoice)" t-as="base_move"
+                                        t-att-BaseDR="format_float(o._l10n_mx_tax_base_dr(invoice, base_move), invoice.currency_id.decimal_places)"
+                                        t-att-ImpuestoDR="format_impuesto(base_move.tax_ids[0])"
+                                        t-att-ImporteDR="format_float(abs(o._l10n_mx_tax_importe_dr(invoice, base_move)), invoice.currency_id.decimal_places)"
+                                        t-att-TasaOCuotaDR="format_tasaocuota(base_move.tax_ids[0])"
+                                        t-att-TipoFactorDR="base_move.tax_ids[0].l10n_mx_tax_type" />
+                                </pago20:TrasladosDR>
+                            </pago20:ImpuestosDR>
+                        </pago20:DoctoRelacionado>
+                        <pago20:ImpuestosP>
+                            <t t-set="retenciones" t-value="o.impuestos_p(tax_type='retenciones')"/>
+                            <pago20:RetencionesP t-if="retenciones">
+                                <pago20:RetencionP t-foreach="retenciones" t-as="tax_total"
+                                    t-attf-ImporteP="{{ tax_total['importe'] }}"
+                                    t-attf-ImpuestoP="format_impuesto(tax_total['tax_id'])" />
+                            </pago20:RetencionesP>
+                            <pago20:TrasladosP>
+                                <pago20:TrasladoP t-foreach="o.impuestos_p()" t-as="tax_total"
+                                    t-att-BaseP="format_float(tax_total['tax_base'], o.currency_id.decimal_places)"
+                                    t-att-ImpuestoP="format_impuesto(tax_total['tax'])"
+                                    t-att-ImporteP="format_float(tax_total['importe'], o.currency_id.decimal_places)"
+                                    t-att-TasaOCuotaP="format_tasaocuota(tax_total['tax'])"
+                                    t-att-TipoFactorP="tax_total['tax'].l10n_mx_tax_type" />
+                            </pago20:TrasladosP>
+                        </pago20:ImpuestosP>
+                    </pago20:Pago>
+                </pago20:Pagos>
+            </cfdi:Complemento>
+        </cfdi:Comprobante>
+
+    </template>
+
+</odoo>
diff --git a/l10n_mx_facturae/templates/account_voucher.txt b/l10n_mx_facturae/templates/account_voucher.txt
index 2a30569ab86b540dba6a2af4dc8e0b8dc515a631..80723d339e619b11ca38a907ce17e49e7061e9a6 100644
--- a/l10n_mx_facturae/templates/account_voucher.txt
+++ b/l10n_mx_facturae/templates/account_voucher.txt
@@ -163,7 +163,7 @@
                         {% end %}
                         NumParcialidad="${ o.numparcialidad(invoice) }"
                         ImpSaldoAnt="${ '{0:.2f}'.format(o.impsaldoant(invoice)) }"
-                        ImpSaldoInsoluto="${ '{0:.2f}'.format(o.impsaldoant(invoice) - o.imppagado(invoice)) }"
+                        ImpSaldoInsoluto="${ '{0:.2f}'.format() }"
                         ImpPagado="${ '{0:.2f}'.format(o.imppagado(invoice)) }"
                         ObjetoImpDR="02"
                         >
diff --git a/l10n_mx_facturae/tests/__init__.py b/l10n_mx_facturae/tests/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cc3112cf63efe6bf12538cc714c53aefc013e4c5 100644
--- a/l10n_mx_facturae/tests/__init__.py
+++ b/l10n_mx_facturae/tests/__init__.py
@@ -0,0 +1,4 @@
+
+from . import test_account_invoice
+# from . import test_account_voucher
+# from . import test_cancel_invoice
\ No newline at end of file
diff --git a/l10n_mx_facturae/tests/test_account_invoice.py b/l10n_mx_facturae/tests/test_account_invoice.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9a77406523ea7c335130d12859213bac5276dc9
--- /dev/null
+++ b/l10n_mx_facturae/tests/test_account_invoice.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo import fields
+from odoo.tests import tagged
+
+
+@tagged('post_install', '-at_install')
+class TestCancelInvoice(AccountTestInvoicingCommon):
+
+    @classmethod
+    def setUpClass(cls, chart_template_ref=None):
+        # Setup for required fields and configurations
+        super().setUpClass(chart_template_ref=chart_template_ref)
+        main_company = cls.env.ref('l10n_mx.demo_company_mx')
+        """Add a company to the user's allowed & set to current."""
+        cls.env.user.write(
+            {
+                "company_ids": [(6, 0, (main_company + cls.env.user.company_ids).ids)],
+                "company_id": main_company.id,
+            }
+        )
+        cls.tax_group = cls.env.ref('l10n_mx.tax_group_iva_16')
+        cls.customer = cls.env.ref('l10n_mx_facturae.res_partner_2023')
+        cls.cfdi_use = cls.env['cfdi.use'].sudo().search([], limit=1)
+        cls.fiscal_regime = cls.env['cfdi.fiscal.regime'].sudo().search([], limit=1)
+        cls.product = cls.env.ref('product.product_product_7')
+        cls.uom = cls.env['uom.uom'].search([], limit=1)
+        cls.journal = cls.env['account.journal'].sudo().search([('type', '=', 'sale'),
+                                                                ('company_id', '=', main_company.id)], limit=1)
+        cls.payment_type_id = cls.env['payment.type'].sudo().search([], limit=1)
+        if not cls.payment_type_id:
+            raise ValueError("No payment method was found in the database.")
+
+        # Configure tax group and tax for the test
+        cls.taxes_ids = cls.env['account.tax'].search([
+            ('company_id', '=', main_company.id),
+            ('type_tax_use', '=', 'sale'),
+            ('tax_group_id', '=', cls.tax_group.id)
+        ], limit=1)
+        if not cls.taxes_ids:
+            raise ValueError("The tax 'IVA 16% VENTAS' was not found in the database")
+
+        cfdi_product_service = cls.env['cfdi.product.service'].sudo().search([], limit=1).id
+
+        # Set up product with the tax and cfdi_product_service
+        cls.product.write({
+            'taxes_id': [(6, 0, [cls.taxes_ids.id])],
+            'cfdi_product_service_id': cfdi_product_service,
+            'company_id': main_company.id,
+            'uom_id': cls.uom.id,
+        })
+
+        receivable_account = cls.env['account.account'].sudo().search([
+            ('company_id', '=', main_company.id),
+            ('internal_type', '=', 'receivable')
+        ], limit=1)
+
+        income_account = cls.env['account.account'].sudo().search([
+            ('company_id', '=', main_company.id),
+            ('internal_type', '=', 'income')
+        ], limit=1)
+
+        cls.customer.sudo().write({
+            'company_id': main_company.id,
+            'cfdi_fiscal_regime_id': cls.fiscal_regime.id,
+            'zip': '20928',
+            'property_account_receivable_id': receivable_account.id,
+        })
+
+        # Create invoice with line items
+        cls.invoice = cls.env['account.move'].sudo().create({
+            'date': fields.Date.context_today(cls.customer),
+            'partner_id': cls.customer.id,
+            'journal_id': cls.journal.id,
+            'move_type': 'out_invoice',
+            'cfdi_periodicity': '04',
+            'invoice_line_ids': [
+                (0, 0, {
+                    'product_id': cls.product.id,
+                    'account_id': income_account.id,
+                    'price_unit': 130.00,
+                    'quantity': 1.0,
+                    'tax_ids': [(6, 0, [cls.taxes_ids.id])],
+                    'uom_id': cls.uom.id,
+                }),
+            ],
+            'company_id': main_company.id,
+        })
+
+        # Configure journal for invoicing with SAT signature enabled
+        cls.journal.sudo().write({'sign_sat': True})
+        cls.customer.sudo().write({'vat': 'MXXAXX010101000'})
+
+    def test_cancel_invoice_with_out_cfdi(self):
+        """
+        This scenario cancels the invoice, CFDI and verifies that:
+        - There is 1 CfdiRelacion node
+        - The TipoRelacion for the node is '04' (Substitution of the previous CFDI)
+        - The UUID for the node corresponds to the UUID of the cancelled CFDI
+        """
+        self.journal.sign_sat = True
+        self.invoice.action_post()
+        self.assertEqual(self.invoice.state, 'posted')
+        self.assertEqual(self.invoice.cfdi_state, 'done')
+
+        self.invoice.action_cancel()
+        # self.assertEqual(self.invoice.state, "cancel")
+        # uuid_cancelado = self.invoice.cfdi_uuid_cancelled
+        # self.assertTrue(uuid_cancelado, "Debe existir un UUID para el CFDI cancelado")
+        # cfdi_xml = self.invoice.get_cfdi_xml_cancelled()
+        # self.assertTrue(cfdi_xml, "Debe existir un XML del CFDI cancelado")
+        # tree = etree.fromstring(cfdi_xml.encode('utf-8'))
+        # namespaces = {
+        #     'cfdi': 'http://www.sat.gob.mx/cfd/4',
+        #     'tfd': 'http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd',
+        # }
+        # cfdi_relacionados = tree.find('.//cfdi:CfdiRelacionados', namespaces=namespaces)
+        # self.assertIsNotNone(cfdi_relacionados)
+        # cfdi_relacionados_list = cfdi_relacionados.findall('cfdi:CfdiRelacionado', namespaces=namespaces)
+        # self.assertEqual(len(cfdi_relacionados_list), 1)
+        # tipo_relacion = cfdi_relacionados.get('TipoRelacion')
+        # self.assertEqual(tipo_relacion, '04')
+        # uuid_relacionado = cfdi_relacionados_list[0].get('UUID')
+        # self.assertEqual(uuid_relacionado, uuid_cancelado)
diff --git a/l10n_mx_facturae/tests/test_account_voucher.py b/l10n_mx_facturae/tests/test_account_voucher.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1c83a7d3aa697ac32390d34391a8bb7688e6436
--- /dev/null
+++ b/l10n_mx_facturae/tests/test_account_voucher.py
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+from odoo import fields, Command
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo.tests import tagged
+
+
+@tagged('post_install', '-at_install')
+class TestPaymentReceipt(AccountTestInvoicingCommon):
+
+    @classmethod
+    def setUpClass(cls):
+        """ Configuración inicial para los datos requeridos. """
+        super().setUpClass()
+        cls.cfdi_use = cls.env["cfdi.use"].search([], limit=1)
+        cls.fiscal_regime = cls.env["cfdi.fiscal.regime"].search([], limit=1)
+        cls.payment_method_id = cls.env["payment.method"].search([], limit=1)
+        cls.customer.write(
+            {
+                "cfdi_fiscal_regime_id": cls.fiscal_regime.id,
+                "payment_method_customer": cls.payment_method_id.id,
+                "cfdi_use": cls.cfdi_use.id,
+                "zip": "20928",
+            }
+        )
+
+        # Crear cuenta contable y configuración de IVA
+        cls.account_iva_pendiente = cls.env['account.account.template'].create({
+            'code': '1151004000',
+            'name': 'IVA pendiente de acreditar',
+            'user_type_id': cls.env.ref('account.data_account_type_current_liabilities').id,
+        })
+
+        cls.account_iva_pagado = cls.env['account.account.template'].create({
+            'code': '1151003000',
+            'name': 'IVA efectivamente pagado',
+            'user_type_id': cls.env.ref('account.data_account_type_current_liabilities').id,
+        })
+
+        cls.account_banco = cls.env['account.account.template'].create({
+            'code': '1113020000',
+            'name': 'Banco',
+            'user_type_id': cls.env.ref('account.data_account_type_liquidity').id,
+        })
+
+        # Configurar diario para pagos
+        cls.bank_journal = cls.env['account.journal'].create({
+            'name': 'Banco',
+            'type': 'bank',
+            'code': 'BNK',
+            'bank_account_id': cls.account_banco.id,
+        })
+
+        cls.invoice = cls.env["account.move"].create(
+            {
+                "date": fields.Date.context_today(cls.customer),
+                "partner_id": cls.customer.id,
+                "journal_id": cls.sale_journal.id,
+                "type": "out_invoice",
+                "account_id": cls.customer.property_account_payable.id,
+                "cfdi_periodicity": "04",
+                "cfdi_use": cls.customer.cfdi_use.id,
+                "fiscal_regime": cls.customer.cfdi_fiscal_regime_id.id,
+                "payment_method_ids": [(4, cls.customer.payment_method_customer.id)],
+                "invoice_line": [
+                    (
+                        0,
+                        0,
+                        {
+                            "name": 'ProductoA',
+                            "account_id": cls.product.property_account_income.id,
+                            "price_unit":  100.00,
+                            "quantity": 1.0,
+                            "product_id": cls.product.id,
+                            "uos_id": cls.product.uom_id.id,
+                            "invoice_line_tax_id": [(4, cls.product.taxes_id.id)],
+                        },
+                    ),
+                ],
+            }
+        )
+
+        cls.invoice.action_post()
+
+    def test_payment_receipt_with_higher_amount(self):
+        """ Escenario: Recibo de pago con monto mayor al de la factura """
+
+        # Registrar un pago por 116.01 MXN
+        payment_register = self.env['account.payment'].with_context(
+            active_model='account.move',
+            active_ids=self.invoice.ids
+        ).create({
+            'amount': 116.01,
+            'payment_date': fields.Date.context_today(self),
+            'journal_id': self.bank_journal.id,
+            'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
+        })
+        payment = payment_register._create_payments()
+
+        # Validar que la factura se haya pagado
+        self.assertEqual(self.invoice.state, 'posted')
+        self.assertEqual(self.invoice.payment_state, 'paid')
+
+        # Generar el recibo electrónico de pagos (CFDI de pago)
+        payment_move = payment.move_id
+        payment_move.l10n_mx_edi_is_required()
+        payment_move._post()
+
+        # Obtener el XML generado
+        xml_str = payment_move._l10n_mx_edi_create_cfdi()
+        xml_tree = self.env['account.move'].l10n_mx_edi_get_xml_etree(xml_str)
+
+        # Validar nodo DoctoRelacionado
+        docto_relacionado_node = xml_tree.find('.//pago10:DoctoRelacionado',
+                                               namespaces=self.env['account.move']._l10n_mx_edi_get_namespaces())
+        self.assertIsNotNone(docto_relacionado_node, "El XML debería contener el nodo DoctoRelacionado")
+
+        # Validar que el ImpSaldoAnt sea 116.00 MXN
+        self.assertEqual(docto_relacionado_node.get('ImpSaldoAnt'), '116.00',
+                         "El ImpSaldoAnt debería ser 116.00 MXN")
+
+        # Validar que el ImportePagado sea 116.00 MXN
+        self.assertEqual(docto_relacionado_node.get('ImportePagado'), '116.00',
+                         "El ImportePagado debería ser 116.00 MXN")
+
+        # Validar que el ImpoSaldoInsoluto sea 0.00 MXN
+        self.assertEqual(docto_relacionado_node.get('ImpSaldoInsoluto'), '0.00',
+                         "El ImpSaldoInsoluto debería ser 0.00 MXN")
diff --git a/l10n_mx_facturae/tests/test_cancel_invoice.py b/l10n_mx_facturae/tests/test_cancel_invoice.py
index a32976863f48569154488d8a2130f74f55a026c6..c03fa220fb193a6301f631d344d0379e027b22e6 100644
--- a/l10n_mx_facturae/tests/test_cancel_invoice.py
+++ b/l10n_mx_facturae/tests/test_cancel_invoice.py
@@ -1,13 +1,16 @@
 # -*- coding: utf-8 -*-
 # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
-from openerp import fields
-from openerp.addons.account.tests.common import AccountTestInvoicingCommon
+from odoo import fields
+from odoo.addons.account.tests.common import AccountTestInvoicingCommon
 
+from odoo.tests import tagged
 
+
+@tagged('post_install', '-at_install')
 class TestCancelInvoice(AccountTestInvoicingCommon):
     @classmethod
     def setUpClass(cls):
-        super(TestCancelInvoice, cls).setUpClass()
+        super().setUpClass()
         # Create required fields and assign to customer
         cls.cfdi_use = cls.env["cfdi.use"].search([], limit=1)
         cls.fiscal_regime = cls.env["cfdi.fiscal.regime"].search([], limit=1)
diff --git a/l10n_mx_facturae/views/account_invoice.xml b/l10n_mx_facturae/views/account_move.xml
similarity index 55%
rename from l10n_mx_facturae/views/account_invoice.xml
rename to l10n_mx_facturae/views/account_move.xml
index 7bc6bcf9e738c64654dfb282fd6a2a04fb2dd2f8..1495f4fece42a962f2a7a0476c9573b136f83be9 100644
--- a/l10n_mx_facturae/views/account_invoice.xml
+++ b/l10n_mx_facturae/views/account_move.xml
@@ -1,23 +1,15 @@
 <?xml version="1.0"?>
-<openerp>
-<data>
+<odoo>
 
-    <act_window id="account_invoice_action_cfdi_details" name="CFDI Details"
-        domain="[
-            ('res_id', 'in', active_ids),
-            ('type_attachment', '=', 'account.invoice')
-        ]"
-        res_model="ir.attachment.facturae.mx" src_model="account.invoice" />
-
-    <record id="account_invoice_view_search" model="ir.ui.view">
-        <field name="name">account.invoice.view.search</field>
-        <field name="model">account.invoice</field>
+    <record id="account_move_view_search" model="ir.ui.view">
+        <field name="name">account.move.view.search</field>
+        <field name="model">account.move</field>
         <field name="inherit_id" ref="account.view_account_invoice_filter"/>
         <field name="arch" type="xml">
-            <field name="currency_id" position="after">
+            <field name="partner_id" position="after">
                 <field name="cfdi_id" />
             </field>
-            <group position="before">
+            <filter name="due_date" position="after">
                 <separator/>
                 <filter
                     string="To sign"
@@ -27,30 +19,39 @@
                 <filter
                     string="To cancel"
                     name="to_cancel"
-                    domain="[('l10n_mx_edi_to_cancel', '=', True)]"
                     help="Invoices that being substituted and must be cancelled" />
-            </group>
+                   <!--domain="[('l10n_mx_edi_to_cancel', '=', True)]"-->
+            </filter>
         </field>
     </record>
 
-    <record id="account_invoice_view_form_customer" model="ir.ui.view">
-        <field name="name">account.invoice.view.form.customer</field>
-        <field name="model">account.invoice</field>
-        <field name="inherit_id" ref="account.invoice_form"/>
+    <record id="account_move_view_form_customer" model="ir.ui.view">
+        <field name="name">account.move.view.form.customer</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="account.view_move_form"/>
         <field name="arch" type="xml">
-            <button name="invoice_cancel" position="before">
+            <button name="button_cancel" position="before">
+                <button name="l10n_mx_action_cancel"
+                    string="Cancel CFDI"
+                    type="object"
+                    class="btn-primary"
+                    attrs="{'invisible': [
+                        '&amp;',
+                        ('state', '!=', 'posted'),
+                        ('cfdi_state', '!=', 'done')
+                    ]}"/>
                 <field name="is_cfdi_candidate" invisible="1" />
             </button>
             <xpath expr="//header" position="after">
                 <div
                     class="alert alert-danger"
                     attrs="{'invisible':[
-                    '|',
-                        ('state', '=', 'cancel'),
+                        '|',
+                        ('state', '=', 'draft'),
                         (
                             'cfdi_state',
                             'in',
-                            ['signed', 'cancel', 'done', False]
+                            ['signed', 'done', 'waiting', 'cancel',  False]
                         )
                     ]}"
                     role="alert"
@@ -89,63 +90,53 @@
                         }" />
                 </h4>
             </xpath>
-            <xpath expr="//sheet/group//group[last()]" position="inside">
-                <label for="cfdi_state" string="PAC State"
-                    attrs="{
-                        'invisible': [
-                            '|',
-                            ('is_cfdi_candidate', '=', False),
-                            ('state', 'not in', ['open', 'paid', 'cancel'])
-                        ]
-                    }"/>
-                <div class="o_row" 
+            <xpath expr="//field[@name='invoice_date']" position="after">
+                <field name="payment_method_id"
+                    options="{'no_create':True, 'no_open':True}"/>
+            </xpath>
+            <xpath expr="//field[@name='payment_reference']" position="after">
+                <label
+                    for="cfdi_state"
+                    string="PAC State"
                     attrs="{
-                        'invisible': [
+                        'invisible':[
                             '|',
                             ('is_cfdi_candidate', '=', False),
-                            ('state', 'not in', ['open', 'paid', 'cancel'])
+                            ('state', '=', 'draft')
                         ]
-                    }">
-                    <field name="cfdi_state" class="oe_inline"/>
+                    }"
+                />
+                <div class="o_row" >
+                    <field
+                        name="cfdi_state"
+                        class="oe_inline"
+                        attrs="{
+                            'invisible':[
+                                '|',
+                                ('is_cfdi_candidate', '=', False),
+                                ('state', '=', 'draft')
+                            ]
+                        }"
+                    />
                     <button name="action_validate_cfdi" string="Retry"
                         class="oe_link oe_inline" type="object"
                         groups="account.group_account_invoice"
                         attrs="{
                             'invisible':[
-                            '|',
-                                    ('state', '=', 'cancel'),
-                                    ('cfdi_state','in', ['signed', 'cancel', 'done', False])
+                                '|',
+                                ('state', 'in', ['draft', 'cancel', 'waiting']),
+                                ('cfdi_state','in', ['signed', 'cancel', 'done', 'waiting', False])
                             ]
-                        }"/>
+                        }"
+                    />
                 </div>
             </xpath>
-            <field name="partner_id" position="after">
-                <field name="cfdi_use"
-                    attrs="{
-                        'readonly': [('cfdi_state','in', ['signed', 'cancel', 'done'])],
-                        'invisible': [('is_cfdi_candidate', '=', False)]
-                    }"
-                    options="{'no_create':True}"/>
-                <field name="cfdi_adenda_ids"
-                    attrs="{
-                        'readonly': [('state','in',('cancel','paid'))],
-                        'invisible': [('is_cfdi_candidate', '=', False)]
-                    }"
-                    options="{'no_create': True,'no_open':True}"
-                    widget="many2many_tags" />
-                <field name="l10n_mx_export" invisible="1" />
-            </field>
-            <xpath expr="//page[@string='Payments']" position='after'>
-                <page name="Adendas" string="Adendas"
-                    attrs="{'invisible': [('cfdi_adenda_ids', '=', False)]}">
-                    <group name="adenda">
-                    </group>
-                </page>
+            <xpath expr="//page[@name='cfdi_configuration_move_mx']" position='after'>
                 <page string="Related" attrs="{
                         'invisible': [
                             '|', '|',
                             ('is_cfdi_candidate', '=', False),
-                            ('type', 'not in', ('out_refund','out_invoice')),
+                            ('move_type', 'not in', ('out_refund','out_invoice')),
                             ('state', '!=', 'draft'),
                             ('cfdi_relation_type', '=', False),
                         ]
@@ -159,11 +150,11 @@
                         </group>
                         <group>
                             <field name="commercial_partner_id" invisible="1"/>
-                            <field name="origin_invoice_ids"
+                            <!--<field name="origin_invoice_ids"
                                 domain="[
                                     ('commercial_partner_id', '=', commercial_partner_id),
-                                    ('state','in', ['open','paid']),
-                                    ('type','=','out_invoice'),
+                                    ('state','in', ['posted']),
+                                    ('move_type','=','out_invoice'),
                                 ]"
                                 widget="many2many_tags"
                                 options="{'no_create': True}"
@@ -174,17 +165,15 @@
                                 }"
                                 context="{
                                     'form_view_ref': 'account.invoice_form',
-                                }" />
+                                }" />-->
                         </group>
                     </group>
                  </page>
             </xpath>
-            <xpath expr="//field[@name='origin']" position="before">
-                <field name="address_issued_id"/>
-            </xpath>
-            <xpath expr="//field[@name='payment_term']" position="after">
-                <field name="payment_method_id" class="oe_inline"
-                    options="{'no_create':True, 'no_open':True}"/>
+            <xpath expr="//group[@name='sale_info_group']" position="after">
+                <group name="Extra information">
+                    <field name="address_issued_id"/>
+                </group>
             </xpath>
             <xpath expr="//field[@name='partner_id']" position="attributes">
                 <attribute
@@ -194,7 +183,6 @@
                 <attribute
                     name="domain"
                     translation="off">[
-                        ('customer', '=', True),
                         '|',
                         ('is_company', '=', True),
                         ('type', '=', 'invoice')]
@@ -204,21 +192,56 @@
                     translation="off">{'always_reload': True,'no_quick_create': True}
                 </attribute>
             </xpath>
-            <xpath expr="//field[@name='invoice_line']//tree//field[@name='account_analytic_id']" position="after">
+            <xpath expr="//field[@name='invoice_line_ids']//tree//field[@name='analytic_account_id']" position="after">
                 <field name="cfdi_cuentapredial" groups="l10n_mx_facturae.cfdi_cuentapredial" />
             </xpath>
-            <xpath expr="//page//tree//field[@name='invoice_line_tax_id']" position="before">
+            <xpath expr="//page//tree//field[@name='tax_ids']" position="before">
                 <field name="cfdi_custom_number"
                     widget="many2many_tags"
-                    groups="l10n_mx.group_cfdi_custom_number"/>
+                    groups="l10n_mx_base.group_cfdi_custom_number"/>
+            </xpath>
+        </field>
+    </record>
+
+    <record id="account_move_cfdi_inherit_view_form" model="ir.ui.view">
+        <field name="name">account.move.cfdi.inherit.view.form</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="l10n_mx_base.account_move_cfdi_view_form"/>
+        <field name="arch" type="xml">
+            <xpath expr="//group[@name='Payment Type']" position="after">
+                <field name="invoice_global" invisible="True"/>
+                <group id="global_invoice" name="Global Invoice"
+                    attrs="{
+                        'invisible': [('invoice_global', '=', False)]
+                    }">
+                    <field name="cfdi_periodicity"/>
+                </group>
+                <group name="Fiscal data">
+                    <field name="cfdi_use"
+                        attrs="{
+                            'readonly': [('cfdi_state','in', ['signed', 'cancel', 'done'])],
+                            'invisible': [('is_cfdi_candidate', '=', False)]
+                        }"
+                        options="{'no_create':True}"/>
+                    <field name="l10n_mx_export" invisible="1"/>
+                    <field name="cfdi_adenda_ids"
+                        attrs="{
+                            'readonly': [('state','in',('cancel','paid'))],
+                            'invisible': [('is_cfdi_candidate', '=', False)]
+                        }"
+                        options="{'no_create': True,'no_open':True}"
+                        widget="many2many_tags" />
+                </group>
+                <group name="adenda">
+                </group>
             </xpath>
         </field>
     </record>
 
-    <record id="account_invoice_view_tree" model="ir.ui.view">
-        <field name="name">account.invoice.view.tree</field>
-        <field name="model">account.invoice</field>
-        <field name="inherit_id" ref="account.invoice_tree"/>
+    <record id="account_move_view_tree" model="ir.ui.view">
+        <field name="name">account.move.view.tree</field>
+        <field name="model">account.move</field>
+        <field name="inherit_id" ref="account.view_out_invoice_tree"/>
         <field name="arch" type="xml">
             <field name="name" position="after">
                 <field string="Fiscal Number" name="cfdi_id" invisible="1" />
@@ -226,5 +249,4 @@
         </field>
     </record>
 
-</data>
-</openerp>
+</odoo>
diff --git a/l10n_mx_facturae/views/account_payment.xml b/l10n_mx_facturae/views/account_payment.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fbee1ae8573548d48c20745ee908fa0bc23ce592
--- /dev/null
+++ b/l10n_mx_facturae/views/account_payment.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<odoo>
+
+    <!--<record id="account_payment_action_sign" model="ir.actions.server">
+        <field name="name">Sign payments</field>
+        <field name="type">ir.actions.server</field>
+        <field name="model_id" ref="model_account_payment"/>
+        <field name="state">code</field>
+        <field name="code">self.sign_payment(cr, uid, context.get('active_ids', []), context=context)</field>
+    </record>-->
+
+    <!--<record id="ir_values_action_sign" model="ir.values">
+        <field name="name">Sign payments</field>
+        <field name="action_id" ref="account_payment_action_sign"/>
+        <field name="value" eval="'ir.actions.server,' + str(ref('account_payment_action_sign'))"/>
+        <field name="key">action</field>
+        <field name="model_id" ref="model_account_payment"/>
+        <field name="model">account.payment</field>
+        <field name="key2">client_action_multi</field>
+    </record>-->
+
+    <record id="account_payment_cfdi_view_form" model="ir.ui.view">
+        <field name="name">account.payment.cfdi.view.form</field>
+        <field name="model">account.payment</field>
+        <field name="inherit_id" ref="account.view_account_payment_form"/>
+        <field name="arch" type="xml">
+             <button name="action_draft" position="attributes">
+                <attribute name="attrs">
+                    {'invisible': ['&amp;',('state', 'in', ('posted', 'cancel')),('cfdi_state', 'in', ('done', 'cancel'))]}
+                </attribute>
+            </button>
+            <button name="action_post" position="after">
+                <button name="sign_payment" type="object" string="Sign"
+                    class="oe_highlight"
+                    attrs="{'invisible': [
+                        '|',
+                        ('state', '!=', 'posted'),
+                        ('cfdi_state', '!=', False)
+                    ]}" />
+                <!--<button name="substitute_payment" type="object" string="Replace"
+                    attrs="{'invisible': ['|', ('cfdi_state', 'not in', ['signed',
+                    'done']), ('state', '=', 'cancel')]}"/>-->
+                <button name="replace_cfdi" type="object" class="btn-primary" string="Cancel"
+                    confirm="Are you sure to cancel this payment?"
+                    attrs="{'invisible': ['|', ('cfdi_state', 'not in', ['signed',
+                    'done']), ('state', '=', 'cancel')]}"/>-->
+            </button>
+            <button name="mark_as_sent" position="after">
+                <field name="show_unreconcile" invisible="1"/>
+            </button>
+            <xpath expr="//header" position="after">
+                <div
+                    class="alert alert-danger"
+                    attrs="{'invisible':[
+                        '|',
+                        ('state', '=', 'draft'),
+                        (
+                            'cfdi_state',
+                            'in',
+                            ['signed', 'cancel', 'done', False]
+                        )
+                    ]}"
+                    role="alert"
+                    style="margin-bottom:0px;" >
+                    <field
+                        class="oe_inline"
+                        name="l10n_mx_edi_error"
+                        readonly="1" />
+                </div>
+            </xpath>
+            <xpath expr="//h1[2]" position="after">
+                <h4 collspan="2">
+                    <field string="Fiscal Number" name="cfdi_id" readonly="1"/>
+                </h4>
+            </xpath>
+            <!-- Hide cancel button when payment have a related CFDI
+            <xpath expr="//button[@string='Unreconcile']" position="attributes">
+                <attribute name="states" translation="off"></attribute>
+                <attribute name="attrs" translation="off">{'invisible': [('show_unreconcile', '=', False)]}</attribute>
+            </xpath>-->
+            <field name="partner_bank_id" position="after">
+                <label
+                    for="cfdi_state"
+                    string="PAC State"
+                    attrs="{
+                        'invisible':[
+                            ('state', '=', 'draft')
+                        ]
+                    }"
+                />
+                <div class="o_row">
+                    <field
+                        name="cfdi_state"
+                        class="oe_inline"
+                        attrs="{
+                            'invisible':[
+                                ('state', '=', 'draft')
+                            ]
+                        }"
+                    />
+                    <button name="action_validate_cfdi" string="Retry"
+                        class="oe_link oe_inline" type="object"
+                        groups="account.group_account_invoice"
+                        attrs="{'invisible':[
+                            '|',
+                            ('state', 'in', ['draft', 'cancel', 'waiting']),
+                            (
+                                'cfdi_state',
+                                'in',
+                                ['signed', 'cancel', 'done', 'waiting', False]
+                            )
+                        ]}" />
+                </div>
+            </field>
+        </field>
+    </record>
+
+    <!--<record id="account_payment_view_search" model="ir.ui.view">
+        <field name="name">account.payment.view.search</field>
+        <field name="model">account.payment</field>
+        <field name="inherit_id" ref="account_payment.view_payment_filter_customer_pay"/>
+        <field name="arch" type="xml">
+            <field name="partner_id" position="after">
+                <field name="cfdi_id" string="UUID" />
+            </field>
+            <filter string="Posted" position="after">
+                <separator/>
+                <filter string="To Sign" domain="[('cfdi_state', '=', 'draft')]" help="Vochers to be signed"/>
+                <filter string="Signed" domain="[('cfdi_state', 'in', ['signed', 'done'])]" help="Signed payments"/>
+            </filter>
+        </field>
+    </record>-->
+
+</odoo>
diff --git a/l10n_mx_facturae/views/account_voucher.xml b/l10n_mx_facturae/views/account_voucher.xml
deleted file mode 100644
index d8f142e71d7c9a41568c0501761c613db1d21f80..0000000000000000000000000000000000000000
--- a/l10n_mx_facturae/views/account_voucher.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0"?>
-<openerp>
-<data>
-
-    <record id="account_voucher_action_sign" model="ir.actions.server">
-        <field name="name">Sign Vouchers</field>
-        <field name="type">ir.actions.server</field>
-        <field name="model_id" ref="model_account_voucher"/>
-        <field name="state">code</field>
-        <field name="code">self.sign_voucher(cr, uid, context.get('active_ids', []), context=context)</field>
-    </record>
-
-    <record id="ir_values_action_sign" model="ir.values">
-        <field name="name">Sign Vouchers</field>
-        <field name="action_id" ref="account_voucher_action_sign"/>
-        <field name="value" eval="'ir.actions.server,' + str(ref('account_voucher_action_sign'))"/>
-        <field name="key">action</field>
-        <field name="model_id" ref="model_account_voucher"/>
-        <field name="model">account.voucher</field>
-        <field name="key2">client_action_multi</field>
-    </record>
-
-    <record id="account_voucher_view_form" model="ir.ui.view">
-        <field name="name">account.voucher.view.form</field>
-        <field name="model">account.voucher</field>
-        <field name="inherit_id" ref="account_voucher.view_vendor_receipt_form"/>
-        <field name="arch" type="xml">
-            <button name="proforma_voucher" position="after">
-                <field name="show_unreconcile" invisible="1"/>
-                <button name="sign_voucher" type="object" string="Sign"
-                    class="oe_highlight"
-                    attrs="{'invisible': ['|', ('state', '!=', 'posted'), ('cfdi_state', '!=', False)]}"/>
-                <button name="substitute_voucher" type="object" string="Replace"
-                    attrs="{'invisible': ['|', ('cfdi_state', 'not in', ['signed', 'done']), ('state', '=', 'cancel')]}"/>
-                <button name="replace_cfdi" type="object" string="Cancel"
-                    confirm="Are you sure to cancel this voucher?"
-                    attrs="{'invisible': ['|', ('cfdi_state', 'not in', ['signed', 'done']), ('state', '=', 'cancel')]}"/>
-            </button>
-            <xpath expr="//header" position="after">
-                <div
-                    class="alert alert-danger"
-                    attrs="{'invisible':[
-                        (
-                            'cfdi_state',
-                            'in',
-                            ['signed', 'cancel', 'done', False]
-                        )
-                    ]}"
-                    role="alert"
-                    style="margin-bottom:0px;" >
-                    <field
-                        class="oe_inline"
-                        name="l10n_mx_edi_error"
-                        readonly="1" />
-                </div>
-            </xpath>
-            <xpath expr="//sheet/h1" position="after">
-                <h4 attrs="{'invisible': [('number','=',False)]}" collspan="2">
-                    <field string="Fiscal Number" name="cfdi_id" readonly="1"/>
-                </h4>
-            </xpath>
-            <!-- Hide cancel button when voucher have a related CFDI -->
-            <xpath expr="//button[@string='Unreconcile']" position="attributes">
-                <attribute name="states" translation="off"></attribute>
-                <attribute name="attrs" translation="off">{'invisible': [('show_unreconcile', '=', False)]}</attribute>
-            </xpath>
-            <xpath expr="//field[@name='name']" position="after">
-                <label for="cfdi_state" string="PAC State" states="posted,signed,cancel" />
-                <div class="o_row" states="posted,signed,cancel">
-                    <field name="cfdi_state" class="oe_inline"/>
-                    <button name="action_validate_cfdi" string="Retry"
-                        class="oe_link oe_inline" type="object"
-                        groups="account.group_account_invoice"
-                        attrs="{'invisible':[('cfdi_state', 'in', ['signed', 'cancelled', 'done', False])]}"/>
-                </div>
-            </xpath>
-        </field>
-    </record>
-
-    <record id="account_voucher_view_search" model="ir.ui.view">
-        <field name="name">account.voucher.view.search</field>
-        <field name="model">account.voucher</field>
-        <field name="inherit_id" ref="account_voucher.view_voucher_filter_customer_pay"/>
-        <field name="arch" type="xml">
-            <field name="partner_id" position="after">
-                <field name="cfdi_id" string="UUID" />
-            </field>
-            <filter string="Posted" position="after">
-                <separator/>
-                <filter string="To Sign" domain="[('cfdi_state', '=', 'draft')]" help="Vochers to be signed"/>
-                <filter string="Signed" domain="[('cfdi_state', 'in', ['signed', 'done'])]" help="Signed Vouchers"/>
-            </filter>
-        </field>
-    </record>
-
-</data>
-</openerp>
diff --git a/l10n_mx_facturae/views/res_company.xml b/l10n_mx_facturae/views/res_company.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5c6c743672562495d1675e854397355adda535b0
--- /dev/null
+++ b/l10n_mx_facturae/views/res_company.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+
+    <record id="l10_mx_facturae_res_company_view_form" model="ir.ui.view">
+        <field name="name">l10n.mx.facturae.res.company.view.form</field>
+        <field name="model">res.company</field>
+        <field name="inherit_id" ref="l10n_mx_base.res_company_view_form"/>
+        <field name="arch" type="xml">
+            <field name="cfdi_fiscal_regime_id" position="after">
+                <field name="cfdi_use_id"/>
+            </field>
+        </field>
+    </record>
+
+</odoo>
diff --git a/l10n_mx_facturae/views/res_partner.xml b/l10n_mx_facturae/views/res_partner.xml
index 00ed9269703086cd942e449e9325bbe5a93c9ef1..fb28220319066218219adc4d4d0a19b3ad395575 100644
--- a/l10n_mx_facturae/views/res_partner.xml
+++ b/l10n_mx_facturae/views/res_partner.xml
@@ -1,50 +1,67 @@
 <?xml version="1.0"?>
-<openerp>
-<data>
+<odoo>
 
-    <record id="res_partner_view_form" model="ir.ui.view">
-        <field name="name">res.partner.view.form</field>
+    <record id="l10n_mx_facturae_res_partner_view_form" model="ir.ui.view">
+        <field name="name">l10n.mx.facturae.res.partner.view.form</field>
         <field name="model">res.partner</field>
-        <field name="inherit_id" ref="account.view_partner_property_form"/>
+        <field name="inherit_id" ref="l10n_mx_base.res_partner_view_form"/>
         <field name="arch" type="xml">
-            <xpath expr="//page[@string='Accounting']" position="after">
-                <page name="Invoicing" string="Invoicing">
-                    <group>
-                        <group name="Configuraciones" string="Configuraciones">
-                            <field name="cfdi_fiscal_regime_id" options="{'no_create': True,'no_open':True}" />
-                            <field name="cfdi_use" options="{'no_create': True,'no_open':True}"/>
-                            <field name="payment_method_id" options="{'no_create': True,'no_open':True}"/>
-                        </group>
-                        <group>
-                        </group>
-                        <group string="Adendas">
-                            <p>Addends are used to add additional content to the invoice that  the SAT. 
-                            An addendum contains information of a commercial, logistic and  operation,
-                            often required by the receiving company (client).
-                            <br/><br/>
-                            Once you have selected the addendum, you must add the necessary information
-                            in all or some of the following sections: Customers, suppliers, company,
-                            products, services, invoices or delivery notes
-                            <br/><br/>
-                            Done the necessary configurations, you will be able to stamp your invoices
-                            with the selected complement.
-                            </p>
-                        </group>
-                        <group>
-                            <p colspan="2"><b><br/>  </b></p>
-                            <field name="show_glnnumber" invisible="True"/>
-                            <field name="show_suppliernumber" invisible="True"/>
-                            <field name="show_edi" invisible="True"/>
-                            <field name="cfdi_adenda_ids" widget="many2many_tags" options="{'no_create': True,'no_open':True}"/>
-                            <field name="gln_number" attrs="{'required':[('show_glnnumber', '=', True)], 'invisible':[('show_glnnumber', '=', False)]}"/>
-                            <field name="supplier_number" attrs="{'required':[('show_suppliernumber', '=', True)], 'invisible':[('show_suppliernumber', '=', False)]}"/>
-                            <field name="edi" attrs="{'required':[('show_edi', '=', True)], 'invisible':[('show_edi', '=', False)]}"/>
-                        </group>
-                    </group>
-                </page>
-            </xpath>
+            <field name="cfdi_fiscal_regime_id" position="after">
+                <field name="cfdi_use_id" options="{'no_create': True,'no_open':True}"/>
+                <field name="payment_method_id" options="{'no_create': True,'no_open':True}"/>
+            </field>
+            <group name="cfdi_taxes" position="after">
+                <group name="cfdi_adendum" string="Adendas">
+                    <p>Addends are used to add additional content to the invoice that  the SAT.
+                    An addendum contains information of a commercial, logistic and  operation,
+                    often required by the receiving company (client).
+                    <br/><br/>
+                    Once you have selected the addendum, you must add the necessary information
+                    in all or some of the following sections: Customers, suppliers, company,
+                    products, services, invoices or delivery notes
+                    <br/><br/>
+                    Done the necessary configurations, you will be able to stamp your invoices
+                    with the selected complement.
+                    </p>
+                </group>
+                <group name="cfdi_adendum_fields">
+                    <p colspan="2"><b><br/>  </b></p>
+                    <field name="show_glnnumber" invisible="True"/>
+                    <field name="show_suppliernumber" invisible="True"/>
+                    <field name="show_edi" invisible="True"/>
+                    <field name="cfdi_adenda_ids"
+                        widget="many2many_tags"
+                        options="{'no_create': True,'no_open':True}"/>
+                    <field name="gln_number"
+                        attrs="{
+                            'required':[
+                                ('show_glnnumber', '=', True)
+                            ],
+                            'invisible':[
+                                ('show_glnnumber', '=', False)
+                            ]
+                        }"/>
+                    <field name="supplier_number"
+                        attrs="{
+                            'required':[
+                                ('show_suppliernumber', '=', True)
+                            ],
+                            'invisible':[
+                                ('show_suppliernumber', '=', False)
+                            ]
+                        }"/>
+                    <field name="edi"
+                        attrs="{
+                            'required':[
+                                ('show_edi', '=', True)
+                            ],
+                            'invisible':[
+                                ('show_edi', '=', False)
+                            ]
+                        }"/>
+                </group>
+            </group>
         </field>
     </record>
 
-</data>
-</openerp>
+</odoo>
diff --git a/l10n_mx_facturae/wizard/__init__.py b/l10n_mx_facturae/wizard/__init__.py
index 30e4ebec8a85a7685bbdf5206a43ad6e21c58ab7..799aa57d0a7f750f4d26befd9e1fce051060a2ac 100644
--- a/l10n_mx_facturae/wizard/__init__.py
+++ b/l10n_mx_facturae/wizard/__init__.py
@@ -1,4 +1,4 @@
 # -*- coding: utf-8 -*-
 
-from . import account_invoice_refund
-from . import wizard_multi_charts_accounts
+#from . import account_invoice_refund
+#from . import wizard_multi_charts_accounts
diff --git a/l10n_mx_facturae/wizard/account_invoice_refund.py b/l10n_mx_facturae/wizard/account_invoice_refund.py
index e292b5146ccd344ce209932a1d64f748a2dcd011..1c8e4cb1ae098fabbb50632ec6bde077929d6f54 100644
--- a/l10n_mx_facturae/wizard/account_invoice_refund.py
+++ b/l10n_mx_facturae/wizard/account_invoice_refund.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-from openerp import fields, models
+from odoo import fields, models
 
 
 class AccountInvoiceRefund(models.TransientModel):
diff --git a/l10n_mx_facturae/wizard/account_invoice_refund.xml b/l10n_mx_facturae/wizard/account_invoice_refund.xml
index e9fc4949fd554e14f08532f2ee0f1618655b6d5d..cd47e01e5d69dcafad9f8c94f9bafa80b77a971b 100644
--- a/l10n_mx_facturae/wizard/account_invoice_refund.xml
+++ b/l10n_mx_facturae/wizard/account_invoice_refund.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<openerp>
+<odoo>
 <data>
 
     <record id="view_account_invoice_refund" model="ir.ui.view">
@@ -14,4 +14,4 @@
     </record>
 
 </data>
-</openerp>
+</odoo>
diff --git a/l10n_mx_facturae/wizard/wizard_multi_charts_accounts.py b/l10n_mx_facturae/wizard/wizard_multi_charts_accounts.py
index e90f7d41de142e09f554451569e6cb91a9434414..f10ab67b0bbdbadacc53ceeb36f3aa650d8a9248 100644
--- a/l10n_mx_facturae/wizard/wizard_multi_charts_accounts.py
+++ b/l10n_mx_facturae/wizard/wizard_multi_charts_accounts.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-from openerp import api, models
+from odoo import api, models
 
 
 class WizardMultiChartsAccounts(models.TransientModel):