def _update_attribute_value(self, new_value): """Update value from received JSON. If self is a Date-type CAV, convert the received value to YYYY-MM-DD. """ from ggrc.models import CustomAttributeDefinition literal_date = CustomAttributeDefinition.ValidTypes.DATE # pylint: disable=access-member-before-definition # pylint: disable=attribute-defined-outside-init # false positives on the next block; the author doesn't like that block too if self.custom_attribute is None: # self is newly created and is not yet flushed to the db # manually store self.custom_attribute because it is cached as None until # flush & expire self.custom_attribute = (db.session.query(CustomAttributeDefinition) .filter_by(id=self.custom_attribute_id).one()) self_is_date = self.custom_attribute.attribute_type == literal_date if self_is_date and new_value: try: new_value = utils.convert_date_format(new_value, self.DATE_FORMAT_JSON, self.DATE_FORMAT_DB) except ValueError: # invalid format or not a date, don't convert pass self.attribute_value = new_value
def _validate_date(self): """Convert date format.""" if self.attribute_value: # Validate the date format by trying to parse it self.attribute_value = utils.convert_date_format( self.attribute_value, utils.DATE_FORMAT_ISO, utils.DATE_FORMAT_ISO, )
def _validate_date(self): """Convert date format.""" from ggrc.models.custom_attribute_definition import ( CustomAttributeDefinition) if (self.custom_attribute.attribute_type == CustomAttributeDefinition.ValidTypes.DATE): # convert the date formats for dates if self.attribute_value: self.attribute_value = utils.convert_date_format( self.attribute_value, CustomAttributeValue.DATE_FORMAT_JSON, CustomAttributeValue.DATE_FORMAT_DB, )
def _publish_attribute_value(self): """Return value serialized for JSON. If self is a Date-type CAV, convert it to MM/DD/YYYY. """ from ggrc.models import CustomAttributeDefinition result = self.attribute_value literal_date = CustomAttributeDefinition.ValidTypes.DATE self_is_date = self.custom_attribute.attribute_type == literal_date if self_is_date and self.attribute_value: try: result = utils.convert_date_format(self.attribute_value, self.DATE_FORMAT_DB, self.DATE_FORMAT_JSON) except ValueError: # invalid format or not a date, don't convert pass return result
def autocast(o_key, operator_name, value): """Try to guess the type of `value` and parse it from the string. Args: o_key (basestring): the name of the field being compared; the `value` is converted to the type of that field. operator_name: the name of the operator being applied. value: the value being compared. Returns: a list of one or several possible meanings of `value` type compliant with `getattr(object_class, o_key)`. """ def has_date_or_non_date_cad(title, definition_type): """Check if there is a date and a non-date CA named title. Returns: (bool, bool) - flags indicating the presence of date and non-date CA. """ cad_query = db.session.query(CustomAttributeDefinition).filter( CustomAttributeDefinition.title == title, CustomAttributeDefinition.definition_type == definition_type, ) date_cad = bool( cad_query.filter( CustomAttributeDefinition.attribute_type == CustomAttributeDefinition.ValidTypes.DATE, ).count()) non_date_cad = bool( cad_query.filter( CustomAttributeDefinition.attribute_type != CustomAttributeDefinition.ValidTypes.DATE, ).count()) return date_cad, non_date_cad if not isinstance(o_key, basestring): return [value] key, custom_filter = (self.attr_name_map[object_class].get( o_key, (o_key, None))) date_attr = date_cad = non_date_cad = False try: attr_type = getattr(object_class, key).property.columns[0].type except AttributeError: date_cad, non_date_cad = has_date_or_non_date_cad( title=key, definition_type=object_class.__name__, ) if not (date_cad or non_date_cad) and not custom_filter: # no CA with this name and no custom filter for the field raise BadQueryException( u"Model {} has no field or CA {}".format( object_class.__name__, o_key)) else: if isinstance(attr_type, sa.sql.sqltypes.Date): date_attr = True converted_date = None if (date_attr or date_cad) and isinstance(value, basestring): try: converted_date = convert_date_format( value, CustomAttributeValue.DATE_FORMAT_JSON, CustomAttributeValue.DATE_FORMAT_DB, ) except (TypeError, ValueError): # wrong format or not a date if not non_date_cad: # o_key is not a non-date CA raise BadQueryException( u"Field '{}' expects a '{}' date".format( o_key, CustomAttributeValue.DATE_FORMAT_JSON, )) if date_attr or (date_cad and not non_date_cad): # Filter by converted date return [converted_date] elif date_cad and non_date_cad and converted_date is None: # Filter by unconverted string as date conversion was unsuccessful return [value] elif date_cad and non_date_cad: if operator_name in ("<", ">"): # "<" and ">" works incorrectly when searching by CA in both formats return [converted_date] else: # Since we can have two local CADs with same name when one is Date # and another is Text, we should handle the case when the user wants # to search by the Text CA that should not be converted return [converted_date, value] else: # Filter by unconverted string return [value]
def autocast(o_key, operator_name, value): """Try to guess the type of `value` and parse it from the string. Args: o_key (basestring): the name of the field being compared; the `value` is converted to the type of that field. operator_name: the name of the operator being applied. value: the value being compared. Returns: a list of one or several possible meanings of `value` type compliant with `getattr(object_class, o_key)`. """ def has_date_or_non_date_cad(title, definition_type): """Check if there is a date and a non-date CA named title. Returns: (bool, bool) - flags indicating the presence of date and non-date CA. """ cad_query = db.session.query(CustomAttributeDefinition).filter( CustomAttributeDefinition.title == title, CustomAttributeDefinition.definition_type == definition_type, ) date_cad = bool(cad_query.filter( CustomAttributeDefinition. attribute_type == CustomAttributeDefinition.ValidTypes.DATE, ).count()) non_date_cad = bool(cad_query.filter( CustomAttributeDefinition. attribute_type != CustomAttributeDefinition.ValidTypes.DATE, ).count()) return date_cad, non_date_cad if not isinstance(o_key, basestring): return [value] key, custom_filter = (self.attr_name_map[tgt_class].get(o_key, (o_key, None))) date_attr = date_cad = non_date_cad = False try: attr_type = getattr(tgt_class, key).property.columns[0].type except AttributeError: date_cad, non_date_cad = has_date_or_non_date_cad( title=key, definition_type=tgt_class.__name__, ) if not (date_cad or non_date_cad) and not custom_filter: # TODO: this logic fails on CA search for Snapshots pass # no CA with this name and no custom filter for the field # raise BadQueryException(u"Model {} has no field or CA {}" # .format(object_class.__name__, o_key)) else: if isinstance(attr_type, sa.sql.sqltypes.Date): date_attr = True converted_date = None if (date_attr or date_cad) and isinstance(value, basestring): try: converted_date = convert_date_format( value, CustomAttributeValue.DATE_FORMAT_US, CustomAttributeValue.DATE_FORMAT_ISO, ) except (TypeError, ValueError): # wrong format or not a date if not non_date_cad: # o_key is not a non-date CA raise BadQueryException(u"Field '{}' expects a '{}' date" .format( o_key, CustomAttributeValue.DATE_FORMAT_US, )) if date_attr or (date_cad and not non_date_cad): # Filter by converted date return [converted_date] elif date_cad and non_date_cad and converted_date is None: # Filter by unconverted string as date conversion was unsuccessful return [value] elif date_cad and non_date_cad: if operator_name in ("<", ">"): # "<" and ">" works incorrectly when searching by CA in both formats return [converted_date] else: # Since we can have two local CADs with same name when one is Date # and another is Text, we should handle the case when the user wants # to search by the Text CA that should not be converted return [converted_date, value] else: # Filter by unconverted string return [value]