Initial commit: OCA Financial packages (186 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:04 +02:00
commit 3e0e8473fb
8757 changed files with 947473 additions and 0 deletions

View file

@ -0,0 +1,45 @@
# Account Global Discount
Odoo addon: account_global_discount
## Installation
```bash
pip install odoo-bringout-oca-account-invoicing-account_global_discount
```
## Dependencies
This addon depends on:
- account
- base_global_discount
## Manifest Information
- **Name**: Account Global Discount
- **Version**: 16.0.2.0.0
- **Category**: Accounting
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/account-invoicing](https://github.com/OCA/account-invoicing) branch 16.0, addon `account_global_discount`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,130 @@
=======================
Account Global Discount
=======================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:58d81491b08d762ad414c2d4327aae330e0a1f8c0c4a6d0986a847f150c48327
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github
:target: https://github.com/OCA/account-invoicing/tree/16.0/account_global_discount
:alt: OCA/account-invoicing
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-invoicing-16-0/account-invoicing-16-0-account_global_discount
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
Apply global discounts to invoices
**Table of contents**
.. contents::
:local:
Configuration
=============
To configure this module, you need to:
#. Go to *Settings > Parameters > Global Discounts*.
#. Add a new discount percentage.
#. Choose the discount scope (sales or purchases).
#. You can also restrict it to a certain company if needed.
You can assign global discounts to partners as well:
#. Go to a partner that is a company.
#. Go to the *Sales & Purchases* tab.
#. In section sale, you can set sale discounts.
#. In section purchase, you can set purchase discounts.
Usage
=====
To use this module, you need to:
#. Go to *Invoicing > Customers > Invoices*.
#. Create a new sales invoice, choose a customer with a defined global
discount and you will see how the value of the 'Invoice Global Discounts'
field is auto-completed with the global discounts defined in the customer
(See configuration section in this readme), although you can choose
then other global discounts defined in configuration.
#. Add several invoice lines.
#. At the bottom of the form you will see how global discounts affect the
total values.
#. Go to the 'Journal Items' tab (if you have permissions for that).
There you will see how the tax lines have the discount percentage applied
and you will also see the lines that reflect the global discount applied.
#. In the 'Other info' tab, you can see in the 'Global Discounts' table,
the global discounts applied to each of the invoice lines.
Known issues / Roadmap
======================
* Not all the taxes combination can be compatible with global discounts, as
the generated journal items won't be correct for taxes declarations. An error
is raised in that cases.
* Currently, taxes in invoice lines are mandatory with global discounts.
* No tax tags are populated for the global discount move lines, only `tax_ids`.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-invoicing/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-invoicing/issues/new?body=module:%20account_global_discount%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Tecnativa
Contributors
~~~~~~~~~~~~
* `Tecnativa <https://www.tecnativa.com>`_
* Pedro M. Baeza
* David Vidal
* Carlos Dauden
* Rafael Blasco
* Ernesto Tejeda
* Víctor Martínez
* Omar Castiñeira <omar@comunitea.com>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/account-invoicing <https://github.com/OCA/account-invoicing/tree/16.0/account_global_discount>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1,3 @@
from . import models
from . import report
from .hooks import _pre_init_global_discount_fields

View file

@ -0,0 +1,22 @@
# Copyright 2019 Tecnativa S.L. - David Vidal
# Copyright 2020-2021 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Account Global Discount",
"version": "16.0.2.0.0",
"category": "Accounting",
"author": "Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/account-invoicing",
"license": "AGPL-3",
"depends": ["account", "base_global_discount"],
"data": [
"security/ir.model.access.csv",
"security/security.xml",
"views/account_invoice_views.xml",
"views/global_discount_views.xml",
"views/report_account_invoice.xml",
],
"application": False,
"installable": True,
"pre_init_hook": "_pre_init_global_discount_fields",
}

View file

@ -0,0 +1,28 @@
from odoo.tools.sql import column_exists
def _pre_init_global_discount_fields(cr):
if not column_exists(cr, "account_move", "amount_global_discount"):
cr.execute(
"""
ALTER TABLE "account_move"
ADD COLUMN "amount_global_discount" double precision DEFAULT 0
"""
)
cr.execute(
"""
ALTER TABLE "account_move" ALTER COLUMN "amount_global_discount" DROP DEFAULT
"""
)
if not column_exists(cr, "account_move", "amount_untaxed_before_global_discounts"):
cr.execute(
"""
ALTER TABLE "account_move"
ADD COLUMN "amount_untaxed_before_global_discounts" double precision
"""
)
cr.execute(
"""
update account_move set amount_untaxed_before_global_discounts = amount_untaxed
"""
)

View file

@ -0,0 +1,218 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_untaxed_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr ""
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
msgid "Display Name"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr ""
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
msgid "ID"
msgstr ""
#. module: account_global_discount
#. odoo-python
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__invoice_global_discount_ids
msgid "Invoice Global Discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_report
msgid "Invoices Statistics"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entry"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
msgid "Last Modified on"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_global_discount
msgid "Total Global Discounts"
msgstr ""
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr ""
#. module: account_global_discount
#. odoo-python
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr ""

View file

@ -0,0 +1,218 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr "<strong>Međuzbir bez popusta</strong>"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr "Konto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_untaxed_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr "Iznos bez poreza pre popusta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr "Analitički konto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr "Osnova posle popusta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr "Osnova pre popusta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr "Preduzeće"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr "Valuta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr "Popust"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr "Popust (broj)"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr "Naziv popusta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr "Iznos sa popustom"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr "Popusti..."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
msgid "Display Name"
msgstr "Prikazani naziv"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr "Globalni popust"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr "Stavka globalnog popusta"
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr "Globalni popust"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
msgid "ID"
msgstr "ID"
#. module: account_global_discount
#. odoo-python
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr "Pronađeni nekompatibilni porezi za globalne popuste."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr "Faktura"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__invoice_global_discount_ids
msgid "Invoice Global Discount"
msgstr "Globalni popust fakture"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr "Globalni popusti fakture"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr "Globalni popusti fakture (samo čitanje)"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_report
msgid "Invoices Statistics"
msgstr "Statistika faktura"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entry"
msgstr "Žurnal"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr "Stavka žurnala"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
msgid "Last Modified on"
msgstr "Zadnje mijenjano"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr "Porezi"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_global_discount
msgid "Total Global Discounts"
msgstr "Ukupno globalnih popusta"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr "Iznos bez poreza pre popusta"
#. module: account_global_discount
#. odoo-python
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr "Sa globalnim popustima, porezi u linijama su obavezni."

View file

@ -0,0 +1,223 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-03-10 10:46+0000\n"
"Last-Translator: Ana Suárez <ana.suarez@qubiq.es>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3.2\n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
"<strong>Descuentos Globales</strong>\n"
" <br/>"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr "<strong>Subtotal sin desc.</strong>"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr "Cuenta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr "Base Imponible sin Descuentos"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr "Cuenta analítica"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr "Compañía"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr "Creado en"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr "Moneda"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr "Descuento"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr "Descuento (número)"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr "Nombre del descuento"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr "Importe Descontado"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr "Descuentos..."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
msgid "Display Name"
msgstr "Nombre mostrado"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr "Descuento Global"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr "Artículo de Descuento Global"
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr "Descuentos Globales"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
msgid "ID"
msgstr "ID (identificación)"
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr "Impuestos incompatibles encontrados para descuentos globales."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr "Factura"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
msgid "Invoice Global Discount"
msgstr "Descuento Global en Factura"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr "Descuentos Globales en Factura"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entries"
msgstr "Asientos contables"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr "Apunte contable"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
msgid "Last Modified on"
msgstr "Última modificación en"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr "Última actualización de"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
msgid "Total Global Discounts"
msgstr "Total Descuentos Globales"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr "Base Imponible Antes Desc."
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr "Con descuentos globales, se requieren impuestos en las líneas."
#~ msgid "Base discounted"
#~ msgstr "Base descontada"
#~ msgid "Discounted amount"
#~ msgstr "Importe Descontado"
#~ msgid "Tax"
#~ msgstr "Impuesto"
#~ msgid "<strong>Global Discounts</strong><br/>"
#~ msgstr "<strong>Descuento Global</strong>"
#, fuzzy
#~ msgid "Invoice Tax"
#~ msgstr "Factura"

