def action(topic_id: TopicId,
            factor_id: FactorId) -> ParameterCondition:
     if is_blank(bucket_id):
         raise IndicatorKernelException(
             'Bucket of achievement indicator not declared.')
     if is_blank(bucket_segment_name):
         raise IndicatorKernelException(
             'Bucket segment name of achievement indicator not declared.'
         )
     bucket = ask_bucket(bucket_id, self.principalService)
     segment = ArrayHelper(
         bucket.segments).find(lambda x: x.name == bucket_segment_name)
     if segment is None:
         raise IndicatorKernelException(
             f'Bucket segment[name={bucket_segment_name}] not found.')
     if isinstance(bucket, NumericSegmentsHolder):
         include = bucket.include
         return self.fake_numeric_segment_to_condition(
             include, segment)(topic_id, factor_id)
     elif isinstance(bucket, CategorySegmentsHolder):
         return self.fake_category_segment_to_condition(
             segment, bucket.segments)(topic_id, factor_id)
     else:
         bucket_data = bucket.to_dict()
         if bucket_data.get('include') is not None:
             return self.fake_numeric_segment_to_condition(
                 bucket_data.get('include'), segment)(topic_id,
                                                      factor_id)
         else:
             # noinspection PyTypeChecker
             return self.fake_category_segment_to_condition(
                 segment, bucket.segments)(topic_id, factor_id)
 def action(topic_id: TopicId,
            factor_id: FactorId) -> ParameterExpression:
     if operator is None:
         raise IndicatorKernelException(
             'Operator of achievement indicator not declared.')
     if is_blank(value):
         raise IndicatorKernelException(
             'Compare value of achievement indicator not declared.')
     if operator == AchievementIndicatorCriteriaOperator.EQUALS:
         expression_operator = ParameterExpressionOperator.EQUALS
     elif operator == AchievementIndicatorCriteriaOperator.NOT_EQUALS:
         expression_operator = ParameterExpressionOperator.NOT_EQUALS
     elif operator == AchievementIndicatorCriteriaOperator.LESS:
         expression_operator = ParameterExpressionOperator.LESS
     elif operator == AchievementIndicatorCriteriaOperator.LESS_EQUALS:
         expression_operator = ParameterExpressionOperator.LESS_EQUALS
     elif operator == AchievementIndicatorCriteriaOperator.MORE:
         expression_operator = ParameterExpressionOperator.MORE
     elif operator == AchievementIndicatorCriteriaOperator.MORE_EQUALS:
         expression_operator = ParameterExpressionOperator.MORE_EQUALS
     else:
         raise IndicatorKernelException(
             f'Criteria value operator[{operator}] is not supported.')
     return ParameterExpression(
         left=self.build_value_criteria_left(topic_id, factor_id,
                                             value),
         operator=expression_operator,
         right=self.build_value_criteria_right(topic_id, factor_id,
                                               value))
    def action() -> SubjectForIndicator:
        subject: Optional[Subject] = subject_service.find_by_id(subject_id)
        if subject is None:
            raise_404()
        if subject.tenantId != principal_service.get_tenant_id():
            raise_403()
        connected_space_service = get_connected_space_service(subject_service)
        connected_space: Optional[
            ConnectedSpace] = connected_space_service.find_by_id(
                subject.connectId)
        if connected_space is None:
            raise IndicatorKernelException(
                f'Connected space not found for subject[id={subject_id}].')
        space_service = get_space_service(subject_service)
        space: Optional[Space] = space_service.find_by_id(
            connected_space.spaceId)
        if space is None:
            raise IndicatorKernelException(
                f'Space not found for subject[id={subject_id}].')
        topic_service = get_topic_service(subject_service)
        topics = topic_service.find_by_ids(space.topicIds,
                                           principal_service.get_tenant_id())
        topic_map: Dict[TopicId, Topic] = ArrayHelper(topics).to_map(
            lambda x: x.topicId, lambda x: x)

        all_topic_ids = space.topicIds
        all_topics = ArrayHelper(all_topic_ids).map(
            lambda x: topic_map[x]).to_list()
        return SubjectForIndicator(**subject.to_dict(), topics=all_topics)
 def action(topic_id: TopicId,
            factor_id: FactorId) -> ParameterExpression:
     values = ArrayHelper(
         segment.value).filter(lambda x: is_not_blank(x)).to_list()
     if len(values) == 0:
         raise IndicatorKernelException(
             'Value of category segment not declared.')
     if len(values) == 1 and values[0] == OtherCategorySegmentValue:
         # other values
         values = self.gather_defined_category_values(segments)
         if len(values) == 0:
             raise IndicatorKernelException(
                 'No values rather than others of category segment not declared.'
             )
         return ParameterExpression(
             left=TopicFactorParameter(kind=ParameterKind.TOPIC,
                                       topicId=topic_id,
                                       factorId=factor_id),
             operator=ParameterExpressionOperator.NOT_IN,
             right=values)
     else:
         return ParameterExpression(
             left=TopicFactorParameter(kind=ParameterKind.TOPIC,
                                       topicId=topic_id,
                                       factorId=factor_id),
             operator=ParameterExpressionOperator.IN,
             right=values)
