odoo-addon-l10n-br-fiscal 16.0.11.5.0__py3-none-any.whl → 16.0.12.0.0__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.

@@ -5,11 +5,10 @@ from copy import deepcopy
5
5
 
6
6
  from lxml import etree
7
7
 
8
- from odoo import api, models
8
+ from odoo import Command, api, models
9
9
 
10
10
  from ..constants.fiscal import CFOP_DESTINATION_EXPORT, FISCAL_IN
11
11
  from ..constants.icms import ICMS_BASE_TYPE_DEFAULT, ICMS_ST_BASE_TYPE_DEFAULT
12
- from .tax import TAX_DICT_VALUES
13
12
 
14
13
  FISCAL_TAX_ID_FIELDS = [
15
14
  "cofins_tax_id",
@@ -207,37 +206,6 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
207
206
  record.financial_total_gross = record.financial_total = 0.0
208
207
  record.financial_discount_value = 0.0
209
208
 
210
- def _compute_taxes(self, taxes, cst=None):
211
- self.ensure_one()
212
- return taxes.compute_taxes(
213
- company=self._get_fiscal_company(),
214
- partner=self._get_fiscal_partner(),
215
- product=self.product_id,
216
- price_unit=self.price_unit,
217
- quantity=self.quantity,
218
- uom_id=self.uom_id,
219
- fiscal_price=self.fiscal_price,
220
- fiscal_quantity=self.fiscal_quantity,
221
- uot_id=self.uot_id,
222
- discount_value=self.discount_value,
223
- insurance_value=self.insurance_value,
224
- ii_customhouse_charges=self.ii_customhouse_charges,
225
- ii_iof_value=self.ii_iof_value,
226
- other_value=self.other_value,
227
- freight_value=self.freight_value,
228
- ncm=self.ncm_id,
229
- nbs=self.nbs_id,
230
- nbm=self.nbm_id,
231
- cest=self.cest_id,
232
- operation_line=self.fiscal_operation_line_id,
233
- cfop=self.cfop_id,
234
- icmssn_range=self.icmssn_range_id,
235
- icms_origin=self.icms_origin,
236
- icms_cst_id=self.icms_cst_id,
237
- ind_final=self._get_ind_final(),
238
- icms_relief_id=self.icms_relief_id,
239
- )
240
-
241
209
  @api.depends("tax_icms_or_issqn", "partner_is_public_entity")
242
210
  def _compute_allow_csll_irpj(self):
243
211
  """Calculates the possibility of 'CSLL' and 'IRPJ' tax charges."""
@@ -265,78 +233,197 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
265
233
  return {f"default_{k}": vals[k] for k in vals.keys()}
266
234
  return vals
267
235
 
268
- def _get_all_tax_id_fields(self):
269
- self.ensure_one()
270
- taxes = self.env["l10n_br_fiscal.tax"]
236
+ @api.onchange("fiscal_operation_id", "company_id", "partner_id", "product_id")
237
+ def _onchange_fiscal_operation_id(self):
238
+ if self.fiscal_operation_id:
239
+ self.fiscal_operation_line_id = self.fiscal_operation_id.line_definition(
240
+ company=self.company_id,
241
+ partner=self._get_fiscal_partner(),
242
+ product=self.product_id,
243
+ )
271
244
 
272
- for fiscal_tax_field in FISCAL_TAX_ID_FIELDS:
273
- taxes |= self[fiscal_tax_field]
245
+ def _get_fiscal_tax_ids_dependencies(self):
246
+ """
247
+ Dynamically get the list of fields dependencies, overriden in l10n_br_purchase.
248
+ """
249
+ return [
250
+ "company_id",
251
+ "partner_id",
252
+ "fiscal_operation_line_id",
253
+ "product_id",
254
+ "ncm_id",
255
+ "nbs_id",
256
+ "nbm_id",
257
+ "cest_id",
258
+ "city_taxation_code_id",
259
+ "service_type_id",
260
+ "ind_final",
261
+ ]
274
262
 
275
- return taxes
263
+ @api.depends(lambda self: self._get_fiscal_tax_ids_dependencies())
264
+ def _compute_fiscal_tax_ids(self):
265
+ """
266
+ Use fiscal_operation_line_id to map and compute the applicable Brazilian taxes.
276
267
 
277
- def _remove_all_fiscal_tax_ids(self):
278
- if self._is_imported():
268
+ Among the dependencies, company_id, partner_id and ind_final are related
269
+ to the fiscal document/line container. When called from account.move.line
270
+ via _inherits on newID records, we read these values from the related aml
271
+ to work around and _inherits/precompute limitation.
272
+ """
273
+ if self._context.get("skip_compute_fiscal_tax_ids"):
279
274
  return
280
275
  for line in self:
281
- to_update = {"fiscal_tax_ids": False}
282
- for fiscal_tax_field in FISCAL_TAX_ID_FIELDS:
283
- to_update[fiscal_tax_field] = False
284
- tax_methods = [
285
- self._prepare_fields_issqn,
286
- self._prepare_fields_csll,
287
- self._prepare_fields_irpj,
288
- self._prepare_fields_inss,
289
- self._prepare_fields_icms,
290
- self._prepare_fields_icmsfcp,
291
- self._prepare_fields_icmsfcpst,
292
- self._prepare_fields_icmsst,
293
- self._prepare_fields_icmssn,
294
- self._prepare_fields_ipi,
295
- self._prepare_fields_ii,
296
- self._prepare_fields_pis,
297
- self._prepare_fields_pisst,
298
- self._prepare_fields_cofins,
299
- self._prepare_fields_cofinsst,
300
- self._prepare_fields_issqn_wh,
301
- self._prepare_fields_pis_wh,
302
- self._prepare_fields_cofins_wh,
303
- self._prepare_fields_csll_wh,
304
- self._prepare_fields_irpj_wh,
305
- self._prepare_fields_inss_wh,
306
- ]
307
- for method in tax_methods:
308
- prepared_fields = method(TAX_DICT_VALUES)
309
- if prepared_fields:
310
- to_update.update(prepared_fields)
311
- # Update all fields at once
312
- line.update(to_update)
313
-
314
- def _update_fiscal_tax_ids(self, taxes):
315
- for line in self:
316
- taxes_groups = line.fiscal_tax_ids.mapped("tax_domain")
317
- fiscal_taxes = line.fiscal_tax_ids.filtered(
318
- lambda ft, taxes_groups=taxes_groups: ft.tax_domain not in taxes_groups
276
+ if hasattr(line, "account_line_ids") and line.account_line_ids:
277
+ # it seems Odoo 16 ORM has a limitation when line is an
278
+ # l10n_br_fiscal.document.line that is edited via an account.move.line
279
+ # form and when both are a newID, then line relational field might be
280
+ # empty here. But in this case, we detect it and we wrap it back in the
281
+ wrapped_line = line.account_line_ids[0]
282
+ else:
283
+ wrapped_line = line
284
+
285
+ if wrapped_line.fiscal_operation_line_id:
286
+ mapping_result = wrapped_line.fiscal_operation_line_id.map_fiscal_taxes(
287
+ company=wrapped_line.company_id,
288
+ partner=wrapped_line._get_fiscal_partner(),
289
+ product=wrapped_line.product_id,
290
+ ncm=wrapped_line.ncm_id,
291
+ nbm=wrapped_line.nbm_id,
292
+ nbs=wrapped_line.nbs_id,
293
+ cest=wrapped_line.cest_id,
294
+ city_taxation_code=wrapped_line.city_taxation_code_id,
295
+ service_type=wrapped_line.service_type_id,
296
+ ind_final=wrapped_line.ind_final,
297
+ )
298
+ line.cfop_id = mapping_result["cfop"]
299
+ line.ipi_guideline_id = mapping_result["ipi_guideline"]
300
+ line.icms_tax_benefit_id = mapping_result["icms_tax_benefit_id"]
301
+ if wrapped_line._is_imported():
302
+ return
303
+
304
+ taxes = line.env["l10n_br_fiscal.tax"]
305
+ for tax in mapping_result["taxes"].values():
306
+ taxes |= tax
307
+ line.fiscal_tax_ids = taxes
308
+ line.comment_ids = line.fiscal_operation_line_id.comment_ids
309
+
310
+ else:
311
+ line.fiscal_tax_ids = [Command.clear()]
312
+
313
+ @api.model
314
+ def _build_null_mask_dict(self) -> dict:
315
+ """
316
+ Build a null values mask dict to reset all fiscal fields.
317
+ """
318
+ mask_dict = {
319
+ f[0]: False
320
+ for f in filter(
321
+ lambda f: f[1].compute == "_compute_tax_fields",
322
+ self.env["l10n_br_fiscal.document.line.mixin"]._fields.items(),
319
323
  )
320
- line.fiscal_tax_ids = fiscal_taxes + taxes
324
+ }
325
+ for fiscal_tax_field in FISCAL_TAX_ID_FIELDS:
326
+ mask_dict[fiscal_tax_field] = False
327
+ return mask_dict
321
328
 
322
- def _update_fiscal_taxes(self):
323
- for line in self:
324
- compute_result = line._compute_taxes(line.fiscal_tax_ids)
325
- to_update = {
326
- "amount_tax_included": compute_result.get("amount_included", 0.0),
327
- "amount_tax_not_included": compute_result.get(
328
- "amount_not_included", 0.0
329
- ),
330
- "amount_tax_withholding": compute_result.get("amount_withholding", 0.0),
331
- "estimate_tax": compute_result.get("estimate_tax", 0.0),
332
- }
333
- to_update.update(line._prepare_tax_fields(compute_result))
329
+ def _get_tax_fields_dependencies(self):
330
+ """
331
+ Dynamically get the list of fields dependencies, overriden in l10n_br_purchase.
332
+ """
333
+ # IMPORTANT NOTE: as _compute_fiscal_tax_ids triggers _compute_tax_fields,
334
+ # we don't put fields that trigger _compute_fiscal_tax_ids as dependencies here.
335
+ return [
336
+ "price_unit",
337
+ "quantity",
338
+ "uom_id",
339
+ "fiscal_price",
340
+ "fiscal_quantity",
341
+ "uot_id",
342
+ "discount_value",
343
+ "insurance_value",
344
+ "ii_customhouse_charges",
345
+ "ii_iof_value",
346
+ "other_value",
347
+ "freight_value",
348
+ "cfop_id",
349
+ "icmssn_range_id",
350
+ "icms_origin",
351
+ "icms_cst_id",
352
+ "icms_relief_id",
353
+ "fiscal_tax_ids",
354
+ ]
355
+
356
+ @api.depends(lambda self: self._get_tax_fields_dependencies())
357
+ def _compute_tax_fields(self):
358
+ """
359
+ Compute base, percent, value... tax fields for ICMS, IPI, PIS, COFINS... taxes.
360
+ """
361
+ if self._context.get("skip_compute_tax_fields"):
362
+ return
334
363
 
335
- in_draft_mode = line != line._origin
364
+ null_mask = None
365
+ for line in self.filtered(lambda line: not line._is_imported()):
366
+ if hasattr(line, "account_line_ids") and line.account_line_ids:
367
+ # it seems Odoo 16 ORM has a limitation when line is an
368
+ # l10n_br_fiscal.document.line that is edited via an account.move.line
369
+ # form and when both are a newID, then line relational field might be
370
+ # empty here. But in this case, we detect it and we wrap it back in the
371
+ wrapped_line = line.account_line_ids[0]
372
+ else:
373
+ wrapped_line = line
374
+
375
+ if null_mask is None:
376
+ null_mask = self._build_null_mask_dict()
377
+ to_update = null_mask.copy()
378
+ if wrapped_line.fiscal_operation_line_id:
379
+ compute_result = wrapped_line.fiscal_tax_ids.compute_taxes(
380
+ company=wrapped_line.company_id,
381
+ partner=wrapped_line._get_fiscal_partner(),
382
+ product=wrapped_line.product_id,
383
+ price_unit=wrapped_line.price_unit,
384
+ quantity=wrapped_line.quantity,
385
+ uom_id=wrapped_line.uom_id,
386
+ fiscal_price=wrapped_line.fiscal_price,
387
+ fiscal_quantity=wrapped_line.fiscal_quantity,
388
+ uot_id=wrapped_line.uot_id,
389
+ discount_value=wrapped_line.discount_value,
390
+ insurance_value=wrapped_line.insurance_value,
391
+ ii_customhouse_charges=wrapped_line.ii_customhouse_charges,
392
+ ii_iof_value=wrapped_line.ii_iof_value,
393
+ other_value=wrapped_line.other_value,
394
+ freight_value=wrapped_line.freight_value,
395
+ ncm=wrapped_line.ncm_id,
396
+ nbs=wrapped_line.nbs_id,
397
+ nbm=wrapped_line.nbm_id,
398
+ cest=wrapped_line.cest_id,
399
+ operation_line=wrapped_line.fiscal_operation_line_id,
400
+ cfop=wrapped_line.cfop_id,
401
+ icmssn_range=wrapped_line.icmssn_range_id,
402
+ icms_origin=wrapped_line.icms_origin,
403
+ icms_cst_id=wrapped_line.icms_cst_id,
404
+ ind_final=wrapped_line.ind_final,
405
+ icms_relief_id=wrapped_line.icms_relief_id,
406
+ )
407
+ to_update.update(wrapped_line._prepare_tax_fields(compute_result))
408
+ else:
409
+ compute_result = {}
410
+ to_update.update(
411
+ {
412
+ "amount_tax_included": compute_result.get("amount_included", 0.0),
413
+ "amount_tax_not_included": compute_result.get(
414
+ "amount_not_included", 0.0
415
+ ),
416
+ "amount_tax_withholding": compute_result.get(
417
+ "amount_withholding", 0.0
418
+ ),
419
+ "estimate_tax": compute_result.get("estimate_tax", 0.0),
420
+ }
421
+ )
422
+ in_draft_mode = wrapped_line != wrapped_line._origin
336
423
  if in_draft_mode:
337
- line.update(to_update)
424
+ wrapped_line.update(to_update)
338
425
  else:
339
- line.write(to_update)
426
+ wrapped_line.write(to_update)
340
427
 
341
428
  def _prepare_tax_fields(self, compute_result):
342
429
  self.ensure_one()
@@ -356,7 +443,13 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
356
443
  tax_values.update(prepared_fields)
357
444
  return tax_values
358
445
 
359
- def _compute_price_unit_fiscal(self):
446
+ @api.depends(
447
+ "product_id",
448
+ "fiscal_operation_id",
449
+ "product_id.list_price",
450
+ "product_id.standard_price",
451
+ )
452
+ def _compute_price_unit_fiscal(self): # OK when edited from aml?? c-> check
360
453
  for line in self:
361
454
  line.price_unit = {
362
455
  "sale_price": line.product_id.list_price,
@@ -368,7 +461,7 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
368
461
  return {
369
462
  "user": self.env.user,
370
463
  "ctx": self._context,
371
- "doc": self.document_id,
464
+ "doc": self.document_id if hasattr(self, "document_id") else None,
372
465
  "item": self,
373
466
  }
374
467
 
@@ -389,93 +482,6 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
389
482
  self.ensure_one()
390
483
  return self.partner_id
391
484
 
392
- def _get_fiscal_company(self):
393
- """
394
- Meant to be overriden in account.move.line.
395
- Indeed when using this mixin in a NewID fiscal document line behind an aml,
396
- self.company_id is None but it can be retrived from the aml.
397
- """
398
- self.ensure_one()
399
- return self.company_id
400
-
401
- def _get_ind_final(self):
402
- """
403
- Meant to be overriden in account.move.line.
404
- Indeed when using this mixin in a NewID fiscal document line behind an aml,
405
- self.ind_final is None but it can be retrived from the aml.
406
- """
407
- self.ensure_one()
408
- return self.ind_final
409
-
410
- @api.onchange(
411
- "fiscal_operation_id", "ncm_id", "nbs_id", "cest_id", "service_type_id"
412
- )
413
- def _onchange_fiscal_operation_id(self):
414
- if self.fiscal_operation_id:
415
- if not self.price_unit:
416
- self._compute_price_unit_fiscal()
417
- self.fiscal_operation_line_id = self.fiscal_operation_id.line_definition(
418
- company=self.company_id,
419
- partner=self._get_fiscal_partner(),
420
- product=self.product_id,
421
- )
422
- self._compute_fiscal_tax_ids() # sadly seems required for composite move
423
-
424
- def _get_fiscal_tax_ids_dependencies(self):
425
- """
426
- Dynamically get the list of fields dependencies, overriden in l10n_br_purchase.
427
- """
428
- return [
429
- "company_id",
430
- "partner_id",
431
- "fiscal_operation_line_id",
432
- "product_id",
433
- "ncm_id",
434
- "nbs_id",
435
- "nbm_id",
436
- "cest_id",
437
- "city_taxation_code_id",
438
- "service_type_id",
439
- "ind_final",
440
- ]
441
-
442
- @api.depends(lambda self: self._get_fiscal_tax_ids_dependencies())
443
- def _compute_fiscal_tax_ids(self):
444
- """
445
- Among the dependencies, company_id, partner_id and ind_final are related
446
- to the fiscal document/line container. When called from account.move.line
447
- via _inherits on newID records, we read these values from the related aml
448
- to work around and _inherits/precompute limitation.
449
- """
450
- for line in self:
451
- line._remove_all_fiscal_tax_ids()
452
- if line.fiscal_operation_line_id:
453
- mapping_result = line.fiscal_operation_line_id.map_fiscal_taxes(
454
- company=line._get_fiscal_company(),
455
- partner=line._get_fiscal_partner(),
456
- product=line.product_id,
457
- ncm=line.ncm_id,
458
- nbm=line.nbm_id,
459
- nbs=line.nbs_id,
460
- cest=line.cest_id,
461
- city_taxation_code=line.city_taxation_code_id,
462
- service_type=line.service_type_id,
463
- ind_final=line._get_ind_final(),
464
- )
465
- line.cfop_id = mapping_result["cfop"]
466
- if line._is_imported():
467
- return
468
- line.ipi_guideline_id = mapping_result["ipi_guideline"]
469
- line.icms_tax_benefit_id = mapping_result["icms_tax_benefit_id"]
470
- taxes = line.env["l10n_br_fiscal.tax"]
471
- for tax in mapping_result["taxes"].values():
472
- taxes |= tax
473
- line.fiscal_tax_ids = taxes
474
- line._update_fiscal_taxes()
475
- line.comment_ids = line.fiscal_operation_line_id.comment_ids
476
- else:
477
- line.cfop_id = False
478
-
479
485
  @api.onchange("product_id")
480
486
  def _onchange_product_id_fiscal(self):
481
487
  if not self.fiscal_operation_id:
@@ -760,40 +766,18 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
760
766
  "cofinsst_value": tax_dict.get("tax_value", 0.00),
761
767
  }
762
768
 
763
- @api.onchange(
764
- "csll_tax_id",
765
- "csll_wh_tax_id",
766
- "irpj_tax_id",
767
- "irpj_wh_tax_id",
768
- "inss_tax_id",
769
- "inss_wh_tax_id",
770
- "issqn_tax_id",
771
- "issqn_wh_tax_id",
772
- "icms_tax_id",
773
- "icmssn_tax_id",
774
- "icmsst_tax_id",
775
- "icmsfcp_tax_id",
776
- "icmsfcpst_tax_id",
777
- "icms_relief_id",
778
- "icms_relief_value",
779
- "ipi_tax_id",
780
- "ii_tax_id",
781
- "pis_tax_id",
782
- "pis_wh_tax_id",
783
- "pisst_tax_id",
784
- "cofins_tax_id",
785
- "cofins_wh_tax_id",
786
- "cofinsst_tax_id",
787
- "fiscal_price",
788
- "fiscal_quantity",
789
- "discount_value",
790
- "insurance_value",
791
- "other_value",
792
- "freight_value",
793
- )
769
+ @api.onchange(*FISCAL_TAX_ID_FIELDS)
794
770
  def _onchange_fiscal_taxes(self):
795
- self._update_fiscal_tax_ids(self._get_all_tax_id_fields())
796
- self._update_fiscal_taxes()
771
+ taxes = self.env["l10n_br_fiscal.tax"]
772
+ for fiscal_tax_field in FISCAL_TAX_ID_FIELDS:
773
+ taxes |= self[fiscal_tax_field]
774
+
775
+ for line in self:
776
+ taxes_groups = line.fiscal_tax_ids.mapped("tax_domain")
777
+ fiscal_taxes = line.fiscal_tax_ids.filtered(
778
+ lambda ft, taxes_groups=taxes_groups: ft.tax_domain not in taxes_groups
779
+ )
780
+ line.fiscal_tax_ids = fiscal_taxes + taxes
797
781
 
798
782
  @api.depends("uom_id")
799
783
  def _compute_uot_id(self):
@@ -837,15 +821,6 @@ class FiscalDocumentLineMixinMethods(models.AbstractModel):
837
821
  else:
838
822
  line.fiscal_quantity = line.quantity
839
823
 
840
- @api.onchange("ii_customhouse_charges")
841
- def _onchange_ii_customhouse_charges(self):
842
- if self.ii_customhouse_charges:
843
- self._update_fiscal_taxes()
844
-
845
- @api.onchange("fiscal_tax_ids")
846
- def _onchange_fiscal_tax_ids(self):
847
- self._update_fiscal_taxes()
848
-
849
824
  @api.onchange("city_taxation_code_id")
850
825
  def _onchange_city_taxation_code_id(self):
851
826
  if self.city_taxation_code_id:
@@ -372,7 +372,7 @@ ul.auto-toc {
372
372
  !! This file is generated by oca-gen-addon-readme !!
373
373
  !! changes will be overwritten. !!
374
374
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375
- !! source digest: sha256:dd9f065758d59e68e7d24a53621956cc9e6911bb9e58b0ac89b2e202085a51dc
375
+ !! source digest: sha256:c7237cc492a3c05bdc327d62bacbd7bc04bf544bc7702fc02c34dcca0c6b8b92
376
376
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377
377
  <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/l10n-brazil/tree/16.0/l10n_br_fiscal"><img alt="OCA/l10n-brazil" src="https://img.shields.io/badge/github-OCA%2Fl10n--brazil-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/l10n-brazil-16-0/l10n-brazil-16-0-l10n_br_fiscal"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/l10n-brazil&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378
378
  <p><img alt="image" src="https://raw.githubusercontent.com/OCA/l10n-brazil/16.0/l10n_br_fiscal/static/img/fiscal_dashboard.png" /></p>
@@ -24,7 +24,7 @@ class TestDocumentEdition(TransactionCase):
24
24
  doc_form.fiscal_operation_id = self.env.ref("l10n_br_fiscal.fo_venda")
25
25
  doc_form.ind_final = "1"
26
26
  product_id = self.env.ref("product.product_product_6")
27
- product_id.list_price = 150 # we will later check we can set priceunit to 100
27
+ product_id.list_price = 150 # we will later check we can set price_unit to 100
28
28
  with doc_form.fiscal_line_ids.new() as line_form:
29
29
  original_method = type(
30
30
  self.env["l10n_br_fiscal.operation.line"]
@@ -59,14 +59,58 @@ class TestDocumentEdition(TransactionCase):
59
59
  ind_final="1",
60
60
  )
61
61
 
62
- line_form.price_unit = 100
62
+ line_form.price_unit = 50
63
63
  line_form.quantity = 2
64
+ self.assertEqual(len(line_form.fiscal_tax_ids), 4)
65
+ self.assertEqual(
66
+ line_form.icms_tax_id, self.env.ref("l10n_br_fiscal.tax_icms_12")
67
+ )
68
+ self.assertEqual(line_form.icms_value, 12.0)
69
+ line_form.price_unit = 100
70
+ self.assertEqual(
71
+ line_form.icms_tax_id, self.env.ref("l10n_br_fiscal.tax_icms_12")
72
+ )
73
+ self.assertEqual(line_form.icms_value, 24.0)
74
+ self.assertEqual(
75
+ line_form.fiscal_operation_line_id,
76
+ self.env.ref("l10n_br_fiscal.fo_venda_revenda"),
77
+ )
78
+ self.assertEqual(
79
+ line_form.ipi_tax_id, self.env.ref("l10n_br_fiscal.tax_ipi_nt")
80
+ )
81
+
82
+ line_form.fiscal_operation_line_id = self.env.ref(
83
+ "l10n_br_fiscal.fo_venda_venda"
84
+ )
85
+ self.assertEqual(
86
+ line_form.ipi_tax_id, self.env.ref("l10n_br_fiscal.tax_ipi_3_25")
87
+ )
88
+
89
+ # ensure manually setting a xx_tax_id is properly saved (not recomputed):
90
+ line_form.icms_tax_id = self.env.ref("l10n_br_fiscal.tax_icms_18")
91
+ self.assertEqual(line_form.icms_value, 37.17)
92
+ self.assertEqual(
93
+ line_form.ipi_tax_id, self.env.ref("l10n_br_fiscal.tax_ipi_3_25")
94
+ )
64
95
 
65
96
  doc = doc_form.save()
66
- self.assertEqual(doc.fiscal_line_ids[0].price_unit, 100)
67
- self.assertEqual(doc.fiscal_line_ids[0].fiscal_price, 100)
68
- self.assertEqual(doc.fiscal_line_ids[0].quantity, 2)
69
- self.assertEqual(doc.fiscal_line_ids[0].fiscal_quantity, 2)
97
+ line = doc.fiscal_line_ids[0]
98
+ self.assertEqual(line.price_unit, 100)
99
+ self.assertEqual(line.fiscal_price, 100)
100
+ self.assertEqual(line.quantity, 2)
101
+ self.assertEqual(line.fiscal_quantity, 2)
102
+ self.assertEqual(len(line.fiscal_tax_ids), 4)
103
+
104
+ self.assertEqual(
105
+ line.fiscal_operation_line_id,
106
+ self.env.ref("l10n_br_fiscal.fo_venda_venda"),
107
+ )
108
+ self.assertEqual(
109
+ line.icms_tax_id.id,
110
+ self.ref("l10n_br_fiscal.tax_icms_18"),
111
+ )
112
+ self.assertEqual(line.ipi_tax_id, self.env.ref("l10n_br_fiscal.tax_ipi_3_25"))
113
+ self.assertEqual(line.icms_value, 37.17)
70
114
 
71
115
  def test_product_fiscal_factor(self):
72
116
  doc_form = Form(
@@ -109,6 +153,10 @@ class TestDocumentEdition(TransactionCase):
109
153
  line_form.quantity = 10
110
154
  line_form.fiscal_price = 112
111
155
  line_form.fiscal_quantity = 5
156
+ self.assertEqual(line_form.price_unit, 110)
157
+ self.assertEqual(line_form.fiscal_price, 112)
158
+ self.assertEqual(line_form.quantity, 10)
159
+ self.assertEqual(line_form.fiscal_quantity, 5)
112
160
 
113
161
  doc = doc_form.save()
114
162
  self.assertEqual(doc.fiscal_line_ids[0].price_unit, 110)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: odoo-addon-l10n_br_fiscal
3
- Version: 16.0.11.5.0
3
+ Version: 16.0.12.0.0
4
4
  Requires-Python: >=3.10
5
5
  Requires-Dist: erpbrasil.base>=2.3.0
6
6
  Requires-Dist: odoo-addon-l10n_br_base>=16.0dev,<16.1dev
@@ -31,7 +31,7 @@ Módulo fiscal brasileiro
31
31
  !! This file is generated by oca-gen-addon-readme !!
32
32
  !! changes will be overwritten. !!
33
33
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
34
- !! source digest: sha256:dd9f065758d59e68e7d24a53621956cc9e6911bb9e58b0ac89b2e202085a51dc
34
+ !! source digest: sha256:c7237cc492a3c05bdc327d62bacbd7bc04bf544bc7702fc02c34dcca0c6b8b92
35
35
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
36
36
 
37
37
  .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
@@ -1,6 +1,6 @@
1
- odoo/addons/l10n_br_fiscal/README.rst,sha256=jKHw-vzleAFwqeOUH1HJ-zbjTBownBUkfxpHDwAjC5A,13957
1
+ odoo/addons/l10n_br_fiscal/README.rst,sha256=c_rR_-ZKGcbKh1MgbxGYeiwkbYIKwtKj_0AJ8x-ni6w,13957
2
2
  odoo/addons/l10n_br_fiscal/__init__.py,sha256=BQXfCjW4ehK1W1j0z6k8xN7Q2LoZBCjjvYDkQt6nSkI,2717
3
- odoo/addons/l10n_br_fiscal/__manifest__.py,sha256=WxIyOq5PUiqu0iEAKeurN2Pr2LdgM2IQXNanzSnuX3E,4964
3
+ odoo/addons/l10n_br_fiscal/__manifest__.py,sha256=UpbtKIzj1bnSk0UsrEs77wRyQUWB_ucO0X-Fep7JS5s,4964
4
4
  odoo/addons/l10n_br_fiscal/tools.py,sha256=HgaCLkPznFxgLfjb76nH36PJ7bN5W7-fdaqtBvM6XC0,4056
5
5
  odoo/addons/l10n_br_fiscal/constants/fiscal.py,sha256=F2a4jYAk2j2Yh1Xw7WeS1GcLfW1DbjeNgEF6l7135wc,14962
6
6
  odoo/addons/l10n_br_fiscal/constants/icms.py,sha256=rHlM6jyRvhrIm03sd6guS1xh7SptADLltPmRJ3C_Vh8,3512
@@ -71,8 +71,8 @@ odoo/addons/l10n_br_fiscal/models/data_ncm_nbs_abstract.py,sha256=a0K-32ockgmQV5
71
71
  odoo/addons/l10n_br_fiscal/models/data_product_abstract.py,sha256=wbc3exJQp33aYK8IOJ490JvDWBPCpU0NEkMR6YjaLfQ,793
72
72
  odoo/addons/l10n_br_fiscal/models/document.py,sha256=-0nT613qIHOz2sNPAhgrNM8pcVuw7_Sw7hSOF-nj6QY,19328
73
73
  odoo/addons/l10n_br_fiscal/models/document_line.py,sha256=rro8uzmZpAte7N04ycd-KKn2dyGJhin_Q-DjCaKm110,2082
74
- odoo/addons/l10n_br_fiscal/models/document_line_mixin.py,sha256=qfsjYBJChLyhb_Oy-1BgzduEbQ551bh3tXYUXSIl-OM,28810
75
- odoo/addons/l10n_br_fiscal/models/document_line_mixin_methods.py,sha256=-i71-iNkhNTv4ji8BLViTG6m-Fyk4pWGBcCpMQbeNJQ,34198
74
+ odoo/addons/l10n_br_fiscal/models/document_line_mixin.py,sha256=0s5u5_4_gXMs02f1pFtJQxfxqNfNbn1Dvo6sAvvVn10,43906
75
+ odoo/addons/l10n_br_fiscal/models/document_line_mixin_methods.py,sha256=DyJjB9f1qkN1-m6ToXSyePR56DfqJ31FzW53WHTT2KI,34446
76
76
  odoo/addons/l10n_br_fiscal/models/document_mixin.py,sha256=hCi-HEIeOHVqk1CF1irIfOrqztRoHGxvmHaPA14-yCI,13519
77
77
  odoo/addons/l10n_br_fiscal/models/document_mixin_methods.py,sha256=jM_lJZC7Nipa6N9GSoUIHKVrS6JmhtxKzmeB7QYqpC4,16326
78
78
  odoo/addons/l10n_br_fiscal/models/document_related.py,sha256=SKUToxuoC2eOZAG8pJnBg0o5269JjvLbpvuy0M8zSlQ,4689
@@ -124,7 +124,7 @@ odoo/addons/l10n_br_fiscal/readme/USAGE.md,sha256=Dw3uZaHJCUtV0xFq6VOQvF2G5fS_oS
124
124
  odoo/addons/l10n_br_fiscal/security/fiscal_security.xml,sha256=PxRef68OVjlCVMOJZbhieVxivgKJYJm9r3TiZO4RerA,3362
125
125
  odoo/addons/l10n_br_fiscal/security/ir.model.access.csv,sha256=RIVYOOLQ2cOWGp9f8hvKflwglZxAN6exGcOwqCEgDuw,14369
126
126
  odoo/addons/l10n_br_fiscal/static/description/icon.png,sha256=Vd1HydYBoGCzNfCqxLlch2i2aeCcyxo-uRxWNp6oMbw,14836
127
- odoo/addons/l10n_br_fiscal/static/description/index.html,sha256=Kf4PBUg1LfcrewsNDdr7DLQNqtLuxPa_irOvxRYEApc,26637
127
+ odoo/addons/l10n_br_fiscal/static/description/index.html,sha256=trNePBGonObhVrHGCtA5TLzr5JP1_69CiRtnCYGhJCQ,26637
128
128
  odoo/addons/l10n_br_fiscal/static/img/fiscal_dashboard.png,sha256=Q0fpqFNqEXh6m6E1aJfzSKV2tQ9lC1Y-ofUt6qxVupc,151668
129
129
  odoo/addons/l10n_br_fiscal/static/img/fiscal_line.png,sha256=S4Q4OGSzGnbfm4W5sQVvnD4uUzxS6tbJGT_gs3pB4K0,134276
130
130
  odoo/addons/l10n_br_fiscal/static/img/fiscal_operation.png,sha256=2614c1XjxwVznh707e9gujlUXg0ttutKD1ZiSMTqyv8,105871
@@ -132,7 +132,7 @@ odoo/addons/l10n_br_fiscal/static/img/fiscal_total.png,sha256=MaR6ZoM6ZZEaNZk2yn
132
132
  odoo/addons/l10n_br_fiscal/static/src/js/list_renderer_with_button.esm.js,sha256=Ucw7pymMrW2yi_nNrDMvq6ubyub9QMlqH3ZOoaTEHN0,1243
133
133
  odoo/addons/l10n_br_fiscal/tests/__init__.py,sha256=83m4BimGb-6EseEmmCVaKTSel5GB_vkzbI3YZi4mStE,393
134
134
  odoo/addons/l10n_br_fiscal/tests/test_cnae.py,sha256=mmskSfWaoFSohjmRbnGci_6Euc9fc2zbhyH5FdyeIeA,616
135
- odoo/addons/l10n_br_fiscal/tests/test_document_edition.py,sha256=w_ANtriwn9IpG3XvMruINMOIcZJyPwUY47iFSgz2bj0,5067
135
+ odoo/addons/l10n_br_fiscal/tests/test_document_edition.py,sha256=aQYSQixnTQGk6xPQJ6-i5qbdbEHlua_-c7-tr-IT0V8,7064
136
136
  odoo/addons/l10n_br_fiscal/tests/test_fiscal_document_generic.py,sha256=nMrevgtmcMgtnZWt-nHZboKLiFO1V_AxfSxIWKd0uLw,39974
137
137
  odoo/addons/l10n_br_fiscal/tests/test_fiscal_document_nfse.py,sha256=nEMaaWfv-sb4o48c1-l7mVnSjks3Tue7XxnQb_Q4cqw,1538
138
138
  odoo/addons/l10n_br_fiscal/tests/test_fiscal_tax.py,sha256=U6JbuqKTcyyFTiW5FZGqGY5yi_aPKaC6_LWz_3sKdpg,11322
@@ -195,7 +195,7 @@ odoo/addons/l10n_br_fiscal/wizards/base_wizard_mixin.py,sha256=-r25us0vdNCSe11Gn
195
195
  odoo/addons/l10n_br_fiscal/wizards/document_import_wizard_mixin.py,sha256=KfbqnzFuVx7WAro__W130rgvMWKkDBvkDFglMwTwgBQ,4115
196
196
  odoo/addons/l10n_br_fiscal/wizards/document_import_wizard_mixin.xml,sha256=h19vP1YvC4hLPvCvA6E1goqre0AAGy0CF4a2R6B78Y4,1833
197
197
  odoo/addons/l10n_br_fiscal/wizards/document_status_wizard.py,sha256=KsYj5YWWePO7uk0psBsFdnCL71eLWhcyg7_c7J4G6vA,818
198
- odoo_addon_l10n_br_fiscal-16.0.11.5.0.dist-info/METADATA,sha256=eaQecQkRORdyybwDttNAjmethP2_797jaxEE7uAet5c,14720
199
- odoo_addon_l10n_br_fiscal-16.0.11.5.0.dist-info/WHEEL,sha256=ZhOvUsYhy81Dx67gN3TV0RchQWBIIzutDZaJODDg2Vo,81
200
- odoo_addon_l10n_br_fiscal-16.0.11.5.0.dist-info/top_level.txt,sha256=QE6RBQ0QX5f4eFuUcGgU5Kbq1A_qJcDs-e_vpr6pmfU,4
201
- odoo_addon_l10n_br_fiscal-16.0.11.5.0.dist-info/RECORD,,
198
+ odoo_addon_l10n_br_fiscal-16.0.12.0.0.dist-info/METADATA,sha256=QdVXWcVMDqB_eqPAkehTkiv07au3Z3IrnPkAcVs1R8k,14720
199
+ odoo_addon_l10n_br_fiscal-16.0.12.0.0.dist-info/WHEEL,sha256=ZhOvUsYhy81Dx67gN3TV0RchQWBIIzutDZaJODDg2Vo,81
200
+ odoo_addon_l10n_br_fiscal-16.0.12.0.0.dist-info/top_level.txt,sha256=QE6RBQ0QX5f4eFuUcGgU5Kbq1A_qJcDs-e_vpr6pmfU,4
201
+ odoo_addon_l10n_br_fiscal-16.0.12.0.0.dist-info/RECORD,,