diff --git a/date_range/README.rst b/date_range/README.rst index 6d897176de..9900836d1e 100644 --- a/date_range/README.rst +++ b/date_range/README.rst @@ -72,7 +72,7 @@ model: _date_range_search_field = "invoice_date" -.. |search_view| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_many2one_search_field.png +.. |search_view| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_many2one_search_field.png Usage ===== @@ -124,14 +124,14 @@ To configure this module, you need to: |image8| -.. |image1| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_type_create.png -.. |image2| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_create.png -.. |image3| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_wizard.png -.. |image4| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_wizard_result.png -.. |image5| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_type_as_filter.png -.. |image6| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_as_filter.png -.. |image7| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_as_filter_result.png -.. |image8| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_type_autogeneration.png +.. |image1| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_type_create.png +.. |image2| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_create.png +.. |image3| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_wizard.png +.. |image4| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_wizard_result.png +.. |image5| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_type_as_filter.png +.. |image6| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_as_filter.png +.. |image7| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_as_filter_result.png +.. |image8| image:: https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_type_autogeneration.png Bug Tracker =========== @@ -161,6 +161,7 @@ Contributors - Stefan Rijnhart - David Ramia <<@ramiadavid>> - Son Ho +- Bert Van Groenendael Maintainers ----------- diff --git a/date_range/__manifest__.py b/date_range/__manifest__.py index 813e3dba25..5262af0e43 100644 --- a/date_range/__manifest__.py +++ b/date_range/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Date Range", "summary": "Manage all kind of date range", - "version": "17.0.1.2.1", + "version": "18.0.1.0.0", "category": "Uncategorized", "website": "https://github.com/OCA/server-ux", "author": "ACSONE SA/NV, Odoo Community Association (OCA)", diff --git a/date_range/data/ir_cron_data.xml b/date_range/data/ir_cron_data.xml index ddf5ceed18..5282588334 100644 --- a/date_range/data/ir_cron_data.xml +++ b/date_range/data/ir_cron_data.xml @@ -4,9 +4,7 @@ Auto-generate date ranges 1 days - -1 True - code model.autogenerate_ranges() diff --git a/date_range/models/date_range.py b/date_range/models/date_range.py index 1047d3600b..00b5e9da80 100644 --- a/date_range/models/date_range.py +++ b/date_range/models/date_range.py @@ -1,7 +1,7 @@ # Copyright 2016 ACSONE SA/NV () # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -from odoo import _, api, fields, models +from odoo import api, fields, models from odoo.exceptions import ValidationError @@ -21,14 +21,16 @@ def _default_company(self): type_id = fields.Many2one( comodel_name="date.range.type", string="Type", - index=1, + index=True, required=True, ondelete="restrict", - domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]", check_company=True, ) company_id = fields.Many2one( - comodel_name="res.company", string="Company", index=1, default=_default_company + comodel_name="res.company", + string="Company", + index=True, + default=_default_company, ) active = fields.Boolean( help="The active field allows you to hide the date range without " @@ -59,7 +61,10 @@ def _validate_range(self): for this in self: if this.date_start > this.date_end: raise ValidationError( - _("%(name)s is not a valid range (%(date_start)s > %(date_end)s)") + self.env._( + "%(name)s is not a valid range " + "(%(date_start)s > %(date_end)s)" + ) % { "name": this.name, "date_start": this.date_start, @@ -97,7 +102,7 @@ def _validate_range(self): if res: dt = self.browse(res[0][0]) raise ValidationError( - _("%(thisname)s overlaps %(dtname)s") + self.env._("%(thisname)s overlaps %(dtname)s") % {"thisname": this.name, "dtname": dt.name} ) diff --git a/date_range/models/date_range_search_mixin.py b/date_range/models/date_range_search_mixin.py index 256a22cde3..d832820c27 100644 --- a/date_range/models/date_range_search_mixin.py +++ b/date_range/models/date_range_search_mixin.py @@ -2,7 +2,7 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from lxml import etree -from odoo import _, api, fields, models +from odoo import api, fields, models from odoo.osv.expression import FALSE_DOMAIN, NEGATIVE_TERM_OPERATORS, TRUE_DOMAIN @@ -75,7 +75,7 @@ def get_view(self, view_id=None, view_type="form", **options): "field", attrib={ "name": "date_range_search_id", - "string": _("Period"), + "string": self.env._("Period"), }, ) groups = root.xpath("/search/group") @@ -97,6 +97,8 @@ def get_views(self, views, options=None): fields list (while still showing up in the Export widget) """ result = super().get_views(views, options=options) - if "date_range_search_id" in result["models"][self._name]: - result["models"][self._name]["date_range_search_id"]["string"] = _("Period") + if "date_range_search_id" in result["models"][self._name]["fields"]: + result["models"][self._name]["fields"]["date_range_search_id"]["string"] = ( + self.env._("Period") + ) return result diff --git a/date_range/models/date_range_type.py b/date_range/models/date_range_type.py index 4c1a849754..5f068d0c6f 100644 --- a/date_range/models/date_range_type.py +++ b/date_range/models/date_range_type.py @@ -5,7 +5,7 @@ from dateutil.relativedelta import relativedelta from dateutil.rrule import DAILY, MONTHLY, WEEKLY, YEARLY -from odoo import _, api, fields, models +from odoo import api, fields, models from odoo.exceptions import ValidationError @@ -89,7 +89,7 @@ def _check_company_id(self): ) ): raise ValidationError( - _( + self.env._( "You cannot change the company, as this " "Date Range Type is assigned to Date Range '%s'." ) @@ -145,6 +145,6 @@ def autogenerate_ranges(self): wizard.action_apply(batch=True) except Exception as e: logger.warning( - "Error autogenerating ranges for date range type " + f"Error autogenerating ranges for date range type " f"{dr_type.name}: {e}" ) diff --git a/date_range/readme/CONFIGURE.md b/date_range/readme/CONFIGURE.md index e4e1633d93..2ffd2b4777 100644 --- a/date_range/readme/CONFIGURE.md +++ b/date_range/readme/CONFIGURE.md @@ -4,7 +4,7 @@ functionality to developers. To configure a model to use the Many2one style search field, make the model inherit from \`date.range.search.mixin\`: -``` +``` class AccountMove(models.Model): _name = "account.move" _inherit = ["account.move", "date.range.search.mixin"] @@ -12,12 +12,12 @@ class AccountMove(models.Model): This will make a Period field show up in the search view: -> ![search_view](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_many2one_search_field.png) +> ![search_view](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_many2one_search_field.png) By default, the mixin works on the date field. If you want the mixin to work on a field with a different name, you can set a property on your model: -``` +``` _date_range_search_field = "invoice_date" ``` diff --git a/date_range/readme/CONTRIBUTORS.md b/date_range/readme/CONTRIBUTORS.md index 975830b80e..96629c1413 100644 --- a/date_range/readme/CONTRIBUTORS.md +++ b/date_range/readme/CONTRIBUTORS.md @@ -5,3 +5,4 @@ - Stefan Rijnhart \<\> - David Ramia \<<@ramiadavid>\> - Son Ho \<\> +- Bert Van Groenendael \<\> diff --git a/date_range/readme/USAGE.md b/date_range/readme/USAGE.md index 642ab03917..5bf1230e86 100644 --- a/date_range/readme/USAGE.md +++ b/date_range/readme/USAGE.md @@ -3,43 +3,43 @@ To configure this module, you need to: - Go to Settings \> Technical \> Date ranges \> Date Range Types where you can create types of date ranges. - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_type_create.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_type_create.png) - Go to Settings \> Technical \> Date ranges \> Date Ranges where you can create date ranges. - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_create.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_create.png) It's also possible to launch a wizard from the 'Generate Date Ranges' menu. - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_wizard.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_wizard.png) The wizard is useful to generate recurring periods. Set an end date or enter the number of ranges to create. - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_wizard_result.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_wizard_result.png) - Your date ranges are now available in the search filter for any date or datetime fields Date range types are proposed as a filter operator - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_type_as_filter.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_type_as_filter.png) Once a type is selected, date ranges of this type are porposed as a filter value - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_as_filter.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_as_filter.png) And the dates specified into the date range are used to filter your result. - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_as_filter_result.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_as_filter_result.png) - You can configure date range types with default values for the generation wizard on the Generation tab. In the same tab you can also configure date range types for auto-generation. New ranges for types configured for this are generated by a scheduled task that runs daily. - ![](https://raw.githubusercontent.com/OCA/server-tools/17.0/date_range/static/description/date_range_type_autogeneration.png) + ![](https://raw.githubusercontent.com/OCA/server-ux/18.0/date_range/static/description/date_range_type_autogeneration.png) diff --git a/date_range/static/description/index.html b/date_range/static/description/index.html index 1b48e65b2e..205e5ec1ca 100644 --- a/date_range/static/description/index.html +++ b/date_range/static/description/index.html @@ -407,7 +407,7 @@

