Browse Source

[12.0][MIG] date_range

pull/25/head
Andrea 6 years ago
parent
commit
a40a8ddfa5
  1. 10
      date_range/README.rst
  2. 1
      date_range/__init__.py
  3. 9
      date_range/__manifest__.py
  4. 9
      date_range/migrations/11.0.2.0.0/noupdate_changes.xml
  5. 3
      date_range/migrations/11.0.2.0.0/openupgrade_analysis.txt
  6. 4
      date_range/migrations/11.0.2.0.0/openupgrade_analysis_work.txt
  7. 11
      date_range/migrations/11.0.2.0.0/post-migration.py
  8. 1
      date_range/models/__init__.py
  9. 14
      date_range/models/date_range.py
  10. 14
      date_range/models/date_range_type.py
  11. 1
      date_range/readme/CONTRIBUTORS.rst
  12. 2
      date_range/readme/INSTALL.rst
  13. 210
      date_range/static/src/js/date_range.js
  14. 1
      date_range/tests/__init__.py
  15. 10
      date_range/tests/test_date_range.py
  16. 13
      date_range/tests/test_date_range_generator.py
  17. 7
      date_range/tests/test_date_range_type.py
  18. 1
      date_range/wizard/__init__.py
  19. 22
      date_range/wizard/date_range_generator.py

10
date_range/README.rst

