Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4234395
[IMP] base_custom_filter: reflect OCA changes
AungKoKoLin1997 May 22, 2026
2b1d655
[IMP] base_tier_validation: reflect OCA changes
AungKoKoLin1997 May 22, 2026
77c9c86
[IMP] base_user_role: reflect OCA changes
AungKoKoLin1997 May 22, 2026
8b124dd
[IMP] hr_attendance_flex_rest_time: reflect OCA changes
AungKoKoLin1997 May 22, 2026
e6b609b
[IMP] hr_attendance_manage_own: reflect OCA changes
AungKoKoLin1997 May 22, 2026
53b8f34
[IMP] hr_timesheet_sheet_attendance: reflect OCA changes
AungKoKoLin1997 May 22, 2026
7c3cb12
[IMP] hr_timesheet_sheet: reflect OCA changes
AungKoKoLin1997 May 22, 2026
407b5cc
[IMP] l10n_jp_country_state: reflect OCA changes
AungKoKoLin1997 May 22, 2026
47e98de
[IMP] mrp_stock_move_actual_date: reflect OCA changes
AungKoKoLin1997 May 22, 2026
f2fcc14
[IMP] product_tag_view: reflect OCA changes
AungKoKoLin1997 May 22, 2026
f759e92
[IMP] product_tier_validation: reflect OCA changes
AungKoKoLin1997 May 22, 2026
ec5d962
[IMP] project_task_default_stage: reflect OCA changes
AungKoKoLin1997 May 22, 2026
f095929
[IMP] purchase_order_secondary_unit: reflect OCA changes
AungKoKoLin1997 May 22, 2026
865869c
[IMP] purchase_stock_secondary_unit: reflect OCA changes
AungKoKoLin1997 May 22, 2026
9bd947e
[IMP] report_qweb_field_option: reflect OCA changes
AungKoKoLin1997 May 22, 2026
35a190e
[IMP] stock_secondary_unit: reflect OCA changes
AungKoKoLin1997 May 22, 2026
44bb8ea
[IMP] template_content_swapper: reflect OCA changes
AungKoKoLin1997 May 22, 2026
18cac18
[IMP] web_form_banner: reflect OCA changes
AungKoKoLin1997 May 22, 2026
a1fd881
[IMP] web_m2x_dialog_no_create: reflect OCA changes
AungKoKoLin1997 May 22, 2026
daeffed
[IMP] web_m2x_options: reflect OCA changes
AungKoKoLin1997 May 22, 2026
254bee3
[IMP] web_widget_x2many_2d_matrix: reflect OCA changes
AungKoKoLin1997 May 22, 2026
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
9 changes: 8 additions & 1 deletion base_custom_filter/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,16 @@ Configuration

Filter:

- Domain (``domain``)
- Domain (``domain``) - OR -
- Date Field (``date_field``) - creates a date filter with period
options
- User Groups (``groups``)

**Note:** For filter type, you must specify either Domain or Date
Field, but not both. Date filters automatically provide period
options like Today, This Week, This Month, This Quarter, and This
Year.

Group By:

- Group By Field (field to be assigned to ``group_by`` context)
Expand Down
5 changes: 4 additions & 1 deletion base_custom_filter/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ def _build_filter_element(self, item, is_groupby=False):
if is_groupby:
attrs["context"] = str({"group_by": item.groupby_field.sudo().name})
else:
attrs["domain"] = item.domain
if item.date_field:
attrs["date"] = item.date_field.sudo().name
else:
attrs["domain"] = item.domain
return etree.Element("filter", attrs)

@api.model
Expand Down
45 changes: 44 additions & 1 deletion base_custom_filter/models/ir_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.osv import expression


Expand Down Expand Up @@ -38,9 +39,51 @@ def _selection_type(self):
help="""Enter a filter domain expression if necessary.
Example: [('default_code', 'ilike', self)]"""
)
date_field = fields.Many2one(
comodel_name="ir.model.fields",
ondelete="cascade",
domain=(
"[('model', '=', model_id), "
"('ttype', 'in', ['date', 'datetime']), "
"('store', '=', True)]"
),
compute="_compute_date_field",
store=True,
readonly=False,
inverse="_inverse_date_field",
help="If set, creates a date filter with period options "
"(Today, This Week, This Month, etc.) instead of a domain filter. "
"Only applicable for filter type.",
)
group_ids = fields.Many2many("res.groups", string="User Groups")
group_id = fields.Many2one(comodel_name="ir.filters.group", string="Filter Group")

