From d489ebff7c69da8980405d55b51b8748199c75ba Mon Sep 17 00:00:00 2001 From: Kaynnan Lemes Date: Tue, 18 Jun 2024 15:42:50 -0300 Subject: [PATCH 1/2] [ADD] dominio_base: add new module --- dominio_base/README.rst | 54 +++ dominio_base/__init__.py | 1 + dominio_base/__manifest__.py | 16 + dominio_base/constants/dominio.py | 7 + dominio_base/models/__init__.py | 1 + dominio_base/models/res_company.py | 164 ++++++++ dominio_base/readme/CONTRIBUTORS.rst | 0 dominio_base/readme/DESCRIPTION.rst | 0 dominio_base/readme/USAGE.rst | 0 dominio_base/static/description/icon.png | Bin 0 -> 2873 bytes dominio_base/static/description/index.html | 408 ++++++++++++++++++++ dominio_base/views/res_company.xml | 31 ++ setup/.setuptools-odoo-make-default-ignore | 2 + setup/README | 2 + setup/dominio_base/odoo/addons/dominio_base | 1 + setup/dominio_base/setup.py | 6 + 16 files changed, 693 insertions(+) create mode 100644 dominio_base/README.rst create mode 100644 dominio_base/__init__.py create mode 100644 dominio_base/__manifest__.py create mode 100644 dominio_base/constants/dominio.py create mode 100644 dominio_base/models/__init__.py create mode 100644 dominio_base/models/res_company.py create mode 100644 dominio_base/readme/CONTRIBUTORS.rst create mode 100644 dominio_base/readme/DESCRIPTION.rst create mode 100644 dominio_base/readme/USAGE.rst create mode 100644 dominio_base/static/description/icon.png create mode 100644 dominio_base/static/description/index.html create mode 100644 dominio_base/views/res_company.xml create mode 100644 setup/.setuptools-odoo-make-default-ignore create mode 100644 setup/README create mode 120000 setup/dominio_base/odoo/addons/dominio_base create mode 100644 setup/dominio_base/setup.py diff --git a/dominio_base/README.rst b/dominio_base/README.rst new file mode 100644 index 0000000..bf53aab --- /dev/null +++ b/dominio_base/README.rst @@ -0,0 +1,54 @@ +============ +Dominio Base +============ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ac0188be54a8cd1b173ceff91eb5462d2b77915eb715a0afe1bf4e82af5bb329 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-Escodoo%2Fclog--addons-lightgray.png?logo=github + :target: https://github.com/Escodoo/clog-addons/tree/14.0/dominio_base + :alt: Escodoo/clog-addons + +|badge1| |badge2| |badge3| + + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Escodoo + +Maintainers +~~~~~~~~~~~ + +This module is part of the `Escodoo/clog-addons `_ project on GitHub. + +You are welcome to contribute. diff --git a/dominio_base/__init__.py b/dominio_base/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/dominio_base/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/dominio_base/__manifest__.py b/dominio_base/__manifest__.py new file mode 100644 index 0000000..bf146a4 --- /dev/null +++ b/dominio_base/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2024 - TODAY, Escodoo +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Dominio Base", + "summary": """ + Dominio API Base""", + "version": "14.0.1.0.0", + "license": "AGPL-3", + "author": "Escodoo", + "website": "https://github.com/Escodoo/clog-addons", + "depends": ["base"], + "data": [ + "views/res_company.xml", + ], +} diff --git a/dominio_base/constants/dominio.py b/dominio_base/constants/dominio.py new file mode 100644 index 0000000..18dceee --- /dev/null +++ b/dominio_base/constants/dominio.py @@ -0,0 +1,7 @@ +# Copyright 2024 - TODAY, Kaynnan Lemes +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +DOMINIO_ENVIRONMENTS = [("1", "Produção"), ("2", "Homologação")] +DOMINIO_ENVIRONMENT_DEFAULT = "2" +COOKIE = "did=s%3Av0%3A145b8a90-ea57-11eb-ae8a-877f15a4a518.QhUcTCGsMP28yWAB%2BYsUUZ5Gw4Srxf%2F0IDRkKPUQQHs; did_compat=s%3Av0%3A145b8a90-ea57-11eb-ae8a-877f15a4a518.QhUcTCGsMP28yWAB%2BYsUUZ5Gw4Srxf%2F0IDRkKPUQQHs" # noqa: B950 +AUDIENCE = "409f91f6-dc17-44c8-a5d8-e0a1bafd8b67" diff --git a/dominio_base/models/__init__.py b/dominio_base/models/__init__.py new file mode 100644 index 0000000..aff44f3 --- /dev/null +++ b/dominio_base/models/__init__.py @@ -0,0 +1 @@ +from . import res_company diff --git a/dominio_base/models/res_company.py b/dominio_base/models/res_company.py new file mode 100644 index 0000000..3f1346c --- /dev/null +++ b/dominio_base/models/res_company.py @@ -0,0 +1,164 @@ +# Copyright 2024 - TODAY, Kaynnan Lemes +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import requests + +from odoo import _, fields, models +from odoo.exceptions import UserError + +from ..constants.dominio import ( + AUDIENCE, + COOKIE, + DOMINIO_ENVIRONMENT_DEFAULT, + DOMINIO_ENVIRONMENTS, +) + + +class ResCompany(models.Model): + + _inherit = "res.company" + + dominio_environment = fields.Selection( + selection=DOMINIO_ENVIRONMENTS, + string="Environment", + default=DOMINIO_ENVIRONMENT_DEFAULT, + ) + dominio_client_token = fields.Char( + string="Client ID Token", + ) + dominio_secret_token = fields.Char( + string="Client Secret Token", + ) + dominio_production_integration_key = fields.Char( + string="Integration Production Token" + ) + dominio_homologation_integration_key = fields.Char( + string="Integration Homologation Token" + ) + + def get_dominio_environment(self): + """ + Retrieve the appropriate Dominio token based on the current environment setting. + Decide between the production and homologation (test) environment tokens by + examining the 'dominio_environment' field of the record. + + Precondition: + - Call this method on a single record only. The method uses ensure_one to + enforce this rule. + + Returns: + - str: The Dominio token. Return the production token if 'dominio_environment' + is set to "1"; otherwise, return the homologation token. + + Raises: + - ValueError: If the method is called on a recordset containing more than one + record. + """ + self.ensure_one() + return ( + self.dominio_production_integration_key + if self.dominio_environment == "1" + else self.dominio_homologation_integration_key + ) + + def _generate_dominio_token(self): + """ + Generate OAuth2 token for Dominio service. + + Returns: + requests.Response: Response object containing the token. + + Raises: + UserError: If an error occurs during token generation. + """ + try: + url = "https://auth.thomsonreuters.com/oauth/token" + + payload = { + "grant_type": "client_credentials", + "client_id": self.dominio_client_token, + "client_secret": self.dominio_secret_token, + "audience": AUDIENCE, + } + headers = { + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": COOKIE, + } + + response = requests.post(url, data=payload, headers=headers) + response.raise_for_status() + return response + + except requests.HTTPError as e: + raise UserError( + _("Error communicating with Dominio service: %s") % e + ) from e + + def _generate_key_integration(self): + """ + Generate integration key for Dominio activation. + + Returns: + str: Integration key retrieved from the response. + + Raises: + UserError: If an error occurs during integration key generation. + """ + try: + url = "https://api.onvio.com.br/dominio/integration/v1/activation/enable" + + x_integration_key = self.get_dominio_environment() + token_response = self._generate_dominio_token() + token_data = token_response.json() + access_token = token_data.get("access_token") + + headers = { + "Authorization": f"Bearer {access_token}", + "x-integration-key": x_integration_key, + } + + response = requests.post(url, headers=headers) + response.raise_for_status() + response_data = response.json() + + return { + "integrationKey": response_data.get("integrationKey"), + "access_token": access_token, + } + + except requests.HTTPError as e: + raise UserError( + _("Error while generating integration key in Dominio: %s") % e + ) from e + + def _check_dominio_customer(self): + """ + Check customer authorization status in Dominio service. + + Returns: + requests.Response: Response object containing the authorization status. + + Raises: + UserError: If an error occurs while verifying customer authorization. + """ + try: + url = "https://api.onvio.com.br/dominio/integration/v1/activation/info" + + x_integration_key = self.get_dominio_environment() + token_response = self._generate_dominio_token() + token_data = token_response.json() + access_token = token_data.get("access_token") + + headers = { + "Authorization": "Bearer " + access_token, + "x-integration-key": x_integration_key, + } + + response = requests.get(url, headers=headers) + response.raise_for_status() + return response + + except requests.HTTPError as e: + raise UserError( + _("Error while verifying customer authorization: %s") % e + ) from e diff --git a/dominio_base/readme/CONTRIBUTORS.rst b/dominio_base/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..e69de29 diff --git a/dominio_base/readme/DESCRIPTION.rst b/dominio_base/readme/DESCRIPTION.rst new file mode 100644 index 0000000..e69de29 diff --git a/dominio_base/readme/USAGE.rst b/dominio_base/readme/USAGE.rst new file mode 100644 index 0000000..e69de29 diff --git a/dominio_base/static/description/icon.png b/dominio_base/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..12ab0051e3b9ac413f0f0016b7cff54f02fc763e GIT binary patch literal 2873 zcmV-93&!+`P)`uGecH7++*a9tqf=D4K3Mya}O@tpzNQ@yQCf@Kr zF!+nnKqBHT7^8%kXfz5&3vvk;1t}w7Z?N*D?A{ zHrd_G%z4iDJn#2;p6~mP`2CNcJjDNjrs?X8sbe)Nav^9t4K(ppCb-d2d)&lZ>k%SMT{9YBg-a+&W{!hd#wDr8Wl{eXS z*$7*96lqpl{PUr=s8^hIiDg}g*f5f1&&S6&>%w7_k{mf$=0jJV!9`c@;PA^Op1%JL zjvcP7X-sQIgb*+?KF9@EjIw?AMgZbC#&KNql%Q6tlgni}^ZZSmdHyEeJ2=g=55CEv zmnMkgHHh!qH~xB6FC&#;=S7>@bLA+-%~=4VD8ltxIF5^^DFQzvj6#%BWV03ng*-|r z04k*>&p&>cm!5nFzZI@poU2BJnbtV_!&|uU$}y~h2|yTz*p5r9WG&z2} zgzMT!DN#yCDn%xfCZEq?8U_G%-Q$HP-sbto4&yXiD<1EPFO7UL&G{c2<=nkn(2e#} z^@9M%@$h}0bjoDo#v;0Q@};9FB8of+1YzLQY&J2?6oo>LOfJpk*PX*9*NpSZGe>#u zk%LT6G*&F`6(eG3TaNRu7-jszVWetTW!G!rx-L-^kx8c+94Mev4;4F(2?8GipD+k; zT^B>w$>nooEsH%@Z0CZHj&bnk*sdZMTrtMhorAOY5aYNW zj^iMu#L8sIWYP#BmUN9U4B9_|Ps?vnt=7opvgGFp>%@^N2Od4dtIr-Kik7z0m!uI& z6O3QDnTtL##=x*O8*qf7`Rm>4UQp;#P5$@Lpq;;yjH>WJ5(YUt#1IdZuydp@>#C#ExmKro8|zO=gyYw6f?D@) zO;dA3C`t5Rlo9o%65&TKb${xF|7l7xRh|Jrss7IhDMeQ!8kOD#v=fMk38}gh#3yucyF^u$%5|2^EB4zY-za^N18QYBnvew`D8=+@OK&R~LPuuFnak z5RxG1S0Y4rSxl9B-?Ncn+@jtppZ0~in(HN$Qhl2d2r+LOZT9>&S#ggO^|0ZoX&U8; zxe^-mDG~ECqBhz4)_{zn-quh%Bicmtw?+sw)hV4`&+qGbY?M+kRi3RJQuVP$%xk8m zlMs=>LhJMrN-3f!BJR6pqJ1xO8qvGCE0Z{hwdp2N6m<>Qe#;6W1VV_mm6ZWIN8uMj|6uCNY-{rRJ5;e(WU#y58<6D+!hbBs>^A*b2-{&Q*;#Zg1T713H;K=R@>9XTTE9 zP&rKx*J&YTyG-?qTh;9$q{Oj3+~(r@7#~EU&JsXZigKwlbI87Nw1tq}(m6FzJI$+4 zMxxFVKvNp!iT?C2I~5~o4*?0wC$w$y(y@7a9Q~pZa&FkF_2^vBM`DdIPVgoACnMTE zL^~sz)5(t(B_={j$z;dK?IVo4u1Q7!R3n?fOf%0ptS1tBDwuA^x>gM$O;x=tL$)Tfg*Q?P{c2@pqu zU)=d88g(1fG#DJnBc)_&YMNTDz6OSkKq(E~Fv(`KY#rH5*2++;Ho4~~4-ojtm#f-) z?x${z;$$;}Qi|7Kdz(idcoxIdIcw)OOw&Nub!^AQwrw;`>!#}I&}cNS}g>5^ShC!i_>z<-r2tA#lnjNu~rZZ5;lh5Z6Lh%04GI!naN2*7BwiZWO z%2EeVdv{%ZYqY>N-{OHm$}q@V7UhWw5AEAey>4^P?j5AlCaIK3%lE0(8wfzx^#xDZ zoh~Dk($F*m%gVBO(-7%&8ow3r`(Ho8FYnmL2DVbnZdfu20OFh1e?M-8%U6Bd^C(v; zScMc{`pRe7d--kvS}mWZZ6kzappeHf^poDZP)4-H&_LHUHWZ7b(L-7u zAciSg8V#p4 zVHhW5$Eh+x({yyhAeYOrX?O@-*O{KI^7A|I<>B8QVEe#MEYn(c+#RUPc3pF87$=+5 z7J?9hjF}>r$?(qG$9Qnxe!?K)oZVxXrh#dixSmI&VWX7ldI$4~kW!%=DbkrV!^1=5 zvKCPkbN_u$@}uwmj#RVArotAaSlN?&;+E@gi@h*;-R%Vp$EGw>VPtfOo4@{f#?KuE zm=)7@Wf>^snVg))^Bj~m+Y<~Fx~KLIzHyYhe((pviouqF5t7bEy+Yh_!)>t_tPT+X zVH7c4t5LNZeDuma+<5b+$>lS|aZJ;8a9xi$0wKY&=FV+48xFs@`$6_U{3>S+??hM0 zOJWkNYDUb5+iFpssh|wS7r%TpS6zECLJ0gIpfpio$BvQi5#pyFe}Q{`wvQom8v~ia zRgVooTS{lS6r>D;ZNrHuU^O2v0>bXk7=45J37f-Kl}rwLv_YC zo`+ar9as$FmK$!5y&##tw_F5a$W*n8-E#TlXD;F5OLueVjrVxyzGpb2xRbQ8a@C+$ zh;Q9+d+e?;5gjxghjO)oP?FJsF}4hhu1g#MTFduVONdVkE1hOTc8IJ|M9GsIt+j&Z z+sJbD{dKvxCUuJG5elhI>q(I({QN z2z?sv45gWOvE4eFE>qZUjkoRBK+sicvFHdR7XOOU0%|W1q%;d9)-MBq*+VWTdKUiy XXqTGI$C0NT00000NkvXXu0mjf?G|(} literal 0 HcmV?d00001 diff --git a/dominio_base/static/description/index.html b/dominio_base/static/description/index.html new file mode 100644 index 0000000..19ae746 --- /dev/null +++ b/dominio_base/static/description/index.html @@ -0,0 +1,408 @@ + + + + + +Dominio Base + + + +
+

