Skip to content
Open
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
98 changes: 98 additions & 0 deletions sale_customer_order_frequency/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
=============================
Sale Customer Order Frequency
=============================

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

.. |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%2Fpartner--contact-lightgray.png?logo=github
:target: https://github.com/OCA/partner-contact/tree/18.0/sale_customer_order_frequency
:alt: OCA/partner-contact
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/partner-contact-18-0/partner-contact-18-0-sale_customer_order_frequency
: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/partner-contact&target_branch=18.0
:alt: Try me on Runboat

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

This module adds computed fields to partners to analyze their order
frequency.

Fields added to Contact/Partner:

- Average duration between orders
- Days since last order
- Days until next order

**Table of contents**

.. contents::
:local:

Usage
=====

To use this module, you need to:

#. Go to **Contacts**. #. Open a partner form. #. In the **Sales &
Purchase** tab, look for the following fields in the **Sale** group: \*
**Average order duration**: Average number of days between confirmed
orders. \* **Days since last order**: Number of days elapsed since the
last confirmed order. \* **Days until next order**: Estimated number of
days until the next order based on the average duration.

These fields are computed based on confirmed sale orders
(``state="sale"``).

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

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

* Pierre Verkest <[email protected]>

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

- Pierre Verkest [email protected]

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/partner-contact <https://github.com/OCA/partner-contact/tree/18.0/sale_customer_order_frequency>`_ 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 sale_customer_order_frequency/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
18 changes: 18 additions & 0 deletions sale_customer_order_frequency/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2025 Pierre Verkest <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Sale Customer Order Frequency",
"summary": "Compute customer order frequency statistics",
"version": "18.0.1.0.0",
"category": "Sales",
"website": "https://github.com/OCA/partner-contact",
"author": "Pierre Verkest <[email protected]>, Odoo Community Association (OCA)",
"license": "AGPL-3",
"depends": [
"sale",
],
"data": [
"views/res_partner_views.xml",
],
"installable": True,
}
56 changes: 56 additions & 0 deletions sale_customer_order_frequency/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_customer_order_frequency
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__average_order_duration
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__average_order_duration
msgid "Average Duration Between Orders"
msgstr "Durée moyenne entre les commandes"

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__average_order_duration
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__average_order_duration
msgid "Average number of days between orders"
msgstr "Nombre moyen de jours entre les commandes"

#. module: sale_customer_order_frequency
#: model:ir.model,name:sale_customer_order_frequency.model_res_partner
msgid "Contact"
msgstr "Contact"

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__days_until_next_order
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__days_until_next_order
msgid "Days Before Next Order"
msgstr "Jours avant la prochaine commande"

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__days_since_last_order
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__days_since_last_order
msgid "Days Since Last Order"
msgstr "Jours depuis la dernière commande"

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__days_until_next_order
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__days_until_next_order
msgid "Number of days before the next theoretical order"
msgstr "Nombre de jours avant la prochaine commande théorique"

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__days_since_last_order
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__days_since_last_order
msgid "Number of days since the last order"
msgstr "Nombre de jours depuis la dernière commande"
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_customer_order_frequency
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.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: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__average_order_duration
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__average_order_duration
msgid "Average Duration Between Orders"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__average_order_duration
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__average_order_duration
msgid "Average number of days between orders"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model,name:sale_customer_order_frequency.model_res_partner
msgid "Contact"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__days_until_next_order
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__days_until_next_order
msgid "Days Before Next Order"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__days_since_last_order
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__days_since_last_order
msgid "Days Since Last Order"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__days_until_next_order
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__days_until_next_order
msgid "Number of days before the next theoretical order"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__days_since_last_order
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__days_since_last_order
msgid "Number of days since the last order"
msgstr ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_customer_order_frequency
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.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: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__average_order_duration
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__average_order_duration
msgid "Average Duration Between Orders"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__average_order_duration
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__average_order_duration
msgid "Average number of days between orders"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model,name:sale_customer_order_frequency.model_res_partner
msgid "Contact"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__days_until_next_order
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__days_until_next_order
msgid "Days Before Next Order"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_partner__days_since_last_order
#: model:ir.model.fields,field_description:sale_customer_order_frequency.field_res_users__days_since_last_order
msgid "Days Since Last Order"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__days_until_next_order
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__days_until_next_order
msgid "Number of days before the next theoretical order"
msgstr ""

#. module: sale_customer_order_frequency
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_partner__days_since_last_order
#: model:ir.model.fields,help:sale_customer_order_frequency.field_res_users__days_since_last_order
msgid "Number of days since the last order"
msgstr ""
1 change: 1 addition & 0 deletions sale_customer_order_frequency/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import res_partner
58 changes: 58 additions & 0 deletions sale_customer_order_frequency/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from odoo import api, fields, models


class ResPartner(models.Model):
_inherit = "res.partner"

average_order_duration = fields.Float(
string="Average Duration Between Orders",
compute="_compute_order_frequency_stats",
store=True,
help="Average number of days between orders",
)
days_since_last_order = fields.Integer(
compute="_compute_order_frequency_stats",
store=True,
help="Number of days since the last order",
)
days_until_next_order = fields.Integer(
string="Days Before Next Order",
compute="_compute_order_frequency_stats",
store=True,
help="Number of days before the next theoretical order",
)

@api.depends("sale_order_ids.date_order", "sale_order_ids.state")
def _compute_order_frequency_stats(self):
today = fields.Date.context_today(self)
for partner in self:
# We consider confirmed orders
orders = (
partner.sale_order_ids.sudo()
.filtered(lambda o: o.state == "sale" and o.date_order)
.sorted("date_order")
)

if not orders:
partner.average_order_duration = 0.0
partner.days_since_last_order = 0
partner.days_until_next_order = 0
continue

last_order_date = orders[-1].date_order.date()
partner.days_since_last_order = (today - last_order_date).days

if len(orders) > 1:
first_order_date = fields.first(orders).date_order.date()
days_diff = (last_order_date - first_order_date).days
avg_duration = days_diff / (len(orders) - 1)
partner.average_order_duration = avg_duration

# Calculation: Date last order + Avg Duration - Today
# This is equivalent to: Avg Duration - Days since last order
partner.days_until_next_order = int(
avg_duration - partner.days_since_last_order
)
else:
partner.average_order_duration = 0.0
partner.days_until_next_order = 0
3 changes: 3 additions & 0 deletions sale_customer_order_frequency/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
1 change: 1 addition & 0 deletions sale_customer_order_frequency/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Pierre Verkest <[email protected]>
7 changes: 7 additions & 0 deletions sale_customer_order_frequency/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This module adds computed fields to partners to analyze their order frequency.

Fields added to Contact/Partner:

* Average duration between orders
* Days since last order
* Days until next order
10 changes: 10 additions & 0 deletions sale_customer_order_frequency/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
To use this module, you need to:

#. Go to **Contacts**.
#. Open a partner form.
#. In the **Sales & Purchase** tab, look for the following fields in the **Sale** group:
* **Average order duration**: Average number of days between confirmed orders.
* **Days since last order**: Number of days elapsed since the last confirmed order.
* **Days until next order**: Estimated number of days until the next order based on the average duration.

These fields are computed based on confirmed sale orders (`state="sale"`).
Loading