View file

@ -0,0 +1,223 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-12-17 18:06+0000\n"
"Last-Translator: Rémi <remi@le-filament.com>\n"
"Language-Team: none\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.6.2\n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
"<strong>Remise globale</strong>\n"
"<br/>"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr "<strong>Sous-total sans remise.</strong>"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr "Compte"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_untaxed_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr "Montant Hors Taxe Avant Remises"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr "Compte Analytique"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr "Base après remise"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr "Base avant remise"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr "Société"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr "Créé le"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr "Devise"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr "Remise"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr "Remise (nombre)"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr "Nom de la Remise"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr "Montant Remisé"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr "Remises..."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
msgid "Display Name"
msgstr "Nom Affiché"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr "Remise Globale"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr "Ligne de remise globale"
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr "Remises Globales"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
msgid "ID"
msgstr "ID"
#. module: account_global_discount
#. odoo-python
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr "Des taxes incompatibles ont été trouvées pour les remises globales."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr "Facture"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__invoice_global_discount_ids
msgid "Invoice Global Discount"
msgstr "Facture Remise Globale"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr "Facture Remises Globales"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr "Facture Remises Globales (lecture-seule)"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_report
msgid "Invoices Statistics"
msgstr "Statistiques de facturation"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entry"
msgstr "Pièce Comptable"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr "Ecriture Comptable"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
msgid "Last Modified on"
msgstr "Dernière Modification le"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr "Taxes"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_global_discount
msgid "Total Global Discounts"
msgstr "Total Remises Globale"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr "Montant Hors Taxe avant Remise."
#. module: account_global_discount
#. odoo-python
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr "Avec les remises globales, l'alignement des taxes est nécessaire."

View file

@ -0,0 +1,233 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-03 11:06+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.2\n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
"<strong>Sconti Globali</strong>\n"
" <br/>"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr "<strong>Subtotale senza sconto</strong>"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr "Conto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_untaxed_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr "Importo Imponibile Pre-Sconti"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr "Conto analitico"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr "Base dopo lo sconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr "Base prima dello sconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr "Azienda"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr "Creato da"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr "Creato il"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr "Valuta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr "Sconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr "Sconto (numero)"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr "Nome Sconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr "Importo Scontato"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr "Sconti..."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_report__display_name
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__display_name
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__display_name
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__display_name
msgid "Display Name"
msgstr "Nome visualizzato"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr "Sconto Globale"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr "Oggetto Sconto Globale"
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr "Sconti Globali"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_report__id
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__id
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__id
msgid "ID"
msgstr "ID"
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr "Rilevate imposte incompatibili per gli sconti globali."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr "Fattura"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__invoice_global_discount_ids
msgid "Invoice Global Discount"
msgstr "Sconto Globale Fattura"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr "Sconti Globali Fattura"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr "Sconti Globali Fattura (Sola lettura)"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_report
msgid "Invoices Statistics"
msgstr "Statistiche fatture"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entry"
msgstr "Registrazione contabile"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr "Movimento contabile"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_report____last_update
#: model:ir.model.fields,field_description:account_global_discount.field_account_move____last_update
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line____last_update
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount____last_update
msgid "Last Modified on"
msgstr "Ultima modifica il"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr "Ultimo aggiornamento di"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr "Ultimo aggiornamento il"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr "Imposte"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_bank_statement_line__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_payment__amount_global_discount
msgid "Total Global Discounts"
msgstr "Totale Sconti Globali"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr "Importo imponibile pre-sconto"
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr "Con gli sconti globali, sono necessarie le imposte sulle righe."

View file

@ -0,0 +1,218 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2021-01-29 11:44+0000\n"
"Last-Translator: Cas Vissers <c.vissers@brahoo.nl>\n"
"Language-Team: none\n"
"Language: nl_NL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3.2\n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
"<strong>Algemene kortingen</strong>\n"
" <br/>"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr "<strong>Subtotaal zonder korting</strong>"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr "Bedrag"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr "Onbelast bedrag voor kortingen"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr "Kostenplaats"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr "Bedrijf"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr "Aangemaakt door"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr "Aangemaakt op"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr "Valuta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr "Korting"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr "Korting (nummer)"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr "Kortingsnaam"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr "Kortingsbedrag"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr "Korting…"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
msgid "Display Name"
msgstr "Schermnaam"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr "Algemene korting"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr "Algemeen korting item"
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr "Algemene kortingen"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
msgid "ID"
msgstr "ID"
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr "Incompatibele belastingen gevonden voor algemene kortingen."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr "Factuur"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
msgid "Invoice Global Discount"
msgstr "Factuur algemene korting"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr "Factuur algemene kortingen"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr ""
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entries"
msgstr "Boekingen"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr "Boeking"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
msgid "Last Modified on"
msgstr "Laatst gewijzigd op"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr "Laatst bijgewerkt door"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr "Laatst bijgewerkt op"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr ""
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
msgid "Total Global Discounts"
msgstr "Totaal algemene kortingen"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr "Onbelast bedrag voor kort."
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr "Met globale kortingen zijn belastingen in regels vereist."
#~ msgid "Base discounted"
#~ msgstr "Basis korting"
#~ msgid "Discounted amount"
#~ msgstr "Kortingsbedrag"
#~ msgid "Tax"
#~ msgstr "Belasting"
#~ msgid "Company related to this journal"
#~ msgstr "Bedrijf gerelateerd aan journaal"

View file

