From 5e8b7659be2aa2dbacceb2b44b5b132952137315 Mon Sep 17 00:00:00 2001 From: william Date: Fri, 8 May 2020 12:51:16 +0000 Subject: [PATCH] [IMP] base: add tooling for generating datetime Add a new function to generate random datetime within a range around a base date. This allows the base date to change in the future or to be set to today's date easily. --- addons/lunch/populate/lunch.py | 24 +++++----------------- addons/product/populate/product.py | 5 +---- odoo/tools/populate.py | 33 ++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/addons/lunch/populate/lunch.py b/addons/lunch/populate/lunch.py index dedbf6eacae..5e490b82ed0 100644 --- a/addons/lunch/populate/lunch.py +++ b/addons/lunch/populate/lunch.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. import logging -from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta from itertools import groupby from odoo import models @@ -33,10 +33,6 @@ class LunchProduct(models.Model): _populate_dependencies = ['lunch.product.category', 'lunch.supplier'] def _populate_factories(self): - - def get_price(random=None, **kwargs): - return random.randint(1, 500) / 10 - category_ids = self.env.registry.populated_models['lunch.product.category'] category_records = self.env['lunch.product.category'].browse(category_ids) category_by_company = {k: list(v) for k, v in groupby(category_records, key=lambda rec: rec['company_id'].id)} @@ -51,7 +47,7 @@ class LunchProduct(models.Model): return [ ('active', populate.iterate([True, False], [0.9, 0.1])), ('name', populate.constant('lunch_product_{counter}')), - ('price', populate.compute(get_price)), + ('price', populate.randfloat(0.1, 50)), ('supplier_id', populate.randomize(supplier_ids)), ('category_id', populate.compute(get_category)), ] @@ -86,9 +82,6 @@ class LunchSupplier(models.Model): partner_ids = self.env.registry.populated_models['res.partner'] user_ids = self.env.registry.populated_models['res.users'] - def get_email_time(random=None, **kwargs): - return random.randint(0, 120) / 10 - def get_location_ids(random=None, **kwargs): nb_locations = random.randint(0, len(location_ids)) return [(6, 0, random.choices(location_ids, k=nb_locations))] @@ -111,7 +104,7 @@ class LunchSupplier(models.Model): ('partner_id', populate.randomize(partner_ids)), ('responsible_id', populate.randomize(user_ids)), ('moment', populate.iterate(['am', 'pm'])), - ('automatic_email_time', populate.compute(get_email_time)), + ('automatic_email_time', populate.randfloat(0, 12)), ] @@ -147,13 +140,6 @@ class LunchAlert(models.Model): location_ids = self.env.registry.populated_models['lunch.location'] - def get_notification_time(random=None, **kwargs): - return random.randint(0, 120) / 10 - - def get_until_date(random=None, **kwargs): - delta = random.randint(-731, 731) - return datetime(2020, 1, 1) + timedelta(days=delta) - def get_location_ids(random=None, **kwargs): nb_max = len(location_ids) start = random.randint(0, nb_max) @@ -173,8 +159,8 @@ class LunchAlert(models.Model): ('recurrency_sunday', populate.iterate([False, True], [0.9, 0.1])), ('name', populate.constant('alert_{counter}')), ('message', populate.constant('alert message {counter}')), - ('notification_time', populate.compute(get_notification_time)), + ('notification_time', populate.randfloat(0, 12)), ('notification_moment', populate.iterate(['am', 'pm'])), - ('until', populate.compute(get_until_date)), + ('until', populate.randdatetime(relative_before=relativedelta(years=-2), relative_after=relativedelta(years=2))), ('location_ids', populate.compute(get_location_ids)) ] diff --git a/addons/product/populate/product.py b/addons/product/populate/product.py index 85397e819fb..e1a4e1dfcec 100644 --- a/addons/product/populate/product.py +++ b/addons/product/populate/product.py @@ -14,12 +14,9 @@ class ProductCategory(models.Model): _populate_sizes = {"small": 50, "medium": 500, "large": 30000} def _populate_factories(self): - def get_name(values=None, counter=0, complete=False, **kwargs): - return "%s_%s_%s" % ("product_category", int(complete), counter) - # quid of parent_id ??? - return [("name", populate.compute(get_name))] + return [("name", populate.constant('product_category_{counter}'))] class ProductProduct(models.Model): diff --git a/odoo/tools/populate.py b/odoo/tools/populate.py index 5a0f3e2027d..9cd897fefe7 100644 --- a/odoo/tools/populate.py +++ b/odoo/tools/populate.py @@ -1,5 +1,6 @@ import random -from datetime import datetime, timedelta +from datetime import datetime +from dateutil.relativedelta import relativedelta from odoo.tools import pycompat @@ -138,7 +139,7 @@ def compute(function, seed=None): def randint(a, b, seed=None): """ Return a factory for an iterator of values dicts that sets the field - to the random integer between a and b included in each input dict. + to a random integer between a and b included in each input dict. :param int a: minimal random value :param int b: maximal random value @@ -148,3 +149,31 @@ def randint(a, b, seed=None): def get_rand_int(random=None, **kwargs): return random.randint(a, b) return compute(get_rand_int, seed=seed) + +def randfloat(a, b, seed=None): + """ Return a factory for an iterator of values dicts that sets the field + to a random float between a and b included in each input dict. + """ + def get_rand_float(random=None, **kwargs): + return random.uniform(a, b) + return compute(get_rand_float, seed=seed) + +def randdatetime(*, base_date=None, relative_before=None, relative_after=None, seed=None): + """ Return a factory for an iterator of values dicts that sets the field + to a random datetime between relative_before and relative_after, relatively to + base_date + + :param base_date (datetime): override the default base date if needed. + :param relative_after (relativedelta, timedelta): range up which we can go after the + base date. If not set, defaults to 0, i.e. only in the past of reference. + :param relative_before (relativedelta, timedelta): range up which we can go before the + base date. If not set, defaults to 0, i.e. only in the future of reference. + :return (generator): iterator for random dates inside the defined range + """ + base_date = base_date or datetime(2020, 1, 1) + seconds_before = relative_before and ((base_date + relative_before) - base_date).total_seconds() or 0 + seconds_after = relative_after and ((base_date + relative_after) - base_date).total_seconds() or 0 + + def get_rand_datetime(random=None, **kwargs): + return base_date + relativedelta(seconds=random.randint(seconds_before, seconds_after)) + return compute(get_rand_datetime, seed=seed)