def ask_topic(topic_id: TopicId, principal_service: PrincipalService) -> Topic:
    topic = get_topic_service(principal_service).find_by_id(topic_id)
    if topic is None:
        raise IndicatorKernelException(f'Topic[id={topic_id}] not found.')
    if topic.tenantId != principal_service.get_tenant_id():
        raise IndicatorKernelException(f'Topic[id={topic_id}] not found.')

    return topic
def ask_subject(subject_id: SubjectId,
                principal_service: PrincipalService) -> Subject:
    subject = get_subject_service(principal_service).find_by_id(subject_id)
    if subject is None:
        raise IndicatorKernelException(f'Subject[id={subject_id}] not found.')
    if subject.tenantId != principal_service.get_tenant_id():
        raise IndicatorKernelException(f'Subject[id={subject_id}] not found.')

    return subject
	def find_factor(
			self, factor_id: Optional[FactorId],
			on_factor_id_missed: Callable[[], str]) -> Factor:
		if is_blank(factor_id):
			raise IndicatorKernelException(on_factor_id_missed())
		factor: Optional[Factor] = ArrayHelper(self.topic.factors).find(lambda x: x.factorId == factor_id)
		if factor is None:
			raise IndicatorKernelException(self.ask_factor_not_found_message(factor_id))
		return factor
Example #8
0
	def find_column(
			self, column_id: Optional[SubjectDatasetColumnId],
			on_factor_id_missed: Callable[[], str]) -> SubjectDatasetColumn:
		if is_blank(column_id):
			raise IndicatorKernelException(on_factor_id_missed())
		column: Optional[SubjectDatasetColumn] = ArrayHelper(self.subject.dataset.columns) \
			.find(lambda x: x.columnId == column_id)
		if column is None:
			raise IndicatorKernelException(self.ask_column_not_found_message(column_id))
		return column
def ask_indicator(indicator_id: Optional[IndicatorId], principal_service: PrincipalService) -> Indicator:
	if is_blank(indicator_id):
		raise IndicatorKernelException('Indicator not declared.')
	indicator_service = get_indicator_service(principal_service)
	indicator_service.begin_transaction()
	try:
		# noinspection PyTypeChecker
		indicator: Indicator = indicator_service.find_by_id(indicator_id)
		if indicator is None:
			raise IndicatorKernelException(f'Indicator[id={indicator_id}] not found.')
		if indicator.tenantId != principal_service.get_tenant_id():
			raise IndicatorKernelException(f'Indicator[id={indicator_id}] not found.')
		return indicator
	finally:
		indicator_service.close_transaction()
 def action(topic_id: TopicId,
            factor_id: FactorId) -> ParameterCondition:
     if isinstance(criteria, AchievementIndicatorCriteriaOnBucket):
         return self.fake_bucket_criteria_to_condition(
             criteria.bucketId, criteria.bucketSegmentName)(topic_id,
                                                            factor_id)
     elif isinstance(criteria,
                     AchievementIndicatorCriteriaOnExpression):
         return self.fake_value_criteria_to_condition(
             criteria.operator, criteria.value)(topic_id, factor_id)
     else:
         data = criteria.to_dict()
         if is_not_blank(data.get('bucketId')) and is_not_blank(
                 data.get('bucketSegmentName')):
             return self.fake_bucket_criteria_to_condition(
                 data.get('bucketId'),
                 data.get('bucketSegmentName'))(topic_id, factor_id)
         elif data.get('operator') is not None and is_not_blank(
                 str(data.get('value'))):
             return self.fake_value_criteria_to_condition(
                 data.get('operator'),
                 str(data.get('value')))(topic_id, factor_id)
         else:
             raise IndicatorKernelException(
                 f'Achievement indicator criteria[{data}] not supported.'
             )