@ -0,0 +1,221 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_global_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2022-08-17 12:07+0000\n"
"Last-Translator: Pedro Castro Silva <pedrocs@exo.pt>\n"
"Language-Team: none\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.3.2\n"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid ""
"<strong>Global Discounts</strong>\n"
" <br/>"
msgstr ""
"<strong>Descontos Globais</strong>\n"
" <br/>"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.report_invoice_document
msgid "<strong>Subtotal w/o disc.</strong>"
msgstr "<strong>Subtotal s/ Desc.</strong>"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_id
msgid "Account"
msgstr "Conta"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_untaxed_before_global_discounts
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__base_before_global_discounts
msgid "Amount Untaxed Before Discounts"
msgstr "Montante sem Impostos antes de Descontos"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__account_analytic_id
#: model:ir.model.fields,field_description:account_global_discount.field_global_discount__account_analytic_id
msgid "Analytic account"
msgstr "Conta analítica"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base_discounted
msgid "Base after discount"
msgstr "Base após desconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__base
msgid "Base before discount"
msgstr "Base antes de desconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__company_id
msgid "Company"
msgstr "Empresa"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_uid
msgid "Created by"
msgstr "Criado por"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__create_date
msgid "Created on"
msgstr "Criado em"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__currency_id
msgid "Currency"
msgstr "Moeda"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_display
msgid "Discount"
msgstr "Desconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount
msgid "Discount (number)"
msgstr "Desconto (número)"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__name
msgid "Discount Name"
msgstr "Nome do Desconto"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__discount_amount
msgid "Discounted Amount"
msgstr "Valor Descontado"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Discounts..."
msgstr "Descontos..."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__display_name
msgid "Display Name"
msgstr "Nome a Apresentar"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__global_discount_id
msgid "Global Discount"
msgstr "Desconto Global"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__global_discount_item
msgid "Global Discount Item"
msgstr "Item de Desconto Global"
#. module: account_global_discount
#: model:ir.ui.menu,name:account_global_discount.menu_account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Global Discounts"
msgstr "Descontos Globais"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__id
msgid "ID"
msgstr "ID"
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "Incompatible taxes found for global discounts."
msgstr "Foram encontrados impostos incompatíveis nos descontos globais."
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__invoice_id
msgid "Invoice"
msgstr "Fatura"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_invoice_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__invoice_global_discount_ids
#: model:ir.model.fields,field_description:account_global_discount.field_account_move_line__invoice_global_discount_id
msgid "Invoice Global Discount"
msgstr "Desconto Global de Fatura"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Invoice Global Discounts"
msgstr "Descontos Globais de Fatura"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__global_discount_ids_readonly
msgid "Invoice Global Discounts (readonly)"
msgstr "Descontos Globais de Faturas (apenas leitura)"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move
msgid "Journal Entries"
msgstr "Entradas no Diário"
#. module: account_global_discount
#: model:ir.model,name:account_global_discount.model_account_move_line
msgid "Journal Item"
msgstr "Item do Diário"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount____last_update
msgid "Last Modified on"
msgstr "Última Modificação Em"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_uid
msgid "Last Updated by"
msgstr "Atualizado pela última vez por"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__write_date
msgid "Last Updated on"
msgstr "Atualizado pela última vez em"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_invoice_global_discount__tax_ids
msgid "Taxes"
msgstr "Impostos"
#. module: account_global_discount
#: model:ir.model.fields,field_description:account_global_discount.field_account_move__amount_global_discount
msgid "Total Global Discounts"
msgstr "Descontos Globais Totais"
#. module: account_global_discount
#: model_terms:ir.ui.view,arch_db:account_global_discount.view_move_form
msgid "Untaxed Amount Before Disc."
msgstr "Montante sem Impostos antes de Desc."
#. module: account_global_discount
#: code:addons/account_global_discount/models/account_move.py:0
#, python-format
msgid "With global discounts, taxes in lines are required."
msgstr "Com descontos globais, são requeridos impostos nas linhas."
#~ msgid "Base discounted"
#~ msgstr "Base com desconto"
#~ msgid "Discounted amount"
#~ msgstr "Montante descontado"
#~ msgid "Tax"
#~ msgstr "Imposto"
#~ msgid "<strong>Global Discounts</strong><br/>"
#~ msgstr "<strong>Descontos Globais</strong><br/>"
#~ msgid "Invoice Tax"
#~ msgstr "Imposto de Fatura"

View file

@ -0,0 +1,2 @@
from . import account_move
from . import global_discount

View file