Configuration

This will make a Period field show up in the search view:

-search_view
+search_view

By default, the mixin works on the date field. If you want the mixin to work on a field with a different name, you can set a property on your model:

@@ -421,35 +421,35 @@

Usage

  • Go to Settings > Technical > Date ranges > Date Range Types where you can create types of date ranges.

    -

    image1

    +

    image1

  • Go to Settings > Technical > Date ranges > Date Ranges where you can create date ranges.

    -

    image2

    +

    image2

    It’s also possible to launch a wizard from the ‘Generate Date Ranges’ menu.

    -

    image3

    +

    image3

    The wizard is useful to generate recurring periods. Set an end date or enter the number of ranges to create.

    -

    image4

    +

    image4

  • Your date ranges are now available in the search filter for any date or datetime fields

    Date range types are proposed as a filter operator

    -

    image5

    +

    image5

    Once a type is selected, date ranges of this type are porposed as a filter value

    -

    image6

    +

    image6

    And the dates specified into the date range are used to filter your result.

    -

    image7

    +

    image7

  • You can configure date range types with default values for the generation wizard on the Generation tab. In the same tab you can also configure date range types for auto-generation. New ranges for types configured for this are generated by a scheduled task that runs daily.

    -

    image8

    +

    image8

@@ -479,6 +479,7 @@