def ask_bucket(bucket_id: BucketId,
               principal_service: PrincipalService) -> Bucket:
    bucket_service = get_bucket_service(principal_service)
    bucket_service.begin_transaction()
    try:
        # noinspection PyTypeChecker
        bucket: Bucket = bucket_service.find_by_id(bucket_id)
        if bucket is None:
            raise IndicatorKernelException(
                f'Bucket[id={bucket_id}] not found.')
        if bucket.tenantId != principal_service.get_tenant_id():
            raise IndicatorKernelException(
                f'Bucket[id={bucket_id}] not found.')
        return bucket
    finally:
        bucket_service.close_transaction()
	def fake_time_range_to_dataset_filter(self) -> Optional[ParameterJoint]:
		time_range_factor_id = self.inspection.timeRangeFactorId
		if is_blank(time_range_factor_id):
			return None
		time_range_factor = self.find_factor(time_range_factor_id, lambda: 'Time range factor not declared.')
		time_ranges = ArrayHelper(self.inspection.timeRanges) \
			.filter(lambda x: x is not None and x.value is not None).to_list()
		if len(time_ranges) == 0:
			# no ranges given
			return None

		operator = ParameterExpressionOperator.EQUALS if len(time_ranges) == 1 else ParameterExpressionOperator.IN
		right = time_ranges[0].value if len(time_ranges) == 1 \
			else ArrayHelper(time_ranges).map(lambda x: x.value).join(',')
		time_range_measure = self.inspection.timeRangeMeasure
		if self.has_year_or_month(time_range_factor):
			if time_range_measure == MeasureMethod.YEAR:
				compute_type = ParameterComputeType.YEAR_OF
			elif time_range_measure == MeasureMethod.MONTH:
				compute_type = ParameterComputeType.MONTH_OF
			else:
				raise IndicatorKernelException(
					f'Measure method[{time_range_measure}] for factor type[{time_range_factor.type}] is not supported.')
			joint = ParameterJoint(
				jointType=ParameterJointType.AND,
				filters=[
					ParameterExpression(
						left=ComputedParameter(
							kind=ParameterKind.COMPUTED,
							type=compute_type,
							parameters=[
								TopicFactorParameter(
									kind=ParameterKind.TOPIC,
									topicId=self.topic.topicId, factorId=time_range_factor_id)
							]
						),
						operator=operator,
						right=ConstantParameter(kind=ParameterKind.CONSTANT, value=str(right))
					)
				]
			)
		else:
			joint = ParameterJoint(
				jointType=ParameterJointType.AND,
				filters=[
					ParameterExpression(
						left=TopicFactorParameter(
							kind=ParameterKind.TOPIC, topicId=self.topic.topicId, factorId=time_range_factor_id),
						operator=operator,
						right=ConstantParameter(kind=ParameterKind.CONSTANT, value=str(right))
					)
				]
			)
		return joint
