odoo-addon-l10n-br-fiscal 17.0.1.0.0.11__py3-none-any.whl → 18.0.5.0.0.1__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-br-fiscal might be problematic. Click here for more details.
- odoo/addons/l10n_br_fiscal/README.rst +10 -10
- odoo/addons/l10n_br_fiscal/__init__.py +1 -0
- odoo/addons/l10n_br_fiscal/__manifest__.py +3 -2
- odoo/addons/l10n_br_fiscal/constants/fiscal.py +51 -24
- odoo/addons/l10n_br_fiscal/data/ir_cron.xml +19 -34
- odoo/addons/l10n_br_fiscal/data/l10n_br_fiscal.document.type.csv +1 -0
- odoo/addons/l10n_br_fiscal/data/l10n_br_fiscal_cfop_data.xml +0 -2
- odoo/addons/l10n_br_fiscal/data/l10n_br_fiscal_data.xml +6 -8
- odoo/addons/l10n_br_fiscal/data/l10n_br_fiscal_icms_tax_definition_data.xml +4055 -4033
- odoo/addons/l10n_br_fiscal/data/l10n_br_fiscal_server_action.xml +0 -2
- odoo/addons/l10n_br_fiscal/data/l10n_br_fiscal_tax_icms_data.xml +54 -50
- odoo/addons/l10n_br_fiscal/data/operation_data.xml +198 -182
- odoo/addons/l10n_br_fiscal/data/product_data.xml +0 -2
- odoo/addons/l10n_br_fiscal/data/res_partner_data.xml +0 -2
- odoo/addons/l10n_br_fiscal/data/simplified_tax_data.xml +0 -2
- odoo/addons/l10n_br_fiscal/data/uom_data.xml +0 -2
- odoo/addons/l10n_br_fiscal/demo/city_taxation_code_demo.xml +0 -2
- odoo/addons/l10n_br_fiscal/demo/company_demo.xml +0 -3
- odoo/addons/l10n_br_fiscal/demo/fiscal_document_demo.xml +40 -228
- odoo/addons/l10n_br_fiscal/demo/fiscal_document_nfse_demo.xml +0 -5
- odoo/addons/l10n_br_fiscal/demo/fiscal_operation_demo.xml +2 -4
- odoo/addons/l10n_br_fiscal/demo/icms_tax_definition_demo.xml +0 -2
- odoo/addons/l10n_br_fiscal/demo/partner_demo.xml +0 -2
- odoo/addons/l10n_br_fiscal/demo/product_demo.xml +0 -1705
- odoo/addons/l10n_br_fiscal/demo/res_users_demo.xml +0 -2
- odoo/addons/l10n_br_fiscal/hooks.py +68 -0
- odoo/addons/l10n_br_fiscal/i18n/l10n_br_fiscal.pot +232 -201
- odoo/addons/l10n_br_fiscal/i18n/pt_BR.po +1272 -1344
- odoo/addons/l10n_br_fiscal/migrations/18.0.2.0.0/pre-migration.py +25 -0
- odoo/addons/l10n_br_fiscal/migrations/18.0.3.0.0/pre-migration.py +30 -0
- odoo/addons/l10n_br_fiscal/models/cfop.py +1 -1
- odoo/addons/l10n_br_fiscal/models/cnae.py +2 -2
- odoo/addons/l10n_br_fiscal/models/comment.py +12 -27
- odoo/addons/l10n_br_fiscal/models/cst.py +2 -2
- odoo/addons/l10n_br_fiscal/models/data_abstract.py +11 -24
- odoo/addons/l10n_br_fiscal/models/document.py +57 -9
- odoo/addons/l10n_br_fiscal/models/document_line.py +65 -5
- odoo/addons/l10n_br_fiscal/models/document_line_mixin.py +118 -38
- odoo/addons/l10n_br_fiscal/models/document_line_mixin_methods.py +261 -295
- odoo/addons/l10n_br_fiscal/models/document_mixin.py +8 -16
- odoo/addons/l10n_br_fiscal/models/document_mixin_methods.py +49 -177
- odoo/addons/l10n_br_fiscal/models/document_related.py +1 -1
- odoo/addons/l10n_br_fiscal/models/document_serie.py +35 -2
- odoo/addons/l10n_br_fiscal/models/document_type.py +0 -1
- odoo/addons/l10n_br_fiscal/models/ibpt.py +1 -1
- odoo/addons/l10n_br_fiscal/models/icms_regulation.py +1 -1
- odoo/addons/l10n_br_fiscal/models/invalidate_number.py +6 -7
- odoo/addons/l10n_br_fiscal/models/legal_nature.py +1 -1
- odoo/addons/l10n_br_fiscal/models/nbm.py +2 -2
- odoo/addons/l10n_br_fiscal/models/nbs.py +4 -4
- odoo/addons/l10n_br_fiscal/models/ncm.py +4 -4
- odoo/addons/l10n_br_fiscal/models/operation.py +2 -2
- odoo/addons/l10n_br_fiscal/models/operation_dashboard.py +3 -2
- odoo/addons/l10n_br_fiscal/models/operation_line.py +1 -1
- odoo/addons/l10n_br_fiscal/models/partner_profile.py +7 -1
- odoo/addons/l10n_br_fiscal/models/product_template.py +1 -1
- odoo/addons/l10n_br_fiscal/models/res_partner.py +9 -0
- odoo/addons/l10n_br_fiscal/models/tax.py +12 -4
- odoo/addons/l10n_br_fiscal/models/tax_group.py +6 -6
- odoo/addons/l10n_br_fiscal/models/tax_pis_cofins.py +4 -4
- odoo/addons/l10n_br_fiscal/models/tax_pis_cofins_base.py +3 -3
- odoo/addons/l10n_br_fiscal/models/tax_pis_cofins_credit.py +3 -3
- odoo/addons/l10n_br_fiscal/security/fiscal_security.xml +6 -18
- odoo/addons/l10n_br_fiscal/security/ir.model.access.csv +1 -2
- odoo/addons/l10n_br_fiscal/static/description/index.html +8 -8
- odoo/addons/l10n_br_fiscal/tests/__init__.py +1 -0
- odoo/addons/l10n_br_fiscal/tests/test_document_edition.py +200 -14
- odoo/addons/l10n_br_fiscal/tests/test_fiscal_document_generic.py +16 -44
- odoo/addons/l10n_br_fiscal/tests/test_fiscal_document_nfse.py +0 -5
- odoo/addons/l10n_br_fiscal/tests/test_fiscal_document_serie.py +60 -0
- odoo/addons/l10n_br_fiscal/tests/test_tax_benefit.py +2 -5
- odoo/addons/l10n_br_fiscal/views/cest_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/cfop_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/city_taxation_code.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/cnae_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/comment_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/cst_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/document_line_mixin_view.xml +1 -1
- odoo/addons/l10n_br_fiscal/views/document_line_view.xml +6 -4
- odoo/addons/l10n_br_fiscal/views/document_related_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/document_serie_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/document_type_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/document_view.xml +29 -29
- odoo/addons/l10n_br_fiscal/views/icms_regulation_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/icms_relief_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/invalidate_number_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/l10n_br_fiscal_action.xml +36 -36
- odoo/addons/l10n_br_fiscal/views/l10n_br_fiscal_menu.xml +0 -9
- odoo/addons/l10n_br_fiscal/views/legal_nature_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/nbm_view.xml +5 -5
- odoo/addons/l10n_br_fiscal/views/nbs_view.xml +5 -5
- odoo/addons/l10n_br_fiscal/views/ncm_view.xml +5 -5
- odoo/addons/l10n_br_fiscal/views/operation_dashboard_view.xml +7 -8
- odoo/addons/l10n_br_fiscal/views/operation_line_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/operation_view.xml +4 -4
- odoo/addons/l10n_br_fiscal/views/partner_profile_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/product_genre_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/product_product_view.xml +38 -11
- odoo/addons/l10n_br_fiscal/views/product_template_view.xml +22 -9
- odoo/addons/l10n_br_fiscal/views/res_config_settings_view.xml +8 -8
- odoo/addons/l10n_br_fiscal/views/res_partner_view.xml +9 -0
- odoo/addons/l10n_br_fiscal/views/service_type_view.xml +5 -5
- odoo/addons/l10n_br_fiscal/views/simplified_tax_range_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/simplified_tax_view.xml +4 -4
- odoo/addons/l10n_br_fiscal/views/tax_definition_view.xml +4 -4
- odoo/addons/l10n_br_fiscal/views/tax_estimate_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_group_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_ipi_control_seal_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_ipi_guideline_class_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_ipi_guideline_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_pis_cofins_base_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_pis_cofins_credit_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_pis_cofins_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/tax_view.xml +2 -2
- odoo/addons/l10n_br_fiscal/views/uom_uom.xml +2 -2
- odoo/addons/l10n_br_fiscal/wizards/base_wizard_mixin.py +1 -1
- {odoo_addon_l10n_br_fiscal-17.0.1.0.0.11.dist-info → odoo_addon_l10n_br_fiscal-18.0.5.0.0.1.dist-info}/METADATA +16 -16
- {odoo_addon_l10n_br_fiscal-17.0.1.0.0.11.dist-info → odoo_addon_l10n_br_fiscal-18.0.5.0.0.1.dist-info}/RECORD +120 -116
- {odoo_addon_l10n_br_fiscal-17.0.1.0.0.11.dist-info → odoo_addon_l10n_br_fiscal-18.0.5.0.0.1.dist-info}/WHEEL +0 -0
- {odoo_addon_l10n_br_fiscal-17.0.1.0.0.11.dist-info → odoo_addon_l10n_br_fiscal-18.0.5.0.0.1.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,6 @@ from ..constants.fiscal import (
|
|
|
8
8
|
DOCUMENT_ISSUER,
|
|
9
9
|
DOCUMENT_ISSUER_COMPANY,
|
|
10
10
|
FINAL_CUSTOMER,
|
|
11
|
-
FINAL_CUSTOMER_YES,
|
|
12
11
|
FISCAL_COMMENT_DOCUMENT,
|
|
13
12
|
NFE_IND_PRES,
|
|
14
13
|
NFE_IND_PRES_DEFAULT,
|
|
@@ -48,10 +47,6 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
48
47
|
def _date_server_format(self):
|
|
49
48
|
return fields.Datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
|
50
49
|
|
|
51
|
-
@api.model
|
|
52
|
-
def _default_operation(self):
|
|
53
|
-
return False
|
|
54
|
-
|
|
55
50
|
@api.model
|
|
56
51
|
def _operation_domain(self):
|
|
57
52
|
domain = (
|
|
@@ -66,7 +61,6 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
66
61
|
comodel_name="l10n_br_fiscal.operation",
|
|
67
62
|
string="Operation",
|
|
68
63
|
domain=lambda self: self._operation_domain(),
|
|
69
|
-
default=_default_operation,
|
|
70
64
|
)
|
|
71
65
|
|
|
72
66
|
operation_name = fields.Char(
|
|
@@ -105,14 +99,10 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
105
99
|
store=True,
|
|
106
100
|
)
|
|
107
101
|
|
|
108
|
-
fiscal_additional_data = fields.Text()
|
|
109
|
-
|
|
110
102
|
manual_fiscal_additional_data = fields.Text(
|
|
111
103
|
help="Fiscal Additional data manually entered by user",
|
|
112
104
|
)
|
|
113
105
|
|
|
114
|
-
customer_additional_data = fields.Text()
|
|
115
|
-
|
|
116
106
|
manual_customer_additional_data = fields.Text(
|
|
117
107
|
help="Customer Additional data manually entered by user",
|
|
118
108
|
)
|
|
@@ -120,7 +110,11 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
120
110
|
ind_final = fields.Selection(
|
|
121
111
|
selection=FINAL_CUSTOMER,
|
|
122
112
|
string="Final Consumption Operation",
|
|
123
|
-
|
|
113
|
+
compute="_compute_ind_final",
|
|
114
|
+
inverse="_inverse_ind_final",
|
|
115
|
+
store=True,
|
|
116
|
+
precompute=True,
|
|
117
|
+
readonly=False,
|
|
124
118
|
)
|
|
125
119
|
|
|
126
120
|
currency_id = fields.Many2one(
|
|
@@ -135,7 +129,7 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
135
129
|
help="Amount without discount.",
|
|
136
130
|
)
|
|
137
131
|
|
|
138
|
-
|
|
132
|
+
fiscal_amount_untaxed = fields.Monetary(
|
|
139
133
|
compute="_compute_fiscal_amount",
|
|
140
134
|
store=True,
|
|
141
135
|
)
|
|
@@ -403,12 +397,12 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
403
397
|
store=True,
|
|
404
398
|
)
|
|
405
399
|
|
|
406
|
-
|
|
400
|
+
fiscal_amount_tax = fields.Monetary(
|
|
407
401
|
compute="_compute_fiscal_amount",
|
|
408
402
|
store=True,
|
|
409
403
|
)
|
|
410
404
|
|
|
411
|
-
|
|
405
|
+
fiscal_amount_total = fields.Monetary(
|
|
412
406
|
compute="_compute_fiscal_amount",
|
|
413
407
|
store=True,
|
|
414
408
|
)
|
|
@@ -501,14 +495,12 @@ class FiscalDocumentMixin(models.AbstractModel):
|
|
|
501
495
|
document_number = fields.Char(
|
|
502
496
|
copy=False,
|
|
503
497
|
index=True,
|
|
504
|
-
unaccent=False,
|
|
505
498
|
)
|
|
506
499
|
|
|
507
500
|
document_key = fields.Char(
|
|
508
501
|
string="Key",
|
|
509
502
|
copy=False,
|
|
510
503
|
index=True,
|
|
511
|
-
unaccent=False,
|
|
512
504
|
)
|
|
513
505
|
|
|
514
506
|
key_random_code = fields.Char(string="Document Key Random Code")
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
from odoo import api, models
|
|
5
5
|
|
|
6
6
|
from ..constants.fiscal import (
|
|
7
|
-
COMMENT_TYPE_COMMERCIAL,
|
|
8
|
-
COMMENT_TYPE_FISCAL,
|
|
9
7
|
DOCUMENT_ISSUER_COMPANY,
|
|
10
8
|
)
|
|
11
9
|
|
|
@@ -75,7 +73,8 @@ class FiscalDocumentMixinMethods(models.AbstractModel):
|
|
|
75
73
|
def _get_amount_fields(self):
|
|
76
74
|
"""Get all fields with 'amount_' prefix"""
|
|
77
75
|
fields = self.env["l10n_br_fiscal.document.mixin"]._fields.keys()
|
|
78
|
-
|
|
76
|
+
prefixes = ("amount_", "fiscal_amount_")
|
|
77
|
+
amount_fields = [f for f in fields if f.startswith(prefixes)]
|
|
79
78
|
return amount_fields
|
|
80
79
|
|
|
81
80
|
@api.depends("document_serie_id", "issuer")
|
|
@@ -89,7 +88,11 @@ class FiscalDocumentMixinMethods(models.AbstractModel):
|
|
|
89
88
|
@api.depends("document_type_id", "issuer")
|
|
90
89
|
def _compute_document_serie_id(self):
|
|
91
90
|
for doc in self:
|
|
92
|
-
if
|
|
91
|
+
if (
|
|
92
|
+
not doc.document_serie_id
|
|
93
|
+
and doc.document_type_id
|
|
94
|
+
and doc.issuer == DOCUMENT_ISSUER_COMPANY
|
|
95
|
+
):
|
|
93
96
|
doc.document_serie_id = doc.document_type_id.get_document_serie(
|
|
94
97
|
doc.company_id, doc.fiscal_operation_id
|
|
95
98
|
)
|
|
@@ -159,30 +162,6 @@ class FiscalDocumentMixinMethods(models.AbstractModel):
|
|
|
159
162
|
|
|
160
163
|
doc.update(values)
|
|
161
164
|
|
|
162
|
-
def __document_comment_vals(self):
|
|
163
|
-
return {
|
|
164
|
-
"user": self.env.user,
|
|
165
|
-
"ctx": self._context,
|
|
166
|
-
"doc": self,
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
def _document_comment(self):
|
|
170
|
-
for d in self:
|
|
171
|
-
# Fiscal Comments
|
|
172
|
-
d.fiscal_additional_data = d.comment_ids.filtered(
|
|
173
|
-
lambda c: c.comment_type == COMMENT_TYPE_FISCAL
|
|
174
|
-
).compute_message(
|
|
175
|
-
d.__document_comment_vals(), d.manual_fiscal_additional_data
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
# Commercial Comments
|
|
179
|
-
d.customer_additional_data = d.comment_ids.filtered(
|
|
180
|
-
lambda c: c.comment_type == COMMENT_TYPE_COMMERCIAL
|
|
181
|
-
).compute_message(
|
|
182
|
-
d.__document_comment_vals(), d.manual_customer_additional_data
|
|
183
|
-
)
|
|
184
|
-
d.fiscal_line_ids._document_comment()
|
|
185
|
-
|
|
186
165
|
def _get_fiscal_partner(self):
|
|
187
166
|
"""
|
|
188
167
|
Hook method to determine the fiscal partner for the document.
|
|
@@ -199,14 +178,22 @@ class FiscalDocumentMixinMethods(models.AbstractModel):
|
|
|
199
178
|
self.ensure_one()
|
|
200
179
|
return self.partner_id
|
|
201
180
|
|
|
202
|
-
@api.
|
|
203
|
-
def
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
181
|
+
@api.depends("partner_id")
|
|
182
|
+
def _compute_ind_final(self):
|
|
183
|
+
for doc in self:
|
|
184
|
+
partner = doc._get_fiscal_partner()
|
|
185
|
+
if partner:
|
|
186
|
+
doc.ind_final = partner.ind_final
|
|
187
|
+
else:
|
|
188
|
+
# Default Value
|
|
189
|
+
doc.ind_final = "1" # Yes
|
|
190
|
+
|
|
191
|
+
@api.onchange("ind_final")
|
|
192
|
+
def _inverse_ind_final(self):
|
|
193
|
+
for doc in self:
|
|
194
|
+
for line in doc._get_amount_lines():
|
|
195
|
+
if line.ind_final != doc.ind_final:
|
|
196
|
+
line.ind_final = doc.ind_final
|
|
210
197
|
|
|
211
198
|
@api.depends("fiscal_operation_id")
|
|
212
199
|
def _compute_operation_name(self):
|
|
@@ -224,152 +211,37 @@ class FiscalDocumentMixinMethods(models.AbstractModel):
|
|
|
224
211
|
elif doc.comment_ids is None:
|
|
225
212
|
doc.comment_ids = []
|
|
226
213
|
|
|
227
|
-
def
|
|
228
|
-
for record in self
|
|
229
|
-
if (
|
|
214
|
+
def _distribute_amount_to_lines(self, amount_field_name, line_field_name):
|
|
215
|
+
for record in self:
|
|
216
|
+
if not (
|
|
230
217
|
record.delivery_costs == "total"
|
|
231
218
|
or record.force_compute_delivery_costs_by_total
|
|
232
219
|
):
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
record.
|
|
243
|
-
|
|
244
|
-
- sum(
|
|
245
|
-
line.freight_value
|
|
246
|
-
for line in record._get_product_amount_lines()[:-1]
|
|
247
|
-
)
|
|
248
|
-
)
|
|
249
|
-
else:
|
|
250
|
-
amount_total = sum(
|
|
251
|
-
record._get_product_amount_lines().mapped("price_gross")
|
|
252
|
-
)
|
|
253
|
-
for line in record._get_product_amount_lines()[:-1]:
|
|
254
|
-
if line.price_gross and amount_total:
|
|
255
|
-
line.freight_value = amount_freight_value * (
|
|
256
|
-
line.price_gross / amount_total
|
|
257
|
-
)
|
|
258
|
-
record._get_product_amount_lines()[-1].freight_value = (
|
|
259
|
-
amount_freight_value
|
|
260
|
-
- sum(
|
|
261
|
-
line.freight_value
|
|
262
|
-
for line in record._get_product_amount_lines()[:-1]
|
|
263
|
-
)
|
|
220
|
+
continue
|
|
221
|
+
lines = record._get_product_amount_lines()
|
|
222
|
+
if not lines:
|
|
223
|
+
continue
|
|
224
|
+
amount_to_distribute = record[amount_field_name]
|
|
225
|
+
total_gross = sum(lines.mapped("price_gross"))
|
|
226
|
+
if total_gross > 0:
|
|
227
|
+
distributed_amount = 0
|
|
228
|
+
for line in lines[:-1]:
|
|
229
|
+
proportional_amount = record.currency_id.round(
|
|
230
|
+
amount_to_distribute * (line.price_gross / total_gross)
|
|
264
231
|
)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
)
|
|
232
|
+
line[line_field_name] = proportional_amount
|
|
233
|
+
distributed_amount += proportional_amount
|
|
234
|
+
lines[-1][line_field_name] = amount_to_distribute - distributed_amount
|
|
235
|
+
else:
|
|
236
|
+
lines.write({line_field_name: 0.0})
|
|
237
|
+
if lines:
|
|
238
|
+
lines[0][line_field_name] = amount_to_distribute
|
|
239
|
+
|
|
240
|
+
def _inverse_amount_freight(self):
|
|
241
|
+
self._distribute_amount_to_lines("amount_freight_value", "freight_value")
|
|
276
242
|
|
|
277
243
|
def _inverse_amount_insurance(self):
|
|
278
|
-
|
|
279
|
-
if (
|
|
280
|
-
record.delivery_costs == "total"
|
|
281
|
-
or record.force_compute_delivery_costs_by_total
|
|
282
|
-
):
|
|
283
|
-
amount_insurance_value = record.amount_insurance_value
|
|
284
|
-
if all(record._get_product_amount_lines().mapped("insurance_value")):
|
|
285
|
-
amount_insurance_old = sum(
|
|
286
|
-
record._get_product_amount_lines().mapped("insurance_value")
|
|
287
|
-
)
|
|
288
|
-
for line in record._get_product_amount_lines()[:-1]:
|
|
289
|
-
line.insurance_value = amount_insurance_value * (
|
|
290
|
-
line.insurance_value / amount_insurance_old
|
|
291
|
-
)
|
|
292
|
-
record._get_product_amount_lines()[-1].insurance_value = (
|
|
293
|
-
amount_insurance_value
|
|
294
|
-
- sum(
|
|
295
|
-
line.insurance_value
|
|
296
|
-
for line in record._get_product_amount_lines()[:-1]
|
|
297
|
-
)
|
|
298
|
-
)
|
|
299
|
-
else:
|
|
300
|
-
amount_total = sum(
|
|
301
|
-
record._get_product_amount_lines().mapped("price_gross")
|
|
302
|
-
)
|
|
303
|
-
for line in record._get_product_amount_lines()[:-1]:
|
|
304
|
-
if line.price_gross and amount_total:
|
|
305
|
-
line.insurance_value = amount_insurance_value * (
|
|
306
|
-
line.price_gross / amount_total
|
|
307
|
-
)
|
|
308
|
-
record._get_product_amount_lines()[-1].insurance_value = (
|
|
309
|
-
amount_insurance_value
|
|
310
|
-
- sum(
|
|
311
|
-
line.insurance_value
|
|
312
|
-
for line in record._get_product_amount_lines()[:-1]
|
|
313
|
-
)
|
|
314
|
-
)
|
|
315
|
-
for line in record._get_product_amount_lines():
|
|
316
|
-
line._onchange_fiscal_taxes()
|
|
317
|
-
record._fields["amount_total"].compute_value(record)
|
|
318
|
-
record.write(
|
|
319
|
-
{
|
|
320
|
-
name: value
|
|
321
|
-
for name, value in record._cache.items()
|
|
322
|
-
if record._fields[name].compute == "_amount_all"
|
|
323
|
-
and not record._fields[name].inverse
|
|
324
|
-
}
|
|
325
|
-
)
|
|
244
|
+
self._distribute_amount_to_lines("amount_insurance_value", "insurance_value")
|
|
326
245
|
|
|
327
246
|
def _inverse_amount_other(self):
|
|
328
|
-
|
|
329
|
-
if (
|
|
330
|
-
record.delivery_costs == "total"
|
|
331
|
-
or record.force_compute_delivery_costs_by_total
|
|
332
|
-
):
|
|
333
|
-
amount_other_value = record.amount_other_value
|
|
334
|
-
if all(record._get_product_amount_lines().mapped("other_value")):
|
|
335
|
-
amount_other_old = sum(
|
|
336
|
-
record._get_product_amount_lines().mapped("other_value")
|
|
337
|
-
)
|
|
338
|
-
for line in record._get_product_amount_lines()[:-1]:
|
|
339
|
-
line.other_value = amount_other_value * (
|
|
340
|
-
line.other_value / amount_other_old
|
|
341
|
-
)
|
|
342
|
-
record._get_product_amount_lines()[-1].other_value = (
|
|
343
|
-
amount_other_value
|
|
344
|
-
- sum(
|
|
345
|
-
line.other_value
|
|
346
|
-
for line in record._get_product_amount_lines()[:-1]
|
|
347
|
-
)
|
|
348
|
-
)
|
|
349
|
-
else:
|
|
350
|
-
amount_total = sum(
|
|
351
|
-
record._get_product_amount_lines().mapped("price_gross")
|
|
352
|
-
)
|
|
353
|
-
for line in record._get_product_amount_lines()[:-1]:
|
|
354
|
-
if line.price_gross and amount_total:
|
|
355
|
-
line.other_value = amount_other_value * (
|
|
356
|
-
line.price_gross / amount_total
|
|
357
|
-
)
|
|
358
|
-
record._get_product_amount_lines()[-1].other_value = (
|
|
359
|
-
amount_other_value
|
|
360
|
-
- sum(
|
|
361
|
-
line.other_value
|
|
362
|
-
for line in record._get_product_amount_lines()[:-1]
|
|
363
|
-
)
|
|
364
|
-
)
|
|
365
|
-
for line in record._get_product_amount_lines():
|
|
366
|
-
line._onchange_fiscal_taxes()
|
|
367
|
-
record._fields["amount_total"].compute_value(record)
|
|
368
|
-
record.write(
|
|
369
|
-
{
|
|
370
|
-
name: value
|
|
371
|
-
for name, value in record._cache.items()
|
|
372
|
-
if record._fields[name].compute == "_amount_all"
|
|
373
|
-
and not record._fields[name].inverse
|
|
374
|
-
}
|
|
375
|
-
)
|
|
247
|
+
self._distribute_amount_to_lines("amount_other_value", "other_value")
|
|
@@ -104,7 +104,7 @@ class DocumentRelated(models.Model):
|
|
|
104
104
|
return False
|
|
105
105
|
|
|
106
106
|
self.document_type_id = related.document_type_id
|
|
107
|
-
self.document_total_amount = related.
|
|
107
|
+
self.document_total_amount = related.fiscal_amount_total
|
|
108
108
|
self.document_total_weight = related.total_weight
|
|
109
109
|
|
|
110
110
|
if related.document_type_id.electronic:
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
|
4
4
|
|
|
5
5
|
from odoo import _, api, fields, models
|
|
6
|
+
from odoo.exceptions import ValidationError
|
|
6
7
|
|
|
7
8
|
from ..constants.fiscal import (
|
|
8
9
|
DOCUMENT_ISSUER_COMPANY,
|
|
9
10
|
FISCAL_IN_OUT,
|
|
10
11
|
FISCAL_IN_OUT_DEFAULT,
|
|
12
|
+
SITUACAO_EDOC_EM_DIGITACAO,
|
|
11
13
|
)
|
|
12
14
|
|
|
13
15
|
|
|
@@ -16,9 +18,9 @@ class DocumentSerie(models.Model):
|
|
|
16
18
|
_description = "Fiscal Document Serie"
|
|
17
19
|
_inherit = "l10n_br_fiscal.data.abstract"
|
|
18
20
|
|
|
19
|
-
code = fields.Char(size=3
|
|
21
|
+
code = fields.Char(size=3)
|
|
20
22
|
|
|
21
|
-
name = fields.Char(required=True
|
|
23
|
+
name = fields.Char(required=True)
|
|
22
24
|
|
|
23
25
|
active = fields.Boolean(default=True)
|
|
24
26
|
|
|
@@ -55,6 +57,14 @@ class DocumentSerie(models.Model):
|
|
|
55
57
|
string="Invalidate Number Range",
|
|
56
58
|
)
|
|
57
59
|
|
|
60
|
+
_sql_constraints = [
|
|
61
|
+
(
|
|
62
|
+
"document_serie_unique",
|
|
63
|
+
"unique(code, document_type_id, company_id)",
|
|
64
|
+
"A Fiscal Document Serie already exists for this document type.",
|
|
65
|
+
)
|
|
66
|
+
]
|
|
67
|
+
|
|
58
68
|
@api.model
|
|
59
69
|
def _create_sequence(self, values):
|
|
60
70
|
"""Create new no_gap entry sequence for every
|
|
@@ -83,6 +93,29 @@ class DocumentSerie(models.Model):
|
|
|
83
93
|
for record in self:
|
|
84
94
|
record.display_name = record.name
|
|
85
95
|
|
|
96
|
+
def write(self, vals):
|
|
97
|
+
if "internal_sequence_id" in vals:
|
|
98
|
+
raise ValidationError(_("You cannot change the internal sequence."))
|
|
99
|
+
if "code" in vals:
|
|
100
|
+
for serie in self:
|
|
101
|
+
if serie.code == vals["code"]:
|
|
102
|
+
continue
|
|
103
|
+
if self.env["l10n_br_fiscal.document"].search_count(
|
|
104
|
+
[
|
|
105
|
+
("document_serie_id", "=", serie.id),
|
|
106
|
+
("state_edoc", "not in", [SITUACAO_EDOC_EM_DIGITACAO]),
|
|
107
|
+
],
|
|
108
|
+
limit=1,
|
|
109
|
+
):
|
|
110
|
+
raise ValidationError(
|
|
111
|
+
_(
|
|
112
|
+
"You cannot change the code of a document "
|
|
113
|
+
"serie %(name)s that is already in use.",
|
|
114
|
+
name=serie.name,
|
|
115
|
+
)
|
|
116
|
+
)
|
|
117
|
+
return super().write(vals)
|
|
118
|
+
|
|
86
119
|
def _is_invalid_number(self, document_number):
|
|
87
120
|
self.ensure_one()
|
|
88
121
|
is_invalid_number = True
|
|
@@ -45,7 +45,7 @@ def _request(ws_url, params, ibpt_request_timeout=30):
|
|
|
45
45
|
elif response.status_code == requests.codes.service_unavailable:
|
|
46
46
|
raise UserError(_("IBPT Service Unavailable - {!r}").format(ws_url))
|
|
47
47
|
except Exception as e:
|
|
48
|
-
raise UserError(
|
|
48
|
+
raise UserError(f"Error in the request: {e}") from e
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def get_ibpt_product(
|
|
@@ -2101,7 +2101,7 @@ class ICMSRegulation(models.Model):
|
|
|
2101
2101
|
company.state_id != partner.state_id
|
|
2102
2102
|
and partner.ind_ie_dest == NFE_IND_IE_DEST_9
|
|
2103
2103
|
and operation_line.fiscal_operation_type == FISCAL_OUT
|
|
2104
|
-
or operation_line.fiscal_operation_id.fiscal_type
|
|
2104
|
+
or operation_line.fiscal_operation_id.fiscal_type != "return_in"
|
|
2105
2105
|
and operation_line.fiscal_operation_type == FISCAL_IN
|
|
2106
2106
|
):
|
|
2107
2107
|
domain = self._build_map_tax_def_domain(
|
|
@@ -68,8 +68,8 @@ class InvalidateNumber(models.Model):
|
|
|
68
68
|
|
|
69
69
|
state = fields.Selection(
|
|
70
70
|
selection=[
|
|
71
|
-
("draft",
|
|
72
|
-
("done",
|
|
71
|
+
("draft", "Draft"),
|
|
72
|
+
("done", "Done"),
|
|
73
73
|
],
|
|
74
74
|
string="Status",
|
|
75
75
|
readonly=True,
|
|
@@ -99,11 +99,10 @@ class InvalidateNumber(models.Model):
|
|
|
99
99
|
@api.depends("document_type_id", "document_serie_id", "number_start", "number_end")
|
|
100
100
|
def _compute_name(self):
|
|
101
101
|
for record in self:
|
|
102
|
-
record.name =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
end=record.number_end,
|
|
102
|
+
record.name = (
|
|
103
|
+
f"{record.document_type_id.type}/"
|
|
104
|
+
f"({record.document_serie_id.name}): "
|
|
105
|
+
f"{record.number_start} - {record.number_end}"
|
|
107
106
|
)
|
|
108
107
|
|
|
109
108
|
def unlink(self):
|
|
@@ -11,9 +11,9 @@ class Nbm(models.Model):
|
|
|
11
11
|
_inherit = "l10n_br_fiscal.data.product.abstract"
|
|
12
12
|
_description = "NBM"
|
|
13
13
|
|
|
14
|
-
code = fields.Char(size=12
|
|
14
|
+
code = fields.Char(size=12)
|
|
15
15
|
|
|
16
|
-
code_unmasked = fields.Char(size=10
|
|
16
|
+
code_unmasked = fields.Char(size=10)
|
|
17
17
|
|
|
18
18
|
product_tmpl_ids = fields.One2many(inverse_name="nbm_id")
|
|
19
19
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (C) 2019 Renato Lima - Akretion
|
|
2
2
|
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
|
3
3
|
|
|
4
|
-
from odoo import
|
|
4
|
+
from odoo import fields, models
|
|
5
5
|
|
|
6
6
|
from .ibpt import get_ibpt_service
|
|
7
7
|
|
|
@@ -15,9 +15,9 @@ class Nbs(models.Model):
|
|
|
15
15
|
]
|
|
16
16
|
_description = "NBS"
|
|
17
17
|
|
|
18
|
-
code = fields.Char(size=12
|
|
18
|
+
code = fields.Char(size=12)
|
|
19
19
|
|
|
20
|
-
code_unmasked = fields.Char(size=10
|
|
20
|
+
code_unmasked = fields.Char(size=10)
|
|
21
21
|
|
|
22
22
|
tax_estimate_ids = fields.One2many(inverse_name="nbs_id")
|
|
23
23
|
|
|
@@ -27,7 +27,7 @@ class Nbs(models.Model):
|
|
|
27
27
|
(
|
|
28
28
|
"fiscal_nbs_code_uniq",
|
|
29
29
|
"unique (code)",
|
|
30
|
-
|
|
30
|
+
"NBS already exists with this code!",
|
|
31
31
|
)
|
|
32
32
|
]
|
|
33
33
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (C) 2012 Renato Lima - Akretion <renato.lima@akretion.com.br>
|
|
2
2
|
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
|
3
3
|
|
|
4
|
-
from odoo import
|
|
4
|
+
from odoo import fields, models
|
|
5
5
|
|
|
6
6
|
from ..constants.fiscal import TAX_DOMAIN_II, TAX_DOMAIN_IPI
|
|
7
7
|
from .ibpt import get_ibpt_product
|
|
@@ -16,9 +16,9 @@ class Ncm(models.Model):
|
|
|
16
16
|
]
|
|
17
17
|
_description = "NCM"
|
|
18
18
|
|
|
19
|
-
code = fields.Char(size=10
|
|
19
|
+
code = fields.Char(size=10)
|
|
20
20
|
|
|
21
|
-
code_unmasked = fields.Char(size=8
|
|
21
|
+
code_unmasked = fields.Char(size=8)
|
|
22
22
|
|
|
23
23
|
exception = fields.Char(size=2)
|
|
24
24
|
|
|
@@ -70,7 +70,7 @@ class Ncm(models.Model):
|
|
|
70
70
|
(
|
|
71
71
|
"fiscal_ncm_code_exception_uniq",
|
|
72
72
|
"unique (code, exception)",
|
|
73
|
-
|
|
73
|
+
"NCM already exists with this code!",
|
|
74
74
|
)
|
|
75
75
|
]
|
|
76
76
|
|
|
@@ -98,7 +98,7 @@ class Operation(models.Model):
|
|
|
98
98
|
)
|
|
99
99
|
|
|
100
100
|
default_price_unit = fields.Selection(
|
|
101
|
-
selection=[("sale_price",
|
|
101
|
+
selection=[("sale_price", "Sale Price"), ("cost_price", "Cost Price")],
|
|
102
102
|
string="Default Price Unit?",
|
|
103
103
|
default="sale_price",
|
|
104
104
|
readonly=True,
|
|
@@ -173,7 +173,7 @@ class Operation(models.Model):
|
|
|
173
173
|
(
|
|
174
174
|
"fiscal_operation_code_uniq",
|
|
175
175
|
"unique (code)",
|
|
176
|
-
|
|
176
|
+
"Fiscal Operation already exists with this code!",
|
|
177
177
|
)
|
|
178
178
|
]
|
|
179
179
|
|
|
@@ -127,7 +127,7 @@ class Operation(models.Model):
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
def open_action(self):
|
|
130
|
-
"""
|
|
130
|
+
"""Return action based on type for related journals"""
|
|
131
131
|
|
|
132
132
|
_fiscal_type_map = {
|
|
133
133
|
"purchase": "in",
|
|
@@ -157,7 +157,8 @@ class Operation(models.Model):
|
|
|
157
157
|
}
|
|
158
158
|
)
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
xmlid = f"l10n_br_fiscal.{action_name}"
|
|
161
|
+
[action] = self.env.ref(xmlid).read()
|
|
161
162
|
action["context"] = ctx
|
|
162
163
|
action["domain"] = self._context.get("use_domain", [])
|
|
163
164
|
action["domain"] += [
|
|
@@ -139,7 +139,7 @@ class OperationLine(models.Model):
|
|
|
139
139
|
(
|
|
140
140
|
"fiscal_operation_name_uniq",
|
|
141
141
|
"unique (name, fiscal_operation_id)",
|
|
142
|
-
|
|
142
|
+
"Fiscal Operation Line already exists with this name!",
|
|
143
143
|
)
|
|
144
144
|
]
|
|
145
145
|
|
|
@@ -8,6 +8,7 @@ from odoo.exceptions import ValidationError
|
|
|
8
8
|
from ..constants.fiscal import (
|
|
9
9
|
NFE_IND_IE_DEST,
|
|
10
10
|
NFE_IND_IE_DEST_DEFAULT,
|
|
11
|
+
PUBLIC_ENTIRY_TYPE,
|
|
11
12
|
TAX_FRAMEWORK,
|
|
12
13
|
TAX_FRAMEWORK_NORMAL,
|
|
13
14
|
)
|
|
@@ -32,6 +33,11 @@ class PartnerProfile(models.Model):
|
|
|
32
33
|
"other government-controlled organizations.",
|
|
33
34
|
)
|
|
34
35
|
|
|
36
|
+
public_entity_type = fields.Selection(
|
|
37
|
+
selection=PUBLIC_ENTIRY_TYPE,
|
|
38
|
+
string="Tipo de Entidade Governamental",
|
|
39
|
+
)
|
|
40
|
+
|
|
35
41
|
default = fields.Boolean(string="Default Profile", default=True)
|
|
36
42
|
|
|
37
43
|
ind_ie_dest = fields.Selection(
|
|
@@ -63,7 +69,7 @@ class PartnerProfile(models.Model):
|
|
|
63
69
|
(
|
|
64
70
|
"fiscal_partner_profile_code_uniq",
|
|
65
71
|
"unique (code)",
|
|
66
|
-
"Fiscal Partner Profile already exists with this code
|
|
72
|
+
"Fiscal Partner Profile already exists with this code!",
|
|
67
73
|
)
|
|
68
74
|
]
|
|
69
75
|
|
|
@@ -83,7 +83,7 @@ class ProductTemplate(models.Model):
|
|
|
83
83
|
domain="[('internal_type', '=', 'normal')]",
|
|
84
84
|
)
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
city_taxation_code_ids = fields.Many2many(
|
|
87
87
|
comodel_name="l10n_br_fiscal.city.taxation.code", string="City Taxation Code"
|
|
88
88
|
)
|
|
89
89
|
|