@ -0,0 +1,389 @@
# Copyright 2019 Tecnativa - David Vidal
# Copyright 2020-2021 Tecnativa - Pedro M. Baeza
# Copyright 2021 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, api, exceptions, fields, models
from odoo.tools import config
class AccountMove(models.Model):
_inherit = "account.move"
# HACK: Looks like UI doesn't behave well with Many2many fields and
# negative groups when the same field is shown. In this case, we want to
# show the readonly version to any not in the global discount group.
# TODO: Check if it's fixed in future versions
global_discount_ids_readonly = fields.Many2many(
string="Invoice Global Discounts (readonly)",
related="global_discount_ids",
readonly=True,
)
global_discount_ids = fields.Many2many(
comodel_name="global.discount",
column1="invoice_id",
column2="global_discount_id",
string="Invoice Global Discounts",
domain="[('discount_scope', 'in', {"
" 'out_invoice': ['sale'], "
" 'out_refund': ['sale'], "
" 'in_refund': ['purchase'], "
" 'in_invoice': ['purchase']"
"}.get(move_type, [])), ('account_id', '!=', False), '|', "
"('company_id', '=', company_id), ('company_id', '=', False)]",
readonly=True,
states={"draft": [("readonly", False)]},
)
amount_global_discount = fields.Monetary(
string="Total Global Discounts",
compute="_compute_amount",
currency_field="currency_id",
readonly=True,
compute_sudo=True,
store=True,
)
amount_untaxed_before_global_discounts = fields.Monetary(
string="Amount Untaxed Before Discounts",
compute="_compute_amount",
currency_field="currency_id",
readonly=True,
compute_sudo=True,
store=True,
)
invoice_global_discount_ids = fields.One2many(
comodel_name="account.invoice.global.discount",
inverse_name="invoice_id",
readonly=True,
)
def _prepare_global_discount_vals(self, global_discount, base, tax_ids):
"""Prepare the dictionary values for an invoice global discount
line.
"""
self.ensure_one()
discount = global_discount._get_global_discount_vals(base)
return {
"name": global_discount.display_name,
"invoice_id": self.id,
"global_discount_id": global_discount.id,
"discount": global_discount.discount,
"base": base,
"base_discounted": discount["base_discounted"],
"account_id": global_discount.account_id.id,
"tax_ids": [(4, tax_id) for tax_id in tax_ids],
}
def _set_global_discounts_by_tax(self):
"""Create invoice global discount lines by taxes combinations and
discounts.
This also resets previous global discounts in case they existed.
"""
self.ensure_one()
if not self.is_invoice():
return
in_draft_mode = self != self._origin
taxes_keys = {}
# Perform a sanity check for discarding cases that will lead to
# incorrect data in discounts
_self = self.filtered("global_discount_ids")
for inv_line in _self.invoice_line_ids.filtered(
lambda l: l.display_type not in ["line_section", "line_note"]
):
if inv_line.product_id.bypass_global_discount:
continue
taxes_keys.setdefault(tuple(inv_line.tax_ids.ids), 0)
taxes_keys[tuple(inv_line.tax_ids.ids)] += inv_line.price_subtotal
# Reset previous global discounts
self.invoice_global_discount_ids -= self.invoice_global_discount_ids
model = "account.invoice.global.discount"
create_method = in_draft_mode and self.env[model].new or self.env[model].create
for tax_line in _self.line_ids.filtered("tax_line_id"):
key = []
discount_line_base = 0
for key in taxes_keys:
if tax_line.tax_line_id.id in key:
discount_line_base = taxes_keys[key]
taxes_keys[key] = 0 # mark for not duplicating
break # we leave in key variable the proper taxes value
if not discount_line_base:
continue
for global_discount in self.global_discount_ids:
vals = self._prepare_global_discount_vals(
global_discount, discount_line_base, key
)
create_method(vals)
discount_line_base = vals["base_discounted"]
_self._set_global_discounts_by_zero_tax(taxes_keys, create_method)
def _set_global_discounts_by_zero_tax(self, taxes_keys, create_method):
# Check all moves with defined taxes to check if there's any discount not
# created (tax amount is zero and only one tax is applied)
base_total = 0
zero_taxes = self.env["account.tax"]
for line in self.line_ids.filtered("tax_ids"):
if line.product_id.bypass_global_discount:
continue
key = tuple(line.tax_ids.ids)
if taxes_keys.get(key):
base_total += line.price_subtotal
zero_taxes |= line.tax_ids
for global_discount in self.global_discount_ids:
if not base_total:
break
vals = self._prepare_global_discount_vals(
global_discount, base_total, zero_taxes.ids
)
create_method(vals)
base_total = vals["base_discounted"]
def _recompute_global_discount_lines(self):
"""Append global discounts move lines.
This is called when recomputing dynamic lines before calling
`_recompute_payment_terms_lines`, but after calling `_recompute_tax_lines`.
"""
self.ensure_one()
in_draft_mode = self != self._origin
model = "account.move.line"
create_method = in_draft_mode and self.env[model].new or self.env[model].create
for discount in self.invoice_global_discount_ids.filtered("discount"):
sign = -1 if self.move_type in {"in_invoice", "out_refund"} else 1
disc_amount = sign * discount.discount_amount
disc_amount_company_currency = disc_amount
if self.currency_id != self.company_id.currency_id:
disc_amount_company_currency = self.currency_id._convert(
disc_amount,
self.company_id.currency_id,
self.company_id,
self.date or fields.Date.context_today(self),
)
create_method(
{
"invoice_global_discount_id": discount.id,
"move_id": self.id,
"name": "%s - %s"
% (discount.name, ", ".join(discount.tax_ids.mapped("name"))),
"debit": disc_amount_company_currency > 0.0
and disc_amount_company_currency
or 0.0,
"credit": disc_amount_company_currency < 0.0
and -disc_amount_company_currency
or 0.0,
"amount_currency": (disc_amount > 0.0 and disc_amount or 0.0)
- (disc_amount < 0.0 and -disc_amount or 0.0),
"account_id": discount.account_id.id,
"tax_ids": [(4, x.id) for x in discount.tax_ids],
"partner_id": self.commercial_partner_id.id,
"currency_id": self.currency_id.id,
"price_unit": -1 * abs(disc_amount_company_currency),
}
)
@api.onchange("partner_id", "company_id")
def _onchange_partner_id(self):
res = super()._onchange_partner_id()
discounts = False
if (
self.move_type in ["out_invoice", "out_refund"]
and self.partner_id.customer_global_discount_ids
):
discounts = self.partner_id.customer_global_discount_ids.filtered(
lambda d: d.company_id == self.company_id
)
elif (
self.move_type in ["in_refund", "in_invoice"]
and self.partner_id.supplier_global_discount_ids
):
discounts = self.partner_id.supplier_global_discount_ids.filtered(
lambda d: d.company_id == self.company_id
)
if discounts:
self.global_discount_ids = discounts
return res
def _compute_amount_one(self):
"""Perform totals computation of a move with global discounts."""
if not self.invoice_global_discount_ids:
self.amount_global_discount = 0.0
self.amount_untaxed_before_global_discounts = 0.0
return
round_curr = self.currency_id.round
self.amount_global_discount = sum(
round_curr(discount.discount_amount) * -1
for discount in self.invoice_global_discount_ids
)
self.amount_untaxed_before_global_discounts = (
self.amount_untaxed - self.amount_global_discount
)
@api.depends(
"line_ids.matched_debit_ids.debit_move_id.move_id.payment_id.is_matched",
"line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual",
"line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual_currency",
"line_ids.matched_credit_ids.credit_move_id.move_id.payment_id.is_matched",
"line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual",
"line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual_currency",
"line_ids.balance",
"line_ids.currency_id",
"line_ids.amount_currency",
"line_ids.amount_residual",
"line_ids.amount_residual_currency",
"line_ids.payment_id.state",
"line_ids.full_reconcile_id",
"invoice_global_discount_ids",
"global_discount_ids",
)
def _compute_amount(self):
"""Modify totals computation for including global discounts."""
res = super()._compute_amount()
for record in self:
record._compute_amount_one()
return res
def _clean_global_discount_lines(self):
self.ensure_one()
gbl_disc_lines = self.env["account.move.line"].search(
[
("move_id", "=", self.id),
"|",
("global_discount_item", "=", True),
("invoice_global_discount_id", "!=", False),
]
)
if gbl_disc_lines:
move_container = {"records": self}
with self._check_balanced(move_container), self._sync_dynamic_lines(
move_container
):
gbl_disc_lines.unlink()
@api.model_create_multi
def create(self, vals_list):
"""If we create the invoice with the discounts already set like from
a sales order, we must compute the global discounts as well, as some data
like ``tax_ids`` is not set until the final step.
"""
moves = super().create(vals_list)
for move in moves:
if move.move_type in ["out_refund", "in_refund"]:
move._clean_global_discount_lines()
move._set_global_discounts_by_tax()
move._recompute_global_discount_lines()
return moves
def write(self, vals):
res = super().write(vals)
if "invoice_line_ids" in vals or "global_discount_ids" in vals:
for move in self:
move._clean_global_discount_lines()
move._set_global_discounts_by_tax()
move._recompute_global_discount_lines()
move_container = {"records": self}
self._global_discount_check(move_container)
return res
def _global_discount_check(self, container):
test_condition = not config["test_enable"] or self.env.context.get(
"test_account_global_discount"
)
for move in container["records"]:
if not move.is_invoice() or not move.global_discount_ids:
continue
taxes_keys = {}
for inv_line in move.invoice_line_ids:
if inv_line.display_type != "product":
continue
if not inv_line.tax_ids and test_condition:
raise exceptions.UserError(
_("With global discounts, taxes in lines are required.")
)
for key in taxes_keys:
if key == tuple(inv_line.tax_ids.ids):
break
elif set(key) & set(inv_line.tax_ids.ids) and test_condition:
raise exceptions.UserError(
_("Incompatible taxes found for global discounts.")
)
else:
taxes_keys[tuple(inv_line.tax_ids.ids)] = True
return True
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
invoice_global_discount_id = fields.Many2one(
comodel_name="account.invoice.global.discount",
string="Invoice Global Discount",
)
base_before_global_discounts = fields.Monetary(
string="Amount Untaxed Before Discounts",
readonly=True,
)
# TODO: To be removed on future versions if invoice_global_discount_id is properly filled
# Provided for compatibility in stable branch
# UPD: can be removed past version 16.0
global_discount_item = fields.Boolean()
class AccountInvoiceGlobalDiscount(models.Model):
_name = "account.invoice.global.discount"
_description = "Invoice Global Discount"
name = fields.Char(string="Discount Name", required=True)
invoice_id = fields.Many2one(
"account.move",
string="Invoice",
ondelete="cascade",
index=True,
readonly=True,
domain=[
(
"move_type",
"in",
["out_invoice", "out_refund", "in_invoice", "in_refund"],
)
],
)
global_discount_id = fields.Many2one(
comodel_name="global.discount",
string="Global Discount",
)
discount = fields.Float(string="Discount (number)")
discount_display = fields.Char(
compute="_compute_discount_display",
string="Discount",
)
base = fields.Float(string="Base before discount", digits="Product Price")
base_discounted = fields.Float(string="Base after discount", digits="Product Price")
currency_id = fields.Many2one(related="invoice_id.currency_id", readonly=True)
discount_amount = fields.Monetary(
string="Discounted Amount",
compute="_compute_discount_amount",
currency_field="currency_id",
compute_sudo=True,
)
tax_ids = fields.Many2many(comodel_name="account.tax", string="Taxes")
account_id = fields.Many2one(
comodel_name="account.account",
required=True,
string="Account",
domain="[('account_type', 'not in', ['asset_receivable', 'liability_payable'])]",
)
account_analytic_id = fields.Many2one(
comodel_name="account.analytic.account",
string="Analytic account",
)
company_id = fields.Many2one(related="invoice_id.company_id", readonly=True)
def _compute_discount_display(self):
"""Given a discount type, we need to render a different symbol"""
for one in self:
precision = self.env["decimal.precision"].precision_get("Discount")
one.discount_display = "{0:.{1}f}%".format(one.discount * -1, precision)
@api.depends("base", "base_discounted")
def _compute_discount_amount(self):
"""Compute the amount discounted"""
for one in self:
one.discount_amount = one.base - one.base_discounted

View file

@ -0,0 +1,27 @@
# Copyright 2019 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class GlobalDiscount(models.Model):
_inherit = "global.discount"
_check_company_auto = True
account_id = fields.Many2one(
comodel_name="account.account",
string="Account",
domain="[('account_type', 'not in', ['asset_receivable', 'liability_payable'])]",
check_company=True,
)
account_analytic_id = fields.Many2one(
comodel_name="account.analytic.account",
string="Analytic account",
check_company=True,
)
def _get_global_discount_vals(self, base, account_id=False, **kwargs):
"""Return account as well if passed"""
res = super()._get_global_discount_vals(base)
if account_id:
res.update({"account_id": account_id})
return res

View file

@ -0,0 +1,13 @@
To configure this module, you need to:
#. Go to *Settings > Parameters > Global Discounts*.
#. Add a new discount percentage.
#. Choose the discount scope (sales or purchases).
#. You can also restrict it to a certain company if needed.
You can assign global discounts to partners as well:
#. Go to a partner that is a company.
#. Go to the *Sales & Purchases* tab.
#. In section sale, you can set sale discounts.
#. In section purchase, you can set purchase discounts.