Example #13
0
	def fake_subject(self):
		time_group_column = self.find_column_of_measure_on_time_dimension()
		# to figure out that the time group column is date type or not
		# if it is a date type, must fake a new column into subject
		if time_group_column is not None and isinstance(time_group_column.parameter, TopicFactorParameter):
			topic = get_topic_service(self.principalService).find_by_id(time_group_column.parameter.topicId)
			factor = ArrayHelper(topic.factors).find(lambda x: x.factorId == time_group_column.parameter.factorId)
			if factor is None:
				raise IndicatorKernelException('Factor of time group column not found.')
			if self.has_year_or_month(factor):
				fake_column = self.fake_time_group_column(topic.topicId, factor.factorId, time_group_column.alias)
				if fake_column is not None:
					self.subject.dataset.columns.append(fake_column)
	def fake_to_report(self, subject: Subject) -> Report:
		# in subject,
		# 1st column is value,
		# 2nd column is time group when there is 3rd column, or is measure on when there is no 3rd column,
		# 3rd column is measure on
		indicators: List[ReportIndicator] = []
		arithmetics = self.inspection.aggregateArithmetics
		if arithmetics is None or len(arithmetics) == 0:
			indicators.append(ReportIndicator(columnId='1', name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY))
		else:
			if IndicatorAggregateArithmetic.COUNT in arithmetics or IndicatorAggregateArithmetic.COUNT.value in arithmetics:
				indicators.append(
					ReportIndicator(columnId='1', name='_COUNT_', arithmetic=ReportIndicatorArithmetic.COUNT))
			if IndicatorAggregateArithmetic.SUM in arithmetics or IndicatorAggregateArithmetic.SUM.value in arithmetics:
				indicators.append(
					ReportIndicator(columnId='1', name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY))
			if IndicatorAggregateArithmetic.AVG in arithmetics or IndicatorAggregateArithmetic.AVG.value in arithmetics:
				indicators.append(
					ReportIndicator(columnId='1', name='_AVG_', arithmetic=ReportIndicatorArithmetic.AVERAGE))
			if IndicatorAggregateArithmetic.MAX in arithmetics or IndicatorAggregateArithmetic.MAX.value in arithmetics:
				indicators.append(
					ReportIndicator(columnId='1', name='_MAX_', arithmetic=ReportIndicatorArithmetic.MAXIMUM))
			if IndicatorAggregateArithmetic.MIN in arithmetics or IndicatorAggregateArithmetic.MIN.value in arithmetics:
				indicators.append(
					ReportIndicator(columnId='1', name='_MIN_', arithmetic=ReportIndicatorArithmetic.MINIMUM))

		dimensions: List[ReportDimension] = []
		if len(subject.dataset.columns) == 3:
			dimensions.append(ReportDimension(columnId='3', name='_BUCKET_ON_'))
			fake_column = ArrayHelper(subject.dataset.columns) \
				.find(lambda x: x.columnId == self.FAKE_TIME_GROUP_COLUMN_ID)
			if fake_column is None:
				dimensions.append(ReportDimension(columnId='2', name='_TIME_GROUP_'))
			else:
				dimensions.append(ReportDimension(columnId=self.FAKE_TIME_GROUP_COLUMN_ID, name='_TIME_GROUP_'))
		elif len(subject.dataset.columns) == 2:
			time_group_existing, _, _ = self.has_time_group()
			if time_group_existing:
				fake_column = ArrayHelper(subject.dataset.columns) \
					.find(lambda x: x.columnId == self.FAKE_TIME_GROUP_COLUMN_ID)
				if fake_column is None:
					dimensions.append(ReportDimension(columnId='2', name='_TIME_GROUP_'))
				else:
					dimensions.append(ReportDimension(columnId=self.FAKE_TIME_GROUP_COLUMN_ID, name='_TIME_GROUP_'))
			else:
				dimensions.append(ReportDimension(columnId='2', name='_BUCKET_ON_'))
		else:
			raise IndicatorKernelException('Neither time group nor bucket on found.')

		return Report(indicators=indicators, dimensions=dimensions)
def get_achievement_data_service(
		achievement_indicator: AchievementIndicator, principal_service: PrincipalService) -> AchievementDataService:
	"""
	to identify that given achievement is based on topic or subject
	"""
	indicator = ask_indicator(achievement_indicator.indicatorId, principal_service)
	topic_or_subject_id = indicator.topicOrSubjectId
	base_on = indicator.baseOn
	if base_on == IndicatorBaseOn.TOPIC and is_not_blank(topic_or_subject_id):
		return get_topic_base_service(achievement_indicator, indicator, topic_or_subject_id, principal_service)
	elif base_on == IndicatorBaseOn.SUBJECT and is_not_blank(topic_or_subject_id):
		return get_subject_base_service(achievement_indicator, indicator, topic_or_subject_id, principal_service)
	else:
		raise IndicatorKernelException('Indicator is not based on topic, not supported yet.')
 def action(topic_id: TopicId,
            factor_id: FactorId) -> ParameterCondition:
     min_value = segment.value.min
     max_value = segment.value.max
     if include == RangeBucketValueIncluding.INCLUDE_MIN:
         operator_min = ParameterExpressionOperator.MORE_EQUALS
     else:
         operator_min = ParameterExpressionOperator.MORE
     if include == RangeBucketValueIncluding.INCLUDE_MIN:
         operator_max = ParameterExpressionOperator.LESS
     else:
         operator_max = ParameterExpressionOperator.LESS_EQUALS
     if is_not_blank(min_value) and is_not_blank(max_value):
         return ParameterJoint(
             jointType=ParameterJointType.AND,
             filters=[
                 ParameterExpression(left=TopicFactorParameter(
                     kind=ParameterKind.TOPIC,
                     topicId=topic_id,
                     factorId=factor_id),
                                     operator=operator_min,
                                     right=min_value),
                 ParameterExpression(left=TopicFactorParameter(
                     kind=ParameterKind.TOPIC,
                     topicId=topic_id,
                     factorId=factor_id),
                                     operator=operator_max,
                                     right=max_value)
             ])
     elif is_not_blank(min_value):
         return ParameterExpression(left=TopicFactorParameter(
             kind=ParameterKind.TOPIC,
             topicId=topic_id,
             factorId=factor_id),
                                    operator=operator_min,
                                    right=min_value)
     elif is_not_blank(max_value):
         return ParameterExpression(left=TopicFactorParameter(
             kind=ParameterKind.TOPIC,
             topicId=topic_id,
             factorId=factor_id),
                                    operator=operator_max,
                                    right=max_value)
     else:
         raise IndicatorKernelException(
             'Neither minimum not maximum value of numeric value segment is declared.'
         )