Dominio Base

+ + +

Beta License: AGPL-3 Escodoo/clog-addons

+

Table of contents

+ +
+

Bug Tracker

+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Escodoo
  • +
+
+
+

Maintainers

+

This module is part of the Escodoo/clog-addons project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/dominio_base/views/res_company.xml b/dominio_base/views/res_company.xml new file mode 100644 index 0000000..e41171f --- /dev/null +++ b/dominio_base/views/res_company.xml @@ -0,0 +1,31 @@ + + + + + + res.company.form (in dominio_base) + res.company + + + + + + + + + + + + + + + + + diff --git a/setup/.setuptools-odoo-make-default-ignore b/setup/.setuptools-odoo-make-default-ignore new file mode 100644 index 0000000..207e615 --- /dev/null +++ b/setup/.setuptools-odoo-make-default-ignore @@ -0,0 +1,2 @@ +# addons listed in this file are ignored by +# setuptools-odoo-make-default (one addon per line) diff --git a/setup/README b/setup/README new file mode 100644 index 0000000..a63d633 --- /dev/null +++ b/setup/README @@ -0,0 +1,2 @@ +To learn more about this directory, please visit +https://pypi.python.org/pypi/setuptools-odoo diff --git a/setup/dominio_base/odoo/addons/dominio_base b/setup/dominio_base/odoo/addons/dominio_base new file mode 120000 index 0000000..60192bb --- /dev/null +++ b/setup/dominio_base/odoo/addons/dominio_base @@ -0,0 +1 @@ +../../../../dominio_base \ No newline at end of file diff --git a/setup/dominio_base/setup.py b/setup/dominio_base/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/dominio_base/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 6e25fa8579113b4dcbb2e27ab4dea1d263f7b617 Mon Sep 17 00:00:00 2001 From: Kaynnan Lemes Date: Wed, 3 Jul 2024 16:27:40 -0300 Subject: [PATCH 2/2] [ADD] dominio_fiscal: add new module --- dominio_fiscal/README.rst | 54 +++ dominio_fiscal/__init__.py | 1 + dominio_fiscal/__manifest__.py | 20 + dominio_fiscal/models/__init__.py | 2 + dominio_fiscal/models/closing.py | 178 ++++++++ dominio_fiscal/models/document.py | 102 +++++ dominio_fiscal/readme/CONTRIBUTORS.rst | 0 dominio_fiscal/readme/DESCRIPTION.rst | 0 dominio_fiscal/readme/USAGE.rst | 0 dominio_fiscal/static/description/icon.png | Bin 0 -> 2873 bytes dominio_fiscal/static/description/index.html | 408 ++++++++++++++++++ .../views/l10n_br_fiscal_closing.xml | 24 ++ .../views/l10n_br_fiscal_document.xml | 39 ++ .../dominio_fiscal/odoo/addons/dominio_fiscal | 1 + setup/dominio_fiscal/setup.py | 6 + 15 files changed, 835 insertions(+) create mode 100644 dominio_fiscal/README.rst create mode 100644 dominio_fiscal/__init__.py create mode 100644 dominio_fiscal/__manifest__.py create mode 100644 dominio_fiscal/models/__init__.py create mode 100644 dominio_fiscal/models/closing.py create mode 100644 dominio_fiscal/models/document.py create mode 100644 dominio_fiscal/readme/CONTRIBUTORS.rst create mode 100644 dominio_fiscal/readme/DESCRIPTION.rst create mode 100644 dominio_fiscal/readme/USAGE.rst create mode 100644 dominio_fiscal/static/description/icon.png create mode 100644 dominio_fiscal/static/description/index.html create mode 100644 dominio_fiscal/views/l10n_br_fiscal_closing.xml create mode 100644 dominio_fiscal/views/l10n_br_fiscal_document.xml create mode 120000 setup/dominio_fiscal/odoo/addons/dominio_fiscal create mode 100644 setup/dominio_fiscal/setup.py diff --git a/dominio_fiscal/README.rst b/dominio_fiscal/README.rst new file mode 100644 index 0000000..b322b61 --- /dev/null +++ b/dominio_fiscal/README.rst @@ -0,0 +1,54 @@ +============== +Dominio Fiscal +============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:a137e7c5df9d4a5824d75e38e1950972212de49e52465a9fdb03cac811dfbb55 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-Escodoo%2Fclog--addons-lightgray.png?logo=github + :target: https://github.com/Escodoo/clog-addons/tree/14.0/dominio_fiscal + :alt: Escodoo/clog-addons + +|badge1| |badge2| |badge3| + + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Escodoo + +Maintainers +~~~~~~~~~~~ + +This module is part of the `Escodoo/clog-addons `_ project on GitHub. + +You are welcome to contribute. diff --git a/dominio_fiscal/__init__.py b/dominio_fiscal/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/dominio_fiscal/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/dominio_fiscal/__manifest__.py b/dominio_fiscal/__manifest__.py new file mode 100644 index 0000000..2882b51 --- /dev/null +++ b/dominio_fiscal/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2024 - TODAY, Escodoo +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Dominio Fiscal", + "summary": """ + Dominio integration with L10n BR Fiscal Closing""", + "version": "14.0.1.0.0", + "license": "AGPL-3", + "author": "Escodoo", + "website": "https://github.com/Escodoo/clog-addons", + "depends": [ + "dominio_base", + "l10n_br_fiscal_closing", + ], + "data": [ + "views/l10n_br_fiscal_document.xml", + "views/l10n_br_fiscal_closing.xml", + ], +} diff --git a/dominio_fiscal/models/__init__.py b/dominio_fiscal/models/__init__.py new file mode 100644 index 0000000..c2fa57a --- /dev/null +++ b/dominio_fiscal/models/__init__.py @@ -0,0 +1,2 @@ +from . import closing +from . import document diff --git a/dominio_fiscal/models/closing.py b/dominio_fiscal/models/closing.py new file mode 100644 index 0000000..547bde7 --- /dev/null +++ b/dominio_fiscal/models/closing.py @@ -0,0 +1,178 @@ +# Copyright 2024 - TODAY, Kaynnan Lemes +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import base64 +import logging + +import requests + +from odoo import _, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class FiscalClosing(models.Model): + + _inherit = "l10n_br_fiscal.closing" + + def _send_dominio_xml(self): + """ + Sends fiscal XML data to a third-party API endpoint (Dominio). + + This method prepares and sends an XML payload containing fiscal data + to a specified endpoint using OAuth2 authorization and integration key. + + Raises a UserError if the HTTP request encounters an error. + + Returns: + requests.Response: Response object from the API call. + """ + try: + url = "https://api.onvio.com.br/dominio/invoice/v3/batches" + + integration_data = self.company_id._generate_key_integration() + access_token = integration_data.get("access_token") + integration_key = integration_data.get("integrationKey") + + results = [] + + document_fields = [ + self.document_nfe_ids, + self.document_nfse_ids, + self.document_nfce_ids, + self.document_cfe_ids, + self.document_cfeecf_ids, + self.document_nfse_ids, + self.document_rl_ids, + ] + + for document_field in document_fields: + for document in document_field: + xml_file = document.authorization_file_id or document.send_file_id + + if xml_file and xml_file.datas: + file_content = base64.b64decode(xml_file.datas) + + _logger.info( + f"Preparing to send XML for document {document.id}" + ) + + headers = { + "Authorization": f"Bearer {access_token}", + "x-integration-key": integration_key, + } + + data = { + "file[]": (None, file_content, "application/xml"), + "query": (None, '{"boxe/File": false}', "application/json"), + } + + response = requests.post(url, headers=headers, files=data) + response.raise_for_status() + response_json = response.json() + + results.append( + { + "integrationKey": integration_key, + "access_token": access_token, + "id": response_json["id"], + "document_id": document.id, + } + ) + + _logger.info( + f"Successfully sent XML for document {document.id}" + ) + + else: + raise UserError(_("XML Not found in Fiscal Document")) + + return results + + except requests.HTTPError as e: + raise UserError( + _("Failed to send fiscal XML to Dominio API: %s") % e + ) from e + + def _check_send_xml_dominio(self): + """ + Checks the status of fiscal XML data sent to a third-party API endpoint (Dominio). + + This method checks the status of fiscal XML data previously sent to a specified API + endpoint using OAuth2 authorization and integration key retrieved from each result in + the `results` list. It expects the `results` to be fetched beforehand using the + `_send_dominio_xml()` method. + + Raises a UserError if the API returns an error status related to XML validation, + company registration, or if the HTTP request encounters an error. + + Returns: + bool: True if the XML data was successfully stored in the API. + Raises UserError for any errors encountered during the process. + """ + try: + # Fetch XML sending results + results = self._send_dominio_xml() + # Process each result + for result in results: + access_token = result.get("access_token") + integration_key = result.get("integrationKey") + id_xml = result.get("id") + document_id = result.get("document_id") + + document = self.env["l10n_br_fiscal.document"].browse(document_id) + + # Construct URL for API endpoint + url = f"https://api.onvio.com.br/dominio/invoice/v3/batches/{id_xml}" + + # Prepare headers with integration key and access token + headers = { + "x-integration-key": integration_key, + "Authorization": f"Bearer {access_token}", + } + + _logger.info( + f"Requesting status for document {document.id} from Dominio API" + ) + + # Make a GET request to the API endpoint + response = requests.get(url, headers=headers) + response.raise_for_status() + response_json = response.json() + + # Check for different API response conditions + if response.status_code == 200: + if response_json["filesExpanded"][0]["apiStatus"]["code"] == "SA2": + document.state_dominio = "stored" + _logger.info( + f"Document {document.id} successfully stored in Dominio API" + ) + if response_json["filesExpanded"][0]["apiStatus"]["code"] == "EA10": + document.state_dominio = "duplicated" + _logger.warning( + f"Document {document.id} already exists in Dominio API" + ) + else: + document.state_dominio = "error" + _logger.error( + f"Error storing document {document.id} in Dominio API" + ) + else: + _logger.error( + f"Request error: its status was {response.status_code}" + ) + raise UserError( + _(f"Request error: its status was {response.status_code}") + ) + + _logger.info("Finished checking XML data sent to Dominio API") + + except requests.HTTPError as e: + _logger.error( + "HTTP error occurred while checking XML status with Dominio API: %s", e + ) + raise UserError(_("Request error: %s") % e) from e + + def action_dominio_send(self): + self._check_send_xml_dominio() diff --git a/dominio_fiscal/models/document.py b/dominio_fiscal/models/document.py new file mode 100644 index 0000000..5ced253 --- /dev/null +++ b/dominio_fiscal/models/document.py @@ -0,0 +1,102 @@ +# Copyright 2024 - TODAY, Kaynnan Lemes +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, fields, models + +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + EVENT_ENV_HML, + EVENT_ENV_PROD, + SITUACAO_EDOC_AUTORIZADA, +) + + +class FiscalDocument(models.Model): + + _inherit = "l10n_br_fiscal.document" + + state_dominio = fields.Selection( + [("stored", "Stored"), ("duplicated", "Duplicated"), ("error", "Error")], + string="State Dominio", + readonly=True, + ) + + def action_create_xml_static(self): + for record in self: + xml_content = """ + + + + 12345678000123 + AssinaturaAC123 + 001 + 2023-05-26T10:00:00-03:00 + + + 08318053000167 + 123456789 + 1234567 + 0 + N + + + 12345678901 + Cliente Teste + + + + + 0001 + Produto Teste + 12345678 + 5102 + UN + 1.0000 + 10.00 + 10.00 + A + + + + 10.00 + 0.00 + 0.00 + 0.00 + 0.00 + 10.00 + 0.00 + + + + 01 + 10.00 + + + + Informações adicionais do CF-e + + + + """ + + event_id = record.event_ids.create_event_save_xml( + company_id=self.company_id, + environment=( + EVENT_ENV_PROD if record.nfse_environment == "1" else EVENT_ENV_HML + ), + event_type="0", + xml_file="", + document_id=record, + ) + record.authorization_event_id = event_id + + record.authorization_event_id.set_done( + status_code=4, + response=_("Processado com Sucesso"), + protocol_date=record.authorization_date, + protocol_number=record.authorization_protocol, + file_response_xml=xml_content, + ) + record._change_state(SITUACAO_EDOC_AUTORIZADA) + return diff --git a/dominio_fiscal/readme/CONTRIBUTORS.rst b/dominio_fiscal/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..e69de29 diff --git a/dominio_fiscal/readme/DESCRIPTION.rst b/dominio_fiscal/readme/DESCRIPTION.rst new file mode 100644 index 0000000..e69de29 diff --git a/dominio_fiscal/readme/USAGE.rst b/dominio_fiscal/readme/USAGE.rst new file mode 100644 index 0000000..e69de29 diff --git a/dominio_fiscal/static/description/icon.png b/dominio_fiscal/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..12ab0051e3b9ac413f0f0016b7cff54f02fc763e GIT binary patch literal 2873 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 XXqTGI$C0NT00000NkvXXu0mjf?G|(} literal 0 HcmV?d00001 diff --git a/dominio_fiscal/static/description/index.html b/dominio_fiscal/static/description/index.html new file mode 100644 index 0000000..a3b1be2 --- /dev/null +++ b/dominio_fiscal/static/description/index.html @@ -0,0 +1,408 @@ + + + + + +Dominio Fiscal + + + +
+

Dominio Fiscal

+ + +

Beta License: AGPL-3 Escodoo/clog-addons

+

Table of contents

+ +
+

Bug Tracker

+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Escodoo
  • +
+
+
+

Maintainers

+

This module is part of the Escodoo/clog-addons project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/dominio_fiscal/views/l10n_br_fiscal_closing.xml b/dominio_fiscal/views/l10n_br_fiscal_closing.xml new file mode 100644 index 0000000..a8c0a32 --- /dev/null +++ b/dominio_fiscal/views/l10n_br_fiscal_closing.xml @@ -0,0 +1,24 @@ + + + + + + l10n_br_fiscal.closing.form (in dominio_fiscal) + l10n_br_fiscal.closing + + + +