odoo-addon-l10n-es-verifactu-oca 15.0.1.0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of odoo-addon-l10n-es-verifactu-oca might be problematic. Click here for more details.
- odoo/addons/l10n_es_verifactu_oca/README.rst +154 -0
- odoo/addons/l10n_es_verifactu_oca/__init__.py +3 -0
- odoo/addons/l10n_es_verifactu_oca/__manifest__.py +48 -0
- odoo/addons/l10n_es_verifactu_oca/data/account_fiscal_position_template_data.xml +129 -0
- odoo/addons/l10n_es_verifactu_oca/data/ir_config_parameter.xml +9 -0
- odoo/addons/l10n_es_verifactu_oca/data/ir_cron.xml +14 -0
- odoo/addons/l10n_es_verifactu_oca/data/mail_activity_data.xml +11 -0
- odoo/addons/l10n_es_verifactu_oca/data/verifactu_map_data.xml +120 -0
- odoo/addons/l10n_es_verifactu_oca/data/verifactu_registration_key_data.xml +207 -0
- odoo/addons/l10n_es_verifactu_oca/data/verifactu_tax_agency_data.xml +19 -0
- odoo/addons/l10n_es_verifactu_oca/hooks.py +43 -0
- odoo/addons/l10n_es_verifactu_oca/i18n/ca.po +1630 -0
- odoo/addons/l10n_es_verifactu_oca/i18n/ca_ES.po +1599 -0
- odoo/addons/l10n_es_verifactu_oca/i18n/es.po +1640 -0
- odoo/addons/l10n_es_verifactu_oca/i18n/l10n_es_verifactu_oca.pot +1673 -0
- odoo/addons/l10n_es_verifactu_oca/models/__init__.py +16 -0
- odoo/addons/l10n_es_verifactu_oca/models/account_fiscal_position.py +40 -0
- odoo/addons/l10n_es_verifactu_oca/models/account_fiscal_position_template.py +18 -0
- odoo/addons/l10n_es_verifactu_oca/models/account_journal.py +64 -0
- odoo/addons/l10n_es_verifactu_oca/models/account_move.py +556 -0
- odoo/addons/l10n_es_verifactu_oca/models/aeat_mixin.py +163 -0
- odoo/addons/l10n_es_verifactu_oca/models/aeat_tax_agency.py +30 -0
- odoo/addons/l10n_es_verifactu_oca/models/res_company.py +48 -0
- odoo/addons/l10n_es_verifactu_oca/models/res_partner.py +33 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_chaining.py +30 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_developer.py +16 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_invoice_entry.py +401 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_invoice_entry_response.py +121 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_invoice_entry_response_line.py +35 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_map.py +66 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_mixin.py +449 -0
- odoo/addons/l10n_es_verifactu_oca/models/verifactu_registration_key.py +24 -0
- odoo/addons/l10n_es_verifactu_oca/readme/CONFIGURE.rst +18 -0
- odoo/addons/l10n_es_verifactu_oca/readme/CONTRIBUTORS.rst +19 -0
- odoo/addons/l10n_es_verifactu_oca/readme/DESCRIPTION.rst +1 -0
- odoo/addons/l10n_es_verifactu_oca/readme/INSTALL.rst +4 -0
- odoo/addons/l10n_es_verifactu_oca/readme/ROADMAP.rst +15 -0
- odoo/addons/l10n_es_verifactu_oca/readme/USAGE.rst +1 -0
- odoo/addons/l10n_es_verifactu_oca/security/ir.model.access.csv +22 -0
- odoo/addons/l10n_es_verifactu_oca/security/verifactu_security.xml +6 -0
- odoo/addons/l10n_es_verifactu_oca/static/description/icon.png +0 -0
- odoo/addons/l10n_es_verifactu_oca/static/description/index.html +508 -0
- odoo/addons/l10n_es_verifactu_oca/tests/__init__.py +5 -0
- odoo/addons/l10n_es_verifactu_oca/tests/common.py +304 -0
- odoo/addons/l10n_es_verifactu_oca/tests/json/verifactu_mocked_response_1.json +35 -0
- odoo/addons/l10n_es_verifactu_oca/tests/json/verifactu_mocked_response_2.json +35 -0
- odoo/addons/l10n_es_verifactu_oca/tests/json/verifactu_out_invoice_s_iva10b_s_iva21s_dict.json +59 -0
- odoo/addons/l10n_es_verifactu_oca/tests/json/verifactu_out_invoice_s_iva21s_s_req52_dict.json +58 -0
- odoo/addons/l10n_es_verifactu_oca/tests/json/verifactu_out_refund_s_iva10b_s_iva10b_s_iva21s_dict.json +66 -0
- odoo/addons/l10n_es_verifactu_oca/tests/test_10n_es_verifactu.py +451 -0
- odoo/addons/l10n_es_verifactu_oca/tests/test_account_journal.py +78 -0
- odoo/addons/l10n_es_verifactu_oca/tests/test_account_move_reversal.py +93 -0
- odoo/addons/l10n_es_verifactu_oca/tests/test_res_partner.py +48 -0
- odoo/addons/l10n_es_verifactu_oca/tests/test_verifactu_invoice.py +350 -0
- odoo/addons/l10n_es_verifactu_oca/views/account_fiscal_position_view.xml +30 -0
- odoo/addons/l10n_es_verifactu_oca/views/account_journal_view.xml +28 -0
- odoo/addons/l10n_es_verifactu_oca/views/account_move_view.xml +219 -0
- odoo/addons/l10n_es_verifactu_oca/views/aeat_tax_agency_view.xml +31 -0
- odoo/addons/l10n_es_verifactu_oca/views/report_invoice.xml +55 -0
- odoo/addons/l10n_es_verifactu_oca/views/res_company_view.xml +50 -0
- odoo/addons/l10n_es_verifactu_oca/views/res_partner_view.xml +27 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_chaining_view.xml +47 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_developer_view.xml +48 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_invoice_entry_response_view.xml +149 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_invoice_entry_view.xml +124 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_map_lines_view.xml +20 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_map_view.xml +53 -0
- odoo/addons/l10n_es_verifactu_oca/views/verifactu_registration_keys_view.xml +42 -0
- odoo/addons/l10n_es_verifactu_oca/wizards/__init__.py +1 -0
- odoo/addons/l10n_es_verifactu_oca/wizards/account_move_reversal.py +16 -0
- odoo_addon_l10n_es_verifactu_oca-15.0.1.0.0.2.dist-info/METADATA +171 -0
- odoo_addon_l10n_es_verifactu_oca-15.0.1.0.0.2.dist-info/RECORD +74 -0
- odoo_addon_l10n_es_verifactu_oca-15.0.1.0.0.2.dist-info/WHEEL +5 -0
- odoo_addon_l10n_es_verifactu_oca-15.0.1.0.0.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Copyright 2021 Tecnativa - João Marques
|
|
2
|
+
# Copyright 2022 ForgeFlow - Lois Rilo
|
|
3
|
+
# Copyright 2011-2023 Tecnativa - Pedro M. Baeza
|
|
4
|
+
# Copyright 2023 Aures Tic - Almudena de la Puente <almudena@aurestic.es>
|
|
5
|
+
# Copyright 2023-2024 Aures Tic - Jose Zambudio <jose@aurestic.es>
|
|
6
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
from requests import Session
|
|
10
|
+
|
|
11
|
+
from odoo import _, api, fields, models
|
|
12
|
+
from odoo.exceptions import UserError
|
|
13
|
+
|
|
14
|
+
_logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from zeep import Client
|
|
18
|
+
from zeep.plugins import HistoryPlugin
|
|
19
|
+
from zeep.transports import Transport
|
|
20
|
+
except (ImportError, IOError) as err:
|
|
21
|
+
_logger.debug(err)
|
|
22
|
+
|
|
23
|
+
AEAT_DATE_FORMAT = "%d-%m-%Y"
|
|
24
|
+
AEAT_STATES = [
|
|
25
|
+
("not_sent", "Not sent"),
|
|
26
|
+
("sent", "Sent"),
|
|
27
|
+
("sent_w_errors", "Accepted with errors"),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def round_by_keys(elem, search_keys, prec=2):
|
|
32
|
+
"""This uses ``round`` method directly as if has been tested that Odoo's
|
|
33
|
+
``float_round`` still returns incorrect amounts for certain values. Try
|
|
34
|
+
3 units x 3,77 €/unit with 10% tax and you will be hit by the error
|
|
35
|
+
(on regular x86 architectures)."""
|
|
36
|
+
if isinstance(elem, dict):
|
|
37
|
+
for key, value in elem.items():
|
|
38
|
+
if key in search_keys:
|
|
39
|
+
elem[key] = round(elem[key], prec)
|
|
40
|
+
else:
|
|
41
|
+
round_by_keys(value, search_keys)
|
|
42
|
+
elif isinstance(elem, list):
|
|
43
|
+
for value in elem:
|
|
44
|
+
round_by_keys(value, search_keys)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class AeatMixin(models.AbstractModel):
|
|
48
|
+
_name = "aeat.mixin"
|
|
49
|
+
_description = "Aeat Mixin"
|
|
50
|
+
|
|
51
|
+
aeat_state = fields.Selection(
|
|
52
|
+
selection=AEAT_STATES,
|
|
53
|
+
string="AEAT send state",
|
|
54
|
+
default="not_sent",
|
|
55
|
+
readonly=True,
|
|
56
|
+
copy=False,
|
|
57
|
+
help="Indicates the state of this document in relation with the "
|
|
58
|
+
"presentation at the AEAT",
|
|
59
|
+
)
|
|
60
|
+
aeat_send_error = fields.Text(
|
|
61
|
+
string="AEAT Send Error",
|
|
62
|
+
readonly=True,
|
|
63
|
+
copy=False,
|
|
64
|
+
)
|
|
65
|
+
aeat_send_failed = fields.Boolean(
|
|
66
|
+
string="SII send failed",
|
|
67
|
+
copy=False,
|
|
68
|
+
help="Indicates that the last attempt to communicate this document to "
|
|
69
|
+
"the SII has failed. See SII return for details",
|
|
70
|
+
)
|
|
71
|
+
aeat_header_sent = fields.Text(
|
|
72
|
+
string="AEAT last header sent",
|
|
73
|
+
copy=False,
|
|
74
|
+
readonly=True,
|
|
75
|
+
)
|
|
76
|
+
aeat_content_sent = fields.Text(
|
|
77
|
+
string="AEAT last content sent",
|
|
78
|
+
copy=False,
|
|
79
|
+
readonly=True,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def _get_document_date(self):
|
|
83
|
+
raise NotImplementedError()
|
|
84
|
+
|
|
85
|
+
def _get_document_serial_number(self):
|
|
86
|
+
raise NotImplementedError()
|
|
87
|
+
|
|
88
|
+
def _aeat_get_partner(self):
|
|
89
|
+
raise NotImplementedError()
|
|
90
|
+
|
|
91
|
+
def _get_document_fiscal_date(self):
|
|
92
|
+
raise NotImplementedError()
|
|
93
|
+
|
|
94
|
+
def _get_document_fiscal_year(self):
|
|
95
|
+
return fields.Date.to_date(self._get_document_fiscal_date()).year
|
|
96
|
+
|
|
97
|
+
def _change_date_format(self, date):
|
|
98
|
+
datetimeobject = fields.Date.to_date(date)
|
|
99
|
+
new_date = datetimeobject.strftime(AEAT_DATE_FORMAT)
|
|
100
|
+
return new_date
|
|
101
|
+
|
|
102
|
+
def _get_document_period(self):
|
|
103
|
+
return "%02d" % fields.Date.to_date(self._get_document_fiscal_date()).month
|
|
104
|
+
|
|
105
|
+
def _is_aeat_simplified_invoice(self):
|
|
106
|
+
"""Inheritable method to allow control when an
|
|
107
|
+
invoice are simplified or normal"""
|
|
108
|
+
return self._aeat_get_partner().aeat_simplified_invoice
|
|
109
|
+
|
|
110
|
+
def _get_document_amount_total(self):
|
|
111
|
+
raise NotImplementedError()
|
|
112
|
+
|
|
113
|
+
def _get_mapping_key(self):
|
|
114
|
+
raise NotImplementedError()
|
|
115
|
+
|
|
116
|
+
def _get_aeat_invoice_dict(self):
|
|
117
|
+
raise NotImplementedError()
|
|
118
|
+
|
|
119
|
+
@api.model
|
|
120
|
+
def _get_aeat_taxes_map(self, codes, date):
|
|
121
|
+
raise NotImplementedError()
|
|
122
|
+
|
|
123
|
+
def _get_valid_document_states(self):
|
|
124
|
+
raise NotImplementedError()
|
|
125
|
+
|
|
126
|
+
def _get_aeat_header(self, tipo_comunicacion=False, cancellation=False):
|
|
127
|
+
raise NotImplementedError()
|
|
128
|
+
|
|
129
|
+
def _bind_service(self, client, port_name, address=None):
|
|
130
|
+
raise NotImplementedError()
|
|
131
|
+
|
|
132
|
+
def _connect_params_aeat(self, mapping_key):
|
|
133
|
+
raise NotImplementedError()
|
|
134
|
+
|
|
135
|
+
def _connect_aeat(self, mapping_key):
|
|
136
|
+
self.ensure_one()
|
|
137
|
+
public_crt, private_key = self.env["l10n.es.aeat.certificate"].get_certificates(
|
|
138
|
+
company=self.company_id
|
|
139
|
+
)
|
|
140
|
+
params = self._connect_params_aeat(mapping_key)
|
|
141
|
+
session = Session()
|
|
142
|
+
session.cert = (public_crt, private_key)
|
|
143
|
+
transport = Transport(session=session)
|
|
144
|
+
history = HistoryPlugin()
|
|
145
|
+
client = Client(wsdl=params["wsdl"], transport=transport, plugins=[history])
|
|
146
|
+
return self._bind_service(client, params["port_name"], params["address"])
|
|
147
|
+
|
|
148
|
+
def _get_aeat_country_code(self):
|
|
149
|
+
self.ensure_one()
|
|
150
|
+
return self._aeat_get_partner()._parse_aeat_vat_info()[0]
|
|
151
|
+
|
|
152
|
+
def _aeat_check_exceptions(self):
|
|
153
|
+
"""Inheritable method for exceptions control when sending AEAT documentss."""
|
|
154
|
+
self.ensure_one()
|
|
155
|
+
partner = self._aeat_get_partner()
|
|
156
|
+
country_code = self._get_aeat_country_code()
|
|
157
|
+
is_simplified_invoice = self._is_aeat_simplified_invoice()
|
|
158
|
+
if country_code == "ES" and not partner.vat and not is_simplified_invoice:
|
|
159
|
+
raise UserError(_("The partner has not a VAT configured."))
|
|
160
|
+
if not self.company_id.chart_template_id:
|
|
161
|
+
raise UserError(
|
|
162
|
+
_("You have to select what account chart template use this" " company.")
|
|
163
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright 2024 Aures Tic - Jose Zambudio <jose@aurestic.es>
|
|
2
|
+
# Copyright 2024 Aures TIC - Almudena de La Puente <almudena@aurestic.es>
|
|
3
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
4
|
+
|
|
5
|
+
from odoo import fields, models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AeatTaxAgency(models.Model):
|
|
9
|
+
_inherit = "aeat.tax.agency"
|
|
10
|
+
|
|
11
|
+
verifactu_wsdl_out = fields.Char(string="VERI*FACTU WSDL")
|
|
12
|
+
verifactu_wsdl_out_test_address = fields.Char(string="VERI*FACTU Test Address")
|
|
13
|
+
verifactu_qr_base_url = fields.Char(string="VERI*FACTU QR Base URL")
|
|
14
|
+
verifactu_qr_base_url_test_address = fields.Char(
|
|
15
|
+
string="VERI*FACTU QR Base URL Test"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
def _connect_params_verifactu(self, company):
|
|
19
|
+
self.ensure_one()
|
|
20
|
+
wsdl_field = "verifactu_wsdl_out"
|
|
21
|
+
wsdl_test_field = wsdl_field + "_test_address"
|
|
22
|
+
port_name = "SistemaVerifactu"
|
|
23
|
+
address = self[wsdl_test_field] if company.verifactu_test else False
|
|
24
|
+
if not address and company.verifactu_test:
|
|
25
|
+
port_name += "Pruebas"
|
|
26
|
+
return {
|
|
27
|
+
"wsdl": self[wsdl_field],
|
|
28
|
+
"address": address,
|
|
29
|
+
"port_name": port_name,
|
|
30
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright 2024 Aures TIC - Jose Zambudio
|
|
2
|
+
# Copyright 2025 Tecnativa - Pedro M. Baeza
|
|
3
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
4
|
+
|
|
5
|
+
from odoo import fields, models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ResCompany(models.Model):
|
|
9
|
+
_inherit = "res.company"
|
|
10
|
+
|
|
11
|
+
verifactu_enabled = fields.Boolean(string="VERI*FACTU enabled", tracking=True)
|
|
12
|
+
verifactu_test = fields.Boolean(
|
|
13
|
+
string="VERI*FACTU test environment?", tracking=True
|
|
14
|
+
)
|
|
15
|
+
verifactu_description = fields.Text(
|
|
16
|
+
string="VERI*FACTU description",
|
|
17
|
+
default="/",
|
|
18
|
+
help="The description for VERI*FACTU invoices if not set",
|
|
19
|
+
tracking=True,
|
|
20
|
+
)
|
|
21
|
+
verifactu_developer_id = fields.Many2one(
|
|
22
|
+
comodel_name="verifactu.developer",
|
|
23
|
+
string="VERI*FACTU developer",
|
|
24
|
+
ondelete="restrict",
|
|
25
|
+
tracking=True,
|
|
26
|
+
)
|
|
27
|
+
verifactu_start_date = fields.Date(
|
|
28
|
+
string="VERI*FACTU start date",
|
|
29
|
+
help="If this field is set, the VERI*FACTU won't be enabled on invoices with "
|
|
30
|
+
"lower invoice date. If not set, it can be enabled on all invoice dates",
|
|
31
|
+
tracking=True,
|
|
32
|
+
)
|
|
33
|
+
verifactu_chaining_id = fields.Many2one(
|
|
34
|
+
comodel_name="verifactu.chaining",
|
|
35
|
+
string="VERI*FACTU chaining",
|
|
36
|
+
ondelete="restrict",
|
|
37
|
+
tracking=True,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def write(self, vals):
|
|
41
|
+
# As the compute is not triggered automatically, we need to manually trigger it
|
|
42
|
+
# rewriting the flag at journal level.
|
|
43
|
+
res = super().write(vals)
|
|
44
|
+
if vals.get("verifactu_enabled"):
|
|
45
|
+
self.env["account.journal"].search(
|
|
46
|
+
[("company_id", "in", self.ids), ("type", "=", "sale")]
|
|
47
|
+
).verifactu_enabled = True
|
|
48
|
+
return res
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright 2024 Aures TIC - Jose Zambudio
|
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
3
|
+
|
|
4
|
+
from odoo import api, fields, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ResPartner(models.Model):
|
|
8
|
+
_inherit = "res.partner"
|
|
9
|
+
|
|
10
|
+
verifactu_enabled = fields.Boolean(
|
|
11
|
+
compute="_compute_aeat_sending_enabled", string="VERI*FACTU enabled"
|
|
12
|
+
)
|
|
13
|
+
aeat_simplified_invoice = fields.Boolean(
|
|
14
|
+
string="Simplified invoices in AEAT?",
|
|
15
|
+
help="Checking this mark, invoices done to this partner will be "
|
|
16
|
+
"sent to AEAT as simplified invoices.",
|
|
17
|
+
)
|
|
18
|
+
aeat_sending_enabled = fields.Boolean(
|
|
19
|
+
compute="_compute_aeat_sending_enabled",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
@api.depends("company_id")
|
|
23
|
+
def _compute_aeat_sending_enabled(self):
|
|
24
|
+
verifactu_enabled = any(self.env.companies.mapped("verifactu_enabled"))
|
|
25
|
+
for partner in self:
|
|
26
|
+
partner.aeat_sending_enabled = False
|
|
27
|
+
partner.verifactu_enabled = (
|
|
28
|
+
partner.company_id.verifactu_enabled
|
|
29
|
+
if partner.company_id
|
|
30
|
+
else verifactu_enabled
|
|
31
|
+
)
|
|
32
|
+
if partner.verifactu_enabled:
|
|
33
|
+
partner.aeat_sending_enabled = True
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright 2024 Aures TIC - Almudena de La Puente <almudena@aurestic.es>
|
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
3
|
+
|
|
4
|
+
from odoo import fields, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class VerifactuChaining(models.Model):
|
|
8
|
+
_name = "verifactu.chaining"
|
|
9
|
+
_inherit = "mail.thread"
|
|
10
|
+
_description = "VERI*FACTU chaining"
|
|
11
|
+
|
|
12
|
+
name = fields.Char(required=True, tracking=True)
|
|
13
|
+
last_verifactu_invoice_entry_id = fields.Many2one(
|
|
14
|
+
comodel_name="verifactu.invoice.entry",
|
|
15
|
+
string="Last invoice entry",
|
|
16
|
+
help="Reference to the last VERI*FACTU invoice entry for this company. "
|
|
17
|
+
"Used for atomic chaining.",
|
|
18
|
+
copy=False,
|
|
19
|
+
readonly=True,
|
|
20
|
+
)
|
|
21
|
+
sif_id = fields.Char(string="SIF ID", required=True, tracking=True)
|
|
22
|
+
installation_number = fields.Integer(default=1, required=True, tracking=True)
|
|
23
|
+
|
|
24
|
+
_sql_constraints = [
|
|
25
|
+
(
|
|
26
|
+
"verifactu_chaining_name_uniq",
|
|
27
|
+
"unique(name)",
|
|
28
|
+
"A chaining with the same name already exists!",
|
|
29
|
+
)
|
|
30
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Copyright 2024 Aures TIC - Almudena de La Puente
|
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
3
|
+
|
|
4
|
+
from odoo import fields, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class VerifactuDeveloper(models.Model):
|
|
8
|
+
_name = "verifactu.developer"
|
|
9
|
+
_description = "VERI*FACTU developer"
|
|
10
|
+
_inherit = "mail.thread"
|
|
11
|
+
|
|
12
|
+
name = fields.Char(string="Developer Name", required=True, tracking=True)
|
|
13
|
+
vat = fields.Char(string="Developer VAT", required=True, tracking=True)
|
|
14
|
+
sif_name = fields.Char("SIF Name", required=True, tracking=True)
|
|
15
|
+
version = fields.Char(default="1.0", required=True, tracking=True)
|
|
16
|
+
responsibility_declaration = fields.Binary(attachment=True, copy=False)
|