@api.constrains("type", "domain", "date_field")
def _check_filter_type_fields(self):
for record in self:
if record.type != "filter":
continue
has_domain = record.domain and record.domain != "[]"
if has_domain and record.date_field:
raise ValidationError(
_(
"Filter '%(name)s': You cannot set both Domain and "
"Date Field. Please choose only one.",
name=record.name,
)
)

@api.depends("type", "domain")
def _compute_date_field(self):
for record in self:
if record.type != "filter" or (record.domain and record.domain != "[]"):
record.date_field = False

def _inverse_date_field(self):
for record in self:
if record.date_field:
record.domain = "[]"

@api.model
def get_filters(
self,
Expand Down
17 changes: 11 additions & 6 deletions base_custom_filter/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@

Filter:

> - Domain (`domain`)
> - Domain (`domain`) - OR -
> - Date Field (`date_field`) - creates a date filter with period options
> - User Groups (`groups`)
>
> **Note:** For filter type, you must specify either Domain or Date Field,
> but not both. Date filters automatically provide period options like
> Today, This Week, This Month, This Quarter, and This Year.

Group By:

Expand All @@ -29,8 +34,8 @@
3. Filter groups (accessible via *Settings \> Custom Filters \> Custom
Filter Groups*) support the following optional settings:

> - Insert XPath: XPath expression for the insertion point
> (e.g. `//filter[@name='my_filter']`)
> - Insert Position: Insert before or after the target element
> - Separator Position: Place separator before, after, or none
> (filter type only)
- Insert XPath: XPath expression for the insertion point
(e.g. `//filter[@name='my_filter']`)
- Insert Position: Insert before or after the target element
- Separator Position: Place separator before, after, or none
(filter type only)
19 changes: 14 additions & 5 deletions base_custom_filter/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
: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.
Expand Down Expand Up @@ -274,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
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 }
Expand All @@ -300,7 +301,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -407,9 +408,15 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>Filter:</p>
<blockquote>
<ul class="simple">
<li>Domain (<tt class="docutils literal">domain</tt>)</li>
<li>Domain (<tt class="docutils literal">domain</tt>) - OR -</li>
<li>Date Field (<tt class="docutils literal">date_field</tt>) - creates a date filter with period
options</li>
<li>User Groups (<tt class="docutils literal">groups</tt>)</li>
</ul>
<p><strong>Note:</strong> For filter type, you must specify either Domain or Date
Field, but not both. Date filters automatically provide period
options like Today, This Week, This Month, This Quarter, and This
Year.</p>
</blockquote>
<p>Group By:</p>
<blockquote>
Expand Down Expand Up @@ -485,7 +492,9 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-7">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>
<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>
Expand Down
68 changes: 46 additions & 22 deletions base_custom_filter/tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,31 @@ def test_get_view_content_groupby(self):
"The string is not in the returned view",
)

def test_get_filters_excludes_non_favorites(self):
"""Test that get_filters excludes non-favorite filter types."""
# Create a non-favorite filter
self.filters_obj.create(
{
"name": "Non-Favorite Filter",
"type": "filter",
"model_id": "ir.filters.group",
"domain": '[["id","=",1]]',
}
)
# Create a favorite filter
self.filters_obj.create(
{
"name": "Favorite Filter",
"type": "favorite",
"model_id": "ir.filters.group",
"domain": '[["id","=",2]]',
}
)
results = self.filters_obj.get_filters("ir.filters.group")
result_names = [r["name"] for r in results]
self.assertNotIn("Non-Favorite Filter", result_names)
self.assertIn("Favorite Filter", result_names)