Example #17
0
	def fake_to_report(self) -> Report:
		indicators: List[ReportIndicator] = []
		report_indicator_column_id = self.indicator.factorId
		arithmetics = self.inspection.aggregateArithmetics
		if arithmetics is None or len(arithmetics) == 0:
			indicators.append(ReportIndicator(
				columnId=report_indicator_column_id, name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY))
		else:
			if IndicatorAggregateArithmetic.COUNT in arithmetics or IndicatorAggregateArithmetic.COUNT.value in arithmetics:
				indicators.append(ReportIndicator(
					columnId=report_indicator_column_id, name='_COUNT_', arithmetic=ReportIndicatorArithmetic.COUNT))
			if IndicatorAggregateArithmetic.SUM in arithmetics or IndicatorAggregateArithmetic.SUM.value in arithmetics:
				indicators.append(ReportIndicator(
					columnId=report_indicator_column_id, name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY))
			if IndicatorAggregateArithmetic.AVG in arithmetics or IndicatorAggregateArithmetic.AVG.value in arithmetics:
				indicators.append(ReportIndicator(
					columnId=report_indicator_column_id, name='_AVG_', arithmetic=ReportIndicatorArithmetic.AVERAGE))
			if IndicatorAggregateArithmetic.MAX in arithmetics or IndicatorAggregateArithmetic.MAX.value in arithmetics:
				indicators.append(ReportIndicator(
					columnId=report_indicator_column_id, name='_MAX_', arithmetic=ReportIndicatorArithmetic.MAXIMUM))
			if IndicatorAggregateArithmetic.MIN in arithmetics or IndicatorAggregateArithmetic.MIN.value in arithmetics:
				indicators.append(ReportIndicator(
					columnId=report_indicator_column_id, name='_MIN_', arithmetic=ReportIndicatorArithmetic.MINIMUM))

		dimensions: List[ReportDimension] = []
		bucket_on_column = self.find_column_of_measure_on_dimension()
		if bucket_on_column is not None:
			dimensions.append(ReportDimension(columnId=bucket_on_column.columnId, name='_BUCKET_ON_'))
		time_group_column = self.find_column_of_measure_on_time_dimension()
		if time_group_column is not None:
			fake_column = ArrayHelper(self.subject.dataset.columns) \
				.find(lambda x: x.columnId == self.FAKE_TIME_GROUP_COLUMN_ID)
			if fake_column is None:
				dimensions.append(ReportDimension(columnId=time_group_column.columnId, name='_TIME_GROUP_'))
			else:
				dimensions.append(ReportDimension(columnId=self.FAKE_TIME_GROUP_COLUMN_ID, name='_TIME_GROUP_'))
		if len(dimensions) == 0:
			raise IndicatorKernelException('Neither time group nor bucket not found.')

		report_filter = self.fake_time_range_to_report()
		if report_filter is None:
			return Report(indicators=indicators, dimensions=dimensions)
		else:
			return Report(indicators=indicators, dimensions=dimensions, filters=report_filter)
        def action(factor_id: FactorId) -> Report:
            arithmetic = self.achievementIndicator.aggregateArithmetic
            if arithmetic is None:
                report_indicator = ReportIndicator(
                    columnId=factor_id,
                    name='_SUM_',
                    arithmetic=ReportIndicatorArithmetic.SUMMARY)
            elif IndicatorAggregateArithmetic.COUNT == arithmetic or IndicatorAggregateArithmetic.COUNT.value == arithmetic:
                report_indicator = ReportIndicator(
                    columnId=factor_id,
                    name='_COUNT_',
                    arithmetic=ReportIndicatorArithmetic.COUNT)
            elif IndicatorAggregateArithmetic.SUM == arithmetic or IndicatorAggregateArithmetic.SUM.value == arithmetic:
                report_indicator = ReportIndicator(
                    columnId=factor_id,
                    name='_SUM_',
                    arithmetic=ReportIndicatorArithmetic.SUMMARY)
            elif IndicatorAggregateArithmetic.AVG == arithmetic or IndicatorAggregateArithmetic.AVG.value == arithmetic:
                report_indicator = ReportIndicator(
                    columnId=factor_id,
                    name='_AVG_',
                    arithmetic=ReportIndicatorArithmetic.AVERAGE)
            elif IndicatorAggregateArithmetic.MAX == arithmetic or IndicatorAggregateArithmetic.MAX.value == arithmetic:
                report_indicator = ReportIndicator(
                    columnId=factor_id,
                    name='_MAX_',
                    arithmetic=ReportIndicatorArithmetic.MAXIMUM)
            elif IndicatorAggregateArithmetic.MIN == arithmetic or IndicatorAggregateArithmetic.MIN.value == arithmetic:
                report_indicator = ReportIndicator(
                    columnId=factor_id,
                    name='_MIN_',
                    arithmetic=ReportIndicatorArithmetic.MINIMUM)
            else:
                raise IndicatorKernelException(
                    f'Indicator aggregate arithmetics[{arithmetic}] is not supported.'
                )

            return Report(indicators=[report_indicator], dimensions=[])
	def fake_to_subject(self) -> Subject:
		dataset_columns: List[SubjectDatasetColumn] = []
		indicator_factor_column, _, next_column_index = self.fake_indicator_factor_to_dataset_column(1)
		dataset_columns.append(indicator_factor_column)
		time_group_column, _, next_column_index = \
			self.fake_time_group_to_dataset_column(next_column_index)
		if time_group_column is not None:
			dataset_columns.append(time_group_column)
			topic = get_topic_service(self.principalService).find_by_id(time_group_column.parameter.topicId)
			factor = ArrayHelper(topic.factors).find(lambda x: x.factorId == time_group_column.parameter.factorId)
			if factor is None:
				raise IndicatorKernelException('Factor of time group column not found.')
			if self.has_year_or_month(factor):
				fake_column = self.fake_time_group_column(topic.topicId, factor.factorId, time_group_column.alias)
				if fake_column is not None:
					dataset_columns.append(fake_column)
		measure_on_column, _, next_column_index = \
			self.fake_measure_on_to_dataset_column(next_column_index)
		if measure_on_column is not None:
			dataset_columns.append(measure_on_column)

		dataset_filters: Optional[ParameterJoint] = self.build_filters()
		return Subject(dataset=SubjectDataset(columns=dataset_columns, filters=dataset_filters))
	def fake_time_group_to_dataset_column(
			self, column_index: int) -> Tuple[Optional[SubjectDatasetColumn], Optional[int], int]:
		time_group_existing, measure_on_time_factor_id, measure_on_time = self.has_time_group()
		if not time_group_existing:
			return None, None, column_index

		measure_on_time_factor = self.find_factor(
			measure_on_time_factor_id, lambda: 'Measure on time factor not declared.')
		if self.has_year_or_month(measure_on_time_factor.type):
			if measure_on_time == MeasureMethod.YEAR:
				compute_type = ParameterComputeType.YEAR_OF
			elif measure_on_time == MeasureMethod.MONTH:
				compute_type = ParameterComputeType.MONTH_OF
			else:
				raise IndicatorKernelException(
					f'Measure method[{measure_on_time}] for factor type[{measure_on_time_factor.type}] is not supported.')
			column = SubjectDatasetColumn(
				columnId=str(column_index),
				parameter=ComputedParameter(
					kind=ParameterKind.COMPUTED,
					type=compute_type,
					parameters=[
						TopicFactorParameter(
							kind=ParameterKind.TOPIC,
							topicId=self.topic.topicId, factorId=measure_on_time_factor_id)
					]
				),
				alias=f'column_{column_index}'
			)
		else:
			column = SubjectDatasetColumn(
				columnId=str(column_index),
				parameter=TopicFactorParameter(
					kind=ParameterKind.TOPIC, topicId=self.topic.topicId, factorId=measure_on_time_factor_id),
				alias=f'column_{column_index}'
			)
		return column, column_index, column_index + 1
    def fake_numeric_segment_to_condition(
        self, include: Union[RangeBucketValueIncluding,
                             str], segment: Union[NumericValueSegment, dict]
    ) -> Callable[[TopicId, FactorId], ParameterCondition]:
        if isinstance(include, str):
            include = RangeBucketValueIncluding(include)
        if not isinstance(segment, NumericValueSegment):
            segment = NumericValueSegment(**segment)
        if segment.value is None:
            raise IndicatorKernelException(
                'Numeric bucket segment not declared.')

        def action(topic_id: TopicId,
                   factor_id: FactorId) -> ParameterCondition:
            min_value = segment.value.min
            max_value = segment.value.max
            if include == RangeBucketValueIncluding.INCLUDE_MIN:
                operator_min = ParameterExpressionOperator.MORE_EQUALS
            else:
                operator_min = ParameterExpressionOperator.MORE
            if include == RangeBucketValueIncluding.INCLUDE_MIN:
                operator_max = ParameterExpressionOperator.LESS
            else:
                operator_max = ParameterExpressionOperator.LESS_EQUALS
            if is_not_blank(min_value) and is_not_blank(max_value):
                return ParameterJoint(
                    jointType=ParameterJointType.AND,
                    filters=[
                        ParameterExpression(left=TopicFactorParameter(
                            kind=ParameterKind.TOPIC,
                            topicId=topic_id,
                            factorId=factor_id),
                                            operator=operator_min,
                                            right=min_value),
                        ParameterExpression(left=TopicFactorParameter(
                            kind=ParameterKind.TOPIC,
                            topicId=topic_id,
                            factorId=factor_id),
                                            operator=operator_max,
                                            right=max_value)
                    ])
            elif is_not_blank(min_value):
                return ParameterExpression(left=TopicFactorParameter(
                    kind=ParameterKind.TOPIC,
                    topicId=topic_id,
                    factorId=factor_id),
                                           operator=operator_min,
                                           right=min_value)
            elif is_not_blank(max_value):
                return ParameterExpression(left=TopicFactorParameter(
                    kind=ParameterKind.TOPIC,
                    topicId=topic_id,
                    factorId=factor_id),
                                           operator=operator_max,
                                           right=max_value)
            else:
                raise IndicatorKernelException(
                    'Neither minimum not maximum value of numeric value segment is declared.'
                )

        return action
	def fake_measure_on_to_dataset_column(
			self, column_index: int) -> Tuple[Optional[SubjectDatasetColumn], Optional[int], int]:
		measure_on = self.inspection.measureOn
		if measure_on is None or measure_on == InspectMeasureOn.NONE:
			return None, None, column_index
		if measure_on == InspectMeasureOn.OTHER:
			measure_on_factor_id = self.inspection.measureOnFactorId
			if is_blank(measure_on_factor_id):
				return None, None, column_index
		elif measure_on == InspectMeasureOn.VALUE:
			measure_on_factor_id = self.indicator.factorId
		else:
			return None, None, column_index
		measure_on_factor = self.find_factor(measure_on_factor_id, lambda: 'Measure on factor not declared.')

		measure_on_bucket_id = self.inspection.measureOnBucketId
		if is_blank(measure_on_bucket_id):
			if measure_on == InspectMeasureOn.OTHER:
				# using naturally classification
				column = SubjectDatasetColumn(
					columnId=str(column_index),
					parameter=TopicFactorParameter(
						kind=ParameterKind.TOPIC, topicId=self.topic.topicId, factorId=measure_on_factor_id),
					alias=f'column_{column_index}'
				)
			else:
				raise IndicatorKernelException('Measure on bucket not declared.')
		else:
			bucket = ask_bucket(measure_on_bucket_id, self.principalService)
			if measure_on == InspectMeasureOn.VALUE:
				bucket = self.to_numeric_segments_bucket(bucket)
				include = RangeBucketValueIncluding.INCLUDE_MIN if bucket.include is None else bucket.include
				# at least has one value
				segments = ArrayHelper(bucket.segments) \
					.filter(lambda x: x.value is not None) \
					.filter(lambda x: x.value.min is not None or x.value.max is not None) \
					.to_list()
				if len(segments) == 0:
					raise IndicatorKernelException('Numeric range segments not declared.')
				column = SubjectDatasetColumn(
					columnId=str(column_index),
					parameter=ComputedParameter(
						kind=ParameterKind.COMPUTED, type=ParameterComputeType.CASE_THEN,
						parameters=[
							*ArrayHelper(segments).map(
								lambda x: self.to_numeric_range_case_route(x, include, measure_on_factor)).to_list(),
							# an anyway route, additional
							ConstantParameter(kind=ParameterKind.CONSTANT, value='-')
						]
					),
					alias=f'column_{column_index}'
				)
			elif measure_on == InspectMeasureOn.OTHER:
				bucket = self.to_category_segments_bucket(bucket)
				segments = ArrayHelper(bucket.segments) \
					.filter(lambda x: x.value is not None and len(x.value) != 0).to_list()
				if len(segments) == 0:
					raise IndicatorKernelException('Category segments not declared.')
				anyway_segment: CategorySegment = ArrayHelper(segments) \
					.find(lambda x: len(x.value) == 1 and x.value[0] == OtherCategorySegmentValue)
				if anyway_segment is not None:
					conditional_routes = ArrayHelper(segments).filter(lambda x: x != anyway_segment).to_list()
					anyway_route = ConstantParameter(kind=ParameterKind.CONSTANT, value=anyway_segment.name)
				else:
					conditional_routes = segments
					anyway_route = ConstantParameter(kind=ParameterKind.CONSTANT, value='-')

				column = SubjectDatasetColumn(
					columnId=str(column_index),
					parameter=ComputedParameter(
						kind=ParameterKind.COMPUTED, type=ParameterComputeType.CASE_THEN,
						parameters=[
							*ArrayHelper(conditional_routes).map(
								lambda x: self.to_category_case_route(x, measure_on_factor)).to_list(),
							anyway_route
						]
					),
					alias=f'column_{column_index}'
				)
			else:
				raise IndicatorKernelException(f'Measure[{measure_on}] is not supported.')
		return column, column_index, column_index + 1