View file

@ -0,0 +1,9 @@
* `Tecnativa <https://www.tecnativa.com>`_
* Pedro M. Baeza
* David Vidal
* Carlos Dauden
* Rafael Blasco
* Ernesto Tejeda
* Víctor Martínez
* Omar Castiñeira <omar@comunitea.com>

View file

@ -0,0 +1 @@
Apply global discounts to invoices

View file

@ -0,0 +1,5 @@
* Not all the taxes combination can be compatible with global discounts, as
the generated journal items won't be correct for taxes declarations. An error
is raised in that cases.
* Currently, taxes in invoice lines are mandatory with global discounts.
* No tax tags are populated for the global discount move lines, only `tax_ids`.

View file

@ -0,0 +1,16 @@
To use this module, you need to:
#. Go to *Invoicing > Customers > Invoices*.
#. Create a new sales invoice, choose a customer with a defined global
discount and you will see how the value of the 'Invoice Global Discounts'
field is auto-completed with the global discounts defined in the customer
(See configuration section in this readme), although you can choose
then other global discounts defined in configuration.
#. Add several invoice lines.
#. At the bottom of the form you will see how global discounts affect the
total values.
#. Go to the 'Journal Items' tab (if you have permissions for that).
There you will see how the tax lines have the discount percentage applied
and you will also see the lines that reflect the global discount applied.
#. In the 'Other info' tab, you can see in the 'Global Discounts' table,
the global discounts applied to each of the invoice lines.

View file

@ -0,0 +1 @@
from . import account_invoice_report

View file

@ -0,0 +1,13 @@
from odoo import api, models
class AccountInvoiceReport(models.Model):
_inherit = "account.invoice.report"
@api.model
def _where(self):
where_str = super()._where()
return where_str.replace(
"NOT line.exclude_from_invoice_tab",
"(NOT line.exclude_from_invoice_tab OR global_discount_item = true)",
)

View file

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_invoice_global_discount_user,Invoice Global Discount Users,model_account_invoice_global_discount,base.group_user,1,0,0,0
access_invoice_global_discount_partner_manager,Invoice Global Discount Partner Manager,model_account_invoice_global_discount,account.group_account_invoice,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_invoice_global_discount_user Invoice Global Discount Users model_account_invoice_global_discount base.group_user 1 0 0 0
3 access_invoice_global_discount_partner_manager Invoice Global Discount Partner Manager model_account_invoice_global_discount account.group_account_invoice 1 1 1 1

View file

@ -0,0 +1,19 @@
<?xml version="1.0" ?>
<!-- Copyright 2019 Tecnativa - David Vidal
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.rule" id="global_discount_comp_rule">
<field name="name">Global Discount multi-company</field>
<field
name="model_id"
ref="account_global_discount.model_account_invoice_global_discount"
/>
<field
name="domain_force"
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
<field name="perm_read" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

View file

@ -0,0 +1,482 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Account Global Discount</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="account-global-discount">
<h1 class="title">Account Global Discount</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:58d81491b08d762ad414c2d4327aae330e0a1f8c0c4a6d0986a847f150c48327
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-invoicing/tree/16.0/account_global_discount"><img alt="OCA/account-invoicing" src="https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-invoicing-16-0/account-invoicing-16-0-account_global_discount"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Apply global discounts to invoices</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-3">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>To configure this module, you need to:</p>
<ol class="arabic simple">
<li>Go to <em>Settings &gt; Parameters &gt; Global Discounts</em>.</li>
<li>Add a new discount percentage.</li>
<li>Choose the discount scope (sales or purchases).</li>
<li>You can also restrict it to a certain company if needed.</li>
</ol>
<p>You can assign global discounts to partners as well:</p>
<ol class="arabic simple">
<li>Go to a partner that is a company.</li>
<li>Go to the <em>Sales &amp; Purchases</em> tab.</li>
<li>In section sale, you can set sale discounts.</li>
<li>In section purchase, you can set purchase discounts.</li>
</ol>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<p>To use this module, you need to:</p>
<ol class="arabic simple">
<li>Go to <em>Invoicing &gt; Customers &gt; Invoices</em>.</li>
<li>Create a new sales invoice, choose a customer with a defined global
discount and you will see how the value of the Invoice Global Discounts
field is auto-completed with the global discounts defined in the customer
(See configuration section in this readme), although you can choose
then other global discounts defined in configuration.</li>
<li>Add several invoice lines.</li>
<li>At the bottom of the form you will see how global discounts affect the
total values.</li>
<li>Go to the Journal Items tab (if you have permissions for that).
There you will see how the tax lines have the discount percentage applied
and you will also see the lines that reflect the global discount applied.</li>
<li>In the Other info tab, you can see in the Global Discounts table,
the global discounts applied to each of the invoice lines.</li>
</ol>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Not all the taxes combination can be compatible with global discounts, as
the generated journal items wont be correct for taxes declarations. An error
is raised in that cases.</li>
<li>Currently, taxes in invoice lines are mandatory with global discounts.</li>
<li>No tax tags are populated for the global discount move lines, only <cite>tax_ids</cite>.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-invoicing/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-invoicing/issues/new?body=module:%20account_global_discount%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a><ul>
<li>Pedro M. Baeza</li>
<li>David Vidal</li>
<li>Carlos Dauden</li>
<li>Rafael Blasco</li>
<li>Ernesto Tejeda</li>
<li>Víctor Martínez</li>
</ul>
</li>
<li>Omar Castiñeira &lt;<a class="reference external" href="mailto:omar&#64;comunitea.com">omar&#64;comunitea.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-invoicing/tree/16.0/account_global_discount">OCA/account-invoicing</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1 @@
from . import test_global_discount

View file

