Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions account_customer_early_payment_discount/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

===============================
Customer Early Payment Discount
===============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d8a9269d26f62b027ca5fe3619de83a127ac4025d50a915b93fc4cf650fad73d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/license-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--payment-lightgray.png?logo=github
:target: https://github.com/OCA/account-payment/tree/19.0/account_customer_early_payment_discount
:alt: OCA/account-payment
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-payment-19-0/account-payment-19-0-account_customer_early_payment_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-payment&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Companies that grant their customers a discount for paying within a few
days often settle it with a credit note, because a credit note is a
fiscal document the customer can book and, in countries like Mexico, the
only way to report a discount granted after the invoice was issued.

The native early payment discount of the payment terms does not fit that
flow: it writes the discount off when the payment is registered, counts
calendar days only and takes the same percentage off the whole invoice,
freight and insurance included.

This module keeps the percentage and the days of the payment terms and
adds:

- **Settle with a credit note**: the customer pays the discounted
amount, and the discount is granted with a credit note applied to the
invoice, so the payment receipt reports what was really collected.
- **Business days**: the days to pay within are counted on the working
calendar of the company, skipping weekends and holidays.
- **Goods only**: the discount leaves out the services of the invoice,
such as freight or insurance.
- **Approvals**: the credit note is issued in draft, so any approval
flow of the company (for example ``account_move_tier_validation``) can
gate it. It is reconciled with the invoice as soon as it is posted.
- **Follow-up**: the invoices whose customer paid in time and still wait
for the credit note show under the *Early Payment to Apply* filter.

The last day to pay, the discount, the credit note and the *Apply Early
Payment* button come from ``account_early_payment_base``, shared with
the supplier side (``account_supplier_early_payment_discount``), so both
can be installed together.

**Table of contents**

.. contents::
:local:

Configuration
=============

- Open *Invoicing > Configuration > Payment Terms*, tick *Early
Discount* and fill in the percentage and the days as usual. Then tick
*Settle with a Credit Note* and, if needed, *Count Business Days* and
*On Goods Only*.
- For business days, set the working calendar of the company (*Settings
> Companies*) and its holidays as global time off of that calendar.
- The payment must reduce the balance of the invoice for the module to
see it, so the payment methods of the bank journals need an
outstanding receipts account.

Usage
=====

A posted customer invoice with such payment terms shows the last day to
pay and the amount of the discount. Once the customer pays at least the
discounted amount within that day, the invoice shows under the *Early
Payment to Apply* filter and the button *Apply Early Payment* appears.
Press it: a draft credit note for the discount is created, with the
eligible lines only and their taxes. Post it (after the approvals of
your company, if any) and it is reconciled with the invoice, which is
then fully paid.

Whether an invoice is paid in time is decided by
``account.move._early_payment_paid_on_time()``, and the lines the
discount takes off by ``account.move._early_payment_line_eligible()``;
both can be overridden.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-payment/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-payment/issues/new?body=module:%20account_customer_early_payment_discount%0Aversion:%2019.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
-------

* Jarsa

Contributors
------------

- Jarsa

- Alan Ramos <alan.ramos@jarsa.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-payment <https://github.com/OCA/account-payment/tree/19.0/account_customer_early_payment_discount>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions account_customer_early_payment_discount/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
18 changes: 18 additions & 0 deletions account_customer_early_payment_discount/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2026 Jarsa
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Customer Early Payment Discount",
"summary": "Early payment discount granted to customers settled by a credit note",
"version": "19.0.1.0.0",
"category": "Accounting",
"website": "https://github.com/OCA/account-payment",
"author": "Jarsa, Odoo Community Association (OCA)",
"license": "AGPL-3",
"development_status": "Beta",
"depends": ["account_early_payment_base"],
"data": [
"views/account_payment_term_views.xml",
"views/account_move_views.xml",
],
"installable": True,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_customer_early_payment_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 19.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-18 15:09+0000\n"
"PO-Revision-Date: 2026-09-18 15:09+0000\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_customer_early_payment_discount
#: model:ir.model.fields.selection,name:account_customer_early_payment_discount.selection__account_move__early_payment_state__applied
msgid "Applied"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__early_discount_business_days
msgid "Count Business Days"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_move__display_name
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__display_name
msgid "Display Name"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_bank_statement_line__early_payment_state
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_move__early_payment_state
msgid "Early Payment State"
msgstr ""