def test_insert_xpath_validation(self):
group = self.filters_group_obj.create(
{
Expand Down Expand Up @@ -158,27 +183,26 @@ def test_filter_with_custom_xpath(self):
between_content = view_content[filter_pos:target_pos]
self.assertNotIn("<separator/>", between_content)

def test_get_filters_excludes_non_favorites(self):
"""Test that get_filters excludes non-favorite filter types."""
# Create a non-favorite filter
self.filters_obj.create(
{
"name": "Non-Favorite Filter",
"type": "filter",
"model_id": "ir.filters.group",
"domain": '[["id","=",1]]',
}
def test_get_view_content_date_filter(self):
with Form(self.filters_obj) as date_filter:
date_filter.name = "Test Date Filter"
date_filter.type = "filter"
date_filter.model_id = "ir.filters.group"
date_filter.date_field = self.env.ref(
"base_custom_filter.field_ir_filters_group__create_date"
)
filter_record = self.filters_obj.search([("name", "=", "Test Date Filter")])
self.assertEqual(filter_record.name, "Test Date Filter")
view_dict = self.filters_group_obj.get_view(view_type="search")
view_content = view_dict.get("arch", b"").decode("utf-8")
filter_name = "ir_custom_filter_" + str(filter_record.id)
date_string = (
f'<filter name="{filter_name}" '
'string="Test Date Filter" '
'date="create_date"/>'
)
# Create a favorite filter
self.filters_obj.create(
{
"name": "Favorite Filter",
"type": "favorite",
"model_id": "ir.filters.group",
"domain": '[["id","=",2]]',
}
self.assertIn(
date_string,
view_content,
"The date filter is not in the returned view",
)
results = self.filters_obj.get_filters("ir.filters.group")
result_names = [r["name"] for r in results]
self.assertNotIn("Non-Favorite Filter", result_names)
self.assertIn("Favorite Filter", result_names)
10 changes: 9 additions & 1 deletion base_custom_filter/views/ir_filters_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@
/>
</field>
<field name="domain" position="attributes">
<attribute name="invisible">type in ['search', 'groupby']</attribute>
<attribute
name="invisible"
>type in ['search', 'groupby'] or date_field</attribute>
</field>
<field name="domain" position="after">
<field
name="date_field"
invisible="type != 'filter' or (domain and domain != '[]')"
/>
<field
name="groupby_field"
domain="[('model', '=', model_id), ('store', '=', True)]"
Expand Down Expand Up @@ -66,6 +72,7 @@
</field>
<field name="action_id" position="after">
<field name="type" />
<field name="date_field" optional="hide" />
<field name="groupby_field" optional="hide" />
</field>
</field>
Expand All @@ -81,6 +88,7 @@
<field name="type" />
<field name="group_id" />
<field name="domain" optional="hide" />
<field name="date_field" optional="hide" />
<field name="groupby_field" optional="hide" />
</list>
</field>
Expand Down
2 changes: 1 addition & 1 deletion base_tier_validation/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Base Tier Validation
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:dc242d6c50cc357fbd98be3778c5e3013971e9ea0622db72e500fd72d0de7c80
!! source digest: sha256:1823d16061ca83ece8322b77d320bb735e7462305d7ae60fd3e15819f3c6f276
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
Expand Down
2 changes: 1 addition & 1 deletion base_tier_validation/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Base Tier Validation",
"summary": "Implement a validation process based on tiers.",
"version": "18.0.3.3.1",
"version": "18.0.3.4.0",
"development_status": "Mature",
"maintainers": ["LoisRForgeFlow"],
"category": "Tools",
Expand Down
1 change: 1 addition & 0 deletions base_tier_validation/models/tier_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class TierReview(models.Model):
("pending", "Pending"),
("rejected", "Rejected"),
("approved", "Approved"),
("cancel", "Cancel"),
],
default="waiting",
)
Expand Down
7 changes: 7 additions & 0 deletions base_tier_validation/models/tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,13 @@ def _rejected_tier(self, tiers=False):
)
# We need to notify all pending users if there is approve sequence
if tier_reviews and any(review.approve_sequence for review in tier_reviews):
# If there are waiting reviews that should be approved sequentially,
# they must be marked as canceled
waiting_reviews = self.review_ids.filtered(
lambda r: r.status == "waiting" and r.approve_sequence
)
if waiting_reviews:
waiting_reviews.write({"status": "cancel"})
reviews_to_notify = self.review_ids.filtered(
lambda r: r.status == "pending" and r.definition_id.notify_on_rejected
)
Expand Down
2 changes: 1 addition & 1 deletion base_tier_validation/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ <h1>Base Tier Validation</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:dc242d6c50cc357fbd98be3778c5e3013971e9ea0622db72e500fd72d0de7c80
!! source digest: sha256:1823d16061ca83ece8322b77d320bb735e7462305d7ae60fd3e15819f3c6f276
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-ux/tree/18.0/base_tier_validation"><img alt="OCA/server-ux" src="https://img.shields.io/badge/github-OCA%2Fserver--ux-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-ux-18-0/server-ux-18-0-base_tier_validation"><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/server-ux&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Validating some operations is a common need across different areas in a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
t-key="review.id"
>
<t
t-if="review.status == 'waiting'"
t-if="review.status == 'waiting' or review.status == 'cancel'"
t-set="status_class"
t-value="'text-muted'"
/>
Expand Down
Loading
Loading