@ -0,0 +1,466 @@
# Copyright 2019 Tecnativa - David Vidal
# Copyright 2020 Tecnativa - Pedro M. Baeza
# Copyright 2021 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import exceptions
from odoo.tests import Form, tagged
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
@tagged("post_install", "-at_install")
class TestGlobalDiscount(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.env.ref("base_global_discount.group_global_discount").write(
{"users": [(4, cls.env.user.id)]}
)
cls.currency_eur = cls.env.ref("base.EUR")
cls.currency_usd = cls.env.ref("base.USD")
cls.currency_usd.active = True
# Make sure the currency of the company is USD, as this not always happens
# To be removed in V17: https://github.com/odoo/odoo/pull/107113
cls.company = cls.env.company
cls.env.cr.execute(
"UPDATE res_company SET currency_id = %s WHERE id = %s",
(cls.env.ref("base.USD").id, cls.company.id),
)
cls.account = cls.env["account.account"].create(
{
"name": "Test account",
"code": "TEST",
"account_type": "income_other",
"reconcile": True,
}
)
cls.account_receivable = cls.env["account.account"].create(
{
"name": "Test receivable account",
"code": "ACCRV",
"account_type": "asset_receivable",
"reconcile": True,
}
)
cls.account_payable = cls.env["account.account"].create(
{
"name": "Test receivable account",
"code": "ACCPAY",
"account_type": "liability_payable",
"reconcile": True,
}
)
cls.global_discount_obj = cls.env["global.discount"]
cls.global_discount_1 = cls.global_discount_obj.create(
{
"name": "Test Discount 1",
"discount_scope": "sale",
"discount": 20,
"account_id": cls.account.id,
"sequence": 3,
}
)
cls.global_discount_2 = cls.global_discount_obj.create(
{
"name": "Test Discount 2",
"discount_scope": "purchase",
"discount": 30,
"account_id": cls.account.id,
"sequence": 2,
}
)
cls.global_discount_3 = cls.global_discount_obj.create(
{
"name": "Test Discount 3",
"discount_scope": "purchase",
"discount": 50,
"account_id": cls.account.id,
"sequence": 1,
}
)
cls.partner_1 = cls.env["res.partner"].create(
{
"name": "Mr. Odoo",
"property_account_receivable_id": cls.account_receivable.id,
"property_account_payable_id": cls.account_payable.id,
}
)
cls.partner_2 = cls.env["res.partner"].create(
{
"name": "Mrs. Odoo",
"property_account_receivable_id": cls.account_receivable.id,
"property_account_payable_id": cls.account_payable.id,
}
)
cls.partner_2.supplier_global_discount_ids = cls.global_discount_2
cls.tax = cls.tax_purchase_a
cls.tax.amount = 15
cls.tax_0 = cls.tax_purchase_b
cls.tax_0.amount = 0
cls.journal = cls.env["account.journal"].create(
{"name": "Test purchase journal", "code": "TPUR", "type": "purchase"}
)
cls.invoice_line = cls.env["account.move.line"]
invoice_form = Form(
cls.env["account.move"].with_context(
default_move_type="in_invoice",
test_account_global_discount=True,
)
)
invoice_form.partner_id = cls.partner_1
invoice_form.ref = "Test global discount"
with invoice_form.invoice_line_ids.new() as line_form:
line_form.name = "Line 1"
line_form.price_unit = 200.0
line_form.quantity = 1
line_form.tax_ids.clear()
line_form.tax_ids.add(cls.tax)
cls.invoice = invoice_form.save()
def test_01_global_invoice_succesive_discounts(self):
"""Add global discounts to the invoice"""
invoice_tax_line = self.invoice.line_ids.filtered("tax_line_id")
self.assertAlmostEqual(self.invoice.amount_total, 230)
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 200.0)
self.assertAlmostEqual(invoice_tax_line.balance, 30.0)
# Global discounts are applied to the base and taxes are recomputed:
# 200 - 50% (global disc. 3) = 100
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.clear()
invoice_form.global_discount_ids.add(self.global_discount_3)
self.assertEqual(len(self.invoice.invoice_global_discount_ids), 1)
precision = self.env["decimal.precision"].precision_get("Discount")
self.assertEqual(
self.invoice.invoice_global_discount_ids.discount_display,
"-50.{}%".format("0" * precision),
)
invoice_tax_line = self.invoice.line_ids.filtered("tax_line_id")
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 100.0)
self.assertAlmostEqual(invoice_tax_line.balance, 15.0)
self.assertAlmostEqual(self.invoice.amount_untaxed, 100.0)
self.assertAlmostEqual(self.invoice.amount_total, 115.0)
self.assertAlmostEqual(self.invoice.amount_global_discount, -100.0)
# Global discounts are computed succecively:
# 200 - 50% (global disc. 1) = 100
# 100 - 30% (global disc. 2) = 70
# The global discounts amount is then 200 - 70 = 130
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_2)
self.assertEqual(len(self.invoice.invoice_global_discount_ids), 2)
invoice_tax_line = self.invoice.line_ids.filtered("tax_line_id")
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 70.0)
self.assertAlmostEqual(invoice_tax_line.balance, 10.5)
self.assertAlmostEqual(self.invoice.amount_untaxed, 70.0)
self.assertAlmostEqual(self.invoice.amount_total, 80.5)
self.assertAlmostEqual(self.invoice.amount_global_discount, -130.0)
# Line discounts apply before global ones so:
# 200 - 20% (line discount) = 160
# 160 - 50% (global disc. 1) = 80
# 80 - 30% (global disc. 2) = 56
# The global discounts amount is then 160 - 56 = 104
with Form(self.invoice) as invoice_form:
with invoice_form.invoice_line_ids.edit(0) as line_form:
# Make the test compatible if account_invoice_triple_discount
# is installed
if "discount1" in line_form._model._fields:
line_form.discount1 = 20
else:
line_form.discount = 20
self.assertEqual(len(self.invoice.invoice_global_discount_ids), 2)
invoice_tax_line = self.invoice.line_ids.filtered("tax_line_id")
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 56.0)
self.assertAlmostEqual(invoice_tax_line.balance, 8.4)
self.assertAlmostEqual(self.invoice.amount_untaxed, 56.0)
self.assertAlmostEqual(self.invoice.amount_total, 64.4)
self.assertAlmostEqual(self.invoice.amount_global_discount, -104.0)
def test_02_global_invoice_discounts_from_partner(self):
"""Change the partner and his global discounts go to the invoice"""
invoice_tax_line = self.invoice.line_ids.filtered("tax_line_id")
self.assertAlmostEqual(self.invoice.amount_total, 230)
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 200.0)
self.assertAlmostEqual(invoice_tax_line.balance, 30.0)
# When we change the parter, his global discounts are fetched depending
# on the type of the invoice. In this case, we fetch the supplier
# global discounts
with Form(self.invoice) as invoice_form:
invoice_form.partner_id = self.partner_2
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 140.0)
self.assertAlmostEqual(invoice_tax_line.balance, 21.0)
self.assertAlmostEqual(self.invoice.amount_untaxed, 140.0)
self.assertAlmostEqual(self.invoice.amount_total, 161.0)
self.assertAlmostEqual(self.invoice.amount_global_discount, -60.0)
def test_03_multiple_taxes_multi_line(self):
tax2 = self.tax.copy(default={"amount": 20.0})
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
with invoice_form.invoice_line_ids.new() as line_form:
line_form.name = "Line 2"
line_form.price_unit = 100.0
line_form.quantity = 1
line_form.tax_ids.clear()
line_form.tax_ids.add(tax2)
self.assertEqual(len(self.invoice.invoice_global_discount_ids), 2)
discount_tax_15 = self.invoice.invoice_global_discount_ids.filtered(
lambda x: x.tax_ids == self.tax
)
discount_tax_20 = self.invoice.invoice_global_discount_ids.filtered(
lambda x: x.tax_ids == tax2
)
self.assertAlmostEqual(discount_tax_15.discount_amount, 40)
self.assertAlmostEqual(discount_tax_20.discount_amount, 20)
tax_line_15 = self.invoice.line_ids.filtered(
lambda x: x.tax_line_id == self.tax
)
tax_line_20 = self.invoice.line_ids.filtered(lambda x: x.tax_line_id == tax2)
self.assertAlmostEqual(tax_line_15.tax_base_amount, 160)
self.assertAlmostEqual(tax_line_15.balance, 24)
self.assertAlmostEqual(tax_line_20.tax_base_amount, 80.0)
self.assertAlmostEqual(tax_line_20.balance, 16)
self.assertAlmostEqual(self.invoice.amount_untaxed, 240.0)
self.assertAlmostEqual(self.invoice.amount_total, 280)
self.assertAlmostEqual(self.invoice.amount_global_discount, -60.0)
# Check journal items validity
lines = self.invoice.line_ids
line_15 = lines.filtered(
lambda x: x.invoice_global_discount_id and x.tax_ids == self.tax
)
self.assertAlmostEqual(line_15.credit, 40)
line_20 = lines.filtered(
lambda x: x.invoice_global_discount_id and x.tax_ids == tax2
)
self.assertAlmostEqual(line_20.credit, 20)
def test_04_multiple_taxes_same_line(self):
tax2 = self.tax.copy(
default={"amount": -20.0}
) # negative for testing more use cases
with Form(self.invoice.with_context(check_move_validity=False)) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
with invoice_form.invoice_line_ids.edit(0) as line_form:
line_form.tax_ids.add(tax2)
# Global discounts are applied to the base and taxes are recomputed:
# 300 - 20% (global disc. 1) = 240
self.assertEqual(len(self.invoice.invoice_global_discount_ids), 1)
self.assertAlmostEqual(
self.invoice.invoice_global_discount_ids.discount_amount, 40
)
self.assertEqual(
self.invoice.invoice_global_discount_ids.tax_ids, self.tax + tax2
)
tax_line_15 = self.invoice.line_ids.filtered(
lambda x: x.tax_line_id == self.tax
)
tax_line_20 = self.invoice.line_ids.filtered(lambda x: x.tax_line_id == tax2)
self.assertAlmostEqual(tax_line_15.tax_base_amount, 160)
self.assertAlmostEqual(tax_line_15.balance, 24)
self.assertAlmostEqual(tax_line_20.tax_base_amount, 160.0)
self.assertAlmostEqual(tax_line_20.balance, -32)
self.assertAlmostEqual(self.invoice.amount_untaxed, 160.0)
self.assertAlmostEqual(self.invoice.amount_total, 152)
self.assertAlmostEqual(self.invoice.amount_global_discount, -40.0)
def test_05_incompatible_taxes(self):
# Line 1 with tax and tax2
# Line 2 with only tax2
tax2 = self.tax.copy(
default={"amount": -20.0}
) # negative for testing more use cases
with self.assertRaises(exceptions.UserError):
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
with invoice_form.invoice_line_ids.new() as line_form:
line_form.name = "Line 2"
line_form.price_unit = 100.0
line_form.quantity = 1
line_form.tax_ids.clear()
line_form.tax_ids.add(self.tax)
line_form.tax_ids.add(tax2)
def test_06_no_taxes(self):
with self.assertRaises(exceptions.UserError):
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
with invoice_form.invoice_line_ids.edit(0) as line_form:
line_form.tax_ids.clear()
def test_07_line_with_tax_0(self):
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
with invoice_form.invoice_line_ids.edit(0) as line_form:
line_form.tax_ids.clear()
line_form.tax_ids.add(self.tax_0)
discounts = self.invoice.invoice_global_discount_ids
self.assertEqual(len(discounts), 1)
self.assertAlmostEqual(discounts.discount_amount, 40)
def test_08_line2_with_tax_0(self):
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
with invoice_form.invoice_line_ids.new() as line_form:
line_form.name = "Line 2"
line_form.price_unit = 100.0
line_form.quantity = 1
line_form.tax_ids.clear()
line_form.tax_ids.add(self.tax_0)
self.assertEqual(len(self.invoice.invoice_global_discount_ids), 2)
discount_tax_15 = self.invoice.invoice_global_discount_ids.filtered(
lambda x: x.tax_ids == self.tax
)
self.assertAlmostEqual(discount_tax_15.discount_amount, 40)
discount_tax_0 = self.invoice.invoice_global_discount_ids.filtered(
lambda x: x.tax_ids == self.tax_0
)
self.assertAlmostEqual(discount_tax_0.discount_amount, 20)
def test_09_customer_invoice(self):
global_discount = self.global_discount_obj.create(
{
"name": "Test Discount Sales",
"discount_scope": "sale",
"discount": 50,
"account_id": self.account.id,
"sequence": 1,
}
)
tax = self.tax_sale_a.copy(default={"amount": 15.0})
invoice = (
self.env["account.move"]
.with_context(test_account_global_discount=True)
.create(
{
"move_type": "out_invoice",
"partner_id": self.partner_1.id,
"global_discount_ids": [(6, 0, global_discount.ids)],
"invoice_line_ids": [
(
0,
0,
{
"name": "Line 1",
"price_unit": 200.0,
"quantity": 1,
"tax_ids": [(6, 0, tax.ids)],
},
)
],
}
)
)
self.assertEqual(len(invoice.invoice_global_discount_ids), 1)
invoice_tax_line = invoice.line_ids.filtered("tax_line_id")
self.assertAlmostEqual(invoice_tax_line.tax_base_amount, 100.0)
self.assertAlmostEqual(invoice_tax_line.balance, -15.0)
self.assertAlmostEqual(invoice.amount_untaxed, 100.0)
self.assertAlmostEqual(invoice.amount_total, 115.0)
self.assertAlmostEqual(invoice.amount_global_discount, -100.0)
# Check journal item validity
lines = invoice.line_ids
line_15 = lines.filtered(
lambda x: x.invoice_global_discount_id and x.tax_ids == tax
)
self.assertAlmostEqual(line_15.debit, 100)
def test_10_customer_invoice_currency(self):
"""Multi-currency"""
eur = self.env.ref("base.EUR")
usd = self.env.ref("base.USD")
self.assertEqual(self.env.user.company_id.currency_id, usd)
with Form(self.invoice) as invoice_form:
invoice_form.currency_id = eur
invoice = invoice_form.save()
self.assertAlmostEqual(invoice.amount_total, 230.0)
self.assertAlmostEqual(invoice.amount_untaxed, 200.0)
self.assertAlmostEqual(invoice.amount_global_discount, 0)
base_line = invoice.line_ids.filtered(
lambda l: l.tax_ids and not l.invoice_global_discount_id
)
self.assertEqual(len(base_line), 1)
self.assertAlmostEqual(
base_line.balance,
eur._convert(
invoice.amount_untaxed, usd, self.env.user.company_id, invoice.date
),
)
tax_line = invoice.line_ids.filtered(
lambda l: l.tax_line_id and not l.invoice_global_discount_id
)
self.assertEqual(len(tax_line), 1)
tax_line_balance_before_discount = tax_line.balance
self.assertAlmostEqual(
tax_line_balance_before_discount,
eur._convert(
invoice.amount_untaxed * (self.tax.amount / 100),
usd,
self.env.user.company_id,
invoice.date,
),
)
self.assertAlmostEqual(
tax_line.tax_base_amount,
eur._convert(
invoice.amount_untaxed,
usd,
self.env.user.company_id,
invoice.date,
),
)
discount_line = invoice.line_ids.filtered("invoice_global_discount_id")
self.assertFalse(discount_line)
with Form(self.invoice) as invoice_form:
invoice_form.global_discount_ids.add(self.global_discount_1)
invoice = invoice_form.save()
# Check that when we add a global discount it will be based on the
# correct currency
self.assertAlmostEqual(invoice.amount_total, 184)
self.assertAlmostEqual(invoice.amount_untaxed, 160.0)
self.assertAlmostEqual(invoice.amount_global_discount, -40.0)
base_line = invoice.line_ids.filtered(
lambda l: l.tax_ids and not l.invoice_global_discount_id
)
self.assertEqual(len(base_line), 1)
self.assertAlmostEqual(
base_line.balance,
eur._convert(
invoice.amount_untaxed_before_global_discounts,
usd,
self.env.user.company_id,
invoice.date,
),
)
tax_line = invoice.line_ids.filtered(
lambda l: l.tax_line_id and not l.invoice_global_discount_id
)
self.assertEqual(len(tax_line), 1)
self.assertAlmostEqual(
tax_line.tax_base_amount,
eur._convert(
invoice.amount_untaxed,
usd,
self.env.user.company_id,
invoice.date,
),
)
self.assertAlmostEqual(
tax_line.balance,
eur._convert(
invoice.amount_untaxed * (self.tax.amount / 100),
usd,
self.env.user.company_id,
invoice.date,
),
)
self.assertLess(tax_line.balance, tax_line_balance_before_discount)
discount_line = invoice.line_ids.filtered("invoice_global_discount_id")
self.assertEqual(len(discount_line), 1)
self.assertAlmostEqual(
discount_line.balance,
eur._convert(
invoice.amount_global_discount,
usd,
self.env.user.company_id,
invoice.date,
),
)