#. module: account_customer_early_payment_discount
#: model_terms:ir.ui.view,arch_db:account_customer_early_payment_discount.view_account_invoice_filter
msgid "Early Payment to Apply"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_move__id
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__id
msgid "ID"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model,name:account_customer_early_payment_discount.model_account_move
msgid "Journal Entry"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__early_discount_goods_only
msgid "On Goods Only"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model,name:account_customer_early_payment_discount.model_account_payment_term
msgid "Payment Terms"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__early_discount_credit_note
msgid "Settle with a Credit Note"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_payment_term__early_discount_business_days
msgid ""
"The days to pay within are business days of the working calendar of the "
"company: weekends and holidays do not count."
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_payment_term__early_discount_credit_note
msgid ""
"The discount is granted with a credit note applied to the invoice once the "
"customer pays in time, instead of being written off when the payment is "
"registered."
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_payment_term__early_discount_goods_only
msgid ""
"The discount leaves out the services of the invoice, such as freight or "
"insurance, and takes off the goods only."
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields.selection,name:account_customer_early_payment_discount.selection__account_move__early_payment_state__available
msgid "To Apply"
msgstr ""

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_bank_statement_line__early_payment_state
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_move__early_payment_state
msgid ""
"To Apply: the customer paid in time and the credit note is not issued yet. "
"Applied: the credit note is issued."
msgstr ""
114 changes: 114 additions & 0 deletions account_customer_early_payment_discount/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_customer_early_payment_discount
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 19.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-18 15:09+0000\n"
"PO-Revision-Date: 2026-09-18 15:09+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\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"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields.selection,name:account_customer_early_payment_discount.selection__account_move__early_payment_state__applied
msgid "Applied"
msgstr "Aplicado"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__early_discount_business_days
msgid "Count Business Days"
msgstr "Contar días hábiles"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_move__display_name
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__display_name
msgid "Display Name"
msgstr "Nombre mostrado"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_bank_statement_line__early_payment_state
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_move__early_payment_state
msgid "Early Payment State"
msgstr "Estado del pronto pago"

#. module: account_customer_early_payment_discount
#: model_terms:ir.ui.view,arch_db:account_customer_early_payment_discount.view_account_invoice_filter
msgid "Early Payment to Apply"
msgstr "Pronto pago por aplicar"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_move__id
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__id
msgid "ID"
msgstr "ID"

#. module: account_customer_early_payment_discount
#: model:ir.model,name:account_customer_early_payment_discount.model_account_move
msgid "Journal Entry"
msgstr "Asiento contable"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__early_discount_goods_only
msgid "On Goods Only"
msgstr "Solo sobre bienes"

#. module: account_customer_early_payment_discount
#: model:ir.model,name:account_customer_early_payment_discount.model_account_payment_term
msgid "Payment Terms"
msgstr "Términos de pago"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,field_description:account_customer_early_payment_discount.field_account_payment_term__early_discount_credit_note
msgid "Settle with a Credit Note"
msgstr "Liquidar con nota de crédito"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_payment_term__early_discount_business_days
msgid ""
"The days to pay within are business days of the working calendar of the "
"company: weekends and holidays do not count."
msgstr ""
"Los días del plazo son días hábiles del calendario laboral de la compañía: "
"los fines de semana y los días festivos no cuentan."

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_payment_term__early_discount_credit_note
msgid ""
"The discount is granted with a credit note applied to the invoice once the "
"customer pays in time, instead of being written off when the payment is "
"registered."
msgstr ""
"El descuento se otorga con una nota de crédito aplicada a la factura cuando "
"el cliente paga a tiempo, en lugar de cancelarse como diferencia al "
"registrar el pago."

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_payment_term__early_discount_goods_only
msgid ""
"The discount leaves out the services of the invoice, such as freight or "
"insurance, and takes off the goods only."
msgstr ""
"El descuento excluye los servicios de la factura, como fletes o seguros, y "
"se aplica únicamente a los bienes."

#. module: account_customer_early_payment_discount
#: model:ir.model.fields.selection,name:account_customer_early_payment_discount.selection__account_move__early_payment_state__available
msgid "To Apply"
msgstr "Por aplicar"

#. module: account_customer_early_payment_discount
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_bank_statement_line__early_payment_state
#: model:ir.model.fields,help:account_customer_early_payment_discount.field_account_move__early_payment_state
msgid ""
"To Apply: the customer paid in time and the credit note is not issued yet. "
"Applied: the credit note is issued."
msgstr ""
"Por aplicar: el cliente pagó a tiempo y la nota de crédito aún no se emite. "
"Aplicado: la nota de crédito ya fue emitida."
2 changes: 2 additions & 0 deletions account_customer_early_payment_discount/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import account_move
from . import account_payment_term
Loading
Loading