Skip to content

Commit

Permalink
Merge pull request #3 from chienandalu/imp-related-fields
Browse files Browse the repository at this point in the history
[IMP] Dynamic related fields columns
  • Loading branch information
chienandalu authored Oct 11, 2022
2 parents 26b138d + 26598a9 commit 4a2ee9e
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 16 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ To install with pip, simply:
pip install odooshow
```

## Known issues / Roadmap
## Known issues

- Make an Odoo module so we can plug the funcionality directly into the model abstract.
- Subfield values (AKA dynamic related values)
- Congigurable column totals. Now we're getting them from the field info.
- Better support for OdooRPC.

## Roadmap

- Make an Odoo module so we can plug the funcionality directly into the model abstract.
- Configurable column totals. Now we're getting them from the field info.
2 changes: 1 addition & 1 deletion odooshow/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.5.1"
__version__ = "0.6.0"
__author__ = "David Vidal"
__email__ = "chienandalu@gmail.com"
__doc__ = """A library to give goggles when diving into the Odoo Shell"""
Expand Down
63 changes: 54 additions & 9 deletions odooshow/odooshow.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@
__all__ = ["show", "show_read"]


def unpack_values(method):
"""Decorator to unpack related field values"""

def _unpack_value(*args):
if isinstance(args[1], list):
return " / ".join([method(args[0], x, *args[2:]) for x in args[1]])

def wrapper(*args, **kwargs):
res = _unpack_value(*args)
if res:
return res
res = method(*args, **kwargs)
return res

return wrapper


class OdooShow(object):
"""Trying to make Odoo devs' life easier!"""

Expand Down Expand Up @@ -73,6 +90,11 @@ def _many2many_format(cls):
def _one2many_format(cls):
return cls._relation_format()

@unpack_values
def _char_value(self, field, attrs=None, record=None):
return field

@unpack_values
def _monetary_value(self, field, attrs=None, record=None):
"""Format a monetary value with its currency symbol
Expand All @@ -92,18 +114,22 @@ def _monetary_value(self, field, attrs=None, record=None):
or ""
)

@unpack_values
def _float_value(self, field, attrs=None, record=None):
prec = attrs.get("digits", (0, 2))
return f"{field:.{prec[1]}f}"

@unpack_values
def _date_value(self, field, attrs=None, record=None):
return field and field.strftime("%Y-%m-%d") or ""

@unpack_values
def _datetime_value(self, field, attrs=None, record=None):
return field and field.strftime("%Y-%m-%d %H:%M:%S") or ""

@unpack_values
def _boolean_value(self, field, attrs=None, record=None):
return ":heavy_check_mark:" if field else ""
return ":heavy_check_mark:" if field else ":heavy_multiplication_x:"

def _record_url(self, record):
"""Return a formatted link for relational records. Only supported terminals
Expand Down Expand Up @@ -174,12 +200,12 @@ def _cell_value(self, record, field, attrs):
:return any: formatted value
"""
method_name = f"_{attrs.get('type', '')}_value"
value = record[field]
value = record.mapped(field) if "." in field else record[field]
try:
value = (
method_name in self
and getattr(self, method_name)(record[field], attrs, record)
or record[field]
and getattr(self, method_name)(value, attrs, record)
or value
)
# OdooRPC is not always as flexible as the regular Odoo shell so we try to
# format the record values. Otherwise we throw it as it is.
Expand Down Expand Up @@ -256,6 +282,29 @@ def _render_record_rows(self, table, records, fields, groupby=None):
end_section=(groupby or empty_group_by_cell) and record == last_row,
)

def _get_field_attributes(self, fields, records_obj):
"""Gather fields info. Relations supported.
:param list fields: List of str: field names
:return dict: Dictionary of fields attributes
"""
model_fields = records_obj.fields_get()
fields_attrs_dict = {}
for field in fields:
if "." in field:
relation_route = field.split(".")
relation_path = ".".join(relation_route[1:])
related_field_attrs = self._get_field_attributes(
[relation_path], records_obj[relation_route[0]]
)
fields_attrs_dict.update(
{field: related_field_attrs.get(relation_path, {})}
)
continue
if field in model_fields:
fields_attrs_dict.update({field: model_fields[field]})
return fields_attrs_dict

def _show(
self,
records,
Expand Down Expand Up @@ -294,11 +343,7 @@ def _show(
# Compatibility with OdooRPC to access the object fields properties
records_obj = records.env[records._name]
if fields:
fields = {
key: value
for key, value in records_obj.fields_get().items()
if key in fields
}
fields = self._get_field_attributes(fields, records_obj)
else:
# Get fields from default tree view
# Since v16 the method is deprecated. For the moment just silence warnings
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "odooshow"
version = "0.5.1"
version = "0.6.0"
description = "Make use of rich power tools to have nice formatted data in Odoo shells"
authors = ["David Vidal <chienandalu@gmail.com>"]

Expand Down
2 changes: 1 addition & 1 deletion tests/test_odooshow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

def test_version():
# TODO: Add tests. Not easy though as we need to setup a minimum Odoo instance.
assert __version__ == "0.5.1"
assert __version__ == "0.6.0"

0 comments on commit 4a2ee9e

Please sign in to comment.