diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 14bbc5092c94..000000000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,5 +0,0 @@ -languages: - JavaScript: true - Python: true -exclude_paths: -- "__unported__/*" diff --git a/.editorconfig b/.editorconfig index 62276b0d58fe..bfd7ac53df9f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,11 +7,11 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true -[.eslintrc,*.{json,yml,yaml,rst,md}] +[*.{json,yml,yaml,rst,md}] indent_size = 2 # Do not configure editor for libs and autogenerated content -[*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst] +[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}] charset = unset end_of_line = unset indent_size = unset diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 000000000000..88f2881b4c12 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,180 @@ +env: + browser: true + +# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449 +parserOptions: + ecmaVersion: 2017 + +# Globals available in Odoo that shouldn't produce errorings +globals: + _: readonly + $: readonly + fuzzy: readonly + jQuery: readonly + moment: readonly + odoo: readonly + openerp: readonly + Promise: readonly + +# Styling is handled by Prettier, so we only need to enable AST rules; +# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890 +rules: + accessor-pairs: warn + array-callback-return: warn + callback-return: warn + capitalized-comments: + - warn + - always + - ignoreConsecutiveComments: true + ignoreInlineComments: true + complexity: + - warn + - 15 + constructor-super: warn + dot-notation: warn + eqeqeq: warn + global-require: warn + handle-callback-err: warn + id-blacklist: warn + id-match: warn + init-declarations: error + max-depth: warn + max-nested-callbacks: warn + max-statements-per-line: warn + no-alert: warn + no-array-constructor: warn + no-caller: warn + no-case-declarations: warn + no-class-assign: warn + no-cond-assign: error + no-const-assign: error + no-constant-condition: warn + no-control-regex: warn + no-debugger: error + no-delete-var: warn + no-div-regex: warn + no-dupe-args: error + no-dupe-class-members: error + no-dupe-keys: error + no-duplicate-case: error + no-duplicate-imports: error + no-else-return: warn + no-empty-character-class: warn + no-empty-function: error + no-empty-pattern: error + no-empty: warn + no-eq-null: error + no-eval: error + no-ex-assign: error + no-extend-native: warn + no-extra-bind: warn + no-extra-boolean-cast: warn + no-extra-label: warn + no-fallthrough: warn + no-func-assign: error + no-global-assign: error + no-implicit-coercion: + - warn + - allow: ["~"] + no-implicit-globals: warn + no-implied-eval: warn + no-inline-comments: warn + no-inner-declarations: warn + no-invalid-regexp: warn + no-irregular-whitespace: warn + no-iterator: warn + no-label-var: warn + no-labels: warn + no-lone-blocks: warn + no-lonely-if: error + no-mixed-requires: error + no-multi-str: warn + no-native-reassign: error + no-negated-condition: warn + no-negated-in-lhs: error + no-new-func: warn + no-new-object: warn + no-new-require: warn + no-new-symbol: warn + no-new-wrappers: warn + no-new: warn + no-obj-calls: warn + no-octal-escape: warn + no-octal: warn + no-param-reassign: warn + no-path-concat: warn + no-process-env: warn + no-process-exit: warn + no-proto: warn + no-prototype-builtins: warn + no-redeclare: warn + no-regex-spaces: warn + no-restricted-globals: warn + no-restricted-imports: warn + no-restricted-modules: warn + no-restricted-syntax: warn + no-return-assign: error + no-script-url: warn + no-self-assign: warn + no-self-compare: warn + no-sequences: warn + no-shadow-restricted-names: warn + no-shadow: warn + no-sparse-arrays: warn + no-sync: warn + no-this-before-super: warn + no-throw-literal: warn + no-undef-init: warn + no-undef: error + no-unmodified-loop-condition: warn + no-unneeded-ternary: error + no-unreachable: error + no-unsafe-finally: error + no-unused-expressions: error + no-unused-labels: error + no-unused-vars: error + no-use-before-define: error + no-useless-call: warn + no-useless-computed-key: warn + no-useless-concat: warn + no-useless-constructor: warn + no-useless-escape: warn + no-useless-rename: warn + no-void: warn + no-with: warn + operator-assignment: [error, always] + prefer-const: warn + radix: warn + require-yield: warn + sort-imports: warn + spaced-comment: [error, always] + strict: [error, function] + use-isnan: error + valid-jsdoc: + - warn + - prefer: + arg: param + argument: param + augments: extends + constructor: class + exception: throws + func: function + method: function + prop: property + return: returns + virtual: abstract + yield: yields + preferType: + array: Array + bool: Boolean + boolean: Boolean + number: Number + object: Object + str: String + string: String + requireParamDescription: false + requireReturn: false + requireReturnDescription: false + requireReturnType: false + valid-typeof: warn + yoda: warn diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000000..e397e8ed4e3e --- /dev/null +++ b/.flake8 @@ -0,0 +1,12 @@ +[flake8] +max-line-length = 88 +max-complexity = 16 +# B = bugbear +# B9 = bugbear opinionated (incl line length) +select = C,E,F,W,B,B9 +# E203: whitespace before ':' (black behaviour) +# E501: flake8 line length (covered by bugbear B950) +# W503: line break before binary operator (black behaviour) +ignore = E203,E501,W503 +per-file-ignores= + __init__.py:F401 diff --git a/.gitignore b/.gitignore index 2daa5c852f87..818770fb1bdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] +/.venv +/.pytest_cache # C extensions *.so @@ -13,6 +15,7 @@ build/ develop-eggs/ dist/ eggs/ +lib/ lib64/ parts/ sdist/ @@ -20,6 +23,7 @@ var/ *.egg-info/ .installed.cfg *.egg +*.eggs # Installer logs pip-log.txt @@ -39,6 +43,19 @@ coverage.xml # Pycharm .idea +# Eclipse +.settings + +# Visual Studio cache/options directory +.vs/ +.vscode + +# OSX Files +.DS_Store + +# Django stuff: +*.log + # Mr Developer .mr.developer.cfg .project @@ -53,3 +70,6 @@ docs/_build/ # Backup files *~ *.swp + +# OCA rules +!static/lib/ diff --git a/.isort.cfg b/.isort.cfg index 08469fcdb7ab..0ec187efd1bf 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,2 +1,13 @@ [settings] -known_third_party = OpenSSL,dateutil,erpbrasil,lxml,odoo,openupgradelib,requests,setuptools +; see https://github.com/psf/black +multi_line_output=3 +include_trailing_comma=True +force_grid_wrap=0 +combine_as_imports=True +use_parentheses=True +line_length=88 +known_odoo=odoo +known_odoo_addons=odoo.addons +sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER +default_section=THIRDPARTY +ensure_newline_before_comments = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 876d1e98ee50..325e76b906f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,68 +1,149 @@ -exclude: "^setup/|/static/lib/|/static/src/lib/" +exclude: | + (?x) + # NOT INSTALLABLE ADDONS + # END NOT INSTALLABLE ADDONS + ^l10n_br_account_bank_statement_import_cnab/| + ^l10n_br_account_payment_order/| + ^l10n_br_coa_complete/| + ^l10n_br_coa_generic/| + ^l10n_br_coa_simple/| + ^l10n_br_delivery/| + ^l10n_br_mis_report/| + ^l10n_br_nfe/| + ^l10n_br_nfe_spec/| + ^l10n_br_nfse_ginfes/| + ^l10n_br_nfse_issnet/| + ^l10n_br_nfse_paulistana/| + ^l10n_br_product_contract/| + ^l10n_br_repair/| + ^l10n_br_website_sale/| + ^l10n_br_website_sale_delivery/| + ^payment_cielo/| + ^spec_driven_model/| + # Files and folders generated by bots, to avoid loops + ^setup/|/static/description/index\.html$| + # We don't want to mess with tool-generated files + .svg$|/tests/([^/]+/)?cassettes/|^.github/|.travis.yml|CONTRIBUTING.md| + # Maybe reactivate this when all README files include prettier ignore tags? + ^README\.md$| + # Library files can have extraneous formatting (even minimized) + /static/(src/)?lib/| + # Repos using Sphinx to generate docs don't need prettying + ^docs/_templates/.*\.html$| + # You don't usually want a bot to modify your legal texts + (LICENSE.*|COPYING.*) default_language_version: python: python3 + node: "14.13.0" repos: -- repo: https://github.com/psf/black - rev: 19.3b0 - hooks: - - id: black -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 - hooks: - - id: trailing-whitespace - # exclude autogenerated files - exclude: /README\.rst$|\.pot?$ - - id: end-of-file-fixer - # exclude autogenerated files - exclude: /README\.rst$|\.pot?$ - - id: debug-statements - - id: flake8 - name: flake8 except __init__.py - exclude: /__init__\.py$ - additional_dependencies: ["flake8-bugbear==19.8.0"] - - id: flake8 - name: flake8 only __init__.py - args: ["--extend-ignore=F401"] # ignore unused imports in __init__.py - files: /__init__\.py$ - additional_dependencies: ["flake8-bugbear==19.8.0"] - - id: fix-encoding-pragma - args: ["--remove"] - - id: check-case-conflict - - id: check-docstring-first - - id: check-executables-have-shebangs - - id: check-merge-conflict - - id: check-symlinks - - id: check-xml - - id: mixed-line-ending - args: ["--fix=lf"] -- repo: https://github.com/pre-commit/mirrors-pylint - rev: v2.3.1 - hooks: - - id: pylint - name: pylint with optional checks - args: ["--rcfile=.pylintrc", "--exit-zero"] - verbose: true - additional_dependencies: ["pylint-odoo==3.0.3"] - - id: pylint - name: pylint with mandatory checks - args: ["--rcfile=.pylintrc-mandatory"] - additional_dependencies: ["pylint-odoo==3.0.3"] -- repo: https://github.com/asottile/pyupgrade - rev: v1.24.0 - hooks: - - id: pyupgrade -- repo: https://github.com/asottile/seed-isort-config - rev: v1.9.3 - hooks: - - id: seed-isort-config -- repo: https://github.com/pre-commit/mirrors-isort - rev: v4.3.21 - hooks: - - id: isort - name: isort except __init__.py - exclude: /__init__\.py$ -- repo: https://github.com/pre-commit/mirrors-eslint - rev: v6.5.1 - hooks: - - id: eslint - verbose: true + - repo: local + hooks: + # These files are most likely copier diff rejection junks; if found, + # review them manually, fix the problem (if needed) and remove them + - id: forbidden-files + name: forbidden files + entry: found forbidden files; remove them + language: fail + files: "\\.rej$" + - repo: https://github.com/oca/maintainer-tools + rev: ab1d7f6 + hooks: + # update the NOT INSTALLABLE ADDONS section above + - id: oca-update-pre-commit-excluded-addons + - id: oca-fix-manifest-website + args: ["https://github.com/OCA/l10n-brazil"] + - repo: https://github.com/myint/autoflake + rev: v1.4 + hooks: + - id: autoflake + args: + - --expand-star-imports + - --ignore-init-module-imports + - --in-place + - --remove-all-unused-imports + - --remove-duplicate-keys + - --remove-unused-variables + - repo: https://github.com/psf/black + rev: 20.8b1 + hooks: + - id: black + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v2.1.2 + hooks: + - id: prettier + name: prettier (with plugin-xml) + additional_dependencies: + - "prettier@2.1.2" + - "@prettier/plugin-xml@0.12.0" + args: + - --plugin=@prettier/plugin-xml + files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$ + - repo: https://github.com/pre-commit/mirrors-eslint + rev: v7.8.1 + hooks: + - id: eslint + verbose: true + args: + - --color + - --fix + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + # exclude autogenerated files + exclude: /README\.rst$|\.pot?$ + - id: end-of-file-fixer + # exclude autogenerated files + exclude: /README\.rst$|\.pot?$ + - id: debug-statements + - id: fix-encoding-pragma + args: ["--remove"] + - id: check-case-conflict + - id: check-docstring-first + - id: check-executables-have-shebangs + - id: check-merge-conflict + # exclude files where underlines are not distinguishable from merge conflicts + exclude: /README\.rst$|^docs/.*\.rst$ + - id: check-symlinks + - id: check-xml + - id: mixed-line-ending + args: ["--fix=lf"] + - repo: https://github.com/asottile/pyupgrade + rev: v2.7.2 + hooks: + - id: pyupgrade + args: ["--keep-percent-format"] + - repo: https://github.com/PyCQA/isort + rev: 5.5.1 + hooks: + - id: isort + name: isort except __init__.py + args: + - --settings=. + exclude: /__init__\.py$ + - repo: https://github.com/acsone/setuptools-odoo + rev: 2.6.0 + hooks: + - id: setuptools-odoo-make-default + - repo: https://gitlab.com/PyCQA/flake8 + rev: 3.8.3 + hooks: + - id: flake8 + name: flake8 + additional_dependencies: ["flake8-bugbear==20.1.4"] + - repo: https://github.com/PyCQA/pylint + rev: pylint-2.5.3 + hooks: + - id: pylint + name: pylint with optional checks + args: + - --rcfile=.pylintrc + - --exit-zero + verbose: true + additional_dependencies: &pylint_deps + - pylint-odoo==3.5.0 + - id: pylint + name: pylint with mandatory checks + args: + - --rcfile=.pylintrc-mandatory + additional_dependencies: *pylint_deps diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 000000000000..5b6d4b361ace --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,8 @@ +# Defaults for all prettier-supported languages. +# Prettier will complete this with settings from .editorconfig file. +bracketSpacing: false +printWidth: 88 +proseWrap: always +semi: true +trailingComma: "es5" +xmlWhitespaceSensitivity: "strict" diff --git a/.pylintrc b/.pylintrc index 9e34abde3bdb..005437f40b97 100644 --- a/.pylintrc +++ b/.pylintrc @@ -28,6 +28,7 @@ enable=anomalous-backslash-in-string, class-camelcase, dangerous-default-value, dangerous-view-replace-wo-priority, + development-status-allowed, duplicate-id-csv, duplicate-key, duplicate-xml-fields, @@ -45,8 +46,6 @@ enable=anomalous-backslash-in-string, method-inverse, method-required-super, method-search, - missing-import-error, - missing-manifest-dependency, openerp-exception-warning, pointless-statement, pointless-string-statement, @@ -72,8 +71,8 @@ enable=anomalous-backslash-in-string, deprecated-module, file-not-used, invalid-commit, + missing-manifest-dependency, missing-newline-extrafiles, - missing-readme, no-utf8-coding-comment, odoo-addons-relative-import, old-api7-method-defined, @@ -81,6 +80,7 @@ enable=anomalous-backslash-in-string, too-complex, unnecessary-utf8-coding-comment + [REPORTS] msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} output-format=colorized diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory index 91d657d493d0..ed05c82406db 100644 --- a/.pylintrc-mandatory +++ b/.pylintrc-mandatory @@ -21,6 +21,7 @@ enable=anomalous-backslash-in-string, class-camelcase, dangerous-default-value, dangerous-view-replace-wo-priority, + development-status-allowed, duplicate-id-csv, duplicate-key, duplicate-xml-fields, @@ -38,8 +39,6 @@ enable=anomalous-backslash-in-string, method-inverse, method-required-super, method-search, - missing-import-error, - missing-manifest-dependency, openerp-exception-warning, pointless-statement, pointless-string-statement, diff --git a/.travis.yml b/.travis.yml index 0ce92c107e03..16b9f907939b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: python -sudo: false -cache: pip +cache: + directories: + - $HOME/.cache/pip + - $HOME/.cache/pre-commit python: - "3.6" @@ -16,10 +18,29 @@ addons: - libxslt-dev - swig +stages: + - linting + - test + +jobs: + include: + - stage: linting + name: "pre-commit" + python: "3.6" + before_install: + install: pip install pre-commit + script: pre-commit run --all --show-diff-on-failure --verbose --color always + after_success: + - stage: test + env: + - TESTS="1" ODOO_REPO="odoo/odoo" MAKEPOT="1" + - stage: test + env: + - TESTS="1" ODOO_REPO="OCA/OCB" + env: global: - VERSION="12.0" TESTS="0" LINT_CHECK="0" - - WKHTMLTOPDF_VERSION="0.12.5" matrix: - LINT_CHECK="1" @@ -28,11 +49,11 @@ env: install: - - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools + - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git + ${HOME}/maintainer-quality-tools - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} + - export WKHTMLTOPDF_VERSION=0.12.5 - travis_install_nightly - - pip install -q coverage==4.5.4 - - pip install -q QUnitSuite codecov coveralls script: - travis_run_tests diff --git a/README.md b/README.md index 6dfec7a91583..812c1d0e3b3c 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,9 @@ Available addons ---------------- addon | version | summary --- | --- | --- -[l10n_br_account](l10n_br_account/) | 12.0.5.1.0 | Brazilian Localization Account +[l10n_br_account](l10n_br_account/) | 12.0.7.0.0 | Brazilian Localization Account [l10n_br_account_bank_statement_import_cnab](l10n_br_account_bank_statement_import_cnab/) | 12.0.1.0.0 | Importação de Extrato Bancário CNAB 240 - Segmento E -[l10n_br_account_payment_order](l10n_br_account_payment_order/) | 12.0.1.0.0 | Brazilian Payment Order +[l10n_br_account_payment_order](l10n_br_account_payment_order/) | 12.0.3.0.0 | Brazilian Payment Order [l10n_br_base](l10n_br_base/) | 12.0.3.2.0 | Customization of base module for implementations in Brazil. [l10n_br_coa](l10n_br_coa/) | 12.0.3.1.0 | Base Brasilian Localization for the Chart of Accounts [l10n_br_coa_complete](l10n_br_coa_complete/) | 12.0.1.0.0 | Plano de Contas Completo para empresas Simples, Presumido, Real, SA, Consolidação @@ -88,17 +88,18 @@ addon | version | summary [l10n_br_crm](l10n_br_crm/) | 12.0.1.0.0 | Brazilian Localization CRM [l10n_br_currency_rate_update](l10n_br_currency_rate_update/) | 12.0.1.0.0 | Update exchange rates using OCA modules for Brazil [l10n_br_delivery](l10n_br_delivery/) | 12.0.3.0.0 | This module changes the delivery model strategy to match brazilian standards. -[l10n_br_fiscal](l10n_br_fiscal/) | 12.0.13.3.0 | Brazilian fiscal core module. +[l10n_br_fiscal](l10n_br_fiscal/) | 12.0.15.0.1 | Brazilian fiscal core module. [l10n_br_hr](l10n_br_hr/) | 12.0.1.0.0 | Brazilian Localization HR [l10n_br_hr_contract](l10n_br_hr_contract/) | 12.0.1.1.0 | Brazilian Localization HR Contract -[l10n_br_mis_report](l10n_br_mis_report/) | 12.0.1.2.0 | Templates de relatórios contábeis brasileiros: Balanço Patrimonial e DRE -[l10n_br_nfe](l10n_br_nfe/) | 12.0.2.4.0 | Brazilian Eletronic Invoice NF-e . +[l10n_br_mis_report](l10n_br_mis_report/) | 12.0.1.3.0 | Templates de relatórios contábeis brasileiros: Balanço Patrimonial e DRE +[l10n_br_nfe](l10n_br_nfe/) | 12.0.2.5.0 | Brazilian Eletronic Invoice NF-e . [l10n_br_nfe_spec](l10n_br_nfe_spec/) | 12.0.2.0.0 | nfe spec [l10n_br_nfse](l10n_br_nfse/) | 12.0.4.1.0 | NFS-e [l10n_br_nfse_ginfes](l10n_br_nfse_ginfes/) | 12.0.3.0.0 | NFS-e (Ginfes) [l10n_br_nfse_issnet](l10n_br_nfse_issnet/) | 12.0.3.0.0 | NFS-e (ISSNet) [l10n_br_nfse_paulistana](l10n_br_nfse_paulistana/) | 12.0.1.0.0 | NFS-e (Nota Paulistana) [l10n_br_portal](l10n_br_portal/) | 12.0.1.2.0 | Campos Brasileiros no Portal +[l10n_br_product_contract](l10n_br_product_contract/) | 12.0.1.0.0 | Criação de contratos através dos Pedidos de Vendas [l10n_br_purchase](l10n_br_purchase/) | 12.0.4.3.0 | Brazilian Localization Purchase [l10n_br_purchase_stock](l10n_br_purchase_stock/) | 12.0.2.0.0 | Brazilian Localization Purchase Stock [l10n_br_repair](l10n_br_repair/) | 12.0.5.1.0 | Brazilian Localization Repair diff --git a/l10n_br_account/README.rst b/l10n_br_account/README.rst index a912ea7d621b..b0b451a1191a 100644 --- a/l10n_br_account/README.rst +++ b/l10n_br_account/README.rst @@ -54,11 +54,6 @@ To use this module, you need to: * go to ... -Known issues / Roadmap -====================== - - - Bug Tracker =========== diff --git a/l10n_br_account/__init__.py b/l10n_br_account/__init__.py index be7880719353..21f0c546a8f2 100644 --- a/l10n_br_account/__init__.py +++ b/l10n_br_account/__init__.py @@ -5,3 +5,4 @@ from . import models from . import wizards +from . import report diff --git a/l10n_br_account/__manifest__.py b/l10n_br_account/__manifest__.py index 1a903e3df424..345705f3c74b 100644 --- a/l10n_br_account/__manifest__.py +++ b/l10n_br_account/__manifest__.py @@ -7,37 +7,34 @@ "license": "AGPL-3", "author": "Akretion, Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-brazil", - "version": "12.0.5.1.0", + "version": "12.0.7.0.0", "depends": ["account_cancel", "l10n_br_coa", "l10n_br_fiscal"], "data": [ # security - 'security/ir.model.access.csv', - + "security/ir.model.access.csv", # data "data/account_tax_group.xml", "data/account_tax_template.xml", - # Views "views/account_tax_view.xml", "views/account_tax_template_view.xml", "views/fiscal_operation_view.xml", - 'views/fiscal_operation_line_view.xml', - 'views/account_invoice_view.xml', - 'views/account_invoice_line_view.xml', - 'views/document_line_view.xml', - 'views/document_view.xml', - 'views/fiscal_invoice_view.xml', - 'views/fiscal_invoice_line_view.xml', - + "views/fiscal_operation_line_view.xml", + "views/account_invoice_view.xml", + "views/account_invoice_line_view.xml", + "views/document_line_view.xml", + "views/document_view.xml", + "views/fiscal_invoice_view.xml", + "views/fiscal_invoice_line_view.xml", # Wizards - 'wizards/account_invoice_refund_view.xml', - 'wizards/wizard_document_status.xml', - + "wizards/account_invoice_refund_view.xml", + "wizards/wizard_document_status.xml", # Actions "views/l10n_br_account_action.xml", - # Menus "views/l10n_br_account_menu.xml", + # Report + "report/account_invoice_report_view.xml", ], "demo": [ "demo/res_users_demo.xml", diff --git a/l10n_br_account/data/account_tax_group.xml b/l10n_br_account/data/account_tax_group.xml index 0eed795486db..9eb59f8f5e0b 100644 --- a/l10n_br_account/data/account_tax_group.xml +++ b/l10n_br_account/data/account_tax_group.xml @@ -1,120 +1,120 @@ - + IPI - + II - + ICMS - + ICMS SN - + ICMS ST - + ICMS FCP - + PIS - + PIS ST - + PIS WH - + COFINS - + COFINS ST - + COFINS WH - + ISSQN - + ISSQN WH - + CSLL - + CSLL WH - + IR - + IRPJ - + IRPJ WH - + INSS - + INSS WH - + Simples Nacional - + Outros - + diff --git a/l10n_br_account/data/account_tax_template.xml b/l10n_br_account/data/account_tax_template.xml index 18c0ea3fd504..576eb757b5a7 100644 --- a/l10n_br_account/data/account_tax_template.xml +++ b/l10n_br_account/data/account_tax_template.xml @@ -1,170 +1,293 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/l10n_br_account/demo/res_users_demo.xml b/l10n_br_account/demo/res_users_demo.xml index e6c90f71243c..c0f720546785 100644 --- a/l10n_br_account/demo/res_users_demo.xml +++ b/l10n_br_account/demo/res_users_demo.xml @@ -1,12 +1,12 @@ - + - + - + diff --git a/l10n_br_account/hooks.py b/l10n_br_account/hooks.py index 89943ff36ba9..a9178eae08b8 100644 --- a/l10n_br_account/hooks.py +++ b/l10n_br_account/hooks.py @@ -52,17 +52,25 @@ def load_fiscal_taxes(env, l10n_br_coa_chart): template_source = env.ref(template_source_ref) tax_source_ref = ".".join([ref_module, ref_name]) tax_template = env.ref(tax_source_ref) - tax.fiscal_tax_ids = tax_template.fiscal_tax_ids = \ - template_source.fiscal_tax_ids + tax.fiscal_tax_ids = ( + tax_template.fiscal_tax_ids + ) = template_source.fiscal_tax_ids def post_init_hook(cr, registry): """Relate fiscal taxes to account taxes.""" env = api.Environment(cr, SUPERUSER_ID, {}) - l10n_br_coa_charts = env["account.chart.template"].search([]).filtered( - lambda chart: chart.get_external_id().get( - chart.id).split('.')[0].startswith("l10n_br_coa_") - if chart.get_external_id().get(chart.id) else False + l10n_br_coa_charts = ( + env["account.chart.template"] + .search([]) + .filtered( + lambda chart: chart.get_external_id() + .get(chart.id) + .split(".")[0] + .startswith("l10n_br_coa_") + if chart.get_external_id().get(chart.id) + else False + ) ) for l10n_br_coa_chart in l10n_br_coa_charts: load_fiscal_taxes(env, l10n_br_coa_chart) diff --git a/l10n_br_account/i18n/l10n_br_account.pot b/l10n_br_account/i18n/l10n_br_account.pot index 915c5a0067da..54257bc44266 100644 --- a/l10n_br_account/i18n/l10n_br_account.pot +++ b/l10n_br_account/i18n/l10n_br_account.pot @@ -81,12 +81,29 @@ msgstr "" msgid "All Documents" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Ativo Imobilizado" +msgstr "" + #. module: l10n_br_account #: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_tax_form #: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_tax_template_form msgid "Brazilian Tax" msgstr "" +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__cest_id +#: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_product_view_account_invoice_report_search +msgid "CEST" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__cfop_id +#: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_product_view_account_invoice_report_search +msgid "CFOP" +msgstr "" + #. module: l10n_br_account #: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_line__cfop_destination msgid "CFOP Destination" @@ -114,6 +131,11 @@ msgstr "" msgid "Code" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,issuer:0 +msgid "Company" +msgstr "" + #. module: l10n_br_account #: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_line__partner_company_type msgid "Company Type" @@ -151,6 +173,11 @@ msgstr "" msgid "Display Name" msgstr "" +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__document_serie_id +msgid "Document Serie" +msgstr "" + #. module: l10n_br_account #: model:ir.actions.act_window,name:l10n_br_account.wizard_document_status_act_multi msgid "Document Status" @@ -158,17 +185,18 @@ msgstr "" #. module: l10n_br_account #: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_line__document_type_id +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__document_type_id msgid "Document Type" msgstr "" #. module: l10n_br_account -#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:69 +#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:56 #, python-format msgid "Document line without Operation !" msgstr "" #. module: l10n_br_account -#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:39 +#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:34 #, python-format msgid "Document without Operation !" msgstr "" @@ -178,6 +206,11 @@ msgstr "" msgid "Electronic?" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Embalagem" +msgstr "" + #. module: l10n_br_account #: model_terms:ir.ui.view,arch_db:l10n_br_account.invoice_line_form msgid "Extra Info" @@ -217,12 +250,13 @@ msgstr "" #. module: l10n_br_account #: model:ir.model,name:l10n_br_account.model_l10n_br_fiscal_operation_line +#: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_product_view_account_invoice_report_search msgid "Fiscal Operation Line" msgstr "" #. module: l10n_br_account -#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:47 -#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:76 +#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:41 +#: code:addons/l10n_br_account/wizards/account_invoice_refund.py:63 #, python-format msgid "Fiscal Operation: There is not Return Operation for %s !" msgstr "" @@ -322,6 +356,16 @@ msgstr "" msgid "Invoices" msgstr "" +#. module: l10n_br_account +#: model:ir.model,name:l10n_br_account.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__issuer +msgid "Issuer" +msgstr "" + #. module: l10n_br_account #: model:ir.model,name:l10n_br_account.model_account_move msgid "Journal Entries" @@ -343,6 +387,27 @@ msgstr "" msgid "Legal Name" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Material de Uso e Consumo" +msgstr "" + +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Matéria-prima" +msgstr "" + +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Mercadoria para Revenda" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__ncm_id +#: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_product_view_account_invoice_report_search +msgid "NCM" +msgstr "" + #. module: l10n_br_account #: model:ir.actions.act_window,name:l10n_br_account.fiscal_invoice_nfe_action msgid "NF-e" @@ -363,6 +428,16 @@ msgid "Odoo helps you easily track all activities\n" " related to a fiscal operation." msgstr "" +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__fiscal_operation_id +msgid "Operation" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__fiscal_operation_line_id +msgid "Operation Line" +msgstr "" + #. module: l10n_br_account #: model_terms:ir.ui.view,arch_db:l10n_br_account.invoice_line_form msgid "Others" @@ -373,6 +448,16 @@ msgstr "" msgid "Outgoing Document" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Outras" +msgstr "" + +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Outros insumos" +msgstr "" + #. module: l10n_br_account #: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_line__pis_cst_code msgid "PIS CST Code" @@ -384,6 +469,7 @@ msgid "PIS ST CST Code" msgstr "" #. module: l10n_br_account +#: selection:account.invoice.report,issuer:0 #: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_line__partner_id msgid "Partner" msgstr "" @@ -399,17 +485,47 @@ msgstr "" msgid "Payments" msgstr "" +#. module: l10n_br_account +#: model_terms:ir.ui.view,arch_db:l10n_br_account.l10n_br_account_product_view_account_invoice_report_search +msgid "Product Fiscal Type" +msgstr "" + +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Produto Acabado" +msgstr "" + +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Produto Intermediário" +msgstr "" + +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Produto em Processo" +msgstr "" + #. module: l10n_br_account #: model_terms:ir.ui.view,arch_db:l10n_br_account.invoice_form msgid "Receivable" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Serviços" +msgstr "" + #. module: l10n_br_account #: model_terms:ir.ui.view,arch_db:l10n_br_account.fiscal_invoice_search #: model_terms:ir.ui.view,arch_db:l10n_br_account.invoice_search msgid "State Tax Number" msgstr "" +#. module: l10n_br_account +#: selection:account.invoice.report,fiscal_type:0 +msgid "Subproduto" +msgstr "" + #. module: l10n_br_account #: model:ir.model,name:l10n_br_account.model_account_tax msgid "Tax" @@ -436,6 +552,16 @@ msgstr "" msgid "Templates for Taxes" msgstr "" +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__fiscal_type +msgid "Tipo Fiscal" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__total_with_taxes +msgid "Total com Impostos" +msgstr "" + #. module: l10n_br_account #: model:ir.model.fields,help:l10n_br_account.field_account_invoice__legal_name msgid "Used in fiscal documents" @@ -446,6 +572,36 @@ msgstr "" msgid "Validate" msgstr "" +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__cofins_value +msgid "Valor COFINS" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__icms_value +msgid "Valor ICMS" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__icmsst_value +msgid "Valor ICMS ST" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__ii_value +msgid "Valor II" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__ipi_value +msgid "Valor IPI" +msgstr "" + +#. module: l10n_br_account +#: model:ir.model.fields,field_description:l10n_br_account.field_account_invoice_report__pis_value +msgid "Valor PIS" +msgstr "" + #. module: l10n_br_account #: model_terms:ir.ui.view,arch_db:l10n_br_account.fiscal_invoice_form msgid "Voltar para Digitação" @@ -457,7 +613,7 @@ msgid "You can find a contact by its Name, TIN, Email or Internal Reference." msgstr "" #. module: l10n_br_account -#: code:addons/l10n_br_account/models/account_invoice.py:413 +#: code:addons/l10n_br_account/models/account_invoice.py:432 #, python-format msgid "You can't set this document number: {} to draft because this document is cancelled in SEFAZ" msgstr "" diff --git a/l10n_br_account/migrations/12.0.4.0.0/pre-migration.py b/l10n_br_account/migrations/12.0.4.0.0/pre-migration.py index 6124f055010c..01be40fb3bfd 100644 --- a/l10n_br_account/migrations/12.0.4.0.0/pre-migration.py +++ b/l10n_br_account/migrations/12.0.4.0.0/pre-migration.py @@ -4,8 +4,7 @@ from openupgradelib import openupgrade _columns_rename = { - 'account_invoice_line': [ - ('other_costs_value', 'other_value')], + "account_invoice_line": [("other_costs_value", "other_value")], } @@ -14,5 +13,4 @@ def migrate(env, version): for table in _columns_rename.keys(): for rename_column in _columns_rename[table]: if openupgrade.column_exists(env.cr, table, rename_column[0]): - openupgrade.rename_columns( - env.cr, {table: [rename_column]}) + openupgrade.rename_columns(env.cr, {table: [rename_column]}) diff --git a/l10n_br_account/migrations/12.0.7.0.0/pre-migration.py b/l10n_br_account/migrations/12.0.7.0.0/pre-migration.py new file mode 100644 index 000000000000..95f851a958ab --- /dev/null +++ b/l10n_br_account/migrations/12.0.7.0.0/pre-migration.py @@ -0,0 +1,33 @@ +# Copyright (C) 2021 - Raphaêl Valyi - Akretion +# License AGPL-3.0 or later ( +# http://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + +_column_renames = { + # l10n_br_account/models/account_tax.py + "l10n_br_fiscal_account_tax_rel": [ + ("l10n_br_fiscal_tax_id", "fiscal_tax_id"), + ], + # l10n_br_account/models/account_tax_template.py + "l10n_br_fiscal_account_template_tax_rel": [ + ("l10n_br_fiscal_tax_id", "fiscal_tax_id"), + ], +} + + +@openupgrade.migrate(use_env=True) +def migrate(env, version): + openupgrade.rename_columns(env.cr, _column_renames) + openupgrade.rename_tables( + env.cr, [("l10n_br_fiscal_account_tax_rel", "fiscal_account_tax_rel")] + ) + openupgrade.rename_tables( + env.cr, + [ + ( + "l10n_br_fiscal_account_template_tax_rel", + "fiscal_account_template_tax_rel", + ) + ], + ) diff --git a/l10n_br_account/models/account_document_line_mixin.py b/l10n_br_account/models/account_document_line_mixin.py index 569853f61bff..5c2d9c0b6ef4 100644 --- a/l10n_br_account/models/account_document_line_mixin.py +++ b/l10n_br_account/models/account_document_line_mixin.py @@ -5,17 +5,16 @@ class DocumentLineMixin(models.AbstractModel): - _name = 'l10n_br_account.document.line.mixin' - _description = 'Account Document Line Mixin' + _name = "l10n_br_account.document.line.mixin" + _description = "Account Document Line Mixin" fiscal_position_id = fields.Many2one( - comodel_name='account.fiscal.position', - string='Fiscal Position', + comodel_name="account.fiscal.position", + string="Fiscal Position", ) - @api.onchange('product_id') + @api.onchange("product_id") def _onchange_product_id_account(self): if self.fiscal_operation_id: if self.fiscal_operation_id.fiscal_position_id: - self.fiscal_position_id = ( - self.fiscal_operation_id.fiscal_position_id) + self.fiscal_position_id = self.fiscal_operation_id.fiscal_position_id diff --git a/l10n_br_account/models/account_invoice.py b/l10n_br_account/models/account_invoice.py index b578d9f24cc2..a4a5648f80a6 100644 --- a/l10n_br_account/models/account_invoice.py +++ b/l10n_br_account/models/account_invoice.py @@ -2,6 +2,7 @@ # Copyright (C) 2019 - TODAY Raphaël Valyi - Akretion # Copyright (C) 2020 - TODAY Luis Felipe Mileo - KMEE # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +# pylint: disable=api-one-deprecated from lxml import etree @@ -9,83 +10,84 @@ from odoo.exceptions import UserError from odoo.addons.l10n_br_fiscal.constants.fiscal import ( - FISCAL_OUT, DOCUMENT_ISSUER_COMPANY, DOCUMENT_ISSUER_PARTNER, + FISCAL_OUT, SITUACAO_EDOC_CANCELADA, SITUACAO_EDOC_EM_DIGITACAO, ) INVOICE_TO_OPERATION = { - 'out_invoice': 'out', - 'in_invoice': 'in', - 'out_refund': 'in', - 'in_refund': 'out', + "out_invoice": "out", + "in_invoice": "in", + "out_refund": "in", + "in_refund": "out", } REFUND_TO_OPERATION = { - 'out_invoice': 'in', - 'in_invoice': 'out', - 'out_refund': 'out', - 'in_refund': 'in', + "out_invoice": "in", + "in_invoice": "out", + "out_refund": "out", + "in_refund": "in", } FISCAL_TYPE_REFUND = { - 'out': ['purchase_return', 'in_return'], - 'in': ['sale_return', 'out_return'], + "out": ["purchase_return", "in_return"], + "in": ["sale_return", "out_return"], } SHADOWED_FIELDS = [ - 'partner_id', - 'company_id', - 'currency_id', - 'partner_shipping_id', + "partner_id", + "company_id", + "currency_id", + "partner_shipping_id", ] class AccountInvoice(models.Model): - _name = 'account.invoice' + _name = "account.invoice" _inherit = [ _name, - 'l10n_br_fiscal.document.mixin.methods', - 'l10n_br_fiscal.document.invoice.mixin'] - _inherits = {'l10n_br_fiscal.document': 'fiscal_document_id'} - _order = 'date_invoice DESC, number DESC' + "l10n_br_fiscal.document.mixin.methods", + "l10n_br_fiscal.document.invoice.mixin", + ] + _inherits = {"l10n_br_fiscal.document": "fiscal_document_id"} + _order = "date_invoice DESC, number DESC" # initial account.invoice inherits on fiscal.document that are # disable with active=False in their fiscal_document table. # To make these invoices still visible, we set active=True # in the invoice table. active = fields.Boolean( - string='Active', + string="Active", default=True, ) cnpj_cpf = fields.Char( - string='CNPJ/CPF', - related='partner_id.cnpj_cpf', + string="CNPJ/CPF", + related="partner_id.cnpj_cpf", ) legal_name = fields.Char( - string='Adapted Legal Name', - related='partner_id.legal_name', + string="Adapted Legal Name", + related="partner_id.legal_name", ) ie = fields.Char( - string='Adapted State Tax Number', - related='partner_id.inscr_est', + string="Adapted State Tax Number", + related="partner_id.inscr_est", ) financial_move_line_ids = fields.Many2many( - comodel_name='account.move.line', - string='Financial Move Lines', + comodel_name="account.move.line", + string="Financial Move Lines", store=True, - compute='_compute_financial', + compute="_compute_financial", ) document_electronic = fields.Boolean( - related='document_type_id.electronic', - string='Electronic?', + related="document_type_id.electronic", + string="Electronic?", ) # this default should be overwritten to False in a module pretending to @@ -93,28 +95,29 @@ class AccountInvoice(models.Model): # allows to install the l10n_br_account module without creating issues # with the existing Odoo invoice (demo or not). fiscal_document_id = fields.Many2one( - comodel_name='l10n_br_fiscal.document', - string='Fiscal Document', + comodel_name="l10n_br_fiscal.document", + string="Fiscal Document", required=True, copy=False, - ondelete='cascade', + ondelete="cascade", ) document_type = fields.Char( - related='document_type_id.code', + related="document_type_id.code", stored=True, ) def _get_amount_lines(self): """Get object lines instaces used to compute fields""" - return self.mapped('invoice_line_ids') + return self.mapped("invoice_line_ids") - @api.depends('move_id.line_ids', 'move_id.state') + @api.depends("move_id.line_ids", "move_id.state") def _compute_financial(self): for invoice in self: lines = invoice.move_id.line_ids.filtered( - lambda l: l.account_id == invoice.account_id and - l.account_id.internal_type in ('receivable', 'payable')) + lambda l: l.account_id == invoice.account_id + and l.account_id.internal_type in ("receivable", "payable") + ) invoice.financial_move_line_ids = lines.sorted() @api.model @@ -127,72 +130,77 @@ def _prepare_shadowed_fields_dict(self, default=False): self.ensure_one() vals = self._convert_to_write(self.read(self._shadowed_fields())[0]) if default: # in case you want to use new rather than write later - return {'default_%s' % (k,): vals[k] for k in vals.keys()} + return {"default_%s" % (k,): vals[k] for k in vals.keys()} return vals def _write_shadowed_fields(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for invoice in self: if invoice.fiscal_document_id != dummy_doc: shadowed_fiscal_vals = invoice._prepare_shadowed_fields_dict() invoice.fiscal_document_id.write(shadowed_fiscal_vals) @api.model - def fields_view_get(self, view_id=None, view_type="form", - toolbar=False, submenu=False): + def fields_view_get( + self, view_id=None, view_type="form", toolbar=False, submenu=False + ): - order_view = super().fields_view_get( - view_id, view_type, toolbar, submenu - ) + order_view = super().fields_view_get(view_id, view_type, toolbar, submenu) - if view_type == 'form': - view = self.env['ir.ui.view'] + if view_type == "form": + view = self.env["ir.ui.view"] - if (view_id == self.env.ref( - 'l10n_br_account.fiscal_invoice_form').id): + if view_id == self.env.ref("l10n_br_account.fiscal_invoice_form").id: invoice_line_form_id = self.env.ref( - 'l10n_br_account.fiscal_invoice_line_form').id + "l10n_br_account.fiscal_invoice_line_form" + ).id else: invoice_line_form_id = self.env.ref( - 'l10n_br_account.invoice_line_form').id + "l10n_br_account.invoice_line_form" + ).id - sub_form_view = self.env['account.invoice.line'].fields_view_get( - view_id=invoice_line_form_id, view_type='form')['arch'] + sub_form_view = self.env["account.invoice.line"].fields_view_get( + view_id=invoice_line_form_id, view_type="form" + )["arch"] sub_form_node = etree.fromstring( - self.env['account.invoice.line'].fiscal_form_view( - sub_form_view)) + self.env["account.invoice.line"].fiscal_form_view(sub_form_view) + ) sub_arch, sub_fields = view.postprocess_and_fields( - 'account.invoice.line', sub_form_node, None) + "account.invoice.line", sub_form_node, None + ) - order_view['fields']['invoice_line_ids']['views']['form'] = {} + order_view["fields"]["invoice_line_ids"]["views"]["form"] = {} - order_view['fields']['invoice_line_ids']['views']['form'][ - 'fields'] = sub_fields - order_view['fields']['invoice_line_ids']['views']['form'][ - 'arch'] = sub_arch + order_view["fields"]["invoice_line_ids"]["views"]["form"][ + "fields" + ] = sub_fields + order_view["fields"]["invoice_line_ids"]["views"]["form"]["arch"] = sub_arch return order_view @api.model def default_get(self, fields_list): defaults = super().default_get(fields_list) - invoice_type = self.env.context.get('type', 'out_invoice') - defaults['fiscal_operation_type'] = INVOICE_TO_OPERATION[invoice_type] - if defaults['fiscal_operation_type'] == FISCAL_OUT: - defaults['issuer'] = DOCUMENT_ISSUER_COMPANY + invoice_type = self.env.context.get("type", "out_invoice") + defaults["fiscal_operation_type"] = INVOICE_TO_OPERATION[invoice_type] + if defaults["fiscal_operation_type"] == FISCAL_OUT: + defaults["issuer"] = DOCUMENT_ISSUER_COMPANY else: - defaults['issuer'] = DOCUMENT_ISSUER_PARTNER + defaults["issuer"] = DOCUMENT_ISSUER_PARTNER return defaults @api.model def create(self, values): - if not values.get('document_type_id'): - values.update({ - 'fiscal_document_id': self.env.ref( - 'l10n_br_fiscal.fiscal_document_dummy').id - }) + if not values.get("document_type_id"): + values.update( + { + "fiscal_document_id": self.env.ref( + "l10n_br_fiscal.fiscal_document_dummy" + ).id + } + ) invoice = super().create(values) invoice._write_shadowed_fields() return invoice @@ -204,32 +212,34 @@ def write(self, values): def unlink(self): """Allows delete a draft or cancelled invoices""" - self.filtered(lambda i: i.state in ('draft', 'cancel')).write( - {'move_name': False} + self.filtered(lambda i: i.state in ("draft", "cancel")).write( + {"move_name": False} ) return super().unlink() - @api.returns('self', lambda value: value.id) + @api.returns("self", lambda value: value.id) def copy(self, default=None): default = default or {} - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") if self.fiscal_document_id != dummy_doc: - default['line_ids'] = False + default["line_ids"] = False return super().copy(default) @api.one @api.depends( - 'invoice_line_ids.price_total', - 'tax_line_ids.amount', - 'tax_line_ids.amount_rounding', - 'currency_id', - 'company_id', - 'date_invoice', - 'type') + "invoice_line_ids.price_total", + "tax_line_ids.amount", + "tax_line_ids.amount_rounding", + "currency_id", + "company_id", + "date_invoice", + "type", + ) def _compute_amount(self): inv_lines = self.invoice_line_ids.filtered( - lambda l: not l.fiscal_operation_line_id or - l.fiscal_operation_line_id.add_to_amount) + lambda l: not l.fiscal_operation_line_id + or l.fiscal_operation_line_id.add_to_amount + ) for inv_line in inv_lines: if inv_line.cfop_id: if inv_line.cfop_id.finance_move: @@ -245,16 +255,25 @@ def _compute_amount(self): amount_total_company_signed = self.amount_total amount_untaxed_signed = self.amount_untaxed - if (self.currency_id and self.company_id and - self.currency_id != self.company_id.currency_id): + if ( + self.currency_id + and self.company_id + and self.currency_id != self.company_id.currency_id + ): currency_id = self.currency_id amount_total_company_signed = currency_id._convert( - self.amount_total, self.company_id.currency_id, - self.company_id, self.date_invoice or fields.Date.today()) + self.amount_total, + self.company_id.currency_id, + self.company_id, + self.date_invoice or fields.Date.today(), + ) amount_untaxed_signed = currency_id._convert( - self.amount_untaxed, self.company_id.currency_id, - self.company_id, self.date_invoice or fields.Date.today()) - sign = self.type in ['in_refund', 'out_refund'] and -1 or 1 + self.amount_untaxed, + self.company_id.currency_id, + self.company_id, + self.date_invoice or fields.Date.today(), + ) + sign = self.type in ["in_refund", "out_refund"] and -1 or 1 self.amount_total_company_signed = amount_total_company_signed * sign self.amount_total_signed = self.amount_total * sign self.amount_untaxed_signed = amount_untaxed_signed * sign @@ -264,8 +283,8 @@ def invoice_line_move_line_get(self): move_lines_dict = super().invoice_line_move_line_get() new_mv_lines_dict = [] for line in move_lines_dict: - invoice_line = self.invoice_line_ids.browse(line.get('invl_id')) - line['price'] = invoice_line.price_total + invoice_line = self.invoice_line_ids.browse(line.get("invl_id")) + line["price"] = invoice_line.price_total if invoice_line.cfop_id: if invoice_line.cfop_id.finance_move: new_mv_lines_dict.append(line) @@ -289,21 +308,21 @@ def tax_line_move_line_get(self): def finalize_invoice_move_lines(self, move_lines): lines = super().finalize_invoice_move_lines(move_lines) - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") financial_lines = [ - l for l in lines if l[2]['account_id'] == self.account_id.id] - + line for line in lines if line[2]["account_id"] == self.account_id.id + ] count = 1 - for l in financial_lines: - if l[2]['debit'] or l[2]['credit']: + for line in financial_lines: + if line[2]["debit"] or line[2]["credit"]: if self.fiscal_document_id != dummy_doc: - l[2]['name'] = '{}/{}-{}'.format( + line[2]["name"] = "{}/{}-{}".format( self.fiscal_document_id.with_context( fiscal_document_no_company=True )._compute_document_name(), count, - len(financial_lines) + len(financial_lines), ) count += 1 return lines @@ -339,49 +358,47 @@ def get_taxes_values(self): fiscal_price=line.fiscal_price, fiscal_quantity=line.fiscal_quantity, uot=line.uot_id, - icmssn_range=line.icmssn_range_id)['taxes'] + icmssn_range=line.icmssn_range_id, + )["taxes"] line._update_taxes() for tax in taxes: - if tax.get('amount', 0.0) != 0.0: + if tax.get("amount", 0.0) != 0.0: val = self._prepare_tax_line_vals(line, tax) - key = self.env['account.tax'].browse( - tax['id']).get_grouping_key(val) + key = ( + self.env["account.tax"].browse(tax["id"]).get_grouping_key(val) + ) if key not in tax_grouped: tax_grouped[key] = val - tax_grouped[key]['base'] = round_curr(val['base']) + tax_grouped[key]["base"] = round_curr(val["base"]) else: - tax_grouped[key]['amount'] += val['amount'] - tax_grouped[key]['base'] += round_curr(val['base']) + tax_grouped[key]["amount"] += val["amount"] + tax_grouped[key]["base"] += round_curr(val["base"]) return tax_grouped - @api.onchange('fiscal_operation_id') + @api.onchange("fiscal_operation_id") def _onchange_fiscal_operation_id(self): super()._onchange_fiscal_operation_id() if self.fiscal_operation_id and self.fiscal_operation_id.journal_id: self.journal_id = self.fiscal_operation_id.journal_id def open_fiscal_document(self): - if self.env.context.get('type', '') == 'out_invoice': - action = self.env.ref( - 'l10n_br_account.fiscal_invoice_out_action').read()[0] - elif self.env.context.get('type', '') == 'in_invoice': - action = self.env.ref( - 'l10n_br_account.fiscal_invoice_in_action').read()[0] + if self.env.context.get("type", "") == "out_invoice": + action = self.env.ref("l10n_br_account.fiscal_invoice_out_action").read()[0] + elif self.env.context.get("type", "") == "in_invoice": + action = self.env.ref("l10n_br_account.fiscal_invoice_in_action").read()[0] else: - action = self.env.ref( - 'l10n_br_account.fiscal_invoice_all_action').read()[0] - form_view = [ - (self.env.ref('l10n_br_account.fiscal_invoice_form').id, 'form')] - if 'views' in action: - action['views'] = form_view + [ - (state, view) for state, view in action['views'] - if view != 'form'] + action = self.env.ref("l10n_br_account.fiscal_invoice_all_action").read()[0] + form_view = [(self.env.ref("l10n_br_account.fiscal_invoice_form").id, "form")] + if "views" in action: + action["views"] = form_view + [ + (state, view) for state, view in action["views"] if view != "form" + ] else: - action['views'] = form_view - action['res_id'] = self.id + action["views"] = form_view + action["res_id"] = self.id return action def action_date_assign(self): @@ -389,7 +406,7 @@ def action_date_assign(self): fiscal e numeração do documento fiscal para ser usado nas linhas dos lançamentos contábeis.""" super().action_date_assign() - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for invoice in self: if invoice.fiscal_document_id != dummy_doc: if invoice.issuer == DOCUMENT_ISSUER_COMPANY: @@ -398,57 +415,62 @@ def action_date_assign(self): def action_move_create(self): result = super().action_move_create() - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') - self.mapped('fiscal_document_id').filtered( - lambda d: d != dummy_doc).action_document_confirm() + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") + self.mapped("fiscal_document_id").filtered( + lambda d: d != dummy_doc + ).action_document_confirm() return result def action_invoice_draft(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): if i.state_edoc == SITUACAO_EDOC_CANCELADA: if i.issuer == DOCUMENT_ISSUER_COMPANY: - raise UserError(_( - "You can't set this document number: {} to draft " - "because this document is cancelled in SEFAZ".format( - i.document_number))) + raise UserError( + _( + "You can't set this document number: {} to draft " + "because this document is cancelled in SEFAZ".format( + i.document_number + ) + ) + ) if i.state_edoc != SITUACAO_EDOC_EM_DIGITACAO: i.fiscal_document_id.action_document_back2draft() return super().action_invoice_draft() def action_document_send(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") invoices = self.filtered(lambda d: d.fiscal_document_id != dummy_doc) if invoices: - invoices.mapped('fiscal_document_id').action_document_send() + invoices.mapped("fiscal_document_id").action_document_send() for invoice in invoices: invoice.move_id.post(invoice=invoice) def action_document_cancel(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): return i.fiscal_document_id.action_document_cancel() def action_document_correction(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): return i.fiscal_document_id.action_document_correction() def action_document_invalidate(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): return i.fiscal_document_id.action_document_invalidate() def action_document_back2draft(self): """Sets fiscal document to draft state and cancel and set to draft the related invoice for both documents remain equivalent state.""" - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): i.action_cancel() i.action_invoice_draft() def action_invoice_cancel(self): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): return i.fiscal_document_id.action_document_cancel() return super().action_invoice_cancel() diff --git a/l10n_br_account/models/account_invoice_line.py b/l10n_br_account/models/account_invoice_line.py index 4a09ac0f59db..b3097068f84b 100644 --- a/l10n_br_account/models/account_invoice_line.py +++ b/l10n_br_account/models/account_invoice_line.py @@ -1,13 +1,11 @@ # Copyright (C) 2009 - TODAY Renato Lima - Akretion # Copyright (C) 2019 - TODAY Raphaël Valyi - Akretion # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +# pylint: disable=api-one-deprecated from odoo import api, fields, models -from odoo.addons.l10n_br_fiscal.constants.fiscal import ( - TAX_FRAMEWORK, - # FISCAL_IN_OUT, -) +from odoo.addons.l10n_br_fiscal.constants.fiscal import TAX_FRAMEWORK # FISCAL_IN_OUT, from .account_invoice import INVOICE_TO_OPERATION @@ -17,22 +15,30 @@ # in l10n_br_fiscal but that would make the code unreadable and fiscal mixin # methods would fail to do what we expect from them in the Odoo objects # where they are injected. -SHADOWED_FIELDS = ['name', 'partner_id', 'company_id', 'currency_id', - 'product_id', 'uom_id', 'quantity', 'price_unit', - 'discount_value'] +SHADOWED_FIELDS = [ + "name", + "partner_id", + "company_id", + "currency_id", + "product_id", + "uom_id", + "quantity", + "price_unit", + "discount_value", +] class AccountInvoiceLine(models.Model): - _name = 'account.invoice.line' - _inherit = [_name, 'l10n_br_fiscal.document.line.mixin.methods'] - _inherits = {'l10n_br_fiscal.document.line': 'fiscal_document_line_id'} + _name = "account.invoice.line" + _inherit = [_name, "l10n_br_fiscal.document.line.mixin.methods"] + _inherits = {"l10n_br_fiscal.document.line": "fiscal_document_line_id"} # initial account.invoice.line inherits on fiscal.document.line that are # disable with active=False in their fiscal_document_line table. # To make these invoice lines still visible, we set active=True # in the invoice.line table. active = fields.Boolean( - string='Active', + string="Active", default=True, ) @@ -41,38 +47,35 @@ class AccountInvoiceLine(models.Model): # allows to install the l10n_br_account module without creating issues # with the existing Odoo invoice (demo or not). fiscal_document_line_id = fields.Many2one( - comodel_name='l10n_br_fiscal.document.line', - string='Fiscal Document Line', + comodel_name="l10n_br_fiscal.document.line", + string="Fiscal Document Line", required=True, copy=False, - ondelete='cascade', + ondelete="cascade", ) document_type_id = fields.Many2one( - comodel_name='l10n_br_fiscal.document.type', - related='invoice_id.document_type_id', + comodel_name="l10n_br_fiscal.document.type", + related="invoice_id.document_type_id", ) tax_framework = fields.Selection( selection=TAX_FRAMEWORK, - related='invoice_id.company_id.tax_framework', - string='Tax Framework', + related="invoice_id.company_id.tax_framework", + string="Tax Framework", ) cfop_destination = fields.Selection( - related="cfop_id.destination", - string="CFOP Destination" + related="cfop_id.destination", string="CFOP Destination" ) partner_id = fields.Many2one( - comodel_name='res.partner', - related='invoice_id.partner_id', - string='Partner', + comodel_name="res.partner", + related="invoice_id.partner_id", + string="Partner", ) - partner_company_type = fields.Selection( - related="partner_id.company_type" - ) + partner_company_type = fields.Selection(related="partner_id.company_type") fiscal_genre_code = fields.Char( related="fiscal_genre_id.code", @@ -111,50 +114,59 @@ class AccountInvoiceLine(models.Model): @api.one @api.depends( - 'price_unit', - 'discount', - 'invoice_line_tax_ids', - 'quantity', - 'product_id', - 'invoice_id.partner_id', - 'invoice_id.currency_id', - 'invoice_id.company_id', - 'invoice_id.date_invoice', - 'invoice_id.date', - 'fiscal_tax_ids') + "price_unit", + "discount", + "invoice_line_tax_ids", + "quantity", + "product_id", + "invoice_id.partner_id", + "invoice_id.currency_id", + "invoice_id.company_id", + "invoice_id.date_invoice", + "invoice_id.date", + "fiscal_tax_ids", + ) def _compute_price(self): """Compute the amounts of the SO line.""" super()._compute_price() - dummy_doc_line_id = self.env.ref( - 'l10n_br_fiscal.fiscal_document_line_dummy') - if (self.fiscal_document_line_id and self.fiscal_document_line_id - != dummy_doc_line_id): + dummy_doc_line_id = self.env.ref("l10n_br_fiscal.fiscal_document_line_dummy") + if ( + self.fiscal_document_line_id + and self.fiscal_document_line_id != dummy_doc_line_id + ): # Update taxes fields self._update_taxes() # Call mixin compute method self._compute_amounts() # Update record - self.update({ - 'discount': self.discount_value, - 'price_subtotal': self.amount_untaxed + self.discount_value, - 'price_tax': self.amount_tax, - 'price_total': self.amount_total, - }) + self.update( + { + "discount": self.discount_value, + "price_subtotal": self.amount_untaxed + self.discount_value, + "price_tax": self.amount_tax, + "price_total": self.amount_total, + } + ) price_subtotal_signed = self.price_subtotal - if (self.invoice_id.currency_id and self.invoice_id.currency_id - != self.invoice_id.company_id.currency_id): + if ( + self.invoice_id.currency_id + and self.invoice_id.currency_id + != self.invoice_id.company_id.currency_id + ): currency = self.invoice_id.currency_id date = self.invoice_id._get_currency_rate_date() price_subtotal_signed = currency._convert( - price_subtotal_signed, self.invoice_id.company_id.currency_id, + price_subtotal_signed, + self.invoice_id.company_id.currency_id, self.company_id or self.env.user.company_id, - date or fields.Date.today()) - sign = self.invoice_id.type in ['in_refund', 'out_refund'] and -1 or 1 + date or fields.Date.today(), + ) + sign = self.invoice_id.type in ["in_refund", "out_refund"] and -1 or 1 self.price_subtotal_signed = price_subtotal_signed * sign - @api.depends('price_total') + @api.depends("price_total") def _get_price_tax(self): for line in self: line.price_tax = line.amount_tax @@ -175,39 +187,48 @@ def _prepare_shadowed_fields_dict(self, default=False): @api.model def default_get(self, fields_list): defaults = super().default_get(fields_list) - inv_type = self.env.context.get('type', 'out_invoice') - defaults['fiscal_operation_type'] = INVOICE_TO_OPERATION[inv_type] + inv_type = self.env.context.get("type", "out_invoice") + defaults["fiscal_operation_type"] = INVOICE_TO_OPERATION[inv_type] return defaults @api.model def create(self, values): - dummy_doc_line_id = self.env.ref( - 'l10n_br_fiscal.fiscal_document_line_dummy').id - dummy_doc_id = self.env.ref('l10n_br_fiscal.fiscal_document_dummy').id - fiscal_doc_id = self.env['account.invoice'].browse( - values['invoice_id']).fiscal_document_id.id + dummy_doc_line_id = self.env.ref("l10n_br_fiscal.fiscal_document_line_dummy").id + dummy_doc_id = self.env.ref("l10n_br_fiscal.fiscal_document_dummy").id + fiscal_doc_id = ( + self.env["account.invoice"] + .browse(values["invoice_id"]) + .fiscal_document_id.id + ) if dummy_doc_id == fiscal_doc_id: - values['fiscal_document_line_id'] = dummy_doc_line_id - - values.update(self._update_fiscal_quantity( - values.get('product_id'), values.get('price_unit'), - values.get('quantity'), values.get('uom_id'), - values.get('uot_id'))) + values["fiscal_document_line_id"] = dummy_doc_line_id + + values.update( + self._update_fiscal_quantity( + values.get("product_id"), + values.get("price_unit"), + values.get("quantity"), + values.get("uom_id"), + values.get("uot_id"), + ) + ) line = super().create(values) if dummy_doc_id != fiscal_doc_id: shadowed_fiscal_vals = line._prepare_shadowed_fields_dict() doc_id = line.invoice_id.fiscal_document_id.id - shadowed_fiscal_vals['document_id'] = doc_id + shadowed_fiscal_vals["document_id"] = doc_id line.fiscal_document_line_id.write(shadowed_fiscal_vals) return line def write(self, values): - dummy_line = self.env.ref('l10n_br_fiscal.fiscal_document_line_dummy') - if values.get('invoice_id'): - values['document_id'] = self.env[ - "account.invoice"].browse( - values['invoice_id']).fiscal_document_id.id + dummy_line = self.env.ref("l10n_br_fiscal.fiscal_document_line_dummy") + if values.get("invoice_id"): + values["document_id"] = ( + self.env["account.invoice"] + .browse(values["invoice_id"]) + .fiscal_document_id.id + ) result = super().write(values) for line in self: if line.fiscal_document_line_id != dummy_line: @@ -216,9 +237,8 @@ def write(self, values): return result def unlink(self): - dummy_doc_line_id = self.env.ref( - 'l10n_br_fiscal.fiscal_document_line_dummy').id - unlink_fiscal_lines = self.env['l10n_br_fiscal.document.line'] + dummy_doc_line_id = self.env.ref("l10n_br_fiscal.fiscal_document_line_dummy").id + unlink_fiscal_lines = self.env["l10n_br_fiscal.document.line"] for inv_line in self: if not inv_line.exists(): continue @@ -229,11 +249,12 @@ def unlink(self): self.clear_caches() return result - @api.onchange('fiscal_tax_ids') + @api.onchange("fiscal_tax_ids") def _onchange_fiscal_tax_ids(self): super()._onchange_fiscal_tax_ids() - user_type = 'sale' - if self.invoice_id.type in ('in_invoice', 'in_refund'): - user_type = 'purchase' + user_type = "sale" + if self.invoice_id.type in ("in_invoice", "in_refund"): + user_type = "purchase" self.invoice_line_tax_ids |= self.fiscal_tax_ids.account_taxes( - user_type=user_type) + user_type=user_type + ) diff --git a/l10n_br_account/models/account_journal.py b/l10n_br_account/models/account_journal.py index 12efa5eff1a3..db27b228064f 100644 --- a/l10n_br_account/models/account_journal.py +++ b/l10n_br_account/models/account_journal.py @@ -5,8 +5,8 @@ class AccountJournal(models.Model): - _inherit = 'account.journal' + _inherit = "account.journal" revenue_expense = fields.Boolean( - string='Gera Financeiro', + string="Gera Financeiro", ) diff --git a/l10n_br_account/models/account_move.py b/l10n_br_account/models/account_move.py index 5cd4dc2f03d1..2b602cf847ce 100644 --- a/l10n_br_account/models/account_move.py +++ b/l10n_br_account/models/account_move.py @@ -4,21 +4,23 @@ from odoo import models from odoo.addons.l10n_br_fiscal.constants.fiscal import ( - SITUACAO_EDOC_AUTORIZADA, DOCUMENT_ISSUER_COMPANY, + SITUACAO_EDOC_AUTORIZADA, ) class AccountMove(models.Model): - _inherit = 'account.move' + _inherit = "account.move" def post(self, invoice=False): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + dummy_doc = self.env.ref("l10n_br_fiscal.fiscal_document_dummy") result = super().post(invoice) if invoice: - if (invoice.fiscal_document_id != dummy_doc - and invoice.document_electronic - and invoice.issuer == DOCUMENT_ISSUER_COMPANY - and invoice.state_edoc != SITUACAO_EDOC_AUTORIZADA): + if ( + invoice.fiscal_document_id != dummy_doc + and invoice.document_electronic + and invoice.issuer == DOCUMENT_ISSUER_COMPANY + and invoice.state_edoc != SITUACAO_EDOC_AUTORIZADA + ): self.button_cancel() return result diff --git a/l10n_br_account/models/account_move_line.py b/l10n_br_account/models/account_move_line.py index db278ab9dec3..3e49ffb14ceb 100644 --- a/l10n_br_account/models/account_move_line.py +++ b/l10n_br_account/models/account_move_line.py @@ -6,5 +6,5 @@ class AccountMoveLine(models.Model): - _inherit = 'account.move.line' - _order = 'date_maturity, date desc, id desc' + _inherit = "account.move.line" + _order = "date_maturity, date desc, id desc" diff --git a/l10n_br_account/models/account_tax.py b/l10n_br_account/models/account_tax.py index 76ecfb867537..40d6f320fed6 100644 --- a/l10n_br_account/models/account_tax.py +++ b/l10n_br_account/models/account_tax.py @@ -5,14 +5,14 @@ class AccountTax(models.Model): - _inherit = 'account.tax' + _inherit = "account.tax" fiscal_tax_ids = fields.Many2many( - comodel_name='l10n_br_fiscal.tax', - relation='l10n_br_fiscal_account_tax_rel', - colunm1='account_tax_id', - colunm2='fiscal_tax_id', - string='Fiscal Taxes', + comodel_name="l10n_br_fiscal.tax", + relation="fiscal_account_tax_rel", + column1="account_tax_id", + column2="fiscal_tax_id", + string="Fiscal Taxes", ) def compute_all( @@ -36,9 +36,9 @@ def compute_all( fiscal_quantity=None, uot=None, icmssn_range=None, - icms_origin=None + icms_origin=None, ): - """ Returns all information required to apply taxes + """Returns all information required to apply taxes (in self + their children in case of a tax goup). We consider the sequence of the parent for group of taxes. Eg. considering letters as taxes and alphabetic order @@ -57,15 +57,16 @@ def compute_all( 'refund_account_id': int, 'analytic': boolean, }] - } """ + }""" taxes_results = super().compute_all( - price_unit, currency, quantity, product, partner) + price_unit, currency, quantity, product, partner + ) if not fiscal_taxes: - fiscal_taxes = self.env['l10n_br_fiscal.tax'] + fiscal_taxes = self.env["l10n_br_fiscal.tax"] - product = product or self.env['product.product'] + product = product or self.env["product.product"] # FIXME Should get company from document? fiscal_taxes_results = fiscal_taxes.compute_taxes( @@ -88,38 +89,41 @@ def compute_all( freight_value=freight_value, operation_line=operation_line, icmssn_range=icmssn_range, - icms_origin=icms_origin or product.icms_origin) + icms_origin=icms_origin or product.icms_origin, + ) account_taxes_by_domain = {} for tax in self: tax_domain = tax.tax_group_id.fiscal_tax_group_id.tax_domain account_taxes_by_domain.update({tax.id: tax_domain}) - for account_tax in taxes_results['taxes']: - fiscal_tax = fiscal_taxes_results['taxes'].get( - account_taxes_by_domain.get(account_tax.get('id')) + for account_tax in taxes_results["taxes"]: + fiscal_tax = fiscal_taxes_results["taxes"].get( + account_taxes_by_domain.get(account_tax.get("id")) ) if fiscal_tax: - tax = self.filtered(lambda t: t.id == account_tax.get('id')) - if not fiscal_tax.get('tax_include') and not tax.deductible: - taxes_results['total_included'] += fiscal_tax.get( - 'tax_value') + tax = self.filtered(lambda t: t.id == account_tax.get("id")) + if not fiscal_tax.get("tax_include") and not tax.deductible: + taxes_results["total_included"] += fiscal_tax.get("tax_value") - account_tax.update({ - 'id': account_tax.get('id'), - 'name': '{0} ({1})'.format( - account_tax.get('name'), - fiscal_tax.get('name') - ), - 'amount': fiscal_tax.get('tax_value'), - 'base': fiscal_tax.get('base'), - 'tax_include': fiscal_tax.get('tax_include'), - }) + account_tax.update( + { + "id": account_tax.get("id"), + "name": "{} ({})".format( + account_tax.get("name"), fiscal_tax.get("name") + ), + "amount": fiscal_tax.get("tax_value"), + "base": fiscal_tax.get("base"), + "tax_include": fiscal_tax.get("tax_include"), + } + ) if tax.deductible: - account_tax.update({ - 'amount': fiscal_tax.get('tax_value', 0.0) * -1, - }) + account_tax.update( + { + "amount": fiscal_tax.get("tax_value", 0.0) * -1, + } + ) return taxes_results diff --git a/l10n_br_account/models/account_tax_group.py b/l10n_br_account/models/account_tax_group.py index df4153204e1b..941ff87ecc29 100644 --- a/l10n_br_account/models/account_tax_group.py +++ b/l10n_br_account/models/account_tax_group.py @@ -5,9 +5,9 @@ class AccountTaxGroup(models.Model): - _inherit = 'account.tax.group' + _inherit = "account.tax.group" fiscal_tax_group_id = fields.Many2one( - comodel_name='l10n_br_fiscal.tax.group', - string='Fiscal Tax Group', + comodel_name="l10n_br_fiscal.tax.group", + string="Fiscal Tax Group", ) diff --git a/l10n_br_account/models/account_tax_template.py b/l10n_br_account/models/account_tax_template.py index 6ec1ce50e492..0fd056ca5518 100644 --- a/l10n_br_account/models/account_tax_template.py +++ b/l10n_br_account/models/account_tax_template.py @@ -5,24 +5,24 @@ class AccountTaxTemplate(models.Model): - _inherit = 'account.tax.template' + _inherit = "account.tax.template" fiscal_tax_ids = fields.Many2many( - comodel_name='l10n_br_fiscal.tax', - relation='l10n_br_fiscal_account_template_tax_rel', - colunm1='account_tax_id', - colunm2='fiscal_tax_id', - string='Fiscal Taxes', + comodel_name="l10n_br_fiscal.tax", + relation="fiscal_account_template_tax_rel", + column1="account_tax_template_id", + column2="fiscal_tax_id", + string="Fiscal Taxes", ) def _generate_tax(self, company): mapping = super()._generate_tax(company) - taxes_template = self.browse(mapping.get('tax_template_to_tax').keys()) + taxes_template = self.browse(mapping.get("tax_template_to_tax").keys()) for tax_template in taxes_template: - tax_id = mapping.get('tax_template_to_tax').get(tax_template.id) - self.env['account.tax'].browse(tax_id).write( - {'fiscal_tax_ids': - [(6, False, tax_template.fiscal_tax_ids.ids)]}) + tax_id = mapping.get("tax_template_to_tax").get(tax_template.id) + self.env["account.tax"].browse(tax_id).write( + {"fiscal_tax_ids": [(6, False, tax_template.fiscal_tax_ids.ids)]} + ) return mapping diff --git a/l10n_br_account/models/fiscal_document.py b/l10n_br_account/models/fiscal_document.py index 6fd1ece6e641..a2c3a56e5484 100644 --- a/l10n_br_account/models/fiscal_document.py +++ b/l10n_br_account/models/fiscal_document.py @@ -1,28 +1,28 @@ # Copyright (C) 2009 - TODAY Renato Lima - Akretion # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo import _, models, fields +from odoo import _, fields, models from odoo.exceptions import UserError -from odoo.addons.l10n_br_fiscal.constants.fiscal import ( - SITUACAO_EDOC_EM_DIGITACAO, -) +from odoo.addons.l10n_br_fiscal.constants.fiscal import SITUACAO_EDOC_EM_DIGITACAO class FiscalDocument(models.Model): - _inherit = 'l10n_br_fiscal.document' + _inherit = "l10n_br_fiscal.document" invoice_ids = fields.One2many( - comodel_name='account.invoice', - inverse_name='fiscal_document_id', + comodel_name="account.invoice", + inverse_name="fiscal_document_id", string="Invoices", ) def unlink(self): non_draft_documents = self.filtered( - lambda d: d.state != SITUACAO_EDOC_EM_DIGITACAO) + lambda d: d.state != SITUACAO_EDOC_EM_DIGITACAO + ) if non_draft_documents: - UserError(_("You cannot delete a fiscal document " - "which is not draft state.")) + UserError( + _("You cannot delete a fiscal document " "which is not draft state.") + ) return super().unlink() diff --git a/l10n_br_account/models/fiscal_document_line.py b/l10n_br_account/models/fiscal_document_line.py index 5fe89c4d5629..aa09ec9fd6d3 100644 --- a/l10n_br_account/models/fiscal_document_line.py +++ b/l10n_br_account/models/fiscal_document_line.py @@ -1,14 +1,14 @@ # Copyright (C) 2021 - TODAY Gabriel Cardoso de Faria - Kmee # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo import models, fields +from odoo import fields, models class FiscalDocumentLine(models.Model): - _inherit = 'l10n_br_fiscal.document.line' + _inherit = "l10n_br_fiscal.document.line" invoice_line_ids = fields.One2many( - comodel_name='account.invoice.line', - inverse_name='fiscal_document_line_id', + comodel_name="account.invoice.line", + inverse_name="fiscal_document_line_id", string="Invoice Lines", ) diff --git a/l10n_br_account/models/fiscal_operation.py b/l10n_br_account/models/fiscal_operation.py index 2f4c15e6f6fa..62ad2289838f 100644 --- a/l10n_br_account/models/fiscal_operation.py +++ b/l10n_br_account/models/fiscal_operation.py @@ -3,65 +3,62 @@ # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from odoo import fields, models + from odoo.addons.account.models.account_invoice import TYPE2JOURNAL FISCAL_TYPE_INVOICE = { - 'purchase': 'in_invoice', - 'purchase_refund': 'in_refund', - 'return_in': 'in_refund', - 'sale': 'out_invoice', - 'sale_refund': 'out_refund', - 'return_out': 'out_refund', - 'other': 'out_invoice', + "purchase": "in_invoice", + "purchase_refund": "in_refund", + "return_in": "in_refund", + "sale": "out_invoice", + "sale_refund": "out_refund", + "return_out": "out_refund", + "other": "out_invoice", } class Operation(models.Model): - _inherit = 'l10n_br_fiscal.operation' + _inherit = "l10n_br_fiscal.operation" journal_id = fields.Many2one( - comodel_name='account.journal', - string='Account Journal', + comodel_name="account.journal", + string="Account Journal", company_dependent=True, domain="[('type', 'in', {'out': ['sale', 'general'], 'in': " - "['purchase', 'general'], 'all': ['sale', 'purchase', " - "'general']}.get(fiscal_operation_type, []))]", + "['purchase', 'general'], 'all': ['sale', 'purchase', " + "'general']}.get(fiscal_operation_type, []))]", ) fiscal_position_id = fields.Many2one( - comodel_name='account.fiscal.position', - string='Fiscal Position', + comodel_name="account.fiscal.position", + string="Fiscal Position", company_dependent=True, ) def _change_action_view(self, action): - fiscal_op_type = action.get('context') - if fiscal_op_type == 'out': - new_action = self.env.ref( - 'l10n_br_account.fiscal_invoice_out_action') - elif fiscal_op_type == 'in': - new_action = self.env.ref( - 'l10n_br_account.fiscal_invoice_out_action') + fiscal_op_type = action.get("context") + if fiscal_op_type == "out": + new_action = self.env.ref("l10n_br_account.fiscal_invoice_out_action") + elif fiscal_op_type == "in": + new_action = self.env.ref("l10n_br_account.fiscal_invoice_out_action") else: - new_action = self.env.ref( - 'l10n_br_account.fiscal_invoice_all_action') + new_action = self.env.ref("l10n_br_account.fiscal_invoice_all_action") invoice_type = FISCAL_TYPE_INVOICE[self.fiscal_type] journal_type = TYPE2JOURNAL[invoice_type] - new_action['context'] = ({ - 'type': invoice_type, - 'default_fiscal_operation_type': self.fiscal_type, - 'default_fiscal_operation_id': self.id, - 'journal_type': journal_type, - }) - new_action['domain'] = action.get('domain', {}) + new_action["context"] = { + "type": invoice_type, + "default_fiscal_operation_type": self.fiscal_type, + "default_fiscal_operation_id": self.id, + "journal_type": journal_type, + } + new_action["domain"] = action.get("domain", {}) return new_action.read()[0] def action_create_new(self): action = super().action_create_new() - action['res_model'] = 'account.invoice' - action['view_id'] = self.env.ref( - 'l10n_br_account.fiscal_invoice_form').id - action['context'] = self._change_action_view(action)['context'] + action["res_model"] = "account.invoice" + action["view_id"] = self.env.ref("l10n_br_account.fiscal_invoice_form").id + action["context"] = self._change_action_view(action)["context"] return action def open_action(self): @@ -69,4 +66,4 @@ def open_action(self): return self._change_action_view(action) def _fiscal_document_object(self): - return self.env['account.invoice'] + return self.env["account.invoice"] diff --git a/l10n_br_account/models/fiscal_operation_line.py b/l10n_br_account/models/fiscal_operation_line.py index f89e770471d2..255adfff9d0a 100644 --- a/l10n_br_account/models/fiscal_operation_line.py +++ b/l10n_br_account/models/fiscal_operation_line.py @@ -6,10 +6,10 @@ class OperationLine(models.Model): - _inherit = 'l10n_br_fiscal.operation.line' + _inherit = "l10n_br_fiscal.operation.line" fiscal_position_id = fields.Many2one( - comodel_name='account.fiscal.position', - string='Fiscal Position', + comodel_name="account.fiscal.position", + string="Fiscal Position", company_dependent=True, ) diff --git a/l10n_br_account/models/fiscal_tax.py b/l10n_br_account/models/fiscal_tax.py index dbd5be6ebdee..de13b46cc417 100644 --- a/l10n_br_account/models/fiscal_tax.py +++ b/l10n_br_account/models/fiscal_tax.py @@ -5,45 +5,45 @@ class FiscalTax(models.Model): - _inherit = 'l10n_br_fiscal.tax' + _inherit = "l10n_br_fiscal.tax" - def account_taxes(self, user_type='sale'): - account_taxes = self.env['account.tax'] + def account_taxes(self, user_type="sale"): + account_taxes = self.env["account.tax"] for fiscal_tax in self: taxes = fiscal_tax._account_taxes() account_taxes |= taxes.filtered( - lambda t: t.type_tax_use == user_type and t.active) + lambda t: t.type_tax_use == user_type and t.active + ) return account_taxes def _account_taxes(self): self.ensure_one() account_tax_group = self.tax_group_id.account_tax_group() - return self.env['account.tax'].search([ - ('tax_group_id', '=', account_tax_group.id), - ('active', '=', True)] + return self.env["account.tax"].search( + [("tax_group_id", "=", account_tax_group.id), ("active", "=", True)] ) def _create_account_tax(self): for fiscal_tax in self: account_taxes = fiscal_tax._account_taxes() if not account_taxes: - tax_users = {'sale': 'out', 'purchase': 'in'} + tax_users = {"sale": "out", "purchase": "in"} for tax_use in tax_users.keys(): tax_values = { - 'name': fiscal_tax.name + ' ' + tax_users.get(tax_use), - 'type_tax_use': tax_use, - 'fiscal_tax_ids': [(4, fiscal_tax.id)], - 'tax_group_id': fiscal_tax.account_tax_group().id, - 'amount': 0.00 + "name": fiscal_tax.name + " " + tax_users.get(tax_use), + "type_tax_use": tax_use, + "fiscal_tax_ids": [(4, fiscal_tax.id)], + "tax_group_id": fiscal_tax.account_tax_group().id, + "amount": 0.00, } - self.env['account.tax'].create(tax_values) + self.env["account.tax"].create(tax_values) else: - account_taxes.write({ - 'fiscal_tax_ids': [(4, t.id) for t in account_taxes] - }) + account_taxes.write( + {"fiscal_tax_ids": [(4, t.id) for t in account_taxes]} + ) @api.model def create(self, values): @@ -58,12 +58,13 @@ def unlink(self): account_tax.fiscal_tax_ids -= fiscal_tax if not account_tax.fiscal_tax_ids: - active_datetime = fields.Datetime.to_string( - fields.Datetime.now()) + active_datetime = fields.Datetime.to_string(fields.Datetime.now()) - account_tax.write({ - 'name': (account_tax.name + - ' Inative ' + active_datetime), - 'fiscal_tax_ids': False, - 'active': False}) + account_tax.write( + { + "name": (account_tax.name + " Inative " + active_datetime), + "fiscal_tax_ids": False, + "active": False, + } + ) return super().unlink() diff --git a/l10n_br_account/models/fiscal_tax_group.py b/l10n_br_account/models/fiscal_tax_group.py index 2302052c1793..b8b283034947 100644 --- a/l10n_br_account/models/fiscal_tax_group.py +++ b/l10n_br_account/models/fiscal_tax_group.py @@ -5,9 +5,10 @@ class FiscalTaxGroup(models.Model): - _inherit = 'l10n_br_fiscal.tax.group' + _inherit = "l10n_br_fiscal.tax.group" def account_tax_group(self): self.ensure_one() - return self.env['account.tax.group'].search( - [('fiscal_tax_group_id', 'in', self.ids)], limit=1) + return self.env["account.tax.group"].search( + [("fiscal_tax_group_id", "in", self.ids)], limit=1 + ) diff --git a/l10n_br_account/readme/ROADMAP.rst b/l10n_br_account/readme/ROADMAP.rst index 8b137891791f..e69de29bb2d1 100644 --- a/l10n_br_account/readme/ROADMAP.rst +++ b/l10n_br_account/readme/ROADMAP.rst @@ -1 +0,0 @@ - diff --git a/l10n_br_fiscal/report/__init__.py b/l10n_br_account/report/__init__.py similarity index 100% rename from l10n_br_fiscal/report/__init__.py rename to l10n_br_account/report/__init__.py diff --git a/l10n_br_account/report/account_invoice_report.py b/l10n_br_account/report/account_invoice_report.py new file mode 100644 index 000000000000..140fc5c8cf65 --- /dev/null +++ b/l10n_br_account/report/account_invoice_report.py @@ -0,0 +1,149 @@ +# Copyright (C) 2016-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + +from odoo.addons import decimal_precision as dp +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + DOCUMENT_ISSUER, + PRODUCT_FISCAL_TYPE, +) + + +class AccountInvoiceReport(models.Model): + + _inherit = "account.invoice.report" + + issuer = fields.Selection( + selection=DOCUMENT_ISSUER, + string="Issuer", + ) + + fiscal_operation_id = fields.Many2one( + comodel_name="l10n_br_fiscal.operation", + string="Operation", + ) + + fiscal_operation_line_id = fields.Many2one( + comodel_name="l10n_br_fiscal.operation.line", + string="Operation Line", + ) + + document_type_id = fields.Many2one( + comodel_name="l10n_br_fiscal.document.type", + ) + + document_serie_id = fields.Many2one( + comodel_name="l10n_br_fiscal.document.serie", + ) + + fiscal_type = fields.Selection(selection=PRODUCT_FISCAL_TYPE, string="Tipo Fiscal") + + cfop_id = fields.Many2one( + comodel_name="l10n_br_fiscal.cfop", + string="CFOP", + ) + + icms_value = fields.Float(string="Valor ICMS", digits=dp.get_precision("Account")) + + icmsst_value = fields.Float( + string="Valor ICMS ST", digits=dp.get_precision("Account") + ) + + ipi_value = fields.Float(string="Valor IPI", digits=dp.get_precision("Account")) + + pis_value = fields.Float(string="Valor PIS", digits=dp.get_precision("Account")) + + cofins_value = fields.Float( + string="Valor COFINS", digits=dp.get_precision("Account") + ) + + ii_value = fields.Float(string="Valor II", digits=dp.get_precision("Account")) + + total_with_taxes = fields.Float( + string="Total com Impostos", rdigits=dp.get_precision("Account") + ) + cest_id = fields.Many2one( + comodel_name="l10n_br_fiscal.cest", + string="CEST", + ) + + ncm_id = fields.Many2one(comodel_name="l10n_br_fiscal.ncm", string="NCM") + + def _select(self): + select_str = super()._select() + select_str += """ + , sub.issuer + , sub.document_type_id + , sub.document_serie_id + , sub.fiscal_operation_id + , sub.fiscal_operation_line_id + , sub.ncm_id + , sub.cest_id + , sub.fiscal_type + , sub.cfop_id + , sub.icms_value + , sub.icmsst_value + , sub.ipi_value + , sub.pis_value + , sub.cofins_value + , sub.ii_value + , sub.total_with_taxes + """ + return select_str + + def _sub_select(self): + select_str = super()._sub_select() + + select_str += """ + , fd.issuer + , fd.document_type_id + , fd.document_serie_id + , fdl.fiscal_operation_id + , fdl.fiscal_operation_line_id + , fdl.ncm_id + , fdl.cest_id + , prd_tmpl.fiscal_type + , fdl.cfop_id + , SUM(fdl.icms_value) as icms_value + , SUM(fdl.icmsst_value) as icmsst_value + , SUM(fdl.ipi_value) as ipi_value + , SUM(fdl.pis_value) as pis_value + , SUM(fdl.cofins_value) as cofins_value + , SUM(fdl.ii_value) as ii_value + , SUM( + ail.price_subtotal + fdl.ipi_value + + fdl.icmsst_value + fdl.freight_value + + fdl.insurance_value + fdl.other_value) + as total_with_taxes + """ + return select_str + + def _from(self): + from_str = super()._from() + from_str += """ + LEFT JOIN l10n_br_fiscal_document fd ON + fd.id = ai.fiscal_document_id + LEFT JOIN l10n_br_fiscal_document_line fdl ON + fdl.id = ail.fiscal_document_line_id + LEFT JOIN product_product prd ON prd.id = ail.product_id + LEFT JOIN product_template prd_tmpl ON + prd_tmpl.id = prd.product_tmpl_id + """ + return from_str + + def _group_by(self): + group_by_str = super()._group_by() + group_by_str += """ + , fd.issuer + , prd_tmpl.fiscal_type + , fd.document_type_id + , fd.document_serie_id + , fdl.fiscal_operation_id + , fdl.fiscal_operation_line_id + , fdl.cfop_id + , fdl.ncm_id + , fdl.cest_id + """ + return group_by_str diff --git a/l10n_br_account/report/account_invoice_report_view.xml b/l10n_br_account/report/account_invoice_report_view.xml new file mode 100644 index 000000000000..dc984f038795 --- /dev/null +++ b/l10n_br_account/report/account_invoice_report_view.xml @@ -0,0 +1,47 @@ + + + + + l10n_br_account.invoice.report.search + account.invoice.report + + + + + + + + + + + + + diff --git a/l10n_br_account/static/description/index.html b/l10n_br_account/static/description/index.html index b14fdc39c6b4..c048f494d6ef 100644 --- a/l10n_br_account/static/description/index.html +++ b/l10n_br_account/static/description/index.html @@ -376,12 +376,11 @@