Contributors

  • Stefan Rijnhart <stefan@opener.amsterdam>
  • David Ramia <<@ramiadavid>>
  • Son Ho <sonhd@trobz.com>
  • +
  • Bert Van Groenendael <bert.vangroenendael@dynapps.eu>
  • diff --git a/date_range/static/src/js/condition_tree.esm.js b/date_range/static/src/js/condition_tree.esm.js index b43376c0b0..f20144911b 100644 --- a/date_range/static/src/js/condition_tree.esm.js +++ b/date_range/static/src/js/condition_tree.esm.js @@ -1,4 +1,4 @@ -/** @odoo-module **/ +/* global document */ import { condition, connector, diff --git a/date_range/static/src/js/domain_selector.esm.js b/date_range/static/src/js/domain_selector.esm.js index 42820bb594..31f7fa5a61 100644 --- a/date_range/static/src/js/domain_selector.esm.js +++ b/date_range/static/src/js/domain_selector.esm.js @@ -1,9 +1,9 @@ -/** @odoo-module **/ import {domainFromTreeDateRange, treeFromDomainDateRange} from "./condition_tree.esm"; import {onWillStart, useChildSubEnv} from "@odoo/owl"; import {Domain} from "@web/core/domain"; import {DomainSelector} from "@web/core/domain_selector/domain_selector"; import {patch} from "@web/core/utils/patch"; +import {treeFromDomain} from "@web/core/tree_editor/condition_tree"; import {useService} from "@web/core/utils/hooks"; const ARCHIVED_DOMAIN = `[("active", "in", [True, False])]`; @@ -42,14 +42,17 @@ patch(DomainSelector.prototype, { this.includeArchived = false; return; } + + const tree = treeFromDomain(domain); + const getFieldDef = await this.makeGetFieldDef(p.resModel, tree, ["active"]); + this.tree = treeFromDomainDateRange(domain, { - getFieldDef: this.getFieldDef.bind(this), + getFieldDef: getFieldDef, distributeNot: !p.isDebugMode, }); }, - getOperatorEditorInfo(node) { - const info = super.getOperatorEditorInfo(node); - const fieldDef = this.getFieldDef(node.path); + getOperatorEditorInfo(fieldDef) { + const info = super.getOperatorEditorInfo(fieldDef); const dateRanges = this.dateRanges; const dateRangeTypes = this.dateRangeTypes.filter((dt) => dt.date_ranges_exist); patch(info, { @@ -91,14 +94,6 @@ patch(DomainSelector.prototype, { return props; }, - isSupported([operator]) { - if (node.operator.includes("daterange")) { - return ( - typeof operator === "string" && operator.includes("daterange") - ); - } - return super.isSupported.apply(this, arguments); - }, }); return info; }, diff --git a/date_range/static/src/js/tree_editor.esm.js b/date_range/static/src/js/tree_editor.esm.js index 67d83f7055..4cd7cac32c 100644 --- a/date_range/static/src/js/tree_editor.esm.js +++ b/date_range/static/src/js/tree_editor.esm.js @@ -1,4 +1,3 @@ -/** @odoo-module **/ import { deserializeDate, deserializeDateTime, @@ -46,59 +45,71 @@ patch(TreeEditor.prototype, { ) { info.component = Select; } - // Prevent issues when the domain is not initialized, for example in - // Odoo Studio editing - if (!this.env.domain) { - return info; - } - let dateRanges = this.env.domain.dateRanges; - if (this.update_operator && this.update_operator.split("daterange_")[1]) { - dateRanges = this.env.domain.dateRanges.filter( - (range) => - range.type_id[0] === - Number(this.update_operator.split("daterange_")[1]) - ); - } - patch(info, { - extractProps({value, update}) { - const props = super.extractProps.apply(this, arguments); - if ( - fieldDef && - (fieldDef.type === "date" || fieldDef.type === "datetime") && - node.operator.includes("daterange") - ) { - let selected = dateRanges.find( - (range) => - range.date_start === - fromDateTime(value[1], fieldDef.type) && - range.date_end === fromDateTime(value[0], fieldDef.type) - ); - if (!selected) { - selected = dateRanges[0]; - update([ - toDateTime(selected.date_end, fieldDef.type), - toDateTime(selected.date_start, fieldDef.type, true), - ]); - } - - return { - options: dateRanges.map((dt) => [dt.id, dt.name]), - update: (v) => { - const range = dateRanges.find((r) => r.id === v); + if (typeof this.env.domain !== "undefined") { + let dateRanges = this.env.domain.dateRanges; + if (this.update_operator && this.update_operator.split("daterange_")[1]) { + dateRanges = this.env.domain.dateRanges.filter( + (range) => + range.type_id[0] === + Number(this.update_operator.split("daterange_")[1]) + ); + } + patch(info, { + extractProps({value, update}) { + const props = super.extractProps.apply(this, arguments); + if ( + fieldDef && + (fieldDef.type === "date" || fieldDef.type === "datetime") && + node.operator.includes("daterange") + ) { + let selected = dateRanges.find( + (range) => + range.date_start === + fromDateTime(value[1], fieldDef.type) && + range.date_end === fromDateTime(value[0], fieldDef.type) + ); + if (!selected) { + selected = dateRanges[0]; update([ - toDateTime(range.date_end, fieldDef.type), - toDateTime(range.date_start, fieldDef.type, true), + toDateTime(selected.date_end, fieldDef.type), + toDateTime(selected.date_start, fieldDef.type, true), ]); - }, - value: selected.id, - }; - } + } - return props; - }, - isSupported(value) { + return { + options: dateRanges.map((dt) => [dt.id, dt.name]), + update: (v) => { + const range = dateRanges.find((r) => r.id === v); + update([ + toDateTime(range.date_end, fieldDef.type), + toDateTime(range.date_start, fieldDef.type, true), + ]); + }, + value: selected.id, + }; + } + + return props; + }, + isSupported(value) { + if (node.operator.includes("daterange")) { + return Array.isArray(value) && value.length === 2; + } + return super.isSupported.apply(this, arguments); + }, + }); + } + return info; + }, + + getOperatorEditorInfo(node) { + const info = super.getOperatorEditorInfo(node); + patch(info, { + isSupported([operator]) { if (node.operator.includes("daterange")) { - return Array.isArray(value) && value.length === 2; + return ( + typeof operator === "string" && operator.includes("daterange") + ); } return super.isSupported.apply(this, arguments); }, @@ -110,23 +121,20 @@ patch(TreeEditor.prototype, { super.updateLeafOperator.apply(this, arguments); this.update_operator = operator; const fieldDef = this.getFieldDef(node.path); - // Prevent issues when the domain is not initialized, for example in - // Odoo Studio editing - if (!this.env.domain) { - return; - } - let dateRanges = this.env.domain.dateRanges.filter( - (range) => range.type_id[0] === Number(operator.split("daterange_")[1]) - ); - if (!dateRanges.length) { - dateRanges = this.env.domain.dateRanges; - } - if (operator.includes("daterange") && dateRanges) { - node.value = [ - toDateTime(dateRanges[0].date_end, fieldDef.type), - toDateTime(dateRanges[0].date_start, fieldDef.type, true), - ]; - this.notifyChanges(); + if (typeof this.env.domain !== "undefined") { + let dateRanges = this.env.domain.dateRanges.filter( + (range) => range.type_id[0] === Number(operator.split("daterange_")[1]) + ); + if (!dateRanges.length) { + dateRanges = this.env.domain.dateRanges; + } + if (operator.includes("daterange") && dateRanges) { + node.value = [ + toDateTime(dateRanges[0].date_end, fieldDef.type), + toDateTime(dateRanges[0].date_start, fieldDef.type, true), + ]; + this.notifyChanges(); + } } }, }); diff --git a/date_range/tests/test_date_range_generator.py b/date_range/tests/test_date_range_generator.py index 227d794835..b1b7b52b3c 100644 --- a/date_range/tests/test_date_range_generator.py +++ b/date_range/tests/test_date_range_generator.py @@ -6,7 +6,8 @@ from dateutil.rrule import MONTHLY from odoo.exceptions import ValidationError -from odoo.tests.common import Form, TransactionCase +from odoo.tests import Form +from odoo.tests.common import TransactionCase class DateRangeGeneratorTest(TransactionCase): diff --git a/date_range/tests/test_date_range_search_mixin.py b/date_range/tests/test_date_range_search_mixin.py index d03521ab19..185dcf9779 100644 --- a/date_range/tests/test_date_range_search_mixin.py +++ b/date_range/tests/test_date_range_search_mixin.py @@ -7,7 +7,7 @@ from odoo.tests.common import TransactionCase -class TestDateRangeearchMixin(TransactionCase): +class TestDateRangeSearchMixin(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() @@ -149,7 +149,6 @@ def test_03_read(self): def test_04_load_views(self): """Technical field label is replaced in `load_views`""" - field = self.model.get_views([(None, "form")])["models"][self.model._name][ - "date_range_search_id" - ] + view = self.model.get_views([(None, "form")]) + field = view["models"][self.model._name]["fields"]["date_range_search_id"] self.assertNotIn("technical", field["string"]) diff --git a/date_range/views/date_range_view.xml b/date_range/views/date_range_view.xml index dac3857b92..a2c8c7cd5b 100644 --- a/date_range/views/date_range_view.xml +++ b/date_range/views/date_range_view.xml @@ -1,10 +1,10 @@ - - date.range.tree + + date.range.list date.range - + @@ -17,7 +17,7 @@ options="{'no_create': True}" /> - + @@ -83,11 +83,11 @@ - - date.range.type.tree + + date.range.type.list date.range.type - + - + @@ -127,19 +127,16 @@ >