@ -14,13 +14,13 @@ Date Range
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--ux-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--ux-lightgray.png?logo=github
:target: https://github.com/OCA/server-ux/tree/11.0/date_range
:target: https://github.com/OCA/server-ux/tree/12.0/date_range
:alt: OCA/server-ux :alt: OCA/server-ux
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-ux-11-0/server-ux-11-0-date_range :target: https://translation.odoo-community.org/projects/server-ux-11-0/server-ux-11-0-date_range
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/250/11.0
:target: https://runbot.odoo-community.org/runbot/250/12.0
:alt: Try me on Runbot :alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -97,7 +97,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-ux/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-ux/issues>`_.
In case of trouble, please check there if your issue has already been reported. 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 If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-ux/issues/new?body=module:%20date_range%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/server-ux/issues/new?body=module:%20date_range%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. Do not contact contributors directly about support or help with technical issues.
@ -133,10 +133,10 @@ promote its widespread use.
:target: https://github.com/lmignon :target: https://github.com/lmignon
:alt: lmignon :alt: lmignon
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
Current `maintainer <https://odoo-community.org/page/maintainer-role>`_:
|maintainer-lmignon| |maintainer-lmignon|
This module is part of the `OCA/server-ux <https://github.com/OCA/server-ux/tree/11.0/date_range>`_ project on GitHub.
This module is part of the `OCA/server-ux <https://github.com/OCA/server-ux/tree/12.0/date_range>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

1
date_range/__init__.py

@ -1,4 +1,3 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models from . import models

9
date_range/__manifest__.py

@ -1,14 +1,13 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
"name": "Date Range", "name": "Date Range",
"summary": "Manage all kind of date range", "summary": "Manage all kind of date range",
"version": "11.0.2.0.0",
"version": "12.0.1.0.0",
"category": "Uncategorized", "category": "Uncategorized",
"website": "https://github.com/oca/server-ux", "website": "https://github.com/oca/server-ux",
"author": "ACSONE SA/NV, Odoo Community Association (OCA)", "author": "ACSONE SA/NV, Odoo Community Association (OCA)",
"license": "AGPL-3", "license": "AGPL-3",
"application": False,
"installable": True, "installable": True,
"depends": [ "depends": [
"web", "web",
@ -23,6 +22,6 @@
"qweb": [ "qweb": [
"static/src/xml/date_range.xml", "static/src/xml/date_range.xml",
], ],
'development_status': 'Mature',
'maintainers': ['lmignon'],
"development_status": "Mature",
"maintainers": ["lmignon"],
} }

9
date_range/migrations/11.0.2.0.0/noupdate_changes.xml

@ -1,9 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<record id="date_range_type_comp_rule" model="ir.rule">
<field name="domain_force"> ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field>
</record>
<record id="date_range_comp_rule" model="ir.rule">
<field name="domain_force"> ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field>
</record>
</odoo>

3
date_range/migrations/11.0.2.0.0/openupgrade_analysis.txt

@ -1,3 +0,0 @@
---Fields in module 'date_range'---
---XML records in module 'date_range'---
NEW ir.rule: date_range.date_range_generator_comp_rule (noupdate)

4
date_range/migrations/11.0.2.0.0/openupgrade_analysis_work.txt

@ -1,4 +0,0 @@
---Fields in module 'date_range'---
---XML records in module 'date_range'---
NEW ir.rule: date_range.date_range_generator_comp_rule (noupdate)
# NOTHING TO DO

11
date_range/migrations/11.0.2.0.0/post-migration.py

@ -1,11 +0,0 @@
# Copyright 2017 Eficent <http://www.eficent.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade
@openupgrade.migrate()
def migrate(env, version):
openupgrade.load_data(
env.cr, 'date_range', 'migrations/11.0.2.0.0/noupdate_changes.xml',
)

1
date_range/models/__init__.py

@ -1,4 +1,3 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import date_range_type from . import date_range_type

14
date_range/models/date_range.py

@ -1,13 +1,13 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools.translate import _
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
class DateRange(models.Model): class DateRange(models.Model):
_name = "date.range" _name = "date.range"
_description = "Date Range"
_order = "type_name,date_start" _order = "type_name,date_start"
@api.model @api.model
@ -22,7 +22,7 @@ class DateRange(models.Model):
ondelete='restrict', domain="['|', ('company_id', '=', company_id), " ondelete='restrict', domain="['|', ('company_id', '=', company_id), "
"('company_id', '=', False)]") "('company_id', '=', False)]")
type_name = fields.Char( type_name = fields.Char(
string='Type', related='type_id.name', readonly=True, store=True)
related='type_id.name', readonly=True, store=True, string="Type Name")
company_id = fields.Many2one( company_id = fields.Many2one(
comodel_name='res.company', string='Company', index=1, comodel_name='res.company', string='Company', index=1,
default=_default_company) default=_default_company)
@ -34,7 +34,7 @@ class DateRange(models.Model):
('date_range_uniq', 'unique (name,type_id, company_id)', ('date_range_uniq', 'unique (name,type_id, company_id)',
'A date range must be unique per company !')] 'A date range must be unique per company !')]
@api.onchange('company_id')
@api.onchange('company_id', 'type_id')
def _onchange_company_id(self): def _onchange_company_id(self):
if self.company_id and self.type_id.company_id and \ if self.company_id and self.type_id.company_id and \
self.type_id.company_id != self.company_id: self.type_id.company_id != self.company_id:
@ -54,9 +54,7 @@ class DateRange(models.Model):
@api.constrains('type_id', 'date_start', 'date_end', 'company_id') @api.constrains('type_id', 'date_start', 'date_end', 'company_id')
def _validate_range(self): def _validate_range(self):
for this in self: for this in self:
start = fields.Date.from_string(this.date_start)
end = fields.Date.from_string(this.date_end)
if start > end:
if this.date_start > this.date_end:
raise ValidationError( raise ValidationError(
_("%s is not a valid range (%s > %s)") % ( _("%s is not a valid range (%s > %s)") % (
this.name, this.date_start, this.date_end)) this.name, this.date_start, this.date_end))

14
date_range/models/date_range_type.py

@ -1,13 +1,13 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools.translate import _
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
class DateRangeType(models.Model): class DateRangeType(models.Model):
_name = "date.range.type" _name = "date.range.type"
_description = "Date Range Type"
@api.model @api.model
def _default_company(self): def _default_company(self):
@ -18,8 +18,8 @@ class DateRangeType(models.Model):
help="If sets date range of same type must not overlap.", help="If sets date range of same type must not overlap.",
default=False) default=False)
active = fields.Boolean( active = fields.Boolean(
help="The active field allows you to hide the date range without "
"removing it.", default=True)
help="The active field allows you to hide the date range type "
"without removing it.", default=True)
company_id = fields.Many2one( company_id = fields.Many2one(
comodel_name='res.company', string='Company', index=1, comodel_name='res.company', string='Company', index=1,
default=_default_company) default=_default_company)
@ -35,10 +35,10 @@ class DateRangeType(models.Model):
for rec in self.sudo(): for rec in self.sudo():
if not rec.company_id: if not rec.company_id:
continue continue
if bool(self.date_range_ids.filtered(
if bool(rec.date_range_ids.filtered(
lambda r: r.company_id and lambda r: r.company_id and
r.company_id != rec.company_id)): r.company_id != rec.company_id)):
raise ValidationError( raise ValidationError(
_('You cannot change the company, as this ' _('You cannot change the company, as this '
'Date Range Type is assigned to Date Range ' 'Date Range Type is assigned to Date Range '
'(%s).') % (self.date_range_ids.name_get()[0][1]))
'(%s).') % (rec.date_range_ids.name_get()[0][1]))

1
date_range/readme/CONTRIBUTORS.rst

@ -1,3 +1,4 @@
* Laurent Mignon <laurent.mignon@acsone.eu> * Laurent Mignon <laurent.mignon@acsone.eu>
* Alexis de Lattre <alexis.delattre@akretion.com> * Alexis de Lattre <alexis.delattre@akretion.com>
* Miquel Raïch <miquel.raich@eficent.com> * Miquel Raïch <miquel.raich@eficent.com>
* Andrea Stirpe <a.stirpe@onestein.nl>

2
date_range/readme/INSTALL.rst

@ -1,3 +1 @@
The addon use the daterange method from postgres. This method is supported as of postgresql 9.2 The addon use the daterange method from postgres. This method is supported as of postgresql 9.2

210
date_range/static/src/js/date_range.js

@ -1,125 +1,125 @@
/* © 2016 ACSONE SA/NV (<http://acsone.eu>)
/* Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
odoo.define('date_range.search_filters', function (require) { odoo.define('date_range.search_filters', function (require) {
"use strict";
var core = require('web.core');
var data = require('web.data');
var filters = require('web.search_filters');
var rpc = require('web.rpc');
var framework = require('web.framework');
var _t = core._t;
filters.ExtendedSearchProposition.include({
select_field: function(field) {
this._super.apply(this, arguments);
this.is_date_range_selected = false;
this.is_date = field.type === 'date' || field.type === 'datetime';
this.$value = this.$el.find('.searchview_extended_prop_value, .o_searchview_extended_prop_value');
if (this.is_date){
var ds = new data.DataSetSearch(this, 'date.range.type', this.context, [[1, '=', 1]]);
ds.read_slice(['name'], {}).done(this.proxy('add_date_range_types_operator'));
}
},
add_date_range_types_operator: function(date_range_types){
var self = this;
_.each(date_range_types, function(drt) {
$('<option>', {value: 'drt_' + drt.id})
.text(_('in ') + drt.name)
.appendTo(self.$el.find('.searchview_extended_prop_op, .o_searchview_extended_prop_op'));
});
},
operator_changed: function (e) {
var val = $(e.target).val();
this.is_date_range_selected = val.startsWith('drt_');
if (this.is_date_range_selected){
var type_id = val.replace('drt_', '');
this.date_range_type_operator_selected(type_id);
return;
}
this._super.apply(this, arguments);
},
date_range_type_operator_selected: function(type_id){
this.$value.empty().show();
var ds = new data.DataSetSearch(this, 'date.range', this.context, [['type_id', '=', parseInt(type_id)]]);
ds.read_slice(['name','date_start', 'date_end'], {}).done(this.proxy('on_range_type_selected'));
},
on_range_type_selected: function(date_range_values){
this.value = new filters.ExtendedSearchProposition.DateRange(this, this.value.field, date_range_values);
this.value.appendTo(this.$value);
if (!this.$el.hasClass('o_filter_condition')){
this.$value.find('.date-range-select').addClass('form-control');
}
this.value.on_range_selected();
},
get_filter: function () {
var res = this._super.apply(this, arguments);
if (this.is_date_range_selected){
// in case of date.range, the domain is provided by the server and we don't
// want to put nest the returned value into an array.
res.attrs.domain = this.value.domain;
"use strict";
var core = require('web.core');
var data = require('web.data');
var filters = require('web.search_filters');
var rpc = require('web.rpc');
var framework = require('web.framework');
var _t = core._t;
filters.ExtendedSearchProposition.include({
select_field: function (field) {
this._super.apply(this, arguments);
this.is_date_range_selected = false;
this.is_date = field.type === 'date' || field.type === 'datetime';
this.$value = this.$el.find('.searchview_extended_prop_value, .o_searchview_extended_prop_value');
if (this.is_date) {
var ds = new data.DataSetSearch(this, 'date.range.type', this.context, [[1, '=', 1]]);
ds.read_slice(['name'], {}).done(this.proxy('add_date_range_types_operator'));
}
},
add_date_range_types_operator: function (date_range_types) {
var self = this;
_.each(date_range_types, function (drt) {
$('<option>', {value: 'drt_' + drt.id})
.text(_('in ') + drt.name)
.appendTo(self.$el.find('.searchview_extended_prop_op, .o_searchview_extended_prop_op'));
});
},
operator_changed: function (e) {
var val = $(e.target).val();
this.is_date_range_selected = val.startsWith('drt_');
if (this.is_date_range_selected) {
var type_id = val.replace('drt_', '');
this.date_range_type_operator_selected(type_id);
return;
}
this._super.apply(this, arguments);
},
date_range_type_operator_selected: function (type_id) {
this.$value.empty().show();
var ds = new data.DataSetSearch(this, 'date.range', this.context, [['type_id', '=', parseInt(type_id, 10)]]);
ds.read_slice(['name','date_start', 'date_end'], {}).done(this.proxy('on_range_type_selected'));
},
on_range_type_selected: function (date_range_values) {
this.value = new filters.ExtendedSearchProposition.DateRange(this, this.value.field, date_range_values);
this.value.appendTo(this.$value);
if (!this.$el.hasClass('o_filter_condition')) {
this.$value.find('.date-range-select').addClass('form-control');
}
this.value.on_range_selected();
},
get_filter: function () {
var res = this._super.apply(this, arguments);
if (this.is_date_range_selected) {
// In case of date.range, the domain is provided by the server and we don't
// Want to put nest the returned value into an array.
res.attrs.domain = this.value.domain;
}
return res;
} }
return res;
},
});
});
/**
/**
Since Odoo 11, The Field class used as base class for all specialized filter Since Odoo 11, The Field class used as base class for all specialized filter
widgets is no more exposed by 'web.search_filters'. To create our own class we widgets is no more exposed by 'web.search_filters'. To create our own class we
extend the more simple class available into the search_filters_registry as base extend the more simple class available into the search_filters_registry as base
class class
*/ */
filters.ExtendedSearchProposition.DateRange = core.search_filters_registry.get('id').extend({
template: 'SearchView.extended_search.dateRange.selection',
events: {
'change': 'on_range_selected',
},
init: function (parent, field, date_range_values) {
this._super(parent, field);
this.date_range_values = date_range_values;
},
toString: function () {
var select = this.$el[0];
var option = select.options[select.selectedIndex];
return option.label || option.text;
},
get_value: function() {
return parseInt(this.$el.val());
},
on_range_selected: function(e){
var self = this;
self.domain = '';
framework.blockUI();
return rpc.query({
filters.ExtendedSearchProposition.DateRange = core.search_filters_registry.get('id').extend({
template: 'SearchView.extended_search.dateRange.selection',
events: {
'change': 'on_range_selected'
},
init: function (parent, field, date_range_values) {
this._super(parent, field);
this.date_range_values = date_range_values;
},
toString: function () {
var select = this.$el[0];
var option = select.options[select.selectedIndex];
return option.label || option.text;
},
get_value: function () {
return parseInt(this.$el.val(), 10);
},
on_range_selected: function (e) {
var self = this;
self.domain = '';
framework.blockUI();
return rpc.query({
args: [this.get_value()], args: [this.get_value()],
kwargs: { kwargs: {
field_name: this.field.name field_name: this.field.name
}, },
model: 'date.range', model: 'date.range',
method: 'get_domain',
method: 'get_domain'
}) })
.then(function (domain) {
framework.unblockUI();
self.domain = domain;
});
},
get_domain: function (field, operator) {
return this.domain;
},
.then(function (domain) {
framework.unblockUI();
self.domain = domain;
});
},
get_domain: function (field, operator) {
return this.domain;
}
});
});
}); });

1
date_range/tests/__init__.py

@ -1,4 +1,3 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_date_range_type from . import test_date_range_type

10
date_range/tests/test_date_range.py

@ -1,8 +1,10 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo.tests.common import TransactionCase
import datetime
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
class DateRangeTest(TransactionCase): class DateRangeTest(TransactionCase):
@ -105,8 +107,8 @@ class DateRangeTest(TransactionCase):
# By default the domain include limits # By default the domain include limits
self.assertEqual( self.assertEqual(
domain, domain,
[('my_field', '>=', '2015-01-01'),
('my_field', '<=', '2015-12-31')])
[('my_field', '>=', datetime.date(2015, 1, 1)),
('my_field', '<=', datetime.date(2015, 12, 31))])
def test_date_range_multicompany_1(self): def test_date_range_multicompany_1(self):
dr = self.date_range.new({ dr = self.date_range.new({

13
date_range/tests/test_date_range_generator.py

@ -1,10 +1,13 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)nses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)nses/agpl).
from odoo.tests.common import TransactionCase
from odoo.exceptions import ValidationError
import datetime
from dateutil.rrule import MONTHLY from dateutil.rrule import MONTHLY
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
class DateRangeGeneratorTest(TransactionCase): class DateRangeGeneratorTest(TransactionCase):
post_install = True post_install = True
@ -43,8 +46,8 @@ class DateRangeGeneratorTest(TransactionCase):
[('type_id', '=', self.type.id)]) [('type_id', '=', self.type.id)])
self.assertEqual(len(ranges), 4) self.assertEqual(len(ranges), 4)
range4 = ranges[3] range4 = ranges[3]
self.assertEqual(range4.date_start, '1943-10-01')
self.assertEqual(range4.date_end, '1943-12-31')
self.assertEqual(range4.date_start, datetime.date(1943, 10, 1))
self.assertEqual(range4.date_end, datetime.date(1943, 12, 31))
self.assertEqual(range4.type_id, self.type) self.assertEqual(range4.type_id, self.type)
def test_generator_multicompany_1(self): def test_generator_multicompany_1(self):

7
date_range/tests/test_date_range_type.py

@ -1,10 +1,11 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger
from psycopg2 import IntegrityError from psycopg2 import IntegrityError
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger
class DateRangeTypeTest(TransactionCase): class DateRangeTypeTest(TransactionCase):

1
date_range/wizard/__init__.py

@ -1,4 +1,3 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import date_range_generator from . import date_range_generator

22
date_range/wizard/date_range_generator.py

@ -1,19 +1,16 @@
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools.translate import _
from odoo.exceptions import ValidationError
from dateutil.rrule import (rrule,
YEARLY,
MONTHLY,
WEEKLY,
DAILY)
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from dateutil.rrule import DAILY, MONTHLY, WEEKLY, YEARLY, rrule
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class DateRangeGenerator(models.TransientModel): class DateRangeGenerator(models.TransientModel):
_name = 'date.range.generator' _name = 'date.range.generator'
_description = 'Date Range Generator'
@api.model @api.model
def _default_company(self): def _default_company(self):
@ -41,17 +38,16 @@ class DateRangeGenerator(models.TransientModel):
def _compute_date_ranges(self): def _compute_date_ranges(self):
self.ensure_one() self.ensure_one()
vals = rrule(freq=self.unit_of_time, interval=self.duration_count, vals = rrule(freq=self.unit_of_time, interval=self.duration_count,
dtstart=fields.Date.from_string(self.date_start),
dtstart=self.date_start,
count=self.count+1) count=self.count+1)
vals = list(vals) vals = list(vals)
date_ranges = [] date_ranges = []
count_digits = len(str(self.count)) count_digits = len(str(self.count))
for idx, dt_start in enumerate(vals[:-1]): for idx, dt_start in enumerate(vals[:-1]):
date_start = fields.Date.to_string(dt_start.date())
date_start = dt_start.date()
# always remove 1 day for the date_end since range limits are # always remove 1 day for the date_end since range limits are
# inclusive # inclusive
dt_end = vals[idx+1].date() - relativedelta(days=1)
date_end = fields.Date.to_string(dt_end)
date_end = vals[idx+1].date() - relativedelta(days=1)
date_ranges.append({ date_ranges.append({
'name': '%s%0*d' % ( 'name': '%s%0*d' % (
self.name_prefix, count_digits, idx + 1), self.name_prefix, count_digits, idx + 1),

Loading…
Cancel
Save