Skip to content

Commit

Permalink
[ADD] base_partition: add partition method to base model
Browse files Browse the repository at this point in the history
  • Loading branch information
nans authored and glitchov committed Apr 24, 2023
1 parent 2579c69 commit 056e63c
Show file tree
Hide file tree
Showing 12 changed files with 686 additions and 0 deletions.
84 changes: 84 additions & 0 deletions base_partition/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
==============
Base Partition
==============

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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%2Fserver--tools-lightgray.png?logo=github
:target: https://github.com/OCA/server-tools/tree/12.0/base_partition
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-tools-12-0/server-tools-12-0-base_partition
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/149/12.0
:alt: Try me on Runbot

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

This module adds a `partition(self, accessor)` method to every model.
It accepts for accessor any parameter that would be accepted by `mapped`,
i.e. a string `"field(.subfield)*"` or a function `(lambda x: not x.b)`.
It returns a dictionary with keys that are equal to `set(record.mapped(accessor))`,
and with values that are recordsets
(these recordsets forming a partition of the initial recordset, conveniently).

So if we have a recordset (x | y | z ) such that x.f == True, y.f == z.f == False,
then (x | y | z ).partition("f") == {True: x, False: (y | z)}.

It also provides a backport of `filtered_domain`,
which filters a recordset in place with a provided domain.

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-tools/issues/new?body=module:%20base_partition%0Aversion:%2012.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
~~~~~~~

* Acsone

Contributors
~~~~~~~~~~~~

* Nans Lefebvre <[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/server-tools <https://github.com/OCA/server-tools/tree/12.0/base_partition>`_ 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 base_partition/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
15 changes: 15 additions & 0 deletions base_partition/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2020 Acsone (http://www.acsone.eu)
# Nans Lefebvre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
"name": "Base Partition",
"summary": "Base module that provide the partition method on all models",
"version": "12.0.0.0.0",
"category": "Uncategorized",
"website": "https://github.com/OCA/server-tools",
"author": "Acsone, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["base"],
}
22 changes: 22 additions & 0 deletions base_partition/i18n/base_partition.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * base_partition
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-04 13:29+0000\n"
"PO-Revision-Date: 2020-09-04 13:29+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: base_partition
#: model:ir.model,name:base_partition.model_base
msgid "Base"
msgstr ""

1 change: 1 addition & 0 deletions base_partition/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
41 changes: 41 additions & 0 deletions base_partition/models/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# © 2020 Acsone (http://www.acsone.eu)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import models

class Base(models.AbstractModel):

_inherit = 'base'

def partition(self, accessor):
"""Returns a dictionary forming a partition of self into a dictionary
value/recordset for each value obtained from the accessor.
The accessor itself can be either a string that can be passed to mapped,
or an arbitrary function.
Note that it is always at least as fast to pass a function,
hence the current implementation.
If we have a 'field.subfield' accessor such that subfield is not a relational
then the result is a list (not hashable). Then the str(key) are used.
In the general case a value could both not be hashable nor stringifiable,
in a which case this function would crash.
"""
partition = {}

if isinstance(accessor, str):
if "." not in accessor:
func = lambda r: r[accessor] # noqa: E731
else:
func = lambda r: r.mapped(accessor) # noqa: E731
else:
func = accessor

for record in self:
key = func(record)
if not key.__hash__:
key = str(key)
if key not in partition:
partition[key] = record
else:
partition[key] += record

return partition
1 change: 1 addition & 0 deletions base_partition/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Nans Lefebvre <[email protected]>
12 changes: 12 additions & 0 deletions base_partition/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
This module adds a `partition(self, accessor)` method to every model.
It accepts for accessor any parameter that would be accepted by `mapped`,
i.e. a string `"field(.subfield)*"` or a function `(lambda x: not x.b)`.
It returns a dictionary with keys that are equal to `set(record.mapped(accessor))`,
and with values that are recordsets
(these recordsets forming a partition of the initial recordset, conveniently).

So if we have a recordset (x | y | z ) such that x.f == True, y.f == z.f == False,
then (x | y | z ).partition("f") == {True: x, False: (y | z)}.

It also provides a backport of `filtered_domain`,
which filters a recordset in place with a provided domain.
Binary file added base_partition/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 056e63c

Please sign in to comment.