View file

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2019 Tecnativa - David Vidal
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_move_form" model="ir.ui.view">
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form" />
<field name="arch" type="xml">
<!-- For ensuring the storage of these fields -->
<xpath expr="//field[@name='line_ids']/tree" position="inside">
<field name="invoice_global_discount_id" invisible="1" />
<field name="global_discount_item" invisible="1" />
</xpath>
<xpath expr="//field[@name='invoice_payment_term_id']/.." position="after">
<field
name="global_discount_ids"
widget="many2many_tags"
placeholder="Discounts..."
groups="base_global_discount.group_global_discount"
/>
<field
string="Invoice Global Discounts"
name="global_discount_ids_readonly"
widget="many2many_tags"
readonly="1"
groups="!base_global_discount.group_global_discount"
/>
</xpath>
<field name="tax_totals" position="before">
<field
name="amount_untaxed_before_global_discounts"
string="Untaxed Amount Before Disc."
attrs="{'invisible': ['|',('global_discount_ids', '=', []),('invoice_global_discount_ids','=',[])]}"
groups="base_global_discount.group_global_discount"
/>
<field
name="amount_untaxed_before_global_discounts"
string="Untaxed Amount Before Disc."
attrs="{'invisible': ['|',('global_discount_ids_readonly', '=', []),('invoice_global_discount_ids','=',[])]}"
groups="!base_global_discount.group_global_discount"
/>
<field
name="amount_global_discount"
string="Global Discounts"
attrs="{'invisible': ['|',('global_discount_ids', '=', []),('invoice_global_discount_ids','=',[])]}"
groups="base_global_discount.group_global_discount"
/>
<field
name="amount_global_discount"
string="Global Discounts"
attrs="{'invisible': ['|',('global_discount_ids_readonly', '=', []),('invoice_global_discount_ids','=',[])]}"
groups="!base_global_discount.group_global_discount"
/>
</field>
<field name="tax_totals" position="attributes">
<attribute
name="class"
add="oe_subtotal_footer_separator"
separator=" "
/>
</field>
<page id="other_tab" position="inside">
<separator string="Global Discounts" />
<field
name="invoice_global_discount_ids"
nolabel="1"
readonly="1"
attrs="{'invisible': [('global_discount_ids', '=', [])]}"
force_save="1"
groups="base_global_discount.group_global_discount"
>
<tree create="0" delete="0">
<field name="name" />
<field name="currency_id" invisible="1" />
<field name="global_discount_id" invisible="1" />
<field name="discount" invisible="1" />
<field
name="base"
widget="monetary"
options="{'currency_field': 'currency_id'}"
/>
<field name="discount_display" />
<field name="discount_amount" />
<field
name="base_discounted"
widget="monetary"
options="{'currency_field': 'currency_id'}"
/>
<field name="account_id" />
<field name="tax_ids" widget="many2many_tags" />
<field name="company_id" invisible="1" />
<field
domain="[('company_id', '=', company_id)]"
name="account_analytic_id"
groups="analytic.group_analytic_accounting"
/>
</tree>
</field>
<field
name="invoice_global_discount_ids"
nolabel="1"
readonly="1"
attrs="{'invisible': [('global_discount_ids_readonly', '=', [])]}"
force_save="1"
groups="!base_global_discount.group_global_discount"
>
<tree create="0" delete="0">
<field name="name" />
<field name="currency_id" invisible="1" />
<field name="global_discount_id" invisible="1" />
<field name="discount" invisible="1" />
<field
name="base"
widget="monetary"
options="{'currency_field': 'currency_id'}"
/>
<field name="discount_display" />
<field name="discount_amount" />
<field
name="base_discounted"
widget="monetary"
options="{'currency_field': 'currency_id'}"
/>
<field name="account_id" />
<field name="tax_ids" widget="many2many_tags" />
<field name="company_id" invisible="1" />
<field
domain="[('company_id', '=', company_id)]"
name="account_analytic_id"
groups="analytic.group_analytic_accounting"
/>
</tree>
</field>
</page>
</field>
</record>
</odoo>

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2019 Tecnativa - David Vidal
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="global_discount_view_tree" model="ir.ui.view">
<field name="model">global.discount</field>
<field name="inherit_id" ref="base_global_discount.global_discount_view_tree" />
<field name="arch" type="xml">
<field name="company_id" position="before">
<field
name="account_id"
required="1"
domain="[('company_id', '=', company_id)]"
/>
<field
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]"
name="account_analytic_id"
groups="analytic.group_analytic_accounting"
/>
</field>
</field>
</record>
<record id="global_discount_view_form" model="ir.ui.view">
<field name="model">global.discount</field>
<field name="inherit_id" ref="base_global_discount.global_discount_view_form" />
<field name="arch" type="xml">
<field name="company_id" position="before">
<field
name="account_id"
required="1"
domain="[('company_id', '=', company_id)]"
/>
<field
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]"
name="account_analytic_id"
groups="analytic.group_analytic_accounting"
/>
</field>
</field>
</record>
<menuitem
id="menu_account_global_discount"
action="base_global_discount.action_global_discount_tree"
name="Global Discounts"
groups="base_global_discount.group_global_discount"
parent="account.account_management_menu"
/>
</odoo>

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_invoice_document" inherit_id="account.report_invoice_document">
<xpath expr="//t[@t-set='tax_totals']" position="before">
<t t-if="o.global_discount_ids">
<tr>
<td>
<strong>Subtotal w/o disc.</strong>
</td>
<td class="text-end">
<span
t-field="o.amount_untaxed_before_global_discounts"
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
/>
</td>
</tr>
<tr style="border-bottom:1px solid #dddddd;">
<td>
<strong>Global Discounts</strong>
<br />
<t
t-esc="'→'.join(['{:.2f}%'.format(x.discount) for x in o.global_discount_ids])"
/>
</td>
<td class="text-end">
<span
t-field="o.amount_global_discount"
t-options='{"widget": "monetary", "display_currency": o.currency_id}'
/>
</td>
</tr>
</t>
</xpath>
</template>
</odoo>

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Account_global_discount Module - account_global_discount
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for account_global_discount. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,6 @@
# Dependencies
This addon depends on:
- [account](../../odoo-bringout-oca-ocb-account)
- base_global_discount

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon account_global_discount or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-account-invoicing-account_global_discount"
# or
uv pip install odoo-bringout-oca-account-invoicing-account_global_discount"
```

View file

@ -0,0 +1,15 @@
# Models
Detected core models and extensions in account_global_discount.
```mermaid
classDiagram
class account_invoice_global_discount
class account_move
class account_move_line
class global_discount
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: account_global_discount. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon account_global_discount
- License: LGPL-3

