From e3fb76fae006b0736a8673e4e0bf18b35cd0dada Mon Sep 17 00:00:00 2001 From: Trevor Cox Date: Mon, 4 Jul 2022 10:02:27 -0700 Subject: [PATCH] Add datetime_rule_variable/DateTimeType. --- business_rules/fields.py | 1 + business_rules/operators.py | 41 ++++++++++++++++++++++++++++++++++++- business_rules/variables.py | 6 +++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/business_rules/fields.py b/business_rules/fields.py index a1c64240..087e2879 100644 --- a/business_rules/fields.py +++ b/business_rules/fields.py @@ -3,3 +3,4 @@ FIELD_NO_INPUT = 'none' FIELD_SELECT = 'select' FIELD_SELECT_MULTIPLE = 'select_multiple' +FIELD_DATETIME = 'datetime' diff --git a/business_rules/operators.py b/business_rules/operators.py index d43e5b1f..2af60bd9 100644 --- a/business_rules/operators.py +++ b/business_rules/operators.py @@ -1,10 +1,12 @@ import inspect import re +from datetime import datetime from functools import wraps from six import string_types, integer_types from .fields import (FIELD_TEXT, FIELD_NUMERIC, FIELD_NO_INPUT, - FIELD_SELECT, FIELD_SELECT_MULTIPLE) + FIELD_SELECT, FIELD_SELECT_MULTIPLE, + FIELD_DATETIME) from .utils import fn_name_to_pretty_label, float_to_decimal from decimal import Decimal, Inexact, Context @@ -235,3 +237,40 @@ def shares_exactly_one_element_with(self, other_value): @type_operator(FIELD_SELECT_MULTIPLE) def shares_no_elements_with(self, other_value): return not self.shares_at_least_one_element_with(other_value) + + +@export_type +class DateTimeType(BaseType): + # This implementation handles only naive datetimes, as provided by + # HTML5 datetime-local inputs. For another approach, see: + # business_rules in https://github.com/TencentBlueKing/bk-itsm/ + + name = "datetime" + # HTML5 datetime-local text format: + DATETIME_FORMAT = "%Y-%m-%dT%H:%M" + + def _assert_valid_value_and_cast(self, value): + """ + Parse string into datetime.datetime instance. + """ + if isinstance(value, datetime): + return value + + try: + return datetime.strptime(value, self.DATETIME_FORMAT) + except (ValueError, TypeError): + raise AssertionError("{0} is not a valid date/time.".format(value)) + + @type_operator(FIELD_DATETIME, label="Equal To") + def equal_to(self, other_datetime): + return self.value == other_datetime + + @type_operator(FIELD_DATETIME, label="After") + def after_than_or_equal_to(self, other_datetime): + print(f'after_than_or_equal_to {self.value} {other_datetime}') + return self.value >= other_datetime + + @type_operator(FIELD_DATETIME, label="Before") + def before_than_or_equal_to(self, other_datetime): + print(f'before_than_or_equal_to {self.value} {other_datetime}') + return self.value <= other_datetime diff --git a/business_rules/variables.py b/business_rules/variables.py index b7863f60..0b4fe064 100644 --- a/business_rules/variables.py +++ b/business_rules/variables.py @@ -6,7 +6,8 @@ StringType, BooleanType, SelectType, - SelectMultipleType) + SelectMultipleType, + DateTimeType) class BaseVariables(object): """ Classes that hold a collection of variables to use with the rules @@ -59,3 +60,6 @@ def select_rule_variable(label=None, options=None): def select_multiple_rule_variable(label=None, options=None): return rule_variable(SelectMultipleType, label=label, options=options) + +def datetime_rule_variable(label=None): + return _rule_variable_wrapper(DateTimeType, label)