Ejemplo n.º 1
0
  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
Ejemplo n.º 2
0
 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,
         )
Ejemplo n.º 3
0
 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,
     )
Ejemplo n.º 4
0
 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,
       )
Ejemplo n.º 5
0
  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
Ejemplo n.º 6
0
        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]
Ejemplo n.º 7
0
    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]