View file

@ -0,0 +1,25 @@
# Reports
Report definitions and templates in account_global_discount.
```mermaid
classDiagram
class AccountInvoiceReport
Model <|-- AccountInvoiceReport
```
## Available Reports
No named reports found in XML files.
## Report Files
- **account_invoice_report.py** (Python logic)
- **__init__.py** (Python logic)
## Notes
- Named reports above are accessible through Odoo's reporting menu
- Python files define report logic and data processing
- XML files contain report templates, definitions, and formatting
- Reports are integrated with Odoo's printing and email systems

View file

@ -0,0 +1,41 @@
# Security
Access control and security definitions in account_global_discount.
## Access Control Lists (ACLs)
Model access permissions defined in:
- **[ir.model.access.csv](../account_global_discount/security/ir.model.access.csv)**
- 2 model access rules
## Record Rules
Row-level security rules defined in:
## Security Groups & Configuration
Security groups and permissions defined in:
- **[security.xml](../account_global_discount/security/security.xml)**
```mermaid
graph TB
subgraph "Security Layers"
A[Users] --> B[Groups]
B --> C[Access Control Lists]
C --> D[Models]
B --> E[Record Rules]
E --> F[Individual Records]
end
```
Security files overview:
- **[ir.model.access.csv](../account_global_discount/security/ir.model.access.csv)**
- Model access permissions (CRUD rights)
- **[security.xml](../account_global_discount/security/security.xml)**
- Security groups, categories, and XML-based rules
Notes
- Access Control Lists define which groups can access which models
- Record Rules provide row-level security (filter records by user/group)
- Security groups organize users and define permission sets
- All security is enforced at the ORM level by Odoo

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon account_global_discount
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,43 @@
[project]
name = "odoo-bringout-oca-account-invoicing-account_global_discount"
version = "16.0.0"
description = "Account Global Discount - Odoo addon"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-account>=16.0.0",
"odoo-bringout-oca-account-invoicing-base_global_discount>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["account_global_discount"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]