Brazilian Localization Account

  • Installation
  • Configuration
  • Usage
  • -
  • Known issues / Roadmap
  • -
  • Bug Tracker
  • -
  • Credits @@ -407,11 +406,8 @@

    Usage

  • go to …
  • -
    -

    Bug Tracker

    +

    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 smashing it by providing a detailed and welcomed @@ -419,22 +415,22 @@

    Bug Tracker

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

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Akretion
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose diff --git a/l10n_br_account/tests/test_account_taxes.py b/l10n_br_account/tests/test_account_taxes.py index e51ecc80006d..e182db2fca3d 100644 --- a/l10n_br_account/tests/test_account_taxes.py +++ b/l10n_br_account/tests/test_account_taxes.py @@ -8,29 +8,36 @@ class TestAccountTaxes(TransactionCase): def setUp(self): super(TestAccountTaxes, self).setUp() - self.l10n_br_company = self.env['res.company'].create({ - 'name': 'Empresa Teste do Plano de Contas Simplificado'}) + self.l10n_br_company = self.env["res.company"].create( + {"name": "Empresa Teste do Plano de Contas Simplificado"} + ) self.env.user.company_ids += self.l10n_br_company self.env.user.company_id = self.l10n_br_company def test_account_taxes(self): """Test if account taxes are related with fiscal taxes""" - l10n_br_coa_charts = self.env["account.chart.template"].search( - []).filtered( - lambda chart: chart.get_external_id().get( - chart.id).split('.')[0].startswith("l10n_br_coa_") - if chart.get_external_id().get(chart.id) else False + l10n_br_coa_charts = ( + self.env["account.chart.template"] + .search([]) + .filtered( + lambda chart: chart.get_external_id() + .get(chart.id) + .split(".")[0] + .startswith("l10n_br_coa_") + if chart.get_external_id().get(chart.id) + else False + ) ) for l10n_br_coa_chart in l10n_br_coa_charts: l10n_br_coa_chart.try_loading_for_current_company() - account_taxes = self.env['account.tax'].search( - [('company_id', '=', self.l10n_br_company.id)]) + account_taxes = self.env["account.tax"].search( + [("company_id", "=", self.l10n_br_company.id)] + ) is_fiscal_taxes = False for tax in account_taxes: - if tax.tax_group_id.fiscal_tax_group_id and \ - tax.fiscal_tax_ids: + if tax.tax_group_id.fiscal_tax_group_id and tax.fiscal_tax_ids: is_fiscal_taxes = True assert is_fiscal_taxes, "There are not fiscal taxes related" diff --git a/l10n_br_account/tests/test_customer_invoice_dummy.py b/l10n_br_account/tests/test_customer_invoice_dummy.py index 6ec2d48f0644..8149aa26b8ab 100644 --- a/l10n_br_account/tests/test_customer_invoice_dummy.py +++ b/l10n_br_account/tests/test_customer_invoice_dummy.py @@ -6,7 +6,6 @@ class TestCustomerInvoice(SavepointCase): - @classmethod def setUpClass(cls): super().setUpClass() @@ -54,9 +53,9 @@ def setUpClass(cls): ), ( "company_id", - '=', + "=", cls.env.user.company_id.id, - ) + ), ], limit=1, ) @@ -122,9 +121,9 @@ def setUpClass(cls): ), ( "company_id", - '=', + "=", cls.env.user.company_id.id, - ) + ), ], limit=1, ) @@ -153,7 +152,7 @@ def setUpClass(cls): "name": "Tax 20.0% (Discount)", "amount": 20.0, "amount_type": "percent", - "include_base_amount": False + "include_base_amount": False, } ) cls.invoice_3 = cls.env["account.invoice"].create( @@ -182,9 +181,9 @@ def setUpClass(cls): ), ( "company_id", - '=', + "=", cls.env.user.company_id.id, - ) + ), ], limit=1, ) @@ -244,12 +243,14 @@ def test_invoice_other_currency(self): self.invoice_3.action_invoice_open() assert self.invoice_3.move_id, "Move Receivable not created for open invoice" self.assertEqual( - self.invoice_3.state, "open", "Invoice should be in state Open") + self.invoice_3.state, "open", "Invoice should be in state Open" + ) def test_invoice_line_ids_write(self): - self.invoice_3.invoice_line_ids.write({'invoice_id': self.invoice_3.id}) + self.invoice_3.invoice_line_ids.write({"invoice_id": self.invoice_3.id}) for line in self.invoice_3.invoice_line_ids: self.assertEqual( line.document_id.id, self.invoice_3.fiscal_document_id.id, - "line.document_id should be equal account.fiscal_document_id") + "line.document_id should be equal account.fiscal_document_id", + ) diff --git a/l10n_br_account/tests/test_supplier_invoice_dummy.py b/l10n_br_account/tests/test_supplier_invoice_dummy.py index d0f9a236fa63..c0f013e31048 100644 --- a/l10n_br_account/tests/test_supplier_invoice_dummy.py +++ b/l10n_br_account/tests/test_supplier_invoice_dummy.py @@ -13,7 +13,8 @@ def setUp(self): code="X1020", name="Product Purchase - (test)", user_type_id=self.env.ref("account.data_account_type_revenue").id, - )) + ) + ) self.purchase_journal = self.env["account.journal"].create( dict( @@ -51,9 +52,9 @@ def setUp(self): ), ( "company_id", - '=', + "=", self.env.user.company_id.id, - ) + ), ], limit=1, ) diff --git a/l10n_br_account/views/account_invoice_line_view.xml b/l10n_br_account/views/account_invoice_line_view.xml index fa4b0ea17666..2537b81478ac 100644 --- a/l10n_br_account/views/account_invoice_line_view.xml +++ b/l10n_br_account/views/account_invoice_line_view.xml @@ -1,55 +1,93 @@ - + l10n_br_account.invoice.line.form account.invoice.line - + + 100 - - + + -

    - - + +
    - + 1 - + - - - - + + + + - - - - - - + + + + + + - + - - - + + + - + - + diff --git a/l10n_br_account/views/account_invoice_view.xml b/l10n_br_account/views/account_invoice_view.xml index 9bca68b17499..b4bf50e299d8 100644 --- a/l10n_br_account/views/account_invoice_view.xml +++ b/l10n_br_account/views/account_invoice_view.xml @@ -1,18 +1,20 @@ - + l10n_br_account.invoice.search account.invoice - + - - - + + + - ['|','|','|', '|', ('document_number','ilike',self), ('number','ilike',self), ('origin','ilike',self), ('reference', 'ilike', self), ('partner_id', 'child_of', self)] + ['|','|','|', '|', ('document_number','ilike',self), ('number','ilike',self), ('origin','ilike',self), ('reference', 'ilike', self), ('partner_id', 'child_of', self)] Account Number @@ -21,12 +23,18 @@ l10n_br_account.invoice.tree account.invoice - + - - -
    - {'invisible': [('document_type_id', '!=', False)]} + {'invisible': [('document_type_id', '!=', False)]}

    - : - + : +

    - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - + - {'default_company_id': company_id, 'default_partner_id': partner_id, 'default_fiscal_operation_id': fiscal_operation_id, 'default_document_type_id': document_type_id} + {'default_company_id': company_id, 'default_partner_id': partner_id, 'default_fiscal_operation_id': fiscal_operation_id, 'default_document_type_id': document_type_id} - - - + + + - + 1 - + - + - + - + @@ -111,61 +169,106 @@ l10n_br_account.invoice.supplier.form account.invoice - +
    -
    - - - - - - - - + + + + + + + + - - - - - - - + + + + + + + - + - {'default_company_id': company_id, 'default_partner_id': partner_id, 'default_fiscal_operation_type': fiscal_operation_type, 'default_fiscal_operation_id': fiscal_operation_id, 'default_document_type_id': document_type_id} + {'default_company_id': company_id, 'default_partner_id': partner_id, 'default_fiscal_operation_type': fiscal_operation_type, 'default_fiscal_operation_id': fiscal_operation_id, 'default_document_type_id': document_type_id} - - - + + + - + 1 - + - + - + - + diff --git a/l10n_br_account/views/account_tax_template_view.xml b/l10n_br_account/views/account_tax_template_view.xml index c01ce6273223..a94660455900 100644 --- a/l10n_br_account/views/account_tax_template_view.xml +++ b/l10n_br_account/views/account_tax_template_view.xml @@ -1,22 +1,26 @@ - + l10n_br_account.tax.template.form account.tax.template - + - + - {'readonly': [('fiscal_tax_ids', '!=', False)]} + {'readonly': [('fiscal_tax_ids', '!=', False)]} 1 - {'readonly': [('fiscal_tax_ids', '!=', False)]} + {'readonly': [('fiscal_tax_ids', '!=', False)]} 1 diff --git a/l10n_br_account/views/account_tax_view.xml b/l10n_br_account/views/account_tax_view.xml index eba068c68b5b..9532601a7273 100644 --- a/l10n_br_account/views/account_tax_view.xml +++ b/l10n_br_account/views/account_tax_view.xml @@ -1,22 +1,26 @@ - + l10n_br_account.tax.form account.tax - + - {'readonly': [('fiscal_tax_ids', '!=', False)]} + {'readonly': [('fiscal_tax_ids', '!=', False)]} 1 - {'readonly': [('fiscal_tax_ids', '!=', False)]} + {'readonly': [('fiscal_tax_ids', '!=', False)]} 1 - + diff --git a/l10n_br_account/views/document_line_view.xml b/l10n_br_account/views/document_line_view.xml index 749698029ae6..bc70c56e0111 100644 --- a/l10n_br_account/views/document_line_view.xml +++ b/l10n_br_account/views/document_line_view.xml @@ -1,12 +1,12 @@ - + l10n_br_fiscal.document.line.form l10n_br_fiscal.document.line - + - + diff --git a/l10n_br_account/views/document_view.xml b/l10n_br_account/views/document_view.xml index 64664d7f2417..43ec3c6d85fe 100644 --- a/l10n_br_account/views/document_view.xml +++ b/l10n_br_account/views/document_view.xml @@ -1,13 +1,13 @@ - + l10n_br_nfe.document.form.inherit l10n_br_fiscal.document - + - + diff --git a/l10n_br_account/views/fiscal_invoice_line_view.xml b/l10n_br_account/views/fiscal_invoice_line_view.xml index ce053614a7b6..ac504b0d68ef 100644 --- a/l10n_br_account/views/fiscal_invoice_line_view.xml +++ b/l10n_br_account/views/fiscal_invoice_line_view.xml @@ -1,24 +1,47 @@ - + l10n_br_account.invoice.line.form account.invoice.line - + primary - - - - + + + + - + - + diff --git a/l10n_br_account/views/fiscal_invoice_view.xml b/l10n_br_account/views/fiscal_invoice_view.xml index 8c899ac69555..38c5f709213a 100644 --- a/l10n_br_account/views/fiscal_invoice_view.xml +++ b/l10n_br_account/views/fiscal_invoice_view.xml @@ -1,17 +1,17 @@ - + l10n_br_account.fiscal.invoice.search account.invoice - + primary - - - - + + + + @@ -19,18 +19,18 @@ l10n_br_account.fiscal.invoice.tree account.invoice - + primary - - - - - - - - + + + + + + + + @@ -38,47 +38,93 @@ l10n_br_account.fiscal.invoice.form account.invoice - + primary + 100 - - + + -