Example #23
0
	def fake_time_range_to_report(self) -> Optional[ParameterJoint]:
		time_range_factor_id = self.inspection.timeRangeFactorId
		if is_blank(time_range_factor_id):
			return None
		time_range_column = self.find_column(time_range_factor_id, lambda: 'Time range factor not declared.')
		time_ranges = ArrayHelper(self.inspection.timeRanges) \
			.filter(lambda x: x is not None and x.value is not None).to_list()
		if len(time_ranges) == 0:
			# no ranges given
			return None

		operator = ParameterExpressionOperator.EQUALS if len(time_ranges) == 1 else ParameterExpressionOperator.IN
		right = time_ranges[0].value if len(time_ranges) == 1 \
			else ArrayHelper(time_ranges).map(lambda x: x.value).join(',')
		time_range_measure = self.inspection.timeRangeMeasure
		if isinstance(time_range_column.parameter, TopicFactorParameter):
			topic_id = time_range_column.parameter.topicId
			if is_blank(topic_id):
				raise IndicatorKernelException(f'Topic not declared for time range factor[id={time_range_factor_id}].')
			topic = get_topic_service(self.principalService).find_by_id(topic_id)
			if topic is None:
				raise IndicatorKernelException(f'Topic[id={topic_id}] not found.')
			factor_id = time_range_column.parameter.factorId
			if is_blank(topic_id):
				raise IndicatorKernelException(f'Factor not declared for time range factor[id={time_range_factor_id}].')
			factor = ArrayHelper(topic.factors).find(lambda x: x.factorId == factor_id)
			if factor is None:
				raise IndicatorKernelException(f'Factor[id={factor_id}] not found on topic[id={topic_id}].')
			if self.has_year_or_month(factor):
				if time_range_measure == MeasureMethod.YEAR:
					compute_type = ParameterComputeType.YEAR_OF
				elif time_range_measure == MeasureMethod.MONTH:
					compute_type = ParameterComputeType.MONTH_OF
				else:
					raise IndicatorKernelException(
						f'Measure method[{time_range_measure}] for factor type[{factor.type}] is not supported.')
				joint = ParameterJoint(
					jointType=ParameterJointType.AND,
					filters=[
						ParameterExpression(
							left=ComputedParameter(
								kind=ParameterKind.COMPUTED,
								type=compute_type,
								parameters=[
									TopicFactorParameter(
										kind=ParameterKind.TOPIC,
										topicId='1', factorId=time_range_factor_id)
								]
							),
							operator=operator,
							right=ConstantParameter(kind=ParameterKind.CONSTANT, value=str(right))
						)
					]
				)
			else:
				joint = ParameterJoint(
					jointType=ParameterJointType.AND,
					filters=[
						ParameterExpression(
							left=TopicFactorParameter(
								kind=ParameterKind.TOPIC, topicId='1', factorId=time_range_factor_id),
							operator=operator,
							right=ConstantParameter(kind=ParameterKind.CONSTANT, value=str(right))
						)
					]
				)
		else:
			joint = ParameterJoint(
				jointType=ParameterJointType.AND,
				filters=[
					ParameterExpression(
						left=TopicFactorParameter(
							kind=ParameterKind.TOPIC, topicId='1', factorId=time_range_factor_id),
						operator=operator,
						right=ConstantParameter(kind=ParameterKind.CONSTANT, value=str(right))
					)
				]
			)
		return joint