diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0cd6cc..518c430 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,17 +70,20 @@ jobs: restore-keys: | ${{ runner.os }}-yarn- + - name: Install MariaDB Client + run: sudo apt-get install mariadb-client-10.6 + - name: Setup run: | pip install frappe-bench - bench init --frappe-branch version-14 --skip-redis-config-generation --skip-assets --python "$(which python)" ~/frappe-bench - mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'" - mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'" + bench init --frappe-branch version-15 --skip-redis-config-generation --skip-assets --python "$(which python)" ~/frappe-bench + mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'" + mariadb --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'" - name: Install working-directory: /home/runner/frappe-bench run: | - bench get-app erpnext --branch version-14 + bench get-app erpnext --branch version-15 bench get-app erpnext_mexico_compliance $GITHUB_WORKSPACE bench setup requirements --dev bench new-site --db-root-password root --admin-password admin test_site diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b0b12f2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "tabWidth": 2, + "useTabs": false, + "overrides": [ + { + "files": "*.json", + "options": { + "tabWidth": 1 + } + } + ] +} diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/__init__.py b/erpnext_mexico_compliance/controllers/__init__.py similarity index 100% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/__init__.py rename to erpnext_mexico_compliance/controllers/__init__.py diff --git a/erpnext_mexico_compliance/controllers/common.py b/erpnext_mexico_compliance/controllers/common.py new file mode 100644 index 0000000..a1e99f0 --- /dev/null +++ b/erpnext_mexico_compliance/controllers/common.py @@ -0,0 +1,75 @@ +""" +Copyright (c) 2024, TI Sin Problemas and contributors +For license information, please see license.txt +""" + +import abc + +import frappe +from frappe.model.naming import NamingSeries +from satcfdi.cfdi import CFDI +from satcfdi.create.cfd import cfdi40 + +from ..erpnext_mexico_compliance.doctype.digital_signing_certificate.digital_signing_certificate import ( + DigitalSigningCertificate, +) + + +class CommonController(abc.ABC): + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + name: DF.Data + naming_series: DF.Data + + @property + def cfdi_series(self) -> str: + """CFDI Series code""" + prefix = str(NamingSeries(self.naming_series).get_prefix()) + return prefix if prefix[-1].isalnum() else prefix[:-1] + + @property + def cfdi_folio(self) -> str: + """CFDI Folio number""" + prefix = str(NamingSeries(self.naming_series).get_prefix()) + return str(int(self.name.replace(prefix, ""))) + + @abc.abstractmethod + def get_cfdi_voucher(self, csd: DigitalSigningCertificate) -> cfdi40.Comprobante: + """Generates a CFDI voucher using the provided digital signing certificate. + + Args: + csd (DigitalSigningCertificate): The digital signing certificate. + + Returns: + cfdi40.Comprobante: The generated CFDI voucher. + """ + raise NotImplementedError("cfdi_voucher method is not implemented") + + def sign_cfdi(self, certificate: str) -> CFDI: + """Signs a CFDI document with the provided digital signing certificate. + + Args: + certificate (str): The name of the Digital Signing Certificate to use for signing. + + Returns: + CFDI: The signed and processed CFDI document. + """ + csd = frappe.get_doc("Digital Signing Certificate", certificate) + voucher = self.get_cfdi_voucher(csd) + voucher.sign(csd.signer) + return voucher.process() + + @abc.abstractmethod + def stamp_cfdi(self, certificate: str): + """Stamps a CFDI document with the provided digital signing certificate. + + Args: + certificate (str): The name of the Digital Signing Certificate to use for signing. + + Returns: + CFDI: A message indicating the result of the stamping operation. + """ + raise NotImplementedError("stamp_cfdi method is not implemented") diff --git a/erpnext_mexico_compliance/controllers/queries.py b/erpnext_mexico_compliance/controllers/queries.py new file mode 100644 index 0000000..81752b2 --- /dev/null +++ b/erpnext_mexico_compliance/controllers/queries.py @@ -0,0 +1,38 @@ +"""Copyright (c) 2024, TI Sin Problemas and contributors +For license information, please see license.txt""" + +import frappe +from erpnext.controllers.queries import get_fields +from frappe.desk.reportview import get_filters_cond + + +@frappe.whitelist() +@frappe.validate_and_sanitize_search_inputs +def cfdi_use_query(doctype, txt, searchfield, start, page_len, filters: dict): + doctype = "SAT CFDI Use" + customer = filters.pop("customer", None) + cfdi_use_table = "`tabSAT CFDI Use`" + tax_regime_table = "`tabSAT CFDI Use Tax Regime`" + + if customer: + customer = frappe.get_doc("Customer", customer) + filters.update({"tax_regime": customer.mx_tax_regime}) + + fields = [f"{cfdi_use_table}.{f}" for f in get_fields(doctype, [])] + filters_cond = get_filters_cond(doctype, filters, []) + + item_list = frappe.db.sql( + f"""select {", ".join(fields)} from {cfdi_use_table} + left join {tax_regime_table} on {tax_regime_table}.parent = {cfdi_use_table}.name + where + {cfdi_use_table}.enabled = 1 + and ( + {cfdi_use_table}.key_name like "%{txt}%" + or {cfdi_use_table}.{searchfield} like "%{txt}%" + ) + {filters_cond} + order by {cfdi_use_table}.{searchfield} asc + limit {page_len} offset {start} + """ + ) + return item_list diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/__init__.py similarity index 100% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/__init__.py rename to erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/__init__.py diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.js b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.js new file mode 100644 index 0000000..38a7a85 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, TI Sin Problemas and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Cancellation Reason", { +// refresh(frm) { + +// }, +// }); diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json new file mode 100644 index 0000000..bfd381d --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json @@ -0,0 +1,69 @@ +{ + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:code", + "creation": "2024-08-17 16:16:03.891107", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "code", + "description", + "requires_relationship" + ], + "fields": [ + { + "allow_in_quick_entry": 1, + "fieldname": "code", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Code", + "length": 2, + "reqd": 1, + "unique": 1 + }, + { + "allow_in_quick_entry": 1, + "fieldname": "description", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Description", + "reqd": 1 + }, + { + "default": "0", + "description": "Check this field if the cancelled invoice needs to have another related invoice", + "fieldname": "requires_relationship", + "fieldtype": "Check", + "label": "Requires relationship" + } + ], + "hide_toolbar": 1, + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-08-17 18:07:26.590842", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "Cancellation Reason", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "show_title_field_in_link": 1, + "sort_field": "description", + "sort_order": "DESC", + "states": [], + "title_field": "description" +} \ No newline at end of file diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.py new file mode 100644 index 0000000..8dfeba8 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.py @@ -0,0 +1,22 @@ +"""Copyright (c) 2024, TI Sin Problemas and contributors +For license information, please see license.txt""" + +# import frappe +from frappe.model.document import Document + + +class CancellationReason(Document): + """Invoice Cancellation Reason""" + + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + code: DF.Data + description: DF.Data + requires_relationship: DF.Check + # end: auto-generated types diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/test_cancellation_reason.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/test_cancellation_reason.py new file mode 100644 index 0000000..b49930b --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cancellation_reason/test_cancellation_reason.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, TI Sin Problemas and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestCancellationReason(FrappeTestCase): + pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.js b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.js new file mode 100644 index 0000000..1476785 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.js @@ -0,0 +1,6 @@ +// Copyright (c) 2024, TI Sin Problemas and contributors +// For license information, please see license.txt + +frappe.ui.form.on("CFDI Stamping Settings", { + // refresh(frm) {}, +}); diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json new file mode 100644 index 0000000..fb50153 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json @@ -0,0 +1,67 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-08-09 14:55:18.675674", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "web_service_section", + "api_key", + "test_mode", + "column_break_zjrm", + "available_credits" + ], + "fields": [ + { + "fieldname": "web_service_section", + "fieldtype": "Section Break", + "label": "Web Service" + }, + { + "fieldname": "api_key", + "fieldtype": "Password", + "label": "API Key" + }, + { + "default": "1", + "fieldname": "test_mode", + "fieldtype": "Check", + "label": "Test mode" + }, + { + "fieldname": "column_break_zjrm", + "fieldtype": "Column Break" + }, + { + "depends_on": "api_key", + "description": "1 credit is consumed every time a CFDI gets stamped", + "fieldname": "available_credits", + "fieldtype": "Int", + "is_virtual": 1, + "label": "Available credits" + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2024-08-13 01:44:43.369481", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "CFDI Stamping Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.py new file mode 100644 index 0000000..f5e561a --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024, TI Sin Problemas and contributors +# For license information, please see license.txt + +import frappe +from erpnext_mexico_compliance import ws_client +from frappe import _ +from frappe.model.document import Document + + +class CFDIStampingSettings(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + api_key: DF.Password | None + available_credits: DF.Int + test_mode: DF.Check + # end: auto-generated types + + def get_api_key(self) -> str: + """Retrieves the API key from the CFDI Stamping Settings document. + + Returns: + str: The API key. + """ + return self.get_password("api_key") + + @property + def available_credits(self) -> int: + """Retrieves the available credits from the CFDI Web Service. + + Returns: + int: The number of available credits. + """ + if self.api_key: + client = ws_client.get_ws_client() + try: + available_credits = client.get_available_credits() + except ws_client.WSClientException as exception: + frappe.throw(str(exception), title=_("CFDI Web Service Error")) + else: + available_credits = 0 + + return available_credits diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/test_cfdi_stamping_settings.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/test_cfdi_stamping_settings.py new file mode 100644 index 0000000..b67f6ed --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/cfdi_stamping_settings/test_cfdi_stamping_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, TI Sin Problemas and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestCFDIStampingSettings(FrappeTestCase): + pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.js b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.js new file mode 100644 index 0000000..90c66b3 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.js @@ -0,0 +1,12 @@ +// Copyright (c) 2024, TI Sin Problemas and contributors +// For license information, please see license.txt + +frappe.ui.form.on("Digital Signing Certificate", { + refresh(frm) { + if (frm.doc.certificate && frm.doc.key && frm.doc.password) { + frm.add_custom_button(__("Validate Certificate"), () => { + frm.call("validate_certificate"); + }); + } + }, +}); diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json new file mode 100644 index 0000000..2b0cb1b --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json @@ -0,0 +1,101 @@ +{ + "actions": [], + "allow_rename": 1, + "autoname": "format:{company}-{##}", + "creation": "2024-08-09 21:12:07.021650", + "description": "Company's Digital Signing Certificate to sign CFDI ", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "company_section", + "company", + "files_section", + "column_break_ymzu", + "certificate", + "key", + "password" + ], + "fields": [ + { + "description": "Company for which this certificate will be used to sign CFDI", + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "reqd": 1 + }, + { + "description": "Certificate file (.cer)", + "fieldname": "certificate", + "fieldtype": "Attach", + "label": "Certificate", + "no_copy": 1 + }, + { + "description": "Certificate key file (.key)", + "fieldname": "key", + "fieldtype": "Attach", + "label": "Key", + "no_copy": 1 + }, + { + "description": "Password for the certificate key", + "fieldname": "password", + "fieldtype": "Password", + "label": "Password", + "no_copy": 1 + }, + { + "fieldname": "column_break_ymzu", + "fieldtype": "Column Break" + }, + { + "fieldname": "company_section", + "fieldtype": "Section Break", + "label": "Company" + }, + { + "fieldname": "files_section", + "fieldtype": "Section Break", + "label": "Files" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-08-13 18:41:10.791522", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "Digital Signing Certificate", + "naming_rule": "Expression", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py new file mode 100644 index 0000000..f2d7f1b --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py @@ -0,0 +1,183 @@ +"""Copyright (c) 2024, TI Sin Problemas and contributors +For license information, please see license.txt""" + +import base64 + +import frappe +from erpnext.setup.doctype.company.company import Company +from frappe import _ +from frappe.model.document import Document +from frappe.utils.file_manager import get_file +from satcfdi.create.cfd.cfdi40 import Emisor +from satcfdi.exceptions import CFDIError +from satcfdi.models import Signer + + +class DigitalSigningCertificate(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + certificate: DF.Attach | None + company: DF.Link + key: DF.Attach | None + password: DF.Password | None + # end: auto-generated types + + def _get_file(self, field: str) -> bytes: + return get_file(getattr(self, field))[1] + + def read_certificate(self) -> bytes: + """Returns the content of the Digital Signing Certificate file + + Returns: + bytes: Digital Signing Certificate content + """ + if not self.certificate: + frappe.throw(_("Certificate file not configured")) + return self._get_file("certificate") + + def read_key(self) -> bytes: + """Returns the content of the Digital Signing Certificate Key file + + Returns: + bytes: Digital Signing Certificate Key content + """ + if not self.key: + frappe.throw(_("Key file not configured")) + return self._get_file("key") + + @property + def signer(self) -> Signer | None: + """Returns a Signer object loaded with the certificate, key, and password of the current + DigitalSigningCertificate instance. + + Returns: + Signer | None: CSD Signer + """ + if not self.triad_is_complete: + return None + + certificate = self.read_certificate() + key = self.read_key() + password = self.get_password() + try: + signer = Signer.load(certificate=certificate, key=key, password=password) + except (CFDIError, ValueError) as e: + frappe.throw(msg=str(e), title="Invalid Signing Certificate") + + return signer + + @frappe.whitelist() + def validate_certificate(self): + """Validates the digital signing certificate by checking if the certificate files and + password are correctly configured.""" + if self.signer: + title = _("Certificate files and password are valid") + msg = [ + _("Branch: {0}", context="Company branch").format(self.branch_name), + _("Legal name: {0}").format(self.legal_name), + _("RFC: {0}").format(self.rfc), + ] + + frappe.msgprint(msg=msg, title=title, indicator="green", as_list=True) + + @property + def triad_is_complete(self) -> bool: + """Checks if the digital signing certificate triad is complete. + + The triad consists of the certificate, key, and password. This property returns True if + all three are present, False otherwise. + + Returns: + bool: Whether the triad is complete. + """ + return all([self.certificate, self.key, self.password]) + + def validate(self): + """Validates the digital signing certificate. + + This function checks if the digital signing certificate is valid by verifying if the + `signer` attribute is not None. If the `signer` is None, it means that the certificate + files and password are not valid, and a `frappe.ValidationError` is raised with the + message "Certificate files and password are not valid". + + Raises: + frappe.ValidationError: If the digital signing certificate is not valid. + """ + + if self.triad_is_complete and not self.signer: + frappe.throw(_("Certificate files and password are not valid")) + + @property + def legal_name(self) -> str | None: + """Returns the legal name associated with the digital signing certificate. + + Returns: + str | None: The legal name associated with the digital signing certificate, or None if + the triad is not complete. + """ + return self.signer.legal_name if self.signer else None + + @property + def rfc(self) -> str | None: + """Returns the RFC associated with the digital signing certificate. + + Returns: + str | None: The RFC associated with the digital signing certificate, or None if the + triad is not complete. + """ + return self.signer.rfc if self.signer else None + + @property + def branch_name(self) -> str | None: + """Returns the branch name associated with the digital signing certificate. + + Returns: + str | None: The branch name associated with the digital signing certificate, or None if + the triad is not complete. + """ + return self.signer.branch_name if self.signer else None + + def get_company_doc(self) -> Company: + """Retrieves the Company doctype associated with the current instance. + + Returns: + Company: The Company doctype. + """ + return frappe.get_doc("Company", self.company) + + def get_issuer(self) -> Emisor: + """Creates an Emisor object from the current instance. + + Returns: + Emisor: The issuer information, including RFC, name, and tax regime. + """ + company = self.get_company_doc() + if not company.mx_tax_regime: + link = f'{company.name}' + msg = _("Company {0} has no tax regime").format(link) + frappe.throw(msg) + return Emisor( + rfc=self.rfc, nombre=self.legal_name, regimen_fiscal=company.mx_tax_regime + ) + + def get_key_b64(self) -> str: + """Returns the key in Base64 format. + + Returns: + str: The key in Base64 format. + """ + return base64.b64encode(self.read_key()).decode("utf-8") + + def get_certificate_b64(self) -> str: + """Returns the certificate in Base64 format. + + Returns: + str: The certificate in Base64 format. + """ + return base64.b64encode(self.read_certificate()).decode("utf-8") diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/test_digital_signing_certificate.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/test_digital_signing_certificate.py new file mode 100644 index 0000000..8e08359 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/digital_signing_certificate/test_digital_signing_certificate.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, TI Sin Problemas and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestDigitalSigningCertificate(FrappeTestCase): + pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json index 82e32ba..ba7b52b 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json @@ -1,89 +1,108 @@ { - "actions": [], - "autoname": "field:key", - "default_view": "List", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "enabled", - "section_break", - "key", - "key_name", - "column_break", - "description" - ], - "fields": [ - { - "default": "1", - "fieldname": "enabled", - "fieldtype": "Check", - "label": "Enabled" - }, - { - "fieldname": "section_break", - "fieldtype": "Section Break" - }, - { - "fieldname": "key_name", - "fieldtype": "Data", - "label": "Key Name", - "read_only": 1 - }, - { - "fieldname": "key", - "fieldtype": "Data", - "label": "Key", - "length": 4, - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "column_break", - "fieldtype": "Column Break" - }, - { - "fieldname": "description", - "fieldtype": "Data", - "label": "Description", - "reqd": 1 - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified_by": "Administrator", - "module": "ERPNext Mexico Compliance", - "name": "SAT CFDI Use", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "show_title_field_in_link": 1, - "sort_field": "key_name", - "sort_order": "ASC", - "states": [], - "title_field": "key_name" -} + "actions": [], + "autoname": "field:key", + "creation": "2024-08-05 22:35:49.169695", + "default_view": "List", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "enabled", + "section_break", + "key", + "key_name", + "column_break", + "description", + "customer_section", + "tax_regimes" + ], + "fields": [ + { + "default": "1", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" + }, + { + "fieldname": "section_break", + "fieldtype": "Section Break" + }, + { + "fieldname": "key_name", + "fieldtype": "Data", + "label": "Key Name", + "read_only": 1 + }, + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "length": 4, + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "column_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "description", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Description", + "reqd": 1 + }, + { + "fieldname": "customer_section", + "fieldtype": "Section Break", + "label": "Customer" + }, + { + "fieldname": "tax_regimes", + "fieldtype": "Table", + "in_filter": 1, + "label": "Tax regimes", + "options": "SAT CFDI Use Tax Regime" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-08-14 21:23:44.236421", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "SAT CFDI Use", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "show_title_field_in_link": 1, + "sort_field": "key_name", + "sort_order": "ASC", + "states": [], + "title_field": "key_name" +} \ No newline at end of file diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.py index 4c28137..3032e57 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.py +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.py @@ -8,6 +8,21 @@ class SATCFDIUse(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from erpnext_mexico_compliance.erpnext_mexico_compliance.doctype.sat_cfdi_use_tax_regime.sat_cfdi_use_tax_regime import SATCFDIUseTaxRegime + from frappe.types import DF + + description: DF.Data + enabled: DF.Check + key: DF.Data + key_name: DF.Data | None + tax_regimes: DF.Table[SATCFDIUseTaxRegime] + # end: auto-generated types """SAT's CFDI Use""" def before_save(self): diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json new file mode 100644 index 0000000..dcfc2a6 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json @@ -0,0 +1,32 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-08-14 16:51:26.535096", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "tax_regime" + ], + "fields": [ + { + "fieldname": "tax_regime", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Tax Regime", + "options": "SAT Tax Regime" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-08-14 17:46:03.491710", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "SAT CFDI Use Tax Regime", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.py new file mode 100644 index 0000000..e7bfef0 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.py @@ -0,0 +1,22 @@ +# Copyright (c) 2024, TI Sin Problemas and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class SATCFDIUseTaxRegime(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + parent: DF.Data + parentfield: DF.Data + parenttype: DF.Data + tax_regime: DF.Link | None + # end: auto-generated types + pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.js b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.js similarity index 78% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.js rename to erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.js index 8bdb74b..b360765 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.js +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.js @@ -1,7 +1,7 @@ // Copyright (c) 2022, TI Sin Problemas and contributors // For license information, please see license.txt -frappe.ui.form.on('SAT Payment Mode', { +frappe.ui.form.on('SAT Payment Method', { // refresh: function(frm) { // } diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json new file mode 100644 index 0000000..1bfe184 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json @@ -0,0 +1,85 @@ +{ + "actions": [], + "autoname": "field:key", + "creation": "2022-12-19 10:40:09.916493", + "default_view": "List", + "description": "Indicates the form in which a payment was made, in accordance with the SAT catalog of forms of payment", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": ["section_break", "enabled", "key", "key_name", "description"], + "fields": [ + { + "default": "1", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" + }, + { + "fieldname": "section_break", + "fieldtype": "Section Break" + }, + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "length": 2, + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "key_name", + "fieldtype": "Data", + "label": "Key Name", + "read_only": 1 + }, + { + "fieldname": "description", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Description", + "reqd": 1 + } + ], + "hide_toolbar": 1, + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-06-27 01:55:39.377966", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "SAT Payment Method", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "show_title_field_in_link": 1, + "sort_field": "key_name", + "sort_order": "ASC", + "states": [], + "title_field": "key_name" +} diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.py similarity index 90% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.py rename to erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.py index fbffa27..445faaa 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.py +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.py @@ -5,7 +5,7 @@ from frappe.model.document import Document -class SATPaymentMode(Document): +class SATPaymentMethod(Document): """SAT's Payment Mode (Forma de pago)""" def before_save(self): diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/test_sat_payment_mode.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/test_sat_payment_method.py similarity index 76% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/test_sat_payment_mode.py rename to erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/test_sat_payment_method.py index dfadba4..1730533 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/test_sat_payment_mode.py +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_method/test_sat_payment_method.py @@ -5,5 +5,5 @@ from frappe.tests.utils import FrappeTestCase -class TestSATPaymentMode(FrappeTestCase): +class TestSATPaymentMethod(FrappeTestCase): pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.json deleted file mode 100644 index edc8860..0000000 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_mode/sat_payment_mode.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "actions": [], - "autoname": "field:key", - "creation": "2022-12-19 10:40:09.916493", - "default_view": "List", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "enabled", - "section_break", - "key", - "key_name", - "column_break", - "description" - ], - "fields": [ - { - "default": "1", - "fieldname": "enabled", - "fieldtype": "Check", - "label": "Enabled" - }, - { - "fieldname": "section_break", - "fieldtype": "Section Break" - }, - { - "fieldname": "key", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Key", - "length": 2, - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "key_name", - "fieldtype": "Data", - "label": "Key Name", - "read_only": 1 - }, - { - "fieldname": "column_break", - "fieldtype": "Column Break" - }, - { - "fieldname": "description", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Description", - "reqd": 1 - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified": "2022-12-19 10:40:09.916493", - "modified_by": "Administrator", - "module": "ERPNext Mexico Compliance", - "name": "SAT Payment Mode", - "naming_rule": "By fieldname", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "show_title_field_in_link": 1, - "sort_field": "key_name", - "sort_order": "ASC", - "states": [], - "title_field": "key_name" -} diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.js b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.js new file mode 100644 index 0000000..3f7d193 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, TI Sin Problemas and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("SAT Payment Option", { +// refresh(frm) { + +// }, +// }); diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json new file mode 100644 index 0000000..edea8a2 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json @@ -0,0 +1,90 @@ +{ + "actions": [], + "autoname": "field:key", + "creation": "2024-06-27 01:29:40.855867", + "default_view": "List", + "description": "Indicates the method used to make a payment, in accordance with the SAT catalog of payment methods", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "section_break_yk87", + "enabled", + "key", + "key_name", + "description" + ], + "fields": [ + { + "fieldname": "section_break_yk87", + "fieldtype": "Section Break" + }, + { + "default": "1", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" + }, + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "length": 3, + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "key_name", + "fieldtype": "Data", + "label": "Key Name", + "read_only": 1 + }, + { + "fieldname": "description", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Description", + "reqd": 1 + } + ], + "hide_toolbar": 1, + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-06-27 02:29:23.445119", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "SAT Payment Option", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "show_title_field_in_link": 1, + "sort_field": "key_name", + "sort_order": "ASC", + "states": [], + "title_field": "key_name" +} diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.py new file mode 100644 index 0000000..2054c97 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.py @@ -0,0 +1,13 @@ +# Copyright (c) 2024, TI Sin Problemas and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class SATPaymentOption(Document): + """SAT's Payment Option (Método de pago)""" + + def before_save(self): + """Set DocType key name""" + self.key_name = f"{self.key} - {self.description}"[:140] diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/test_sat_payment_option.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/test_sat_payment_option.py new file mode 100644 index 0000000..0ebe5a9 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_payment_option/test_sat_payment_option.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, TI Sin Problemas and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestSATPaymentOption(FrappeTestCase): + pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/__init__.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.js b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.js similarity index 79% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.js rename to erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.js index c0840c0..4694196 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.js +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.js @@ -1,7 +1,7 @@ // Copyright (c) 2022, TI Sin Problemas and contributors // For license information, please see license.txt -frappe.ui.form.on('SAT Tax System', { +frappe.ui.form.on('SAT Tax Regime', { // refresh: function(frm) { // } diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json new file mode 100644 index 0000000..51c5229 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json @@ -0,0 +1,94 @@ +{ + "actions": [], + "autoname": "field:key", + "creation": "2024-08-10 14:06:19.157418", + "default_view": "List", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "enabled", + "section_break", + "key", + "key_name", + "column_break", + "description" + ], + "fields": [ + { + "default": "1", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" + }, + { + "fieldname": "section_break", + "fieldtype": "Section Break" + }, + { + "fieldname": "key_name", + "fieldtype": "Data", + "label": "Key Name", + "read_only": 1 + }, + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "length": 3, + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "column_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "description", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Description", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-08-14 16:36:37.232829", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "SAT Tax Regime", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "show_title_field_in_link": 1, + "sort_field": "key_name", + "sort_order": "ASC", + "states": [], + "title_field": "key_name" +} \ No newline at end of file diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.py new file mode 100644 index 0000000..638099c --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.py @@ -0,0 +1,27 @@ +""" +Copyright (c) 2022, TI Sin Problemas and contributors +For license information, please see license.txt +""" +# import frappe +from frappe.model.document import Document + + +class SATTaxRegime(Document): + """SAT's Tax Regime""" + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + description: DF.Data + enabled: DF.Check + key: DF.Data + key_name: DF.Data | None + # end: auto-generated types + + def before_save(self): + """Set DocType key name""" + self.key_name = f"{self.key} - {self.description}"[:140] diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/test_sat_tax_system.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/test_sat_tax_regime.py similarity index 78% rename from erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/test_sat_tax_system.py rename to erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/test_sat_tax_regime.py index c84933c..e2219aa 100644 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/test_sat_tax_system.py +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_regime/test_sat_tax_regime.py @@ -5,5 +5,5 @@ from frappe.tests.utils import FrappeTestCase -class TestSATTaxSystem(FrappeTestCase): +class TestSATTaxRegime(FrappeTestCase): pass diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.json deleted file mode 100644 index b4a61a8..0000000 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "actions": [], - "autoname": "field:key", - "default_view": "List", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "enabled", - "section_break", - "key", - "key_name", - "column_break", - "description" - ], - "fields": [ - { - "default": "1", - "fieldname": "enabled", - "fieldtype": "Check", - "label": "Enabled" - }, - { - "fieldname": "section_break", - "fieldtype": "Section Break" - }, - { - "fieldname": "key_name", - "fieldtype": "Data", - "label": "Key Name", - "read_only": 1 - }, - { - "fieldname": "key", - "fieldtype": "Data", - "label": "Key", - "length": 3, - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "column_break", - "fieldtype": "Column Break" - }, - { - "fieldname": "description", - "fieldtype": "Data", - "label": "Description", - "reqd": 1 - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified_by": "Administrator", - "module": "ERPNext Mexico Compliance", - "name": "SAT Tax System", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - }, - { - "create": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "share": 1, - "write": 1 - } - ], - "quick_entry": 1, - "show_title_field_in_link": 1, - "sort_field": "key_name", - "sort_order": "ASC", - "states": [], - "title_field": "key_name" -} diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.py b/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.py deleted file mode 100644 index d756356..0000000 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/doctype/sat_tax_system/sat_tax_system.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Copyright (c) 2022, TI Sin Problemas and contributors -For license information, please see license.txt -""" -# import frappe -from frappe.model.document import Document - - -class SATTaxSystem(Document): - """SAT's Tax System""" - - def before_save(self): - """Set DocType key name""" - self.key_name = f"{self.key} - {self.description}"[:140] diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json new file mode 100644 index 0000000..cc23b10 --- /dev/null +++ b/erpnext_mexico_compliance/erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json @@ -0,0 +1,140 @@ +{ + "charts": [], + "content": "[{\"id\":\"I0YRNY96Kv\",\"type\":\"header\",\"data\":{\"text\":\"Mexico Compliance\",\"col\":12}},{\"id\":\"2_c8TjCfdY\",\"type\":\"card\",\"data\":{\"card_name\":\"Accounting\",\"col\":4}},{\"id\":\"U5q9et5tJ7\",\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}}]", + "creation": "2024-06-25 23:20:44.180369", + "custom_blocks": [], + "docstatus": 0, + "doctype": "Workspace", + "for_user": "", + "hide_custom": 0, + "icon": "organization", + "idx": 0, + "indicator_color": "green", + "is_hidden": 0, + "label": "Mexico Compliance", + "links": [ + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT Payment Option", + "link_count": 0, + "link_to": "SAT Payment Option", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "description": "Module settings", + "hidden": 0, + "is_query_report": 0, + "label": "Settings", + "link_count": 2, + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "CFDI Stamping Settings", + "link_count": 0, + "link_to": "CFDI Stamping Settings", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "Digital Signing Certificate", + "link_count": 0, + "link_to": "Digital Signing Certificate", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "description": "SAT Catalogs for accounting", + "hidden": 0, + "is_query_report": 0, + "label": "Accounting", + "link_count": 6, + "link_type": "DocType", + "onboard": 0, + "type": "Card Break" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT CFDI Use", + "link_count": 0, + "link_to": "SAT CFDI Use", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT Product or Service Key", + "link_count": 0, + "link_to": "SAT Product or Service Key", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT Tax Regime", + "link_count": 0, + "link_to": "SAT Tax Regime", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT UOM Key", + "link_count": 0, + "link_to": "SAT UOM Key", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT Payment Method", + "link_count": 0, + "link_to": "SAT Payment Method", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + }, + { + "hidden": 0, + "is_query_report": 0, + "label": "SAT Payment Option", + "link_count": 0, + "link_to": "SAT Payment Option", + "link_type": "DocType", + "onboard": 0, + "type": "Link" + } + ], + "modified": "2024-08-10 14:48:14.626153", + "modified_by": "Administrator", + "module": "ERPNext Mexico Compliance", + "name": "Mexico Compliance", + "number_cards": [], + "owner": "Administrator", + "parent_page": "", + "public": 1, + "quick_lists": [], + "roles": [], + "sequence_id": 39.0, + "shortcuts": [], + "title": "Mexico Compliance" +} \ No newline at end of file diff --git a/erpnext_mexico_compliance/erpnext_mexico_compliance/workspace/sat_catalogs/sat_catalogs.json b/erpnext_mexico_compliance/erpnext_mexico_compliance/workspace/sat_catalogs/sat_catalogs.json deleted file mode 100644 index b76ae89..0000000 --- a/erpnext_mexico_compliance/erpnext_mexico_compliance/workspace/sat_catalogs/sat_catalogs.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "charts": [], - "content": "[{\"type\":\"header\",\"data\":{\"text\":\"SAT Catalogs\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Setup\",\"col\":4}}]", - "creation": "2022-12-06 17:25:51.574668", - "docstatus": 0, - "doctype": "Workspace", - "for_user": "", - "hide_custom": 0, - "icon": "table", - "idx": 0, - "label": "SAT Catalogs", - "links": [ - { - "hidden": 0, - "is_query_report": 0, - "label": "Setup", - "link_count": 5, - "onboard": 0, - "type": "Card Break" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "SAT CFDI Use", - "link_count": 0, - "link_to": "SAT CFDI Use", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "SAT Product or Service Key", - "link_count": 0, - "link_to": "SAT Product or Service Key", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "SAT Tax System", - "link_count": 0, - "link_to": "SAT Tax System", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "SAT UOM Key", - "link_count": 0, - "link_to": "SAT UOM Key", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "SAT Payment Mode", - "link_count": 0, - "link_to": "SAT Payment Mode", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - } - ], - "modified": "2022-12-06 17:29:14.082879", - "modified_by": "Administrator", - "module": "ERPNext Mexico Compliance", - "name": "SAT Catalogs", - "owner": "Administrator", - "parent_page": "Accounting", - "public": 1, - "quick_lists": [], - "roles": [], - "sequence_id": 31.0, - "shortcuts": [], - "title": "SAT Catalogs" -} \ No newline at end of file diff --git a/erpnext_mexico_compliance/fixtures/cancellation_reason.json b/erpnext_mexico_compliance/fixtures/cancellation_reason.json new file mode 100644 index 0000000..40522f6 --- /dev/null +++ b/erpnext_mexico_compliance/fixtures/cancellation_reason.json @@ -0,0 +1,34 @@ +[ + { + "code": "01", + "description": "Comprobante emitido con errores con relación", + "docstatus": 0, + "doctype": "Cancellation Reason", + "name": "01", + "requires_relationship": 1 + }, + { + "code": "02", + "description": "Comprobante emitido con errores sin relación", + "docstatus": 0, + "doctype": "Cancellation Reason", + "name": "02", + "requires_relationship": 0 + }, + { + "code": "03", + "description": "No se llevó a cabo la operación", + "docstatus": 0, + "doctype": "Cancellation Reason", + "name": "03", + "requires_relationship": 0 + }, + { + "code": "04", + "description": "Operación nominativa relacionada con una factura global", + "docstatus": 0, + "doctype": "Cancellation Reason", + "name": "04", + "requires_relationship": 0 + } +] diff --git a/erpnext_mexico_compliance/fixtures/custom_field.json b/erpnext_mexico_compliance/fixtures/custom_field.json index 8af4ab6..b4dca7e 100644 --- a/erpnext_mexico_compliance/fixtures/custom_field.json +++ b/erpnext_mexico_compliance/fixtures/custom_field.json @@ -1,6 +1,6 @@ [ { - "allow_in_quick_entry": 0, + "allow_in_quick_entry": 1, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -14,8 +14,8 @@ "dt": "UOM", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "cfdi_40", - "fieldtype": "Tab Break", + "fieldname": "cfdi_section", + "fieldtype": "Section Break", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -29,12 +29,69 @@ "insert_after": "must_be_whole_number", "is_system_generated": 0, "is_virtual": 0, - "label": "CFDI 4.0", + "label": "CFDI", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-07-25 00:18:06.817491", + "module": "ERPNext Mexico Compliance", + "name": "UOM-cfdi_section", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 1, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Mode of Payment", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "cfdi", + "fieldtype": "Section Break", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "accounts", + "is_system_generated": 0, + "is_virtual": 0, + "label": "CFDI", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:59:40.234315", + "modified": "2022-12-19 16:11:37.701411", "module": "ERPNext Mexico Compliance", - "name": "UOM-cfdi_40", + "name": "Mode of Payment-cfdi", "no_copy": 0, "non_negative": 0, "options": null, @@ -48,6 +105,8 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -67,7 +126,7 @@ "dt": "UOM", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_uom_key", + "fieldname": "mx_uom_key", "fieldtype": "Link", "hidden": 0, "hide_border": 0, @@ -79,13 +138,14 @@ "in_list_view": 1, "in_preview": 0, "in_standard_filter": 1, - "insert_after": "cfdi_40", + "insert_after": "cfdi_section", "is_system_generated": 0, "is_virtual": 0, "label": "SAT UOM Key", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:59:28.711146", + "modified": "2024-08-11 23:32:21.659300", "module": "ERPNext Mexico Compliance", "name": "UOM-sat_uom_key", "no_copy": 0, @@ -99,14 +159,16 @@ "read_only": 0, "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null }, { - "allow_in_quick_entry": 0, + "allow_in_quick_entry": 1, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -120,8 +182,8 @@ "dt": "Mode of Payment", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "cfdi_40", - "fieldtype": "Section Break", + "fieldname": "sat_payment_method", + "fieldtype": "Link", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -132,18 +194,19 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "accounts", + "insert_after": "cfdi", "is_system_generated": 0, "is_virtual": 0, - "label": "CFDI 4.0", + "label": "SAT Payment Method", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:11:37.701411", + "modified": "2022-12-19 15:58:19.773242", "module": "ERPNext Mexico Compliance", - "name": "Mode of Payment-cfdi_40", + "name": "Mode of Payment-sat_payment_method", "no_copy": 0, "non_negative": 0, - "options": null, + "options": "SAT Payment Method", "permlevel": 0, "precision": "", "print_hide": 0, @@ -154,12 +217,14 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null }, { - "allow_in_quick_entry": 0, + "allow_in_quick_entry": 1, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -170,11 +235,11 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Mode of Payment", + "dt": "Employee", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_payment_mode", - "fieldtype": "Link", + "fieldname": "mx_second_last_name", + "fieldtype": "Data", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -185,18 +250,19 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "cfdi_40", + "insert_after": "last_name", "is_system_generated": 0, "is_virtual": 0, - "label": "SAT Payment Mode", + "label": "Second Last Name", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 15:58:19.773242", + "modified": "2024-08-06 17:44:51.766484", "module": "ERPNext Mexico Compliance", - "name": "Mode of Payment-sat_payment_mode", + "name": "Employee-custom_second_last_name", "no_copy": 0, "non_negative": 0, - "options": "SAT Payment Mode", + "options": null, "permlevel": 0, "precision": "", "print_hide": 0, @@ -205,8 +271,10 @@ "read_only": 0, "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -224,9 +292,9 @@ "docstatus": 0, "doctype": "Custom Field", "dt": "Payment Entry", - "fetch_from": "mode_of_payment.sat_payment_mode", + "fetch_from": "mode_of_payment.sat_payment_method", "fetch_if_empty": 0, - "fieldname": "sat_payment_mode", + "fieldname": "mx_payment_mode", "fieldtype": "Data", "hidden": 0, "hide_border": 0, @@ -243,8 +311,9 @@ "is_virtual": 0, "label": "SAT Payment Mode", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-20 16:53:50.909607", + "modified": "2024-08-22 18:41:43.820068", "module": "ERPNext Mexico Compliance", "name": "Payment Entry-sat_payment_mode", "no_copy": 0, @@ -260,6 +329,64 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Company", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mx_tax_regime", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "tax_id", + "is_system_generated": 0, + "is_virtual": 0, + "label": "SAT Tax Regime", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-10 02:01:55.589523", + "module": "ERPNext Mexico Compliance", + "name": "Company-mx_tax_regime", + "no_copy": 0, + "non_negative": 0, + "options": "SAT Tax Regime", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -296,6 +423,7 @@ "is_virtual": 0, "label": "Tax Type", "length": 0, + "link_filters": null, "mandatory_depends_on": "eval:doc.account_type == 'Tax'", "modified": "2022-12-19 15:45:47.468341", "module": "ERPNext Mexico Compliance", @@ -313,6 +441,8 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -349,6 +479,7 @@ "is_virtual": 0, "label": "CLABE", "length": 18, + "link_filters": null, "mandatory_depends_on": null, "modified": "2023-06-12 22:33:46.005100", "module": "ERPNext Mexico Compliance", @@ -366,6 +497,8 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 1, "unique": 0, "width": null @@ -385,7 +518,7 @@ "dt": "Customer", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_tax_system", + "fieldname": "mx_tax_regime", "fieldtype": "Link", "hidden": 0, "hide_border": 0, @@ -400,15 +533,16 @@ "insert_after": "tax_id", "is_system_generated": 0, "is_virtual": 0, - "label": "SAT Tax System", + "label": "SAT Tax Regime", "length": 0, + "link_filters": null, "mandatory_depends_on": "", "modified": "2022-12-19 15:47:09.539300", "module": "ERPNext Mexico Compliance", - "name": "Customer-sat_tax_system", + "name": "Customer-mx_tax_regime", "no_copy": 0, "non_negative": 0, - "options": "SAT Tax System", + "options": "SAT Tax Regime", "permlevel": 0, "precision": "", "print_hide": 0, @@ -417,8 +551,10 @@ "read_only": 0, "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -435,11 +571,11 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice Item", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "cfdi_40", - "fieldtype": "Section Break", + "fieldname": "cfdi_tab", + "fieldtype": "Tab Break", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -450,15 +586,16 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "project", + "insert_after": "title", "is_system_generated": 0, "is_virtual": 0, - "label": "CFDI 4.0", + "label": "CFDI", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:14:38.888661", + "modified": "2024-08-27 01:34:55.810734", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice Item-cfdi_40", + "name": "Payment Entry-cfdi_tab", "no_copy": 0, "non_negative": 0, "options": null, @@ -472,6 +609,8 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -480,19 +619,19 @@ "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 0, + "collapsible": 1, "collapsible_depends_on": null, "columns": 0, "default": null, - "depends_on": "", + "depends_on": null, "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice Item", - "fetch_from": "item_code.sat_product_or_service_key", - "fetch_if_empty": 1, - "fieldname": "sat_product_or_service_key", - "fieldtype": "Link", + "dt": "Payment Entry", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mx_cancellation_section", + "fieldtype": "Section Break", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -503,49 +642,52 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "cfdi_40", + "insert_after": "cfdi_tab", "is_system_generated": 0, "is_virtual": 0, - "label": "SAT Product or Service Key", + "label": "Cancellation", "length": 0, - "mandatory_depends_on": "", - "modified": "2022-12-19 16:14:48.913990", + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-27 01:34:39.111761", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice Item-sat_product_or_service_key", + "name": "Payment Entry-mx_cancellation_section", "no_copy": 0, "non_negative": 0, - "options": "SAT Product or Service Key", + "options": null, "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, "read_only": 0, - "read_only_depends_on": "eval: doc.item_code", + "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null }, { "allow_in_quick_entry": 0, - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "collapsible_depends_on": null, "columns": 0, "default": null, - "depends_on": null, + "depends_on": "eval:doc.mx_stamped_xml != null", "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Item", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "cfdi_40", - "fieldtype": "Tab Break", + "fieldname": "cancellation_reason", + "fieldtype": "Link", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -556,28 +698,31 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "total_projected_qty", + "insert_after": "mx_cancellation_section", "is_system_generated": 0, "is_virtual": 0, - "label": "CFDI 4.0", + "label": "Cancellation reason", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 15:51:31.690229", + "modified": "2024-08-27 01:33:02.504195", "module": "ERPNext Mexico Compliance", - "name": "Item-cfdi_40", - "no_copy": 0, + "name": "Payment Entry-cancellation_reason", + "no_copy": 1, "non_negative": 0, - "options": null, + "options": "Cancellation Reason", "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, "read_only": 0, - "read_only_depends_on": null, + "read_only_depends_on": "eval:doc.docstatus != 1", "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -594,12 +739,12 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Item", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_product_or_service_key", - "fieldtype": "Link", - "hidden": 0, + "fieldname": "requires_relationship", + "fieldtype": "Check", + "hidden": 1, "hide_border": 0, "hide_days": 0, "hide_seconds": 0, @@ -609,49 +754,52 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "cfdi_40", + "insert_after": "cancellation_reason", "is_system_generated": 0, - "is_virtual": 0, - "label": "SAT Product or Service Key", + "is_virtual": 1, + "label": "Requires relationship", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 15:51:48.922472", + "modified": "2024-08-29 13:20:00.851548", "module": "ERPNext Mexico Compliance", - "name": "Item-sat_product_or_service_key", + "name": "Payment Entry-requires_relationship", "no_copy": 0, "non_negative": 0, - "options": "SAT Product or Service Key", + "options": null, "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, - "read_only": 0, + "read_only": 1, "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null }, { "allow_in_quick_entry": 0, - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "collapsible_depends_on": null, "columns": 0, "default": null, - "depends_on": null, + "depends_on": "eval:doc.cancellation_reason == \"01\"", "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "cfdi_40", - "fieldtype": "Tab Break", + "fieldname": "substitute_payment_entry", + "fieldtype": "Link", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -662,18 +810,19 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "connections_tab", + "insert_after": "requires_relationship", "is_system_generated": 0, "is_virtual": 0, - "label": "CFDI 4.0", + "label": "Substitute payment entry", "length": 0, - "mandatory_depends_on": null, - "modified": "2022-12-19 16:54:24.912637", + "link_filters": null, + "mandatory_depends_on": "eval:doc.cancellation_reason == \"01\"", + "modified": "2024-08-27 01:15:39.970278", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice-cfdi_40", - "no_copy": 0, + "name": "Payment Entry-substitute_payment_entry", + "no_copy": 1, "non_negative": 0, - "options": null, + "options": "Payment Entry", "permlevel": 0, "precision": "", "print_hide": 0, @@ -684,6 +833,8 @@ "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -692,7 +843,7 @@ "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 0, + "collapsible": 1, "collapsible_depends_on": null, "columns": 0, "default": null, @@ -700,11 +851,11 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "mode_of_payment", - "fieldtype": "Link", + "fieldname": "stamped_xml", + "fieldtype": "Section Break", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -715,28 +866,31 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "cfdi_40", + "insert_after": "substitute_payment_entry", "is_system_generated": 0, "is_virtual": 0, - "label": "Mode of Payment", + "label": "XML", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:24:16.564574", + "modified": "2024-08-27 01:58:55.441725", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice-mode_of_payment", + "name": "Payment Entry-stamped_xml", "no_copy": 0, "non_negative": 0, - "options": "Mode of Payment", + "options": null, "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, "read_only": 0, - "read_only_depends_on": "", + "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -753,11 +907,11 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice", - "fetch_from": "mode_of_payment.sat_payment_mode", + "dt": "Payment Entry", + "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_payment_mode", - "fieldtype": "Data", + "fieldname": "column_break_vv65n", + "fieldtype": "Column Break", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -768,15 +922,16 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "mode_of_payment", + "insert_after": "stamped_xml", "is_system_generated": 0, "is_virtual": 0, - "label": "SAT Payment Mode", + "label": "", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 21:38:43.086168", + "modified": "2024-08-27 01:49:05.618820", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice-sat_payment_mode", + "name": "Payment Entry-column_break_vv65n", "no_copy": 0, "non_negative": 0, "options": null, @@ -785,18 +940,20 @@ "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, - "read_only": 1, + "read_only": 0, "read_only_depends_on": null, "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null }, { "allow_in_quick_entry": 0, - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "collapsible_depends_on": null, @@ -806,31 +963,32 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "column_break_206", - "fieldtype": "Column Break", + "fieldname": "mx_stamped_xml", + "fieldtype": "HTML Editor", "hidden": 0, "hide_border": 0, "hide_days": 0, "hide_seconds": 0, "ignore_user_permissions": 0, - "ignore_xss_filter": 0, + "ignore_xss_filter": 1, "in_global_search": 0, "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "sat_payment_mode", + "insert_after": "column_break_vv65n", "is_system_generated": 0, "is_virtual": 0, - "label": null, + "label": "Stamped XML", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:53:24.995485", + "modified": "2024-08-27 01:15:40.009641", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice-column_break_206", - "no_copy": 0, + "name": "Payment Entry-mx_stamped_xml", + "no_copy": 1, "non_negative": 0, "options": null, "permlevel": 0, @@ -838,11 +996,13 @@ "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, - "read_only": 0, + "read_only": 1, "read_only_depends_on": null, "report_hide": 0, "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null @@ -851,7 +1011,7 @@ "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, - "collapsible": 0, + "collapsible": 1, "collapsible_depends_on": null, "columns": 0, "default": null, @@ -859,11 +1019,11 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice", + "dt": "Sales Invoice Item", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_payment_method", - "fieldtype": "Select", + "fieldname": "cfdi", + "fieldtype": "Section Break", "hidden": 0, "hide_border": 0, "hide_days": 0, @@ -874,18 +1034,19 @@ "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "column_break_206", + "insert_after": "project", "is_system_generated": 0, "is_virtual": 0, - "label": "SAT Payment Method", + "label": "CFDI", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:43:21.441790", + "modified": "2024-08-11 21:15:30.639653", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice-sat_payment_method", + "name": "Sales Invoice Item-cfdi_section", "no_copy": 0, "non_negative": 0, - "options": "\nPUE - Pago en una sola exhibición\nPPD - Pago en parcialidades o diferido", + "options": null, "permlevel": 0, "precision": "", "print_hide": 0, @@ -894,15 +1055,17 @@ "read_only": 0, "read_only_depends_on": null, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null }, { "allow_in_quick_entry": 0, - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "collapsible_depends_on": null, @@ -912,45 +1075,944 @@ "description": null, "docstatus": 0, "doctype": "Custom Field", - "dt": "Sales Invoice", + "dt": "Payment Entry", "fetch_from": null, "fetch_if_empty": 0, - "fieldname": "sat_cfdi_use", - "fieldtype": "Link", + "fieldname": "cancellation_acknowledgement", + "fieldtype": "HTML Editor", "hidden": 0, "hide_border": 0, "hide_days": 0, "hide_seconds": 0, "ignore_user_permissions": 0, - "ignore_xss_filter": 0, + "ignore_xss_filter": 1, "in_global_search": 0, "in_list_view": 0, "in_preview": 0, "in_standard_filter": 0, - "insert_after": "sat_payment_method", + "insert_after": "mx_stamped_xml", "is_system_generated": 0, "is_virtual": 0, - "label": "SAT CFDI Use", + "label": "Cancellation acknowledgement", "length": 0, + "link_filters": null, "mandatory_depends_on": null, - "modified": "2022-12-19 16:43:34.645756", + "modified": "2024-08-27 01:23:45.661672", "module": "ERPNext Mexico Compliance", - "name": "Sales Invoice-sat_cfdi_use", - "no_copy": 0, + "name": "Payment Entry-cancellation_acknowledgement", + "no_copy": 1, "non_negative": 0, - "options": "SAT CFDI Use", + "options": null, "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "print_width": null, - "read_only": 0, + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": "", + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice Item", + "fetch_from": "item_code.mx_product_service_key", + "fetch_if_empty": 1, + "fieldname": "mx_product_service_key", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "cfdi", + "is_system_generated": 0, + "is_virtual": 0, + "label": "SAT Product or Service Key", + "length": 0, + "link_filters": null, + "mandatory_depends_on": "", + "modified": "2024-08-11 22:03:06.415334", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice Item-sat_product_or_service_key", + "no_copy": 0, + "non_negative": 0, + "options": "SAT Product or Service Key", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": "eval: doc.item_code", + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Item", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "cfdi", + "fieldtype": "Tab Break", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "total_projected_qty", + "is_system_generated": 0, + "is_virtual": 0, + "label": "CFDI", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-11 19:46:06.465750", + "module": "ERPNext Mexico Compliance", + "name": "Item-cfdi_40", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Item", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mx_product_service_key", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "cfdi", + "is_system_generated": 0, + "is_virtual": 0, + "label": "SAT Product or Service Key", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-11 21:37:19.858147", + "module": "ERPNext Mexico Compliance", + "name": "Item-sat_product_or_service_key", + "no_copy": 0, + "non_negative": 0, + "options": "SAT Product or Service Key", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "cfdi_40", + "fieldtype": "Tab Break", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "connections_tab", + "is_system_generated": 0, + "is_virtual": 0, + "label": "CFDI", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2022-12-19 16:54:24.912637", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-cfdi_40", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mx_payment_option", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "cfdi_40", + "is_system_generated": 0, + "is_virtual": 0, + "label": "SAT Payment Option", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-06-27 19:53:20.792645", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-mx_payment_option", + "no_copy": 0, + "non_negative": 0, + "options": "SAT Payment Option", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, "read_only_depends_on": null, "report_hide": 0, "reqd": 1, "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mx_cfdi_use", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "mx_payment_option", + "is_system_generated": 0, + "is_virtual": 0, + "label": "SAT CFDI Use", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-06-27 19:53:20.818669", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-mx_cfdi_use", + "no_copy": 0, + "non_negative": 0, + "options": "SAT CFDI Use", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "column_break_206", + "fieldtype": "Column Break", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "mx_cfdi_use", + "is_system_generated": 0, + "is_virtual": 0, + "label": null, + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2022-12-19 16:53:24.995485", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-column_break_206", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "column_break_206", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Mode of Payment", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2022-12-19 16:24:16.564574", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-mode_of_payment", + "no_copy": 0, + "non_negative": 0, + "options": "Mode of Payment", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": "", + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": "mode_of_payment.sat_payment_method", + "fetch_if_empty": 0, + "fieldname": "mx_payment_mode", + "fieldtype": "Data", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "mode_of_payment", + "is_system_generated": 0, + "is_virtual": 0, + "label": "SAT Payment Method", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2022-12-19 21:38:43.086168", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-mx_payment_mode", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "cancellation_section", + "fieldtype": "Section Break", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "mx_payment_mode", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Cancellation", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-17 18:57:09.032783", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-cancellation_section", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": "eval:doc.mx_stamped_xml != null", + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "cancellation_reason", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "cancellation_section", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Cancellation reason", + "length": 0, + "link_filters": null, + "mandatory_depends_on": "", + "modified": "2024-08-17 18:57:42.717062", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-cancellation_reason", + "no_copy": 1, + "non_negative": 0, + "options": "Cancellation Reason", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": "eval:doc.docstatus != 1", + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "requires_relationship", + "fieldtype": "Check", + "hidden": 1, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "cancellation_reason", + "is_system_generated": 0, + "is_virtual": 1, + "label": "Requires relationship", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-21 23:50:43.024068", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-requires_relationship", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": "eval:doc.cancellation_reason == \"01\"", + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "substitute_invoice", + "fieldtype": "Link", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "requires_relationship", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Substitute invoice", + "length": 0, + "link_filters": null, + "mandatory_depends_on": "eval:doc.cancellation_reason == \"01\"", + "modified": "2024-08-21 23:50:42.992235", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-substitute_invoice", + "no_copy": 1, + "non_negative": 0, + "options": "Sales Invoice", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": "eval:doc.docstatus != 1", + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "section_break_9ww80", + "fieldtype": "Section Break", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "substitute_invoice", + "is_system_generated": 0, + "is_virtual": 0, + "label": "XML", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-28 23:24:24.344099", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-section_break_9ww80", + "no_copy": 0, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "mx_stamped_xml", + "fieldtype": "HTML Editor", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "section_break_9ww80", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Stamped XML", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-16 17:05:22.837922", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-mx_stamped_xml", + "no_copy": 1, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "allow_in_quick_entry": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "doctype": "Custom Field", + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "cancellation_acknowledgement", + "fieldtype": "HTML Editor", + "hidden": 0, + "hide_border": 0, + "hide_days": 0, + "hide_seconds": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 1, + "in_global_search": 0, + "in_list_view": 0, + "in_preview": 0, + "in_standard_filter": 0, + "insert_after": "mx_stamped_xml", + "is_system_generated": 0, + "is_virtual": 0, + "label": "Cancellation acknowledgement", + "length": 0, + "link_filters": null, + "mandatory_depends_on": null, + "modified": "2024-08-22 01:17:52.961407", + "module": "ERPNext Mexico Compliance", + "name": "Sales Invoice-cancellation_acknowledgement", + "no_copy": 1, + "non_negative": 0, + "options": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "read_only_depends_on": null, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "show_dashboard": 0, + "sort_options": 0, "translatable": 0, "unique": 0, "width": null } -] \ No newline at end of file +] diff --git a/erpnext_mexico_compliance/fixtures/property_setter.json b/erpnext_mexico_compliance/fixtures/property_setter.json index 51d52aa..f2ff952 100644 --- a/erpnext_mexico_compliance/fixtures/property_setter.json +++ b/erpnext_mexico_compliance/fixtures/property_setter.json @@ -7,7 +7,7 @@ "doctype_or_field": "DocField", "field_name": "tax_id", "is_system_generated": 0, - "modified": "2022-12-23 22:48:41.912479", + "modified": "2024-08-28 18:24:27.487429", "module": "ERPNext Mexico Compliance", "name": "Customer-tax_id-allow_in_quick_entry", "property": "allow_in_quick_entry", diff --git a/erpnext_mexico_compliance/fixtures/sat_cfdi_use.json b/erpnext_mexico_compliance/fixtures/sat_cfdi_use.json index 09e6ae1..4e6e51b 100644 --- a/erpnext_mexico_compliance/fixtures/sat_cfdi_use.json +++ b/erpnext_mexico_compliance/fixtures/sat_cfdi_use.json @@ -5,7 +5,75 @@ "enabled": 1, "key": "G01", "key_name": "G01 - Adquisición de mercancías.", - "name": "G01" + "name": "G01", + "tax_regimes": [ + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "G01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Devoluciones, descuentos o bonificaciones.", @@ -13,7 +81,81 @@ "enabled": 1, "key": "G02", "key_name": "G02 - Devoluciones, descuentos o bonificaciones.", - "name": "G02" + "name": "G02", + "tax_regimes": [ + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "616" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "G02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Gastos en general.", @@ -21,7 +163,75 @@ "enabled": 1, "key": "G03", "key_name": "G03 - Gastos en general.", - "name": "G03" + "name": "G03", + "tax_regimes": [ + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "G03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Construcciones.", @@ -29,7 +239,75 @@ "enabled": 1, "key": "I01", "key_name": "I01 - Construcciones.", - "name": "I01" + "name": "I01", + "tax_regimes": [ + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Mobiliario y equipo de oficina por inversiones.", @@ -37,7 +315,75 @@ "enabled": 1, "key": "I02", "key_name": "I02 - Mobiliario y equipo de oficina por inversiones.", - "name": "I02" + "name": "I02", + "tax_regimes": [ + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Equipo de transporte.", @@ -45,7 +391,75 @@ "enabled": 1, "key": "I03", "key_name": "I03 - Equipo de transporte.", - "name": "I03" + "name": "I03", + "tax_regimes": [ + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Equipo de computo y accesorios.", @@ -53,7 +467,75 @@ "enabled": 1, "key": "I04", "key_name": "I04 - Equipo de computo y accesorios.", - "name": "I04" + "name": "I04", + "tax_regimes": [ + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Dados, troqueles, moldes, matrices y herramental.", @@ -61,7 +543,75 @@ "enabled": 1, "key": "I05", "key_name": "I05 - Dados, troqueles, moldes, matrices y herramental.", - "name": "I05" + "name": "I05", + "tax_regimes": [ + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Comunicaciones telefónicas.", @@ -69,7 +619,75 @@ "enabled": 1, "key": "I06", "key_name": "I06 - Comunicaciones telefónicas.", - "name": "I06" + "name": "I06", + "tax_regimes": [ + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Comunicaciones satelitales.", @@ -77,7 +695,75 @@ "enabled": 1, "key": "I07", "key_name": "I07 - Comunicaciones satelitales.", - "name": "I07" + "name": "I07", + "tax_regimes": [ + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Otra maquinaria y equipo.", @@ -85,7 +771,75 @@ "enabled": 1, "key": "I08", "key_name": "I08 - Otra maquinaria y equipo.", - "name": "I08" + "name": "I08", + "tax_regimes": [ + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "I08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Honorarios médicos, dentales y gastos hospitalarios.", @@ -93,7 +847,63 @@ "enabled": 1, "key": "D01", "key_name": "D01 - Honorarios médicos, dentales y gastos hospitalarios.", - "name": "D01" + "name": "D01", + "tax_regimes": [ + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Gastos médicos por incapacidad o discapacidad.", @@ -101,7 +911,63 @@ "enabled": 1, "key": "D02", "key_name": "D02 - Gastos médicos por incapacidad o discapacidad.", - "name": "D02" + "name": "D02", + "tax_regimes": [ + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D02", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Gastos funerales.", @@ -109,7 +975,63 @@ "enabled": 1, "key": "D03", "key_name": "D03 - Gastos funerales.", - "name": "D03" + "name": "D03", + "tax_regimes": [ + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D03", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Donativos.", @@ -117,7 +1039,63 @@ "enabled": 1, "key": "D04", "key_name": "D04 - Donativos.", - "name": "D04" + "name": "D04", + "tax_regimes": [ + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D04", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Intereses reales efectivamente pagados por créditos hipotecarios (casa habitación).", @@ -125,7 +1103,63 @@ "enabled": 1, "key": "D05", "key_name": "D05 - Intereses reales efectivamente pagados por créditos hipotecarios (casa habitación).", - "name": "D05" + "name": "D05", + "tax_regimes": [ + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D05", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Aportaciones voluntarias al SAR.", @@ -133,7 +1167,63 @@ "enabled": 1, "key": "D06", "key_name": "D06 - Aportaciones voluntarias al SAR.", - "name": "D06" + "name": "D06", + "tax_regimes": [ + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D06", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Primas por seguros de gastos médicos.", @@ -141,7 +1231,63 @@ "enabled": 1, "key": "D07", "key_name": "D07 - Primas por seguros de gastos médicos.", - "name": "D07" + "name": "D07", + "tax_regimes": [ + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D07", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Gastos de transportación escolar obligatoria.", @@ -149,7 +1295,63 @@ "enabled": 1, "key": "D08", "key_name": "D08 - Gastos de transportación escolar obligatoria.", - "name": "D08" + "name": "D08", + "tax_regimes": [ + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D08", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.", @@ -157,7 +1359,63 @@ "enabled": 1, "key": "D09", "key_name": "D09 - Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.", - "name": "D09" + "name": "D09", + "tax_regimes": [ + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D09", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Pagos por servicios educativos (colegiaturas).", @@ -165,7 +1423,63 @@ "enabled": 1, "key": "D10", "key_name": "D10 - Pagos por servicios educativos (colegiaturas).", - "name": "D10" + "name": "D10", + "tax_regimes": [ + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "D10", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + } + ] }, { "description": "Sin efectos fiscales.", @@ -173,7 +1487,123 @@ "enabled": 1, "key": "S01", "key_name": "S01 - Sin efectos fiscales.", - "name": "S01" + "name": "S01", + "tax_regimes": [ + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "610" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "616" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "S01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Pagos", @@ -181,7 +1611,123 @@ "enabled": 1, "key": "CP01", "key_name": "CP01 - Pagos", - "name": "CP01" + "name": "CP01", + "tax_regimes": [ + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "601" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "603" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "606" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "608" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "610" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "611" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "612" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "614" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "616" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "620" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "621" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "622" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "623" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "624" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "607" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "615" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "625" + }, + { + "parent": "CP01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "626" + } + ] }, { "description": "Nómina", @@ -189,6 +1735,14 @@ "enabled": 1, "key": "CN01", "key_name": "CN01 - Nómina", - "name": "CN01" + "name": "CN01", + "tax_regimes": [ + { + "parent": "CN01", + "parentfield": "tax_regimes", + "parenttype": "SAT CFDI Use", + "tax_regime": "605" + } + ] } ] \ No newline at end of file diff --git a/erpnext_mexico_compliance/fixtures/sat_payment_mode.json b/erpnext_mexico_compliance/fixtures/sat_payment_method.json similarity index 79% rename from erpnext_mexico_compliance/fixtures/sat_payment_mode.json rename to erpnext_mexico_compliance/fixtures/sat_payment_method.json index e93890c..6344e4f 100644 --- a/erpnext_mexico_compliance/fixtures/sat_payment_mode.json +++ b/erpnext_mexico_compliance/fixtures/sat_payment_method.json @@ -1,7 +1,7 @@ [ { "description": "Efectivo", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "01", "key_name": "01 - Efectivo", @@ -9,7 +9,7 @@ }, { "description": "Cheque nominativo", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "02", "key_name": "02 - Cheque nominativo", @@ -17,7 +17,7 @@ }, { "description": "Transferencia electrónica de fondos", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "03", "key_name": "03 - Transferencia electrónica de fondos", @@ -25,7 +25,7 @@ }, { "description": "Tarjeta de crédito", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "04", "key_name": "04 - Tarjeta de crédito", @@ -33,7 +33,7 @@ }, { "description": "Monedero electrónico", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "05", "key_name": "05 - Monedero electrónico", @@ -41,7 +41,7 @@ }, { "description": "Dinero electrónico", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "06", "key_name": "06 - Dinero electrónico", @@ -49,7 +49,7 @@ }, { "description": "Vales de despensa", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "08", "key_name": "08 - Vales de despensa", @@ -57,7 +57,7 @@ }, { "description": "Dación en pago", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "12", "key_name": "12 - Dación en pago", @@ -65,7 +65,7 @@ }, { "description": "Pago por subrogación", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "13", "key_name": "13 - Pago por subrogación", @@ -73,7 +73,7 @@ }, { "description": "Pago por consignación", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "14", "key_name": "14 - Pago por consignación", @@ -81,7 +81,7 @@ }, { "description": "Condonación", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "15", "key_name": "15 - Condonación", @@ -89,7 +89,7 @@ }, { "description": "Compensación", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "17", "key_name": "17 - Compensación", @@ -97,7 +97,7 @@ }, { "description": "Novación", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "23", "key_name": "23 - Novación", @@ -105,7 +105,7 @@ }, { "description": "Confusión", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "24", "key_name": "24 - Confusión", @@ -113,7 +113,7 @@ }, { "description": "Remisión de deuda", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "25", "key_name": "25 - Remisión de deuda", @@ -121,7 +121,7 @@ }, { "description": "Prescripción o caducidad", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "26", "key_name": "26 - Prescripción o caducidad", @@ -129,7 +129,7 @@ }, { "description": "A satisfacción del acreedor", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "27", "key_name": "27 - A satisfacción del acreedor", @@ -137,7 +137,7 @@ }, { "description": "Tarjeta de débito", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "28", "key_name": "28 - Tarjeta de débito", @@ -145,7 +145,7 @@ }, { "description": "Tarjeta de servicios", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "29", "key_name": "29 - Tarjeta de servicios", @@ -153,7 +153,7 @@ }, { "description": "Aplicación de anticipos", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "30", "key_name": "30 - Aplicación de anticipos", @@ -161,7 +161,7 @@ }, { "description": "Intermediario pagos", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "31", "key_name": "31 - Intermediario pagos", @@ -169,7 +169,7 @@ }, { "description": "Por definir", - "doctype": "SAT Payment Mode", + "doctype": "SAT Payment Method", "enabled": 1, "key": "99", "key_name": "99 - Por definir", diff --git a/erpnext_mexico_compliance/fixtures/sat_payment_option.json b/erpnext_mexico_compliance/fixtures/sat_payment_option.json new file mode 100644 index 0000000..92fd10c --- /dev/null +++ b/erpnext_mexico_compliance/fixtures/sat_payment_option.json @@ -0,0 +1,18 @@ +[ + { + "description": "Pago en parcialidades o diferido", + "doctype": "SAT Payment Option", + "enabled": 1, + "key": "PPD", + "key_name": "PPD - Pago en parcialidades o diferido", + "name": "PPD" + }, + { + "description": "Pago en una sola exhibición", + "doctype": "SAT Payment Option", + "enabled": 1, + "key": "PUE", + "key_name": "PUE - Pago en una sola exhibición", + "name": "PUE" + } +] \ No newline at end of file diff --git a/erpnext_mexico_compliance/fixtures/sat_tax_system.json b/erpnext_mexico_compliance/fixtures/sat_tax_regime.json similarity index 85% rename from erpnext_mexico_compliance/fixtures/sat_tax_system.json rename to erpnext_mexico_compliance/fixtures/sat_tax_regime.json index 45b6fb2..a567f75 100644 --- a/erpnext_mexico_compliance/fixtures/sat_tax_system.json +++ b/erpnext_mexico_compliance/fixtures/sat_tax_regime.json @@ -1,7 +1,7 @@ [ { "description": "General de Ley Personas Morales", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "601", "key_name": "601 - General de Ley Personas Morales", @@ -9,7 +9,7 @@ }, { "description": "Personas Morales con Fines no Lucrativos", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "603", "key_name": "603 - Personas Morales con Fines no Lucrativos", @@ -17,7 +17,7 @@ }, { "description": "Sueldos y Salarios e Ingresos Asimilados a Salarios", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "605", "key_name": "605 - Sueldos y Salarios e Ingresos Asimilados a Salarios", @@ -25,7 +25,7 @@ }, { "description": "Arrendamiento", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "606", "key_name": "606 - Arrendamiento", @@ -33,7 +33,7 @@ }, { "description": "Régimen de Enajenación o Adquisición de Bienes", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "607", "key_name": "607 - Régimen de Enajenación o Adquisición de Bienes", @@ -41,7 +41,7 @@ }, { "description": "Demás ingresos", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "608", "key_name": "608 - Demás ingresos", @@ -49,7 +49,7 @@ }, { "description": "Residentes en el Extranjero sin Establecimiento Permanente en México", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "610", "key_name": "610 - Residentes en el Extranjero sin Establecimiento Permanente en México", @@ -57,7 +57,7 @@ }, { "description": "Ingresos por Dividendos (socios y accionistas)", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "611", "key_name": "611 - Ingresos por Dividendos (socios y accionistas)", @@ -65,7 +65,7 @@ }, { "description": "Personas Físicas con Actividades Empresariales y Profesionales", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "612", "key_name": "612 - Personas Físicas con Actividades Empresariales y Profesionales", @@ -73,7 +73,7 @@ }, { "description": "Ingresos por intereses", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "614", "key_name": "614 - Ingresos por intereses", @@ -81,7 +81,7 @@ }, { "description": "Régimen de los ingresos por obtención de premios", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "615", "key_name": "615 - Régimen de los ingresos por obtención de premios", @@ -89,7 +89,7 @@ }, { "description": "Sin obligaciones fiscales", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "616", "key_name": "616 - Sin obligaciones fiscales", @@ -97,7 +97,7 @@ }, { "description": "Sociedades Cooperativas de Producción que optan por diferir sus ingresos", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "620", "key_name": "620 - Sociedades Cooperativas de Producción que optan por diferir sus ingresos", @@ -105,7 +105,7 @@ }, { "description": "Incorporación Fiscal", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "621", "key_name": "621 - Incorporación Fiscal", @@ -113,7 +113,7 @@ }, { "description": "Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "622", "key_name": "622 - Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras", @@ -121,7 +121,7 @@ }, { "description": "Opcional para Grupos de Sociedades", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "623", "key_name": "623 - Opcional para Grupos de Sociedades", @@ -129,7 +129,7 @@ }, { "description": "Coordinados", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "624", "key_name": "624 - Coordinados", @@ -137,7 +137,7 @@ }, { "description": "Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "625", "key_name": "625 - Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas", @@ -145,10 +145,10 @@ }, { "description": "Régimen Simplificado de Confianza", - "doctype": "SAT Tax System", + "doctype": "SAT Tax Regime", "enabled": 1, "key": "626", "key_name": "626 - Régimen Simplificado de Confianza", "name": "626" } -] \ No newline at end of file +] diff --git a/erpnext_mexico_compliance/hooks.py b/erpnext_mexico_compliance/hooks.py index 17c2b3d..7a602b5 100644 --- a/erpnext_mexico_compliance/hooks.py +++ b/erpnext_mexico_compliance/hooks.py @@ -32,11 +32,19 @@ # page_js = {"page" : "public/js/file.js"} # include js in doctype views -# doctype_js = {"doctype" : "public/js/doctype.js"} +doctype_js = { + "Sales Invoice": "public/js/sales_invoice.js", + "Payment Entry": "public/js/payment_entry.js", +} # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} # doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"} +# Svg Icons +# ------------------ +# include app icons in desk +# app_include_icons = "erpnext_mexico_compliance/public/icons.svg" + # Home Pages # ---------- @@ -82,6 +90,22 @@ # after_migrate = "erpnext_mexico_compliance.migrate.after_migrate" # before_migrate = "erpnext_mexico_compliance.migrate.before_migrate" +# Integration Setup +# ------------------ +# To set up dependencies/integrations with other apps +# Name of the app being installed is passed as an argument + +# before_app_install = "erpnext_mexico_compliance.utils.before_app_install" +# after_app_install = "erpnext_mexico_compliance.utils.after_app_install" + +# Integration Cleanup +# ------------------- +# To clean up dependencies/integrations with other apps +# Name of the app being uninstalled is passed as an argument + +# before_app_uninstall = "erpnext_mexico_compliance.utils.before_app_uninstall" +# after_app_uninstall = "erpnext_mexico_compliance.utils.after_app_uninstall" + # Desk Notifications # ------------------ # See frappe.core.notifications.get_notification_config @@ -106,6 +130,7 @@ override_doctype_class = { "Customer": "erpnext_mexico_compliance.overrides.customer.Customer", + "Payment Entry": "erpnext_mexico_compliance.overrides.payment_entry.PaymentEntry", "Sales Invoice": "erpnext_mexico_compliance.overrides.sales_invoice.SalesInvoice", "Sales Invoice Item": "erpnext_mexico_compliance.overrides.sales_invoice_item.SalesInvoiceItem", } @@ -171,6 +196,15 @@ # ignore_links_on_delete = ["Communication", "ToDo"] +# Request Events +# ---------------- +# before_request = ["erpnext_mexico_compliance.utils.before_request"] +# after_request = ["erpnext_mexico_compliance.utils.after_request"] + +# Job Events +# ---------- +# before_job = ["erpnext_cfdi.utils.before_job"] +# after_job = ["erpnext_cfdi.utils.after_job"] # User Data Protection # -------------------- @@ -203,6 +237,13 @@ # "erpnext_mexico_compliance.auth.validate" # ] +# Automatically update python controller files with type annotations for this app. +export_python_type_annotations = True + +# default_log_clearing_doctypes = { +# "Logging DocType Name": 30 # days to retain logs +# } + fixtures = [ {"doctype": "Custom Field", "filters": [{"module": "ERPNext Mexico Compliance"}]}, { diff --git a/erpnext_mexico_compliance/install.py b/erpnext_mexico_compliance/install.py index 9936b9b..c378194 100644 --- a/erpnext_mexico_compliance/install.py +++ b/erpnext_mexico_compliance/install.py @@ -1,85 +1,21 @@ """Installation tasks""" + import os import frappe -from frappe.core.doctype.data_import.importer import Importer, ImportFile +from frappe.core.doctype.data_import.data_import import import_file from .hooks import app_name - -# TODO: Replace with frappe.core.doctype.data_import.data_import.import_file -# when commit c6b1b02 is merged into version-14 -def import_local_file( - doctype, file_path, import_type, submit_after_import=False, console=False -): - """ - Import documents in from CSV or XLSX using data import. - - :param doctype: DocType to import - :param file_path: Path to .csv, .xls, or .xlsx file to import - :param import_type: One of "Insert" or "Update" - :param submit_after_import: Whether to submit documents after import - :param console: Set to true if this is to be used from command line. Will print errors or progress to stdout. - """ - - class LocalImportFile(ImportFile): - def read_file(self, file_path: str): - _, extn = super().read_file(file_path) - file_content = frappe.read_file(file_path, True) - return file_content, extn - - class LocalImporter(Importer): - def __init__( - self, - doctype, - data_import=None, - file_path=None, - import_type=None, - console=False, - ): - self.doctype = doctype - self.console = console - - self.data_import = data_import - if not self.data_import: - self.data_import = frappe.get_doc(doctype="Data Import") - if import_type: - self.data_import.import_type = import_type - - self.template_options = frappe.parse_json( - self.data_import.template_options or "{}" - ) - self.import_type = self.data_import.import_type - - self.import_file = LocalImportFile( - doctype, - file_path or data_import.google_sheets_url or data_import.import_file, - self.template_options, - self.import_type, - ) - - data_import = frappe.new_doc("Data Import") - data_import.submit_after_import = submit_after_import - data_import.import_type = ( - "Insert New Records" - if import_type.lower() == "insert" - else "Update Existing Records" - ) - - i = LocalImporter( - doctype=doctype, file_path=file_path, data_import=data_import, console=console - ) - i.import_data() +logger = frappe.logger("erpnext_mexico_compliance.install") def after_sync(): """Run tasks after migration sync""" - print("Importing SAT Product or Service Key data...") + logger.info("Importing SAT Product or Service Key data...") fixtures_directory = "fixtures_csv" files = sorted(os.listdir(frappe.get_app_path(app_name, fixtures_directory))) for file in files: - print("\nLoading", f"{file}...") + logger.info("Loading %s...", file) file_path = frappe.get_app_path(app_name, fixtures_directory, file) - import_local_file( - "SAT Product or Service Key", file_path, "Insert", console=True - ) + import_file("SAT Product or Service Key", file_path, "Insert", console=True) diff --git a/erpnext_mexico_compliance/locale/es.po b/erpnext_mexico_compliance/locale/es.po new file mode 100644 index 0000000..8d07be1 --- /dev/null +++ b/erpnext_mexico_compliance/locale/es.po @@ -0,0 +1,508 @@ +# Translations template for ERPNext Mexico Compliance. +# Copyright (C) 2024 TI Sin Problemas +# This file is distributed under the same license as the ERPNext Mexico Compliance project. +# FIRST AUTHOR , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: ERPNext Mexico Compliance VERSION\n" +"Report-Msgid-Bugs-To: info@tisinproblemas.com\n" +"POT-Creation-Date: 2024-08-30 22:42+0000\n" +"PO-Revision-Date: 2024-08-30 22:42+0000\n" +"Last-Translator: info@tisinproblemas.com\n" +"Language-Team: info@tisinproblemas.com\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.13.1\n" + +#. Description of the 'Available credits' (Int) field in DocType 'CFDI Stamping +#. Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "1 credit is consumed every time a CFDI gets stamped" +msgstr "1 crédito es consumido cada vez que se timbra un CFDI" + +#. Header text in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Mexico Compliance" +msgstr "" + +#: public/js/payment_entry.js:81 +msgid "A Cancellation Reason is required to cancel this payment entry." +msgstr "Un Motivo de Cancelación es necesario para cancelar este pago." + +#: public/js/sales_invoice.js:81 +msgid "A Cancellation Reason is required to cancel this sales invoice." +msgstr "Un Motivo de Cancelación es necesario para cancelar esta factura de venta." + +#: overrides/payment_entry.py:257 overrides/sales_invoice.py:327 +msgid "A Cancellation Reason is required." +msgstr "Un Motivo de Cancelación es necesario." + +#. Label of a Password field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "API Key" +msgstr "" + +#. Label of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Accounting" +msgstr "" + +#. Name of a role +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Accounts Manager" +msgstr "" + +#: overrides/payment_entry.py:91 overrides/payment_entry.py:133 +#: overrides/sales_invoice.py:117 +msgid "Address {0} has no zip code" +msgstr "La dirección {0} no tiene código postal" + +#: public/js/payment_entry.js:50 public/js/sales_invoice.js:50 +msgid "Attach PDF" +msgstr "Adjuntar PDF" + +#: public/js/payment_entry.js:64 public/js/sales_invoice.js:64 +msgid "Attach XML" +msgstr "Adjuntar XML" + +#. Label of a Int field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Available credits" +msgstr "Créditos disponibles" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:82 +msgctxt "Company branch" +msgid "Branch: {0}" +msgstr "Sucursal: {0}" + +#: public/js/payment_entry.js:41 public/js/sales_invoice.js:41 +msgid "CFDI Actions" +msgstr "Acciones de CFDI" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "CFDI Stamping Settings" +msgstr "Configuración de Timbrado de CFDI" + +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.py:44 +#: overrides/payment_entry.py:173 overrides/payment_entry.py:309 +#: overrides/sales_invoice.py:279 overrides/sales_invoice.py:375 +msgid "CFDI Web Service Error" +msgstr "Error del Web Service de CFDI" + +#: public/js/payment_entry.js:129 public/js/sales_invoice.js:127 +msgid "Cancel" +msgstr "" + +#. Name of a DocType +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Cancellation Reason" +msgstr "Motivo de Cancelación" + +#. Label of a Attach field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate" +msgstr "" + +#. Description of the 'Certificate' (Attach) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate file (.cer)" +msgstr "Archivo de certificado (.cer)" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:41 +msgid "Certificate file not configured" +msgstr "Archivo de certificado no configurado" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:114 +msgid "Certificate files and password are not valid" +msgstr "Los archivos de certificado y contraseña no son válidos" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:80 +msgid "Certificate files and password are valid" +msgstr "Los archivos de certificado y contraseña son válidos" + +#. Description of the 'Key' (Attach) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate key file (.key)" +msgstr "Archivo de clave de certificado (.key)" + +#. Description of the 'Requires relationship' (Check) field in DocType +#. 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Check this field if the cancelled invoice needs to have another related invoice" +msgstr "Marca este campo si la factura cancelada necesita tener otra factura relacionada" + +#. Label of a Data field in DocType 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Code" +msgstr "" + +#. Label of a Link field in DocType 'Digital Signing Certificate' +#. Label of a Section Break field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company" +msgstr "" + +#. Description of the 'Company' (Link) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company for which this certificate will be used to sign CFDI" +msgstr "Compañía para la cual este certificado será usado para firmar CFDI" + +#: overrides/payment_entry.py:137 overrides/sales_invoice.py:121 +msgid "Company {0} has no address" +msgstr "La compañía {0} no tiene dirección" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:163 +msgid "Company {0} has no tax regime" +msgstr "La compañía {0} no tiene régimen fiscal" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company's Digital Signing Certificate to sign CFDI " +msgstr "" + +#. Label of a Section Break field in DocType 'SAT CFDI Use' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +msgid "Customer" +msgstr "" + +#: overrides/sales_invoice.py:147 +msgid "Customer address {0} has no zip code" +msgstr "La dirección del cliente {0} no tiene código postal" + +#: overrides/sales_invoice.py:138 +msgid "Customer {0} has no tax ID" +msgstr "El cliente {0} no tiene RFC" + +#: overrides/sales_invoice.py:141 +msgid "Customer {0} has no tax regime" +msgstr "El cliente {0} no tiene régimen fiscal" + +#. Label of a Data field in DocType 'Cancellation Reason' +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Small Text field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Description" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +#: public/js/payment_entry.js:8 public/js/payment_entry.js:98 +#: public/js/sales_invoice.js:8 public/js/sales_invoice.js:95 +msgid "Digital Signing Certificate" +msgstr "Certificado de Sello Digital" + +#: config/desktop.py:8 +msgid "ERPNext Mexico Compliance" +msgstr "ERPNext Cumplimiento para México" + +#. Label of a Check field in DocType 'SAT CFDI Use' +#. Label of a Check field in DocType 'SAT Payment Method' +#. Label of a Check field in DocType 'SAT Payment Option' +#. Label of a Check field in DocType 'SAT Product or Service Key' +#. Label of a Check field in DocType 'SAT Tax Regime' +#. Label of a Check field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Enabled" +msgstr "" + +#: public/js/payment_entry.js:31 public/js/sales_invoice.js:31 +msgid "File {0} attached" +msgstr "" + +#. Label of a Section Break field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Files" +msgstr "" + +#: overrides/sales_invoice.py:68 overrides/sales_invoice_item.py:71 +msgid "From {}" +msgstr "De {}" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +msgid "Indicates the form in which a payment was made, in accordance with the SAT catalog of forms of payment" +msgstr "Indica la forma en la que se realiza un pago, de acuerdo al catálogo de formas de pago del SAT" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +msgid "Indicates the method used to make a payment, in accordance with the SAT catalog of payment methods" +msgstr "Indica el método usado para realizar un pago, de acuerdo al catálogo de métodos de pago del SAT" + +#: overrides/payment_entry.py:168 overrides/sales_invoice.py:274 +msgid "Invalid CFDI" +msgstr "CFDI Inválido" + +#: overrides/payment_entry.py:258 overrides/sales_invoice.py:328 +msgid "Invalid Cancellation Reason" +msgstr "Motivo de Cancelación inválido" + +#: overrides/payment_entry.py:334 +msgid "Invalid Document Type" +msgstr "Tipo de Documento inválido" + +#: overrides/customer.py:27 +msgid "Invalid Tax Id" +msgstr "RFC Inválido" + +#: overrides/sales_invoice.py:149 +msgid "Invoice has no billing address" +msgstr "La factura no tiene dirección de facturación" + +#. Label of a Check field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Is Group" +msgstr "" + +#. Label of a Attach field in DocType 'Digital Signing Certificate' +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Key" +msgstr "Clave" + +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Key Name" +msgstr "Clave Nombre" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:51 +msgid "Key file not configured" +msgstr "Archivo de llave no configurado" + +#. Label of a Int field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Left" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:83 +msgid "Legal name: {0}" +msgstr "Razón social: {0}" + +#. Name of a Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Mexico Compliance" +msgstr "Cumplimiento para México" + +#. Description of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Module settings" +msgstr "" + +#. Label of a Link field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Old Parent" +msgstr "" + +#. Label of a Link field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Parent SAT Product or Service Key" +msgstr "Clave de Producto o Servicio del SAT padre" + +#. Label of a Password field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Password" +msgstr "" + +#. Description of the 'Password' (Password) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Password for the certificate key" +msgstr "Contraseña para la llave del certificado" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:84 +msgid "RFC: {0}" +msgstr "RFC: {0}" + +#: overrides/payment_entry.py:153 +msgid "Reference {0} has not being stamped" +msgstr "La referencia {0} no ha sido timbrada" + +#. Label of a Check field in DocType 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Requires relationship" +msgstr "Requiere relación" + +#. Label of a Int field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Right" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT CFDI Use" +msgstr "Uso de CFDI SAT" + +#. Name of a DocType +#: erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json +msgid "SAT CFDI Use Tax Regime" +msgstr "Régimen Fiscal del Uso de CFDI SAT" + +#. Description of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Catalogs for accounting" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Payment Method" +msgstr "Forma de Pago SAT" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Payment Option" +msgstr "Método de Pago SAT" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Product or Service Key" +msgstr "Clave SAT de Producto o Servicio" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Tax Regime" +msgstr "Régimen Fiscal SAT" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT UOM Key" +msgstr "Clave SAT de UDM" + +#: public/js/payment_entry.js:20 public/js/payment_entry.js:114 +#: public/js/sales_invoice.js:20 public/js/sales_invoice.js:111 +msgid "Select a Certificate to sign the CFDI" +msgstr "Selecciona un Certificado para firmar el CFDI" + +#. Label of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Settings" +msgstr "" + +#: public/js/payment_entry.js:131 public/js/sales_invoice.js:129 +msgid "Stamp CFDI" +msgstr "Timbrar CFDI" + +#. Name of a role +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "System Manager" +msgstr "" + +#: overrides/customer.py:26 +msgid "Tax Id does not comply with SAT specifications" +msgstr "El RFC cumple con las especificaciones del SAT" + +#. Label of a Link field in DocType 'SAT CFDI Use Tax Regime' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json +msgid "Tax Regime" +msgstr "Régimen Fiscal" + +#. Label of a Table field in DocType 'SAT CFDI Use' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +msgid "Tax regimes" +msgstr "Regímenes fiscales" + +#. Label of a Check field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Test mode" +msgstr "Modo de pruebas" + +#: public/js/sales_invoice.js:88 +msgid "The Cancellation Reason requires a substitute invoice." +msgstr "El motivo de cancelación requiere una factura sustituta" + +#: public/js/payment_entry.js:89 +msgid "The Cancellation Reason requires a substitute payment entry." +msgstr "El motivo de cancelación requiere una entrada de pago sustituta" + +#: overrides/payment_entry.py:272 overrides/sales_invoice.py:340 +msgid "The reason of cancellation {} requires a substitute invoice" +msgstr "El motivo de cancelación {} requiere una factura sustituta" + +#: overrides/sales_invoice.py:69 overrides/sales_invoice_item.py:75 +msgid "To {}" +msgstr "A {}" + +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "UOM Name" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.js:7 +msgid "Validate Certificate" +msgstr "Validar Certificado" + +#. Label of a Section Break field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Web Service" +msgstr "Web Service" + diff --git a/erpnext_mexico_compliance/locale/es_MX.po b/erpnext_mexico_compliance/locale/es_MX.po new file mode 100644 index 0000000..8d07be1 --- /dev/null +++ b/erpnext_mexico_compliance/locale/es_MX.po @@ -0,0 +1,508 @@ +# Translations template for ERPNext Mexico Compliance. +# Copyright (C) 2024 TI Sin Problemas +# This file is distributed under the same license as the ERPNext Mexico Compliance project. +# FIRST AUTHOR , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: ERPNext Mexico Compliance VERSION\n" +"Report-Msgid-Bugs-To: info@tisinproblemas.com\n" +"POT-Creation-Date: 2024-08-30 22:42+0000\n" +"PO-Revision-Date: 2024-08-30 22:42+0000\n" +"Last-Translator: info@tisinproblemas.com\n" +"Language-Team: info@tisinproblemas.com\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.13.1\n" + +#. Description of the 'Available credits' (Int) field in DocType 'CFDI Stamping +#. Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "1 credit is consumed every time a CFDI gets stamped" +msgstr "1 crédito es consumido cada vez que se timbra un CFDI" + +#. Header text in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Mexico Compliance" +msgstr "" + +#: public/js/payment_entry.js:81 +msgid "A Cancellation Reason is required to cancel this payment entry." +msgstr "Un Motivo de Cancelación es necesario para cancelar este pago." + +#: public/js/sales_invoice.js:81 +msgid "A Cancellation Reason is required to cancel this sales invoice." +msgstr "Un Motivo de Cancelación es necesario para cancelar esta factura de venta." + +#: overrides/payment_entry.py:257 overrides/sales_invoice.py:327 +msgid "A Cancellation Reason is required." +msgstr "Un Motivo de Cancelación es necesario." + +#. Label of a Password field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "API Key" +msgstr "" + +#. Label of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Accounting" +msgstr "" + +#. Name of a role +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Accounts Manager" +msgstr "" + +#: overrides/payment_entry.py:91 overrides/payment_entry.py:133 +#: overrides/sales_invoice.py:117 +msgid "Address {0} has no zip code" +msgstr "La dirección {0} no tiene código postal" + +#: public/js/payment_entry.js:50 public/js/sales_invoice.js:50 +msgid "Attach PDF" +msgstr "Adjuntar PDF" + +#: public/js/payment_entry.js:64 public/js/sales_invoice.js:64 +msgid "Attach XML" +msgstr "Adjuntar XML" + +#. Label of a Int field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Available credits" +msgstr "Créditos disponibles" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:82 +msgctxt "Company branch" +msgid "Branch: {0}" +msgstr "Sucursal: {0}" + +#: public/js/payment_entry.js:41 public/js/sales_invoice.js:41 +msgid "CFDI Actions" +msgstr "Acciones de CFDI" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "CFDI Stamping Settings" +msgstr "Configuración de Timbrado de CFDI" + +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.py:44 +#: overrides/payment_entry.py:173 overrides/payment_entry.py:309 +#: overrides/sales_invoice.py:279 overrides/sales_invoice.py:375 +msgid "CFDI Web Service Error" +msgstr "Error del Web Service de CFDI" + +#: public/js/payment_entry.js:129 public/js/sales_invoice.js:127 +msgid "Cancel" +msgstr "" + +#. Name of a DocType +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Cancellation Reason" +msgstr "Motivo de Cancelación" + +#. Label of a Attach field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate" +msgstr "" + +#. Description of the 'Certificate' (Attach) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate file (.cer)" +msgstr "Archivo de certificado (.cer)" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:41 +msgid "Certificate file not configured" +msgstr "Archivo de certificado no configurado" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:114 +msgid "Certificate files and password are not valid" +msgstr "Los archivos de certificado y contraseña no son válidos" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:80 +msgid "Certificate files and password are valid" +msgstr "Los archivos de certificado y contraseña son válidos" + +#. Description of the 'Key' (Attach) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate key file (.key)" +msgstr "Archivo de clave de certificado (.key)" + +#. Description of the 'Requires relationship' (Check) field in DocType +#. 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Check this field if the cancelled invoice needs to have another related invoice" +msgstr "Marca este campo si la factura cancelada necesita tener otra factura relacionada" + +#. Label of a Data field in DocType 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Code" +msgstr "" + +#. Label of a Link field in DocType 'Digital Signing Certificate' +#. Label of a Section Break field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company" +msgstr "" + +#. Description of the 'Company' (Link) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company for which this certificate will be used to sign CFDI" +msgstr "Compañía para la cual este certificado será usado para firmar CFDI" + +#: overrides/payment_entry.py:137 overrides/sales_invoice.py:121 +msgid "Company {0} has no address" +msgstr "La compañía {0} no tiene dirección" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:163 +msgid "Company {0} has no tax regime" +msgstr "La compañía {0} no tiene régimen fiscal" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company's Digital Signing Certificate to sign CFDI " +msgstr "" + +#. Label of a Section Break field in DocType 'SAT CFDI Use' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +msgid "Customer" +msgstr "" + +#: overrides/sales_invoice.py:147 +msgid "Customer address {0} has no zip code" +msgstr "La dirección del cliente {0} no tiene código postal" + +#: overrides/sales_invoice.py:138 +msgid "Customer {0} has no tax ID" +msgstr "El cliente {0} no tiene RFC" + +#: overrides/sales_invoice.py:141 +msgid "Customer {0} has no tax regime" +msgstr "El cliente {0} no tiene régimen fiscal" + +#. Label of a Data field in DocType 'Cancellation Reason' +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Small Text field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Description" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +#: public/js/payment_entry.js:8 public/js/payment_entry.js:98 +#: public/js/sales_invoice.js:8 public/js/sales_invoice.js:95 +msgid "Digital Signing Certificate" +msgstr "Certificado de Sello Digital" + +#: config/desktop.py:8 +msgid "ERPNext Mexico Compliance" +msgstr "ERPNext Cumplimiento para México" + +#. Label of a Check field in DocType 'SAT CFDI Use' +#. Label of a Check field in DocType 'SAT Payment Method' +#. Label of a Check field in DocType 'SAT Payment Option' +#. Label of a Check field in DocType 'SAT Product or Service Key' +#. Label of a Check field in DocType 'SAT Tax Regime' +#. Label of a Check field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Enabled" +msgstr "" + +#: public/js/payment_entry.js:31 public/js/sales_invoice.js:31 +msgid "File {0} attached" +msgstr "" + +#. Label of a Section Break field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Files" +msgstr "" + +#: overrides/sales_invoice.py:68 overrides/sales_invoice_item.py:71 +msgid "From {}" +msgstr "De {}" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +msgid "Indicates the form in which a payment was made, in accordance with the SAT catalog of forms of payment" +msgstr "Indica la forma en la que se realiza un pago, de acuerdo al catálogo de formas de pago del SAT" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +msgid "Indicates the method used to make a payment, in accordance with the SAT catalog of payment methods" +msgstr "Indica el método usado para realizar un pago, de acuerdo al catálogo de métodos de pago del SAT" + +#: overrides/payment_entry.py:168 overrides/sales_invoice.py:274 +msgid "Invalid CFDI" +msgstr "CFDI Inválido" + +#: overrides/payment_entry.py:258 overrides/sales_invoice.py:328 +msgid "Invalid Cancellation Reason" +msgstr "Motivo de Cancelación inválido" + +#: overrides/payment_entry.py:334 +msgid "Invalid Document Type" +msgstr "Tipo de Documento inválido" + +#: overrides/customer.py:27 +msgid "Invalid Tax Id" +msgstr "RFC Inválido" + +#: overrides/sales_invoice.py:149 +msgid "Invoice has no billing address" +msgstr "La factura no tiene dirección de facturación" + +#. Label of a Check field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Is Group" +msgstr "" + +#. Label of a Attach field in DocType 'Digital Signing Certificate' +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Key" +msgstr "Clave" + +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Key Name" +msgstr "Clave Nombre" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:51 +msgid "Key file not configured" +msgstr "Archivo de llave no configurado" + +#. Label of a Int field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Left" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:83 +msgid "Legal name: {0}" +msgstr "Razón social: {0}" + +#. Name of a Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Mexico Compliance" +msgstr "Cumplimiento para México" + +#. Description of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Module settings" +msgstr "" + +#. Label of a Link field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Old Parent" +msgstr "" + +#. Label of a Link field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Parent SAT Product or Service Key" +msgstr "Clave de Producto o Servicio del SAT padre" + +#. Label of a Password field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Password" +msgstr "" + +#. Description of the 'Password' (Password) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Password for the certificate key" +msgstr "Contraseña para la llave del certificado" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:84 +msgid "RFC: {0}" +msgstr "RFC: {0}" + +#: overrides/payment_entry.py:153 +msgid "Reference {0} has not being stamped" +msgstr "La referencia {0} no ha sido timbrada" + +#. Label of a Check field in DocType 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Requires relationship" +msgstr "Requiere relación" + +#. Label of a Int field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Right" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT CFDI Use" +msgstr "Uso de CFDI SAT" + +#. Name of a DocType +#: erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json +msgid "SAT CFDI Use Tax Regime" +msgstr "Régimen Fiscal del Uso de CFDI SAT" + +#. Description of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Catalogs for accounting" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Payment Method" +msgstr "Forma de Pago SAT" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Payment Option" +msgstr "Método de Pago SAT" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Product or Service Key" +msgstr "Clave SAT de Producto o Servicio" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Tax Regime" +msgstr "Régimen Fiscal SAT" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT UOM Key" +msgstr "Clave SAT de UDM" + +#: public/js/payment_entry.js:20 public/js/payment_entry.js:114 +#: public/js/sales_invoice.js:20 public/js/sales_invoice.js:111 +msgid "Select a Certificate to sign the CFDI" +msgstr "Selecciona un Certificado para firmar el CFDI" + +#. Label of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Settings" +msgstr "" + +#: public/js/payment_entry.js:131 public/js/sales_invoice.js:129 +msgid "Stamp CFDI" +msgstr "Timbrar CFDI" + +#. Name of a role +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "System Manager" +msgstr "" + +#: overrides/customer.py:26 +msgid "Tax Id does not comply with SAT specifications" +msgstr "El RFC cumple con las especificaciones del SAT" + +#. Label of a Link field in DocType 'SAT CFDI Use Tax Regime' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json +msgid "Tax Regime" +msgstr "Régimen Fiscal" + +#. Label of a Table field in DocType 'SAT CFDI Use' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +msgid "Tax regimes" +msgstr "Regímenes fiscales" + +#. Label of a Check field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Test mode" +msgstr "Modo de pruebas" + +#: public/js/sales_invoice.js:88 +msgid "The Cancellation Reason requires a substitute invoice." +msgstr "El motivo de cancelación requiere una factura sustituta" + +#: public/js/payment_entry.js:89 +msgid "The Cancellation Reason requires a substitute payment entry." +msgstr "El motivo de cancelación requiere una entrada de pago sustituta" + +#: overrides/payment_entry.py:272 overrides/sales_invoice.py:340 +msgid "The reason of cancellation {} requires a substitute invoice" +msgstr "El motivo de cancelación {} requiere una factura sustituta" + +#: overrides/sales_invoice.py:69 overrides/sales_invoice_item.py:75 +msgid "To {}" +msgstr "A {}" + +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "UOM Name" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.js:7 +msgid "Validate Certificate" +msgstr "Validar Certificado" + +#. Label of a Section Break field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Web Service" +msgstr "Web Service" + diff --git a/erpnext_mexico_compliance/locale/main.pot b/erpnext_mexico_compliance/locale/main.pot new file mode 100644 index 0000000..54b2611 --- /dev/null +++ b/erpnext_mexico_compliance/locale/main.pot @@ -0,0 +1,508 @@ +# Translations template for ERPNext Mexico Compliance. +# Copyright (C) 2024 TI Sin Problemas +# This file is distributed under the same license as the ERPNext Mexico Compliance project. +# FIRST AUTHOR , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: ERPNext Mexico Compliance VERSION\n" +"Report-Msgid-Bugs-To: info@tisinproblemas.com\n" +"POT-Creation-Date: 2024-08-30 22:42+0000\n" +"PO-Revision-Date: 2024-08-30 22:42+0000\n" +"Last-Translator: info@tisinproblemas.com\n" +"Language-Team: info@tisinproblemas.com\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.13.1\n" + +#. Description of the 'Available credits' (Int) field in DocType 'CFDI Stamping +#. Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "1 credit is consumed every time a CFDI gets stamped" +msgstr "" + +#. Header text in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Mexico Compliance" +msgstr "" + +#: public/js/payment_entry.js:81 +msgid "A Cancellation Reason is required to cancel this payment entry." +msgstr "" + +#: public/js/sales_invoice.js:81 +msgid "A Cancellation Reason is required to cancel this sales invoice." +msgstr "" + +#: overrides/payment_entry.py:257 overrides/sales_invoice.py:327 +msgid "A Cancellation Reason is required." +msgstr "" + +#. Label of a Password field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "API Key" +msgstr "" + +#. Label of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Accounting" +msgstr "" + +#. Name of a role +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Accounts Manager" +msgstr "" + +#: overrides/payment_entry.py:91 overrides/payment_entry.py:133 +#: overrides/sales_invoice.py:117 +msgid "Address {0} has no zip code" +msgstr "" + +#: public/js/payment_entry.js:50 public/js/sales_invoice.js:50 +msgid "Attach PDF" +msgstr "" + +#: public/js/payment_entry.js:64 public/js/sales_invoice.js:64 +msgid "Attach XML" +msgstr "" + +#. Label of a Int field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Available credits" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:82 +msgctxt "Company branch" +msgid "Branch: {0}" +msgstr "" + +#: public/js/payment_entry.js:41 public/js/sales_invoice.js:41 +msgid "CFDI Actions" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "CFDI Stamping Settings" +msgstr "" + +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.py:44 +#: overrides/payment_entry.py:173 overrides/payment_entry.py:309 +#: overrides/sales_invoice.py:279 overrides/sales_invoice.py:375 +msgid "CFDI Web Service Error" +msgstr "" + +#: public/js/payment_entry.js:129 public/js/sales_invoice.js:127 +msgid "Cancel" +msgstr "" + +#. Name of a DocType +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Cancellation Reason" +msgstr "" + +#. Label of a Attach field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate" +msgstr "" + +#. Description of the 'Certificate' (Attach) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate file (.cer)" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:41 +msgid "Certificate file not configured" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:114 +msgid "Certificate files and password are not valid" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:80 +msgid "Certificate files and password are valid" +msgstr "" + +#. Description of the 'Key' (Attach) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Certificate key file (.key)" +msgstr "" + +#. Description of the 'Requires relationship' (Check) field in DocType +#. 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Check this field if the cancelled invoice needs to have another related invoice" +msgstr "" + +#. Label of a Data field in DocType 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Code" +msgstr "" + +#. Label of a Link field in DocType 'Digital Signing Certificate' +#. Label of a Section Break field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company" +msgstr "" + +#. Description of the 'Company' (Link) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company for which this certificate will be used to sign CFDI" +msgstr "" + +#: overrides/payment_entry.py:137 overrides/sales_invoice.py:121 +msgid "Company {0} has no address" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:163 +msgid "Company {0} has no tax regime" +msgstr "" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Company's Digital Signing Certificate to sign CFDI " +msgstr "" + +#. Label of a Section Break field in DocType 'SAT CFDI Use' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +msgid "Customer" +msgstr "" + +#: overrides/sales_invoice.py:147 +msgid "Customer address {0} has no zip code" +msgstr "" + +#: overrides/sales_invoice.py:138 +msgid "Customer {0} has no tax ID" +msgstr "" + +#: overrides/sales_invoice.py:141 +msgid "Customer {0} has no tax regime" +msgstr "" + +#. Label of a Data field in DocType 'Cancellation Reason' +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Small Text field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Description" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +#: public/js/payment_entry.js:8 public/js/payment_entry.js:98 +#: public/js/sales_invoice.js:8 public/js/sales_invoice.js:95 +msgid "Digital Signing Certificate" +msgstr "" + +#: config/desktop.py:8 +msgid "ERPNext Mexico Compliance" +msgstr "" + +#. Label of a Check field in DocType 'SAT CFDI Use' +#. Label of a Check field in DocType 'SAT Payment Method' +#. Label of a Check field in DocType 'SAT Payment Option' +#. Label of a Check field in DocType 'SAT Product or Service Key' +#. Label of a Check field in DocType 'SAT Tax Regime' +#. Label of a Check field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Enabled" +msgstr "" + +#: public/js/payment_entry.js:31 public/js/sales_invoice.js:31 +msgid "File {0} attached" +msgstr "" + +#. Label of a Section Break field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Files" +msgstr "" + +#: overrides/sales_invoice.py:68 overrides/sales_invoice_item.py:71 +msgid "From {}" +msgstr "" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +msgid "Indicates the form in which a payment was made, in accordance with the SAT catalog of forms of payment" +msgstr "" + +#. Description of a DocType +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +msgid "Indicates the method used to make a payment, in accordance with the SAT catalog of payment methods" +msgstr "" + +#: overrides/payment_entry.py:168 overrides/sales_invoice.py:274 +msgid "Invalid CFDI" +msgstr "" + +#: overrides/payment_entry.py:258 overrides/sales_invoice.py:328 +msgid "Invalid Cancellation Reason" +msgstr "" + +#: overrides/payment_entry.py:334 +msgid "Invalid Document Type" +msgstr "" + +#: overrides/customer.py:27 +msgid "Invalid Tax Id" +msgstr "" + +#: overrides/sales_invoice.py:149 +msgid "Invoice has no billing address" +msgstr "" + +#. Label of a Check field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Is Group" +msgstr "" + +#. Label of a Attach field in DocType 'Digital Signing Certificate' +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Key" +msgstr "" + +#. Label of a Data field in DocType 'SAT CFDI Use' +#. Label of a Data field in DocType 'SAT Payment Method' +#. Label of a Data field in DocType 'SAT Payment Option' +#. Label of a Data field in DocType 'SAT Product or Service Key' +#. Label of a Data field in DocType 'SAT Tax Regime' +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "Key Name" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:51 +msgid "Key file not configured" +msgstr "" + +#. Label of a Int field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Left" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:83 +msgid "Legal name: {0}" +msgstr "" + +#. Name of a Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Mexico Compliance" +msgstr "" + +#. Description of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Module settings" +msgstr "" + +#. Label of a Link field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Old Parent" +msgstr "" + +#. Label of a Link field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Parent SAT Product or Service Key" +msgstr "" + +#. Label of a Password field in DocType 'Digital Signing Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Password" +msgstr "" + +#. Description of the 'Password' (Password) field in DocType 'Digital Signing +#. Certificate' +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +msgid "Password for the certificate key" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.py:84 +msgid "RFC: {0}" +msgstr "" + +#: overrides/payment_entry.py:153 +msgid "Reference {0} has not being stamped" +msgstr "" + +#. Label of a Check field in DocType 'Cancellation Reason' +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +msgid "Requires relationship" +msgstr "" + +#. Label of a Int field in DocType 'SAT Product or Service Key' +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +msgid "Right" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT CFDI Use" +msgstr "" + +#. Name of a DocType +#: erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json +msgid "SAT CFDI Use Tax Regime" +msgstr "" + +#. Description of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Catalogs for accounting" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Payment Method" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Payment Option" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Product or Service Key" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT Tax Regime" +msgstr "" + +#. Name of a DocType +#. Label of a Link in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "SAT UOM Key" +msgstr "" + +#: public/js/payment_entry.js:20 public/js/payment_entry.js:114 +#: public/js/sales_invoice.js:20 public/js/sales_invoice.js:111 +msgid "Select a Certificate to sign the CFDI" +msgstr "" + +#. Label of a Card Break in the Mexico Compliance Workspace +#: erpnext_mexico_compliance/workspace/mexico_compliance/mexico_compliance.json +msgid "Settings" +msgstr "" + +#: public/js/payment_entry.js:131 public/js/sales_invoice.js:129 +msgid "Stamp CFDI" +msgstr "" + +#. Name of a role +#: erpnext_mexico_compliance/doctype/cancellation_reason/cancellation_reason.json +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.json +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +#: erpnext_mexico_compliance/doctype/sat_payment_method/sat_payment_method.json +#: erpnext_mexico_compliance/doctype/sat_payment_option/sat_payment_option.json +#: erpnext_mexico_compliance/doctype/sat_product_or_service_key/sat_product_or_service_key.json +#: erpnext_mexico_compliance/doctype/sat_tax_regime/sat_tax_regime.json +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "System Manager" +msgstr "" + +#: overrides/customer.py:26 +msgid "Tax Id does not comply with SAT specifications" +msgstr "" + +#. Label of a Link field in DocType 'SAT CFDI Use Tax Regime' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use_tax_regime/sat_cfdi_use_tax_regime.json +msgid "Tax Regime" +msgstr "" + +#. Label of a Table field in DocType 'SAT CFDI Use' +#: erpnext_mexico_compliance/doctype/sat_cfdi_use/sat_cfdi_use.json +msgid "Tax regimes" +msgstr "" + +#. Label of a Check field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Test mode" +msgstr "" + +#: public/js/sales_invoice.js:88 +msgid "The Cancellation Reason requires a substitute invoice." +msgstr "" + +#: public/js/payment_entry.js:89 +msgid "The Cancellation Reason requires a substitute payment entry." +msgstr "" + +#: overrides/payment_entry.py:272 overrides/sales_invoice.py:340 +msgid "The reason of cancellation {} requires a substitute invoice" +msgstr "" + +#: overrides/sales_invoice.py:69 overrides/sales_invoice_item.py:75 +msgid "To {}" +msgstr "" + +#. Label of a Data field in DocType 'SAT UOM Key' +#: erpnext_mexico_compliance/doctype/sat_uom_key/sat_uom_key.json +msgid "UOM Name" +msgstr "" + +#: erpnext_mexico_compliance/doctype/digital_signing_certificate/digital_signing_certificate.js:7 +msgid "Validate Certificate" +msgstr "" + +#. Label of a Section Break field in DocType 'CFDI Stamping Settings' +#: erpnext_mexico_compliance/doctype/cfdi_stamping_settings/cfdi_stamping_settings.json +msgid "Web Service" +msgstr "" + diff --git a/erpnext_mexico_compliance/overrides/customer.py b/erpnext_mexico_compliance/overrides/customer.py index 808c816..bc3dcbf 100644 --- a/erpnext_mexico_compliance/overrides/customer.py +++ b/erpnext_mexico_compliance/overrides/customer.py @@ -2,40 +2,46 @@ Copyright (c) 2022, TI Sin Problemas and contributors For license information, please see license.txt """ + import re + import frappe -from frappe import _ from erpnext.selling.doctype.customer.customer import Customer as ERPNextCustomer +from frappe import _ class Customer(ERPNextCustomer): """ERPNext Customer override""" + @property + def tax_id_is_rfc(self) -> bool: + """True if tax id complies with RFC format""" + exp = r"^([A-ZÑ]|\&){3,4}[0-9]{2}(0[1-9]|1[0-2])([12][0-9]|0[1-9]|3[01])[A-Z0-9]{3}$" + pattern = re.compile(exp) + return bool(re.match(pattern, self.tax_id)) + def validate_mexican_tax_id(self): """Validate customer name for SAT compliance""" - exp = "^[A-ZÑ&]{3,4}[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])(?:[A-Z\d]{3})$" - pattern = re.compile(exp) - if not re.match(pattern, self.tax_id): - frappe.throw( - _("Tax Id does not comply with SAT specifications"), - title=_("Invalid Tax Id"), - ) + if not self.tax_id_is_rfc: + msg = _("Tax Id does not comply with SAT specifications") + title = _("Invalid Tax Id") + frappe.throw(msg, title=title) - def get_customer_primary_address(self): + def get_primary_address(self): """Get customer primary address document""" return frappe.get_doc("Address", self.customer_primary_address) - @frappe.whitelist() + @property def is_mexican(self): """Return True if primary address is in Mexico""" if not self.customer_primary_address: return False - address = self.get_customer_primary_address() + address = self.get_primary_address() return address.country.upper().startswith("MEX") def validate(self): - if self.tax_id and self.is_mexican(): + if self.is_mexican and self.tax_id: self.tax_id = self.tax_id.upper() self.validate_mexican_tax_id() diff --git a/erpnext_mexico_compliance/overrides/payment_entry.py b/erpnext_mexico_compliance/overrides/payment_entry.py new file mode 100644 index 0000000..f3b92be --- /dev/null +++ b/erpnext_mexico_compliance/overrides/payment_entry.py @@ -0,0 +1,340 @@ +""" +Copyright (c) 2024, TI Sin Problemas and contributors +For license information, please see license.txt +""" + +import sys + +import frappe +from erpnext.accounts.doctype.payment_entry import payment_entry +from erpnext.setup.doctype.company.company import get_default_company_address +from frappe import _ +from frappe.client import attach_file +from frappe.model.document import Document +from frappe.utils.data import get_datetime +from satcfdi.create.cfd import cfdi40, pago20 +from satcfdi.exceptions import SchemaValidationError + +from ..controllers.common import CommonController +from ..erpnext_mexico_compliance.doctype.digital_signing_certificate.digital_signing_certificate import ( + DigitalSigningCertificate, +) +from ..ws_client import WSClientException, WSExistingCfdiException, get_ws_client + +# temporary hack until https://github.com/frappe/frappe/issues/27373 is fixed +if sys.path[0].rsplit("/", maxsplit=1)[-1] == "utils": + sys.path[0] = sys.path[0].replace("apps/frappe/frappe/utils", "sites") + + +class PaymentEntry(CommonController, payment_entry.PaymentEntry): + """ERPNext Payment Entry override""" + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + mx_payment_mode: DF.Data + mx_stamped_xml: DF.HTMLEditor + cancellation_reason: DF.Link + substitute_payment_entry: DF.Link + cancellation_acknowledgement: DF.HTMLEditor + + @property + def company_address(self) -> str: + """Name of the default address of the Company associated with the current payment entry.""" + return get_default_company_address(self.company) + + @property + def cfdi_receiver(self) -> cfdi40.Receptor: + """`cfdi40.Receptor` object representing the receiver of the CFDI document for this payment + entry.""" + customer = frappe.get_doc(self.party_type, self.party) + address = frappe.get_doc("Address", customer.customer_primary_address) + return cfdi40.Receptor( + rfc=customer.tax_id, + nombre=customer.customer_name.upper(), + domicilio_fiscal_receptor=address.pincode, + regimen_fiscal_receptor=customer.mx_tax_regime, + uso_cfdi="CP01", + ) + + @property + def cfdi_related_documents(self) -> list[pago20.DoctoRelacionado]: + """List of `pago20.DoctoRelacionado` objects, each representing a related document for the + current payment entry.""" + result = [] + for pe_ref in self.references: + ref = frappe.get_doc(pe_ref.reference_doctype, pe_ref.reference_name) + last_balance = pe_ref.allocated_amount + pe_ref.outstanding_amount + result.append( + pago20.DoctoRelacionado( + id_documento=ref.cfdi_uuid, + moneda_dr=ref.currency, + num_parcialidad=get_installment_number( + ref.doctype, ref.name, self.name + ), + imp_saldo_ant=last_balance, + imp_pagado=pe_ref.allocated_amount, + objeto_imp_dr="01", + serie=ref.cfdi_series, + folio=ref.cfdi_folio, + ) + ) + + return result + + def get_cfdi_voucher(self, csd: DigitalSigningCertificate) -> cfdi40.Comprobante: + address = frappe.get_doc("Address", self.company_address) + + if not address.pincode: + frappe.throw(_("Address {0} has no zip code").format(address.name)) + + reference_date = self.reference_date + if isinstance(reference_date, str): + reference_date = get_datetime(reference_date) + + payment = pago20.Pago( + fecha_pago=reference_date, + forma_de_pago_p=self.mx_payment_mode, + moneda_p=self.paid_from_account_currency, + docto_relacionado=self.cfdi_related_documents, + tipo_cambio_p=self.source_exchange_rate, + ) + + posting_date = self.posting_date + if isinstance(posting_date, str): + posting_date = get_datetime(posting_date) + + return cfdi40.Comprobante.pago( + emisor=csd.get_issuer(), + lugar_expedicion=address.pincode, + receptor=self.cfdi_receiver, + complemento_pago=pago20.Pagos(pago=payment), + serie=self.cfdi_series, + folio=self.cfdi_folio, + fecha=posting_date, + ) + + def validate_company(self): + """ + Validates the company information associated with the current payment entry. + + This function checks if the company has an address and if it has a valid zip code. + If any issues are found, an error message is thrown with the list of issues. + + Raises: + frappe.ValidationError: If any issues were found. + """ + if self.company_address: + address = frappe.get_doc("Address", self.company_address) + if not address.pincode: + link = f'{address.name}' + frappe.throw(_("Address {0} has no zip code").format(link)) + else: + company = frappe.get_doc("Company", self.company) + link = f'{company.name}' + frappe.throw(_("Company {0} has no address").format(link)) + + def validate_references(self): + """Validates the references in the payment entry. + + Iterates through each reference in the payment entry and checks if the referenced document + has been stamped. + + Throws: + frappe.ValidationError: If any of the references have not been stamped. + """ + msgs = [] + for pe_ref in self.references: + ref = frappe.get_doc(pe_ref.reference_doctype, pe_ref.reference_name) + if not ref.mx_stamped_xml: + anchor = f'{ref.name}' + msgs.append(_("Reference {0} has not being stamped").format(anchor)) + + if len(msgs) > 0: + frappe.throw(msgs, as_list=True) + + @frappe.whitelist() + def stamp_cfdi(self, certificate: str): + self.validate_company() + self.validate_references() + + cfdi = self.sign_cfdi(certificate) + ws = get_ws_client() + try: + data, message = ws.stamp(cfdi) + except SchemaValidationError as e: + frappe.throw(str(e), title=_("Invalid CFDI")) + except WSExistingCfdiException as e: + data = e.data + message = e.message + except WSClientException as e: + frappe.throw(str(e), title=_("CFDI Web Service Error")) + + self.mx_stamped_xml = data + self.save() + + self.attach_pdf() + self.attach_xml() + + return message + + @frappe.whitelist() + def has_file(self, file_name: str) -> bool: + """Returns DocType name if the CFDI document for this sales invoice has a file named as + `file_name` attached.""" + return frappe.db.exists( + "File", + { + "attached_to_doctype": self.doctype, + "attached_to_name": self.name, + "file_name": file_name, + }, + ) + + @frappe.whitelist() + def attach_pdf(self) -> Document: + """Attaches the CFDI PDF to the current document. + + This method generates a PDF file from the CFDI XML and attaches it to the current document. + + Returns: + Document: The result of attaching the PDF file to the current document. + """ + from satcfdi import render # pylint: disable=import-outside-toplevel + + cfdi = cfdi40.CFDI.from_string(self.mx_stamped_xml.encode("utf-8")) + file_name = f"{self.name}_CFDI.pdf" + file_data = render.pdf_bytes(cfdi) + return attach_file(file_name, file_data, self.doctype, self.name, is_private=1) + + @frappe.whitelist() + def attach_xml(self) -> Document: + """Attaches the CFDI XML to the current document. + + This method generates an XML file from the CFDI XML and attaches it to the current document. + + Returns: + Document: The result of attaching the XML file to the current document. + """ + file_name = f"{self.name}_CFDI.xml" + xml = self.mx_stamped_xml + return attach_file(file_name, xml, self.doctype, self.name, is_private=1) + + @property + def requires_relationship(self) -> int: + """Indicates whether a relationship with another payment entry is required for the + cancellation reason. + + Returns: + int: 1 if a relationship is required, 0 otherwise. + """ + if not self.cancellation_reason: + return 0 + reason = frappe.get_doc("Cancellation Reason", self.cancellation_reason) + return reason.requires_relationship + + @property + def cfdi_uuid(self) -> str | None: + """CFDI UUID from the stamped XML. + + Returns: + str | None: The CFDI UUID if the stamped XML is available, otherwise None. + """ + if not self.mx_stamped_xml: + return None + cfdi = cfdi40.CFDI.from_string(self.mx_stamped_xml.encode("utf-8")) + return cfdi.get("Complemento", {}).get("TimbreFiscalDigital", {}).get("UUID") + + def validate_cancel_reason(self): + """Validates whether a cancellation reason is provided before cancelling a payment entry. + + This function checks if a cancellation reason is set for the current payment entry. + If no cancellation reason is found, it throws an error with a corresponding message. + """ + if not self.cancellation_reason: + msg = _("A Cancellation Reason is required.") + title = _("Invalid Cancellation Reason") + frappe.throw(msg, title=title) + + def validate_substitute_payment_entry(self): + """Validates whether a substitute payment entry is required before cancelling a payment + entry. + + This function checks if a substitute payment entry is set for the current payment entry, + and if the cancellation reason requires a substitute payment entry. + If no substitute payment entry is found when required, it throws an error with a + corresponding message. + """ + reason = frappe.get_doc("Cancellation Reason", self.cancellation_reason) + if reason.requires_relationship and not self.substitute_payment_entry: + msg = _("The reason of cancellation {} requires a substitute invoice") + msg = msg.format(self.cancellation_reason) + frappe.throw(msg) + + @frappe.whitelist() + def cancel_cfdi(self, certificate: str): + """Cancels the CFDI document of this payment entry. + + Args: + certificate (str): The name of the Digital Signing Certificate to use for cancellation. + + Raises: + WSClientException: If an error occurs during the cancellation process. + + Returns: + str: A message indicating the result of the cancellation operation. + """ + self.validate_cancel_reason() + self.validate_substitute_payment_entry() + + cfdi = cfdi40.CFDI.from_string(self.mx_stamped_xml.encode("utf-8")) + ws = get_ws_client() + + substitute = ( + frappe.get_doc("Payment Entry", self.substitute_payment_entry) + if self.substitute_payment_entry + else None + ) + + try: + ack, message = ws.cancel( + certificate, + cfdi, + self.cancellation_reason, + substitute.cfdi_uuid if substitute else None, + ) + except WSClientException as e: + frappe.throw(str(e), title=_("CFDI Web Service Error")) + + self.cancellation_acknowledgement = ack + self.save() + + return message + + +def get_installment_number( + doctype: str, docname: str, payment_entry_name: str +) -> int | None: + """Returns the installment number of a payment entry in a sales invoice. + + Args: + doctype (str): The type of document. + docname (str): The name of the document. + payment_entry_name (str): The name of the payment entry. + + Returns: + int: The installment number of the payment entry. + + Raises: + frappe.ValidationError: If the document type is not "Sales Invoice". + """ + if doctype != "Sales Invoice": + raise frappe.ValidationError(_("Invalid Document Type")) + doc = frappe.get_doc(doctype, docname) + for idx, entry in enumerate(doc.payment_entries, 1): + if entry.name == payment_entry_name: + return idx + + return None diff --git a/erpnext_mexico_compliance/overrides/sales_invoice.py b/erpnext_mexico_compliance/overrides/sales_invoice.py index b937860..3ed2f57 100644 --- a/erpnext_mexico_compliance/overrides/sales_invoice.py +++ b/erpnext_mexico_compliance/overrides/sales_invoice.py @@ -2,19 +2,402 @@ Copyright (c) 2022, TI Sin Problemas and contributors For license information, please see license.txt """ + +import sys +from datetime import datetime +from decimal import Decimal + +import frappe from erpnext.accounts.doctype.sales_invoice import sales_invoice +from erpnext.setup.doctype.company.company import Company, get_default_company_address from frappe import _ +from frappe.client import attach_file +from frappe.contacts.doctype.address.address import Address +from frappe.model.document import Document +from frappe.utils import get_datetime +from satcfdi.create.cfd import catalogos, cfdi40 +from satcfdi.exceptions import SchemaValidationError + +from ..controllers.common import CommonController +from ..ws_client import WSClientException, WSExistingCfdiException, get_ws_client +from .customer import Customer +# temporary hack until https://github.com/frappe/frappe/issues/27373 is fixed +if sys.path[0].rsplit("/", maxsplit=1)[-1] == "utils": + sys.path[0] = sys.path[0].replace("apps/frappe/frappe/utils", "sites") -class SalesInvoice(sales_invoice.SalesInvoice): + +class SalesInvoice(CommonController, sales_invoice.SalesInvoice): """ERPNext Sales Invoice override""" - def get_sat_payment_method(self): - """Returns SAT Payment method code""" - return self.sat_payment_method.split("-")[0].strip() + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + mx_payment_option: DF.Link + mode_of_payment: DF.Link + mx_cfdi_use: DF.Link + mx_payment_mode: DF.Data + mx_stamped_xml: DF.HTMLEditor + cancellation_reason: DF.Link + substitute_invoice: DF.Link + cancellation_acknowledgement: DF.HTMLEditor + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if not self.company_address: + self.company_address = get_default_company_address(self.company) + + @property + def subscription_duration_display(self) -> str: + """Returns a string displaying the service duration in a formatted manner. + + The service duration is displayed as a range between the start date and the end date, if + both are provided. If only one of them is provided, the string will display the start or + end date accordingly. If neither is provided, an empty string is returned. - def get_invoice_service_dates(self) -> str: - """Returns invoice dates as a formatted string""" - start_date = _("From {}").format(self.from_date) if self.from_date else None - end_date = _("To {}").format(self.to_date) if self.to_date else None + Examples: + - From `start_date` + - To `end_date` + - From `start_date` To `end_date` + + Returns: + str: The formatted service duration string. + """ + start_date = _("From {}").format(self.from_date) if self.from_date else "" + end_date = _("To {}").format(self.to_date) if self.to_date else "" return f"{start_date} {end_date}".strip() + + @property + def company_doc(self) -> Company: + """Company DocType that created the invoice""" + return frappe.get_doc("Company", self.company) + + @property + def customer_doc(self) -> Customer: + """Customer DocType of the invoice""" + return frappe.get_doc("Customer", self.customer) + + @property + def customer_address_doc(self) -> Address: + """Address DocType of the customer""" + return frappe.get_doc("Address", self.customer_address) + + @property + def tax_accounts(self) -> list[dict]: + """Returns a list of dictionaries containing tax account information. + + The list includes the name, tax type, and tax rate of each account. + The accounts are filtered by the names of the account heads in the invoice's taxes. + + Returns: + list[dict]: A list of dictionaries containing tax account information. + """ + heads = [t.account_head for t in self.taxes] + return frappe.get_list( + "Account", + filters={"name": ["in", heads]}, + fields=["name", "tax_type", "tax_rate"], + ) + + def validate_company(self): + """Validates the company information on the invoice. + + This function checks if the company has an address and if it has a valid zip code. + If any issues are found, an error message is thrown with the list of issues. + + Raises: + frappe.ValidationError: If any issues were found. + """ + if self.company_address: + address = frappe.get_doc("Address", self.company_address) + if not address.pincode: + link = f'{address.name}' + frappe.throw(_("Address {0} has no zip code").format(link)) + else: + company = self.company_doc + link = f'{company.name}' + frappe.throw(_("Company {0} has no address").format(link)) + + def validate_customer(self): + """Validates the customer information on the invoice. + + This function checks if the customer has a tax ID, tax regime, and a valid billing address. + It also checks if the customer's address has a valid zip code. + If any issues are found, an error message is thrown with the list of issues. + + Raises: + frappe.ValidationError: If any issues were found. + """ + customer_link = ( + f'{self.customer_doc.name}' + ) + msgs = [] + if not self.customer_doc.tax_id: + msgs.append(_("Customer {0} has no tax ID").format(customer_link)) + + if not self.customer_doc.mx_tax_regime: + msgs.append(_("Customer {0} has no tax regime").format(customer_link)) + + if self.customer_address: + address = self.customer_address_doc + if not address.pincode: + link = f'{address.name}' + msgs.append(_("Customer address {0} has no zip code").format(link)) + else: + msgs.append(_("Invoice has no billing address")) + + if len(msgs) > 0: + frappe.throw(msgs, as_list=True) + + self.customer_doc.validate_mexican_tax_id() + + @property + def cfdi_receiver(self) -> cfdi40.Receptor: + """`cfdi40.Receptor` object representing the receiver of the CFDI document for this sales + invoice.""" + return cfdi40.Receptor( + rfc=self.customer_doc.tax_id, + nombre=self.customer_name.upper(), + domicilio_fiscal_receptor=self.customer_address_doc.pincode, + regimen_fiscal_receptor=self.customer_doc.mx_tax_regime, + uso_cfdi=self.mx_cfdi_use, + ) + + @property + def cfdi_items(self) -> list[cfdi40.Concepto]: + """Returns a list of `cfdi40.Concepto` objects representing the items of the CFDI document + for this sales invoice.""" + cfdi_items = [] + for item in self.items: + discount = Decimal(item.discount_amount) if item.discount_amount else None + cfdi_items.append( + cfdi40.Concepto( + clave_prod_serv=item.mx_product_service_key, + cantidad=Decimal(item.qty), + clave_unidad=item.uom_doc.mx_uom_key, + descripcion=item.cfdi_description, + valor_unitario=Decimal(item.rate), + no_identificacion=item.item_code, + descuento=discount, + impuestos=item.cfdi_taxes, + ) + ) + return cfdi_items + + @property + def posting_datetime(self) -> datetime: + """`datetime` object representing the posting date and time of the sales invoice.""" + return get_datetime(f"{self.posting_date}T{self.posting_time}") + + def get_cfdi_voucher(self, csd) -> cfdi40.Comprobante: + address = frappe.get_doc("Address", self.company_address) + return cfdi40.Comprobante( + emisor=csd.get_issuer(), + lugar_expedicion=address.pincode, + receptor=self.cfdi_receiver, + conceptos=self.cfdi_items, + moneda=self.currency, + tipo_de_comprobante=catalogos.TipoDeComprobante.INGRESO, + serie=self.cfdi_series, + folio=self.cfdi_folio, + forma_pago=self.mx_payment_mode, + tipo_cambio=( + Decimal(self.conversion_rate) if self.currency != "MXN" else None + ), + metodo_pago=self.mx_payment_option, + fecha=self.posting_datetime, + ) + + @frappe.whitelist() + def has_file(self, file_name: str) -> bool: + """Returns DocType name if the CFDI document for this sales invoice has a file named as + `file_name` attached.""" + return frappe.db.exists( + "File", + { + "attached_to_doctype": self.doctype, + "attached_to_name": self.name, + "file_name": file_name, + }, + ) + + @frappe.whitelist() + def attach_pdf(self) -> Document: + """Attaches the CFDI PDF to the current document. + + This method generates a PDF file from the CFDI XML and attaches it to the current document. + + Returns: + Document: The result of attaching the PDF file to the current document. + """ + from satcfdi import render # pylint: disable=import-outside-toplevel + + cfdi = cfdi40.CFDI.from_string(self.mx_stamped_xml.encode("utf-8")) + file_name = f"{self.name}_CFDI.pdf" + file_data = render.pdf_bytes(cfdi) + return attach_file(file_name, file_data, self.doctype, self.name, is_private=1) + + @frappe.whitelist() + def attach_xml(self) -> Document: + """Attaches the CFDI XML to the current document. + + This method generates an XML file from the CFDI XML and attaches it to the current document. + + Returns: + Document: The result of attaching the XML file to the current document. + """ + file_name = f"{self.name}_CFDI.xml" + xml = self.mx_stamped_xml + return attach_file(file_name, xml, self.doctype, self.name, is_private=1) + + @frappe.whitelist() + def stamp_cfdi(self, certificate: str): + """Stamps a CFDI document for the current sales invoice. + + Args: + certificate (str): The name of the Digital Signing Certificate to use for signing. + + Returns: + str: A message indicating the result of the stamping operation. + """ + + self.validate_company() + self.validate_customer() + + cfdi = self.sign_cfdi(certificate) + ws = get_ws_client() + try: + data, message = ws.stamp(cfdi) + except SchemaValidationError as e: + frappe.throw(str(e), title=_("Invalid CFDI")) + except WSExistingCfdiException as e: + data = e.data + message = e.message + except WSClientException as e: + frappe.throw(str(e), title=_("CFDI Web Service Error")) + + self.mx_stamped_xml = data + self.save() + + self.attach_pdf() + self.attach_xml() + + return message + + @property + def requires_relationship(self) -> int: + """This property determines whether a relationship with another sales invoice is required + for the current sales invoice. + + It checks if a cancellation reason is set, and if so, retrieves the corresponding + Cancellation Reason document. + + The function returns an integer indicating whether a relationship is required, based on the + requires_relationship field of the Cancellation Reason document. + + Returns: + int: 1 if a relationship is required, 0 otherwise. + """ + if not self.cancellation_reason: + return 0 + reason = frappe.get_doc("Cancellation Reason", self.cancellation_reason) + return reason.requires_relationship + + @property + def cfdi_uuid(self) -> str | None: + """CFDI UUID from the stamped XML. + + Returns: + str | None: The CFDI UUID if the stamped XML is available, otherwise None. + """ + if not self.mx_stamped_xml: + return None + cfdi = cfdi40.CFDI.from_string(self.mx_stamped_xml.encode("utf-8")) + return cfdi.get("Complemento", {}).get("TimbreFiscalDigital", {}).get("UUID") + + def validate_cancel_reason(self): + """Validates whether a cancellation reason is provided before cancelling a sales invoice. + + This function checks if a cancellation reason is set for the current sales invoice. + If no cancellation reason is found, it throws an error with a corresponding message. + """ + if not self.cancellation_reason: + msg = _("A Cancellation Reason is required.") + title = _("Invalid Cancellation Reason") + frappe.throw(msg, title=title) + + def validate_substitute_invoice(self): + """Validates whether a substitute invoice is provided for the cancellation reason. + + This function checks if the cancellation reason requires a substitute invoice and if the + substitute invoice is not provided. If both conditions are met, it throws an error with a + corresponding message. + """ + reason = frappe.get_doc("Cancellation Reason", self.cancellation_reason) + if reason.requires_relationship and not self.substitute_invoice: + msg = _("The reason of cancellation {} requires a substitute invoice") + msg = msg.format(self.cancellation_reason) + frappe.throw(msg) + + @frappe.whitelist() + def cancel_cfdi(self, certificate: str): + """Cancels the CFDI document. + + Args: + certificate (str): The name of the Digital Signing Certificate to use for cancellation. + + Returns: + str: A message indicating the result of the cancellation operation. + + Raises: + WSClientException: If an error occurs during the cancellation process. + """ + cfdi = cfdi40.CFDI.from_string(self.mx_stamped_xml.encode("utf-8")) + ws = get_ws_client() + + if self.substitute_invoice: + substitute_invoice = frappe.get_doc( + "Sales Invoice", self.substitute_invoice + ) + else: + substitute_invoice = None + + try: + acknowledgement, message = ws.cancel( + certificate, + cfdi, + self.cancellation_reason, + substitute_invoice.cfdi_uuid if substitute_invoice else None, + ) + except WSClientException as e: + frappe.throw(str(e), title=_("CFDI Web Service Error")) + + self.cancellation_acknowledgement = acknowledgement + self.save() + + return message + + def before_cancel(self): + if self.mx_stamped_xml: + self.validate_cancel_reason() + self.validate_substitute_invoice() + + @property + def payment_entries(self) -> list[frappe._dict]: + """List of Payment Entries associated with the current Sales Invoice.""" + references = frappe.get_all( + "Payment Entry Reference", + filters={ + "reference_doctype": self.doctype, + "reference_name": self.name, + }, + fields=["parent"], + ) + return frappe.get_all( + "Payment Entry", + filters={"name": ["in", [r.parent for r in references]]}, + fields=["name", "posting_date"], + order_by="posting_date asc", + ) diff --git a/erpnext_mexico_compliance/overrides/sales_invoice_item.py b/erpnext_mexico_compliance/overrides/sales_invoice_item.py index e9921b9..240a15f 100644 --- a/erpnext_mexico_compliance/overrides/sales_invoice_item.py +++ b/erpnext_mexico_compliance/overrides/sales_invoice_item.py @@ -2,29 +2,70 @@ Copyright (c) 2022, TI Sin Problemas and contributors For license information, please see license.txt """ + +from decimal import Decimal + import frappe +from erpnext.accounts.doctype.sales_invoice_item import sales_invoice_item +from erpnext.setup.doctype.uom.uom import UOM +from erpnext.stock.doctype.item.item import Item from frappe import _ from frappe.utils import strip_html -from erpnext.accounts.doctype.sales_invoice_item import sales_invoice_item +from satcfdi.create.cfd import catalogos, cfdi40 class SalesInvoiceItem(sales_invoice_item.SalesInvoiceItem): """ERPNext Sales Invoice Item override""" + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + mx_product_service_key: DF.Link + def before_validate(self): """Add missing fields before validation""" if self.item_code: item = frappe.get_doc("Item", self.item_code) - self.sat_product_or_service_key = item.sat_product_or_service_key + self.mx_product_service_key = item.mx_product_service_key - def get_item(self): - """Returns related Item DocType if any""" - if not self.item_code: - return None - return frappe.get_doc("Item", self.item_code) + @property + def item_doc(self) -> Item: + """Related Item DocType + + Returns: + Item: Item doctype + """ + if self.item_code: + return frappe.get_doc("Item", self.item_code) + return None - def get_service_duration(self): - """Returns a string with From and To dates of services""" + @property + def uom_doc(self) -> UOM: + """The UOM (Unit of Measure) DocType of the item. + + Returns: + UOM: UOM of the item + """ + return frappe.get_doc("UOM", self.uom) + + @property + def service_duration_display(self) -> str: + """Returns a string displaying the service duration in a formatted manner. + + The service duration is displayed as a range between the start date and the end date, if + both are provided. If only one of them is provided, the string will display the start or + end date accordingly. If neither is provided, an empty string is returned. + + Examples: + - From `start_date` + - To `end_date` + - From `start_date` To `end_date` + + Returns: + str: The formatted service duration string. + """ start_date = "" if self.service_start_date: start_date = _("From {}").format(self.service_start_date) @@ -35,15 +76,44 @@ def get_service_duration(self): return f"{start_date} {end_date}".strip() - def get_cfdi_description(self): + @property + def cfdi_description(self): """Returns description ready to stamp a CFDI""" cfdi_description = f"{self.item_name}" item_description = strip_html(self.description) if all([self.description, self.item_name != item_description]): cfdi_description += f" - {item_description}" - invoice_dates = self.parent_doc.get_invoice_service_dates() + invoice_dates = self.parent_doc.subscription_duration_display if invoice_dates: cfdi_description += f" ({invoice_dates})" return cfdi_description.strip() + + @property + def cfdi_taxes(self) -> cfdi40.Impuestos: + """The `cfdi40.Impuestos` object representing the taxes for this sales invoice item.""" + withholding_taxes = [] + transferred_taxes = [] + for account in self.parent_doc.tax_accounts: + tax_type = catalogos.Impuesto[account["tax_type"]] + tax_rate = Decimal(account["tax_rate"]) / 100 + + if tax_rate < 0: + withholding = cfdi40.Retencion( + impuesto=tax_type, + tipo_factor=catalogos.TipoFactor.TASA, + tasa_o_cuota=Decimal(tax_rate * -1), + ) + withholding_taxes.append(withholding) + else: + transferred = cfdi40.Traslado( + impuesto=tax_type, + tipo_factor=catalogos.TipoFactor.TASA, + tasa_o_cuota=tax_rate, + ) + transferred_taxes.append(transferred) + + return cfdi40.Impuestos( + retenciones=withholding_taxes, traslados=transferred_taxes + ) diff --git a/erpnext_mexico_compliance/public/js/payment_entry.js b/erpnext_mexico_compliance/public/js/payment_entry.js new file mode 100644 index 0000000..f60deb2 --- /dev/null +++ b/erpnext_mexico_compliance/public/js/payment_entry.js @@ -0,0 +1,139 @@ +// Copyright (c) 2024, TI Sin Problemas and contributors +// For license information, please see license.txt + +function stampCfdi(frm) { + frappe.prompt( + [ + { + label: __("Digital Signing Certificate"), + fieldname: "certificate", + fieldtype: "Link", + options: "Digital Signing Certificate", + filters: { company: frm.doc.company }, + }, + ], + async ({ certificate }) => { + const { message } = await frm.call("stamp_cfdi", { certificate }); + frappe.show_alert({ message, indicator: "green" }); + frm.reload_doc(); + }, + __("Select a Certificate to sign the CFDI") + ); +} + +async function attachFile(frm, ext) { + const functionMap = { pdf: "attach_pdf", xml: "attach_xml" }; + + try { + const { message } = await frm.call(functionMap[ext]); + const { file_name } = message; + frappe.show_alert({ + message: __("File {0} attached", [file_name]), + indicator: "green", + }); + frm.reload_doc(); + } catch (error) { + const { message } = error; + frappe.throw(message ? message : error); + } +} + +const cfdiActionsGroup = __("CFDI Actions"); + +async function addAttachPdfButton(frm) { + const { message: hasFile } = await frm.call("has_file", { + file_name: `${frm.doc.name}_CFDI.pdf`, + }); + + if (!hasFile) { + frm.add_custom_button( + __("Attach PDF"), + async () => await attachFile(frm, "pdf"), + cfdiActionsGroup + ); + } +} + +async function addAttachXmlButton(frm) { + const { message: hasFile } = await frm.call("has_file", { + file_name: `${frm.doc.name}_CFDI.xml`, + }); + + if (!hasFile) { + frm.add_custom_button( + __("Attach XML"), + async () => await attachFile(frm, "xml"), + cfdiActionsGroup + ); + } +} + +function cancel(frm) { + const { + mx_stamped_xml, + cancellation_reason, + requires_relationship, + substitute_payment_entry, + } = frm.doc; + + if (mx_stamped_xml) { + if (!cancellation_reason) { + const msg = __( + "A Cancellation Reason is required to cancel this payment entry." + ); + frappe.throw(msg); + } + } + + if (requires_relationship && !substitute_payment_entry) { + const msg = __( + "The Cancellation Reason requires a substitute payment entry." + ); + frappe.throw(msg); + } + + frappe.prompt( + [ + { + label: __("Digital Signing Certificate"), + fieldname: "certificate", + fieldtype: "Link", + options: "Digital Signing Certificate", + filters: { company: frm.doc.company }, + }, + ], + async ({ certificate }) => { + const { message: cfdi_msg } = await frm.call("cancel_cfdi", { + certificate, + }); + frappe.show_alert({ message: cfdi_msg, indicator: "green" }); + const { message: cancelled } = await frm.call("cancel"); + frappe.show_alert({ message: cancelled, indicator: "green" }); + frm.reload_doc(); + }, + __("Select a Certificate to sign the CFDI") + ); +} + +function refresh(frm) { + const { docstatus, mx_stamped_xml } = frm.doc; + + if (mx_stamped_xml) { + addAttachPdfButton(frm); + addAttachXmlButton(frm); + } + + switch (docstatus) { + case 1: + if (mx_stamped_xml) { + frm.page.set_secondary_action(__("Cancel"), () => cancel(frm)); + } else { + frm.add_custom_button(__("Stamp CFDI"), () => stampCfdi(frm)); + } + break; + } +} + +frappe.ui.form.on("Payment Entry", { + refresh, +}); diff --git a/erpnext_mexico_compliance/public/js/sales_invoice.js b/erpnext_mexico_compliance/public/js/sales_invoice.js new file mode 100644 index 0000000..2b1989b --- /dev/null +++ b/erpnext_mexico_compliance/public/js/sales_invoice.js @@ -0,0 +1,157 @@ +// Copyright (c) 2024, TI Sin Problemas and contributors +// For license information, please see license.txt + +function stampCfdi(frm) { + frappe.prompt( + [ + { + label: __("Digital Signing Certificate"), + fieldname: "certificate", + fieldtype: "Link", + options: "Digital Signing Certificate", + filters: { company: frm.doc.company }, + }, + ], + async ({ certificate }) => { + const { message } = await frm.call("stamp_cfdi", { certificate }); + frappe.show_alert({ message, indicator: "green" }); + frm.reload_doc(); + }, + __("Select a Certificate to sign the CFDI") + ); +} + +async function attachFile(frm, ext) { + const functionMap = { pdf: "attach_pdf", xml: "attach_xml" }; + + try { + const { message } = await frm.call(functionMap[ext]); + const { file_name } = message; + frappe.show_alert({ + message: __("File {0} attached", [file_name]), + indicator: "green", + }); + frm.reload_doc(); + } catch (error) { + const { message } = error; + frappe.throw(message ? message : error); + } +} + +const cfdiActionsGroup = __("CFDI Actions"); + +async function addAttachPdfButton(frm) { + const { message: hasFile } = await frm.call("has_file", { + file_name: `${frm.doc.name}_CFDI.pdf`, + }); + + if (!hasFile) { + frm.add_custom_button( + __("Attach PDF"), + async () => await attachFile(frm, "pdf"), + cfdiActionsGroup + ); + } +} + +async function addAttachXmlButton(frm) { + const { message: hasFile } = await frm.call("has_file", { + file_name: `${frm.doc.name}_CFDI.xml`, + }); + + if (!hasFile) { + frm.add_custom_button( + __("Attach XML"), + async () => await attachFile(frm, "xml"), + cfdiActionsGroup + ); + } +} + +function cancel(frm) { + const { + mx_stamped_xml, + cancellation_reason, + requires_relationship, + substitute_invoice, + } = frm.doc; + + if (mx_stamped_xml) { + if (!cancellation_reason) { + const msg = __( + "A Cancellation Reason is required to cancel this sales invoice." + ); + frappe.throw(msg); + } + + if (requires_relationship && !substitute_invoice) { + const msg = __("The Cancellation Reason requires a substitute invoice."); + frappe.throw(msg); + } + + frappe.prompt( + [ + { + label: __("Digital Signing Certificate"), + fieldname: "certificate", + fieldtype: "Link", + options: "Digital Signing Certificate", + filters: { company: frm.doc.company }, + }, + ], + async ({ certificate }) => { + const { message: cfdi_msg } = await frm.call("cancel_cfdi", { + certificate, + }); + frappe.show_alert({ message: cfdi_msg, indicator: "green" }); + const { message: cancelled } = await frm.call("cancel"); + frappe.show_alert({ message: cancelled, indicator: "green" }); + frm.reload_doc(); + }, + __("Select a Certificate to sign the CFDI") + ); + } +} + +function refresh(frm) { + const { docstatus, mx_stamped_xml } = frm.doc; + + if (mx_stamped_xml) { + addAttachPdfButton(frm); + addAttachXmlButton(frm); + } + + switch (docstatus) { + case 1: + if (mx_stamped_xml) { + frm.page.set_secondary_action(__("Cancel"), () => cancel(frm)); + } else { + frm.add_custom_button(__("Stamp CFDI"), () => stampCfdi(frm)); + } + break; + } +} + +function setup(frm) { + frm.set_query("mx_cfdi_use", (doc) => { + return { + query: "erpnext_mexico_compliance.controllers.queries.cfdi_use_query", + filters: { customer: doc.customer }, + }; + }); + + frm.set_query("substitute_invoice", (doc) => { + return { + filters: [ + ["name", "!=", doc.name], + ["customer", "=", doc.customer], + ["mx_stamped_xml", "!=", ""], + ], + }; + }); +} + +frappe.ui.form.on("Sales Invoice", { + refresh, + setup, +}); diff --git a/erpnext_mexico_compliance/translations/es-MX.csv b/erpnext_mexico_compliance/translations/es-MX.csv index c830548..23f1289 100644 --- a/erpnext_mexico_compliance/translations/es-MX.csv +++ b/erpnext_mexico_compliance/translations/es-MX.csv @@ -1,16 +1,78 @@ -CFDI 4.0,CFDI 4.0 -From {},De {} -Invalid Tax Id,RFC Inválido -Key,Clave -Key Name,Clave Nombre -Mexico Compliance,Cumplimiento Mexicano -SAT Catalogs,Catálogos del SAT -SAT CFDI Use,Uso de CFDI SAT -SAT Payment Method,Método de Pago SAT -SAT Payment Mode,Forma de Pago SAT -SAT Product or Service Key,Clave SAT de Producto o Servicio -SAT Tax System,Régimen Fiscal SAT -SAT UOM Key,Clave SAT de UDM -Tax Id does not comply with SAT specifications,El RFC cumple con las especificaciones del SAT -Tax Type,Tipo de Impuesto -To {},A {} +1 credit is consumed every time a CFDI gets stamped,1 crédito es consumido cada vez que se timbra un CFDI, +A Cancellation Reason is required to cancel this payment entry.,Un Motivo de Cancelación es necesario para cancelar este pago., +A Cancellation Reason is required to cancel this sales invoice.,Un Motivo de Cancelación es necesario para cancelar esta factura de venta., +A Cancellation Reason is required.,Un Motivo de Cancelación es necesario., +Address {0} has no zip code,La dirección {0} no tiene código postal, +Attach PDF,Adjuntar PDF, +Attach XML,Adjuntar XML, +Available credits,Créditos disponibles, +Branch: {0},Sucursal: {0}, +Cancellation,Cancelación, +Cancellation acknowledgement,Acuse de cancelación, +Cancellation reason,Motivo de cancelación, +Cancellation Reason,Motivo de Cancelación, +Certificate file (.cer),Archivo de certificado (.cer), +Certificate file not configured,Archivo de certificado no configurado, +Certificate files and password are not valid,Los archivos de certificado y contraseña no son válidos, +Certificate files and password are valid,Los archivos de certificado y contraseña son válidos, +Certificate key file (.key),Archivo de clave de certificado (.key), +CFDI,CFDI, +CFDI Actions,Acciones de CFDI, +CFDI Stamping Settings,Configuración de Timbrado de CFDI, +CFDI Web Service Error,Error del Web Service de CFDI, +Check this field if the cancelled invoice needs to have another related invoice,Marca este campo si la factura cancelada necesita tener otra factura relacionada, +CLABE,CLABE, +Company for which this certificate will be used to sign CFDI,Compañía para la cual este certificado será usado para firmar CFDI, +Company {0} has no address,La compañía {0} no tiene dirección, +Company {0} has no tax regime,La compañía {0} no tiene régimen fiscal, +Company's Digital Signing Certificate to sign CFDI,Certificado de Sello Digital de la empresa para firmar CFDI, +Customer address {0} has no zip code,La dirección del cliente {0} no tiene código postal, +Customer {0} has no tax ID,El cliente {0} no tiene RFC, +Customer {0} has no tax regime,El cliente {0} no tiene régimen fiscal, +Digital Signing Certificate,Certificado de Sello Digital, +ERPNext Mexico Compliance,ERPNext Cumplimiento para México, +File {0} attached,, +From {},De {}, +"Indicates the form in which a payment was made, in accordance with the SAT catalog of forms of payment","Indica la forma en la que se realiza un pago, de acuerdo al catálogo de formas de pago del SAT", +"Indicates the method used to make a payment, in accordance with the SAT catalog of payment methods","Indica el método usado para realizar un pago, de acuerdo al catálogo de métodos de pago del SAT", +Invalid Cancellation Reason,Motivo de Cancelación inválido, +Invalid CFDI,CFDI Inválido, +Invalid Document Type,Tipo de Documento inválido, +Invalid Tax Id,RFC Inválido, +Invoice has no billing address,La factura no tiene dirección de facturación, +Key,Clave, +Key file not configured,Archivo de llave no configurado, +Key Name,Clave Nombre, +Legal name: {0},Razón social: {0}, +Mexico Compliance,Cumplimiento para México, +Parent SAT Product or Service Key,Clave de Producto o Servicio del SAT padre, +Password for the certificate key,Contraseña para la llave del certificado, +Reference {0} has not being stamped,La referencia {0} no ha sido timbrada, +Requires relationship,Requiere relación, +RFC: {0},RFC: {0}, +SAT Catalogs,Catálogos del SAT, +SAT CFDI Use,Uso de CFDI SAT, +SAT CFDI Use Tax Regime,Régimen Fiscal del Uso de CFDI SAT, +SAT Payment Method,Forma de Pago SAT, +SAT Payment Mode,Forma de Pago SAT, +SAT Payment Option,Método de Pago SAT, +SAT Product or Service Key,Clave SAT de Producto o Servicio, +SAT Tax Regime,Régimen Fiscal SAT, +SAT UOM Key,Clave SAT de UDM, +Select a Certificate to sign the CFDI,Selecciona un Certificado para firmar el CFDI, +Stamp CFDI,Timbrar CFDI, +Stamped XML,XML timbrado, +Substitute invoice,Factura sustituta, +Substitute payment entry,Entrada de pago sustituta, +Tax Id does not comply with SAT specifications,El RFC cumple con las especificaciones del SAT, +Tax Regime,Régimen Fiscal, +Tax regimes,Regímenes fiscales, +Tax Type,Tipo de Impuesto, +Test mode,Modo de pruebas, +The Cancellation Reason requires a substitute invoice.,El motivo de cancelación requiere una factura sustituta, +The Cancellation Reason requires a substitute payment entry.,El motivo de cancelación requiere una entrada de pago sustituta, +The reason of cancellation {} requires a substitute invoice,El motivo de cancelación {} requiere una factura sustituta, +To {},A {}, +Validate Certificate,Validar Certificado, +Web Service,Web Service, +XML,XML, diff --git a/erpnext_mexico_compliance/translations/es.csv b/erpnext_mexico_compliance/translations/es.csv index c830548..23f1289 100644 --- a/erpnext_mexico_compliance/translations/es.csv +++ b/erpnext_mexico_compliance/translations/es.csv @@ -1,16 +1,78 @@ -CFDI 4.0,CFDI 4.0 -From {},De {} -Invalid Tax Id,RFC Inválido -Key,Clave -Key Name,Clave Nombre -Mexico Compliance,Cumplimiento Mexicano -SAT Catalogs,Catálogos del SAT -SAT CFDI Use,Uso de CFDI SAT -SAT Payment Method,Método de Pago SAT -SAT Payment Mode,Forma de Pago SAT -SAT Product or Service Key,Clave SAT de Producto o Servicio -SAT Tax System,Régimen Fiscal SAT -SAT UOM Key,Clave SAT de UDM -Tax Id does not comply with SAT specifications,El RFC cumple con las especificaciones del SAT -Tax Type,Tipo de Impuesto -To {},A {} +1 credit is consumed every time a CFDI gets stamped,1 crédito es consumido cada vez que se timbra un CFDI, +A Cancellation Reason is required to cancel this payment entry.,Un Motivo de Cancelación es necesario para cancelar este pago., +A Cancellation Reason is required to cancel this sales invoice.,Un Motivo de Cancelación es necesario para cancelar esta factura de venta., +A Cancellation Reason is required.,Un Motivo de Cancelación es necesario., +Address {0} has no zip code,La dirección {0} no tiene código postal, +Attach PDF,Adjuntar PDF, +Attach XML,Adjuntar XML, +Available credits,Créditos disponibles, +Branch: {0},Sucursal: {0}, +Cancellation,Cancelación, +Cancellation acknowledgement,Acuse de cancelación, +Cancellation reason,Motivo de cancelación, +Cancellation Reason,Motivo de Cancelación, +Certificate file (.cer),Archivo de certificado (.cer), +Certificate file not configured,Archivo de certificado no configurado, +Certificate files and password are not valid,Los archivos de certificado y contraseña no son válidos, +Certificate files and password are valid,Los archivos de certificado y contraseña son válidos, +Certificate key file (.key),Archivo de clave de certificado (.key), +CFDI,CFDI, +CFDI Actions,Acciones de CFDI, +CFDI Stamping Settings,Configuración de Timbrado de CFDI, +CFDI Web Service Error,Error del Web Service de CFDI, +Check this field if the cancelled invoice needs to have another related invoice,Marca este campo si la factura cancelada necesita tener otra factura relacionada, +CLABE,CLABE, +Company for which this certificate will be used to sign CFDI,Compañía para la cual este certificado será usado para firmar CFDI, +Company {0} has no address,La compañía {0} no tiene dirección, +Company {0} has no tax regime,La compañía {0} no tiene régimen fiscal, +Company's Digital Signing Certificate to sign CFDI,Certificado de Sello Digital de la empresa para firmar CFDI, +Customer address {0} has no zip code,La dirección del cliente {0} no tiene código postal, +Customer {0} has no tax ID,El cliente {0} no tiene RFC, +Customer {0} has no tax regime,El cliente {0} no tiene régimen fiscal, +Digital Signing Certificate,Certificado de Sello Digital, +ERPNext Mexico Compliance,ERPNext Cumplimiento para México, +File {0} attached,, +From {},De {}, +"Indicates the form in which a payment was made, in accordance with the SAT catalog of forms of payment","Indica la forma en la que se realiza un pago, de acuerdo al catálogo de formas de pago del SAT", +"Indicates the method used to make a payment, in accordance with the SAT catalog of payment methods","Indica el método usado para realizar un pago, de acuerdo al catálogo de métodos de pago del SAT", +Invalid Cancellation Reason,Motivo de Cancelación inválido, +Invalid CFDI,CFDI Inválido, +Invalid Document Type,Tipo de Documento inválido, +Invalid Tax Id,RFC Inválido, +Invoice has no billing address,La factura no tiene dirección de facturación, +Key,Clave, +Key file not configured,Archivo de llave no configurado, +Key Name,Clave Nombre, +Legal name: {0},Razón social: {0}, +Mexico Compliance,Cumplimiento para México, +Parent SAT Product or Service Key,Clave de Producto o Servicio del SAT padre, +Password for the certificate key,Contraseña para la llave del certificado, +Reference {0} has not being stamped,La referencia {0} no ha sido timbrada, +Requires relationship,Requiere relación, +RFC: {0},RFC: {0}, +SAT Catalogs,Catálogos del SAT, +SAT CFDI Use,Uso de CFDI SAT, +SAT CFDI Use Tax Regime,Régimen Fiscal del Uso de CFDI SAT, +SAT Payment Method,Forma de Pago SAT, +SAT Payment Mode,Forma de Pago SAT, +SAT Payment Option,Método de Pago SAT, +SAT Product or Service Key,Clave SAT de Producto o Servicio, +SAT Tax Regime,Régimen Fiscal SAT, +SAT UOM Key,Clave SAT de UDM, +Select a Certificate to sign the CFDI,Selecciona un Certificado para firmar el CFDI, +Stamp CFDI,Timbrar CFDI, +Stamped XML,XML timbrado, +Substitute invoice,Factura sustituta, +Substitute payment entry,Entrada de pago sustituta, +Tax Id does not comply with SAT specifications,El RFC cumple con las especificaciones del SAT, +Tax Regime,Régimen Fiscal, +Tax regimes,Regímenes fiscales, +Tax Type,Tipo de Impuesto, +Test mode,Modo de pruebas, +The Cancellation Reason requires a substitute invoice.,El motivo de cancelación requiere una factura sustituta, +The Cancellation Reason requires a substitute payment entry.,El motivo de cancelación requiere una entrada de pago sustituta, +The reason of cancellation {} requires a substitute invoice,El motivo de cancelación {} requiere una factura sustituta, +To {},A {}, +Validate Certificate,Validar Certificado, +Web Service,Web Service, +XML,XML, diff --git a/erpnext_mexico_compliance/ws_client/__init__.py b/erpnext_mexico_compliance/ws_client/__init__.py new file mode 100644 index 0000000..7f299c3 --- /dev/null +++ b/erpnext_mexico_compliance/ws_client/__init__.py @@ -0,0 +1,25 @@ +"""Copyright (c) 2024, TI Sin Problemas and contributors +For license information, please see license.txt""" + +import frappe + +from . import client +from .exceptions import WSClientException, WSExistingCfdiException + + +def get_ws_client() -> client.WSClient: + """Retrieves a WSClient instance based on the current CFDI Stamping Settings. + + Returns: + client.WSClient: A WSClient instance configured with the current API key and operation mode. + """ + settings = frappe.get_single("CFDI Stamping Settings") + api_key = settings.get_api_key() + mode_map = { + 0: client.WSClient.OperationMode.PROD, + 1: client.WSClient.OperationMode.TEST, + } + return client.WSClient(api_key, mode_map[settings.test_mode]) + + +__all__ = ["get_ws_client", "WSClientException", "WSExistingCfdiException"] diff --git a/erpnext_mexico_compliance/ws_client/client.py b/erpnext_mexico_compliance/ws_client/client.py new file mode 100644 index 0000000..660d514 --- /dev/null +++ b/erpnext_mexico_compliance/ws_client/client.py @@ -0,0 +1,161 @@ +""" +Copyright (c) 2022, TI Sin Problemas and contributors +For license information, please see license.txt +""" + +import json +from enum import Enum +from typing import Any + +import frappe +from satcfdi.cfdi import CFDI +from zeep import Client +from zeep.cache import SqliteCache +from zeep.transports import Transport + +from .exceptions import WSClientException, WSExistingCfdiException + + +class WSClient: + """Represents a CFDI Web Service client.""" + + response: Any + + class OperationMode(Enum): + """Represents the operation mode of the CFDI Web Service.""" + + PROD = "https://app.facturaloplus.com/ws/servicio.do?wsdl" + TEST = "https://dev.facturaloplus.com/ws/servicio.do?wsdl" + + def __init__(self, api_key: str, mode: OperationMode = OperationMode.TEST) -> None: + self.api_key = api_key + self.client = Client(mode.value, transport=Transport(cache=SqliteCache())) + self.logger = frappe.logger("erpnext_mexico_compliance.ws_client", True) + + def log_error(self, include_data: bool = False) -> None: + """Logs an error message with optional data. + + Args: + include_data (bool, optional): Whether to include the response data in the error + message. Defaults to False. + + This function logs an error message using the logger object. The error message includes the + response code and message. If the `include_data` parameter is set to True, the response data + is also included in the error message. + """ + msg = {"code": self.response.code, "message": self.response.message} + if include_data: + msg["data"] = self.response.data + self.logger.error(msg) + + def raise_from_code(self): + """Raises a WSClientException if the given code is not 200. + + Raises: + WSClientException: If the given code is not 200. + WSExistingCfdiException: If the given code is 307. + """ + res = self.response + match res.code: + case "200" | "201": + return + case "307": + self.logger.error({"code": res.code, "message": res.message}) + raise WSExistingCfdiException(res.message, res.code, res.data) + case _: + self.logger.error({"code": res.code, "message": res.message}) + raise WSClientException(res.message, res.code) + + def stamp(self, cfdi: CFDI) -> tuple[str, str]: + """Stamps a CFDI using the provided client and API key. + + Args: + cfdi (CFDI): The CFDI to be stamped. + + Returns: + tuple[str, str]: A tuple containing the stamped CFDI data and the corresponding message. + + Raises: + WSExistingCfdiException: If the CFDI already exists. + WSClientException: If the stamping operation fails. + """ + xml_cfdi = cfdi.xml_bytes().decode("utf-8") + self.response = self.client.service.timbrar( + apikey=self.api_key, xmlCFDI=xml_cfdi + ) + self.logger.debug({"action": "stamp", "data": xml_cfdi}) + self.raise_from_code() + return self.response.data, self.response.message + + def cancel( + self, + signing_certificate: str, + cfdi: CFDI, + reason: str, + substitute_uuid: str = None, + ) -> tuple[str, str]: + """Cancels a CFDI using the provided signing certificate, CFDI, reason, and optional + substitute UUID. + + Args: + signing_certificate (str): The name of the Digital Signing Certificate DocType to use + for cancellation. + cfdi (CFDI): The CFDI to be cancelled. + reason (str): The reason for cancellation. + substitute_uuid (str, optional): The substitute UUID for cancellation. Defaults to None. + + Returns: + tuple[str, str]: A tuple containing the cancellation data and the corresponding message. + """ + csd = frappe.get_doc("Digital Signing Certificate", signing_certificate) + self.response = self.client.service.cancelar2( + apikey=self.api_key, + keyCSD=csd.get_key_b64(), + cerCSD=csd.get_certificate_b64(), + passCSD=csd.get_password(), + uuid=cfdi["Complemento"]["TimbreFiscalDigital"]["UUID"], + rfcEmisor=cfdi["Emisor"]["Rfc"], + rfcReceptor=cfdi["Receptor"]["Rfc"], + total=cfdi["Total"], + motivo=reason, + folioSustitucion=substitute_uuid or "", + ) + self.logger.debug( + { + "action": "cancel", + "signing_certificate": signing_certificate, + "cfdi": cfdi, + "reason": reason, + "substitute_uuid": substitute_uuid, + } + ) + self.raise_from_code() + return self.response.data, self.response.message + + def get_available_credits(self) -> int: + """Retrieves the available credits from the CFDI Web Service. + + Returns: + int: The number of available credits. + """ + res = self.client.service.consultarCreditosDisponibles(apikey=self.api_key) + self.response = res + self.raise_from_code() + return res.data + + def validate(self, cfdi: CFDI) -> tuple[dict, str]: + """Validate the structure and content of a given CFDI using the CFDI Web Service. + + Args: + cfdi (CFDI): The CFDI to be validated. + + Returns: + tuple[dict, str]: A tuple containing the validation data in JSON format and the + corresponding message. + """ + xml_cfdi = cfdi.xml_bytes().decode("utf-8") + res = self.client.service.validar(apikey=self.api_key, xmlCFDI=xml_cfdi) + self.response = res + self.logger.debug({"action": "validate", "data": xml_cfdi}) + self.raise_from_code() + return json.loads(res.data), res.message diff --git a/erpnext_mexico_compliance/ws_client/exceptions.py b/erpnext_mexico_compliance/ws_client/exceptions.py new file mode 100644 index 0000000..40a6dae --- /dev/null +++ b/erpnext_mexico_compliance/ws_client/exceptions.py @@ -0,0 +1,15 @@ +class WSClientException(Exception): + """Base class for exceptions raised by the CFDI Web Service.""" + + def __init__(self, message: str, code: str): + super().__init__(f"{code}: {message}") + self.message = message + self.code = code + + +class WSExistingCfdiException(WSClientException): + """Raised when an existing CFDI is found in the CFDI Web Service.""" + + def __init__(self, message: str, code: str, data: str): + super().__init__(message, code) + self.data = data diff --git a/license.txt b/license.txt index 2fdf7c7..d4ed839 100644 --- a/license.txt +++ b/license.txt @@ -1 +1,21 @@ -License: MIT \ No newline at end of file +MIT License + +Copyright (c) 2023 TI Sin Problemas + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3cbf183 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,19 @@ +[project] +name = "erpnext_mexico_compliance" +authors = [{ name = "TI Sin Problemas", email = "info@tisinproblemas.com" }] +description = "ERPNext app to serve as base to comply with help with Mexican Rules and Regulations" +requires-python = ">=3.11" +readme = "README.md" +dynamic = ["version"] +dependencies = ["zeep==4.2.1", "satcfdi==4.5.6"] +[build-system] +requires = ["flit_core"] +build-backend = "flit_core.buildapi" + +# These dependencies are only installed when developer mode is enabled +[tool.bench.dev-dependencies] +# package_name = "~=1.1.0" + +[tool.bench.frappe-dependencies] +frappe = ">=15.0.0,<16.0.0" +erpnext = ">=15.0.0,<16.0.0" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 7668191..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -# frappe -- https://github.com/frappe/frappe is installed via 'bench init' \ No newline at end of file