Skip to content

Financial Data Classes

Data models for the financial elements of the tool.

ActivityNpv dataclass

ActivityNpv(value_info=None, component=None, prefix='', base_name='', suffix='', path='', skip_raster=False, enabled=True)

Bases: ConstantRasterComponent

Mapping of the NPV parameters to the corresponding activity.

activity property writable

activity

Wrapper for legacy support returning the activity model.

Returns:

Type Description
Activity

The activity if defined else None.

activity_id property

activity_id

Gets the identifier of the activity model.

Returns:

Type Description
str

The unique identifier of the activity model else an empty string if no activity has been set.

computed_base_name property

computed_base_name

Returns a proposed name for the activity NPV.

An empty string will be return id the activity attribute is not set.

Returns:

Type Description
str

Proposed base name for the activity NPV.

params property writable

params

Wrapper for legacy support returning the activity's parameters object.

Returns:

Type Description
NpvParameters

The activity's parameters object or None if not specified.

ActivityNpvCollection dataclass

ActivityNpvCollection(min_value=0.0, max_value=1.0, component_type=None, components=list(), skip_raster=False, allowable_max=sys.float_info.max, allowable_min=0.0, last_updated='', use_manual=False)

Bases: ConstantRasterCollection

Collection for all ActivityNpv configurations that have been specified by the user.

mappings property writable

mappings

Get the mapping of activity NPVs.

This is a wrapper only used for legacy support.

Returns:

Type Description
typing.List[ActivityNpv]

List of activity NPV mappings.

activity_npv

activity_npv(activity_identifier)

Gets the mapping of an activity's NPV mapping if defined.

Parameters:

Name Type Description Default
activity_identifier str

Unique identifier of an activity whose NPV mapping is to be retrieved.

required

Returns:

Type Description
ActivityNpv

The activity's NPV mapping else None if not found.

Source code in src/cplus_plugin/models/financial.py
def activity_npv(self, activity_identifier: str) -> typing.Optional[ActivityNpv]:
    """Gets the mapping of an activity's NPV mapping if defined.

    :param activity_identifier: Unique identifier of an activity
    whose NPV mapping is to be retrieved.
    :type activity_identifier: str

    :returns: The activity's NPV mapping else None if not found.
    :rtype: ActivityNpv
    """
    matching_mapping = [
        activity_npv
        for activity_npv in self.mappings
        if activity_npv.activity_id == activity_identifier
    ]

    return None if len(matching_mapping) == 0 else matching_mapping[0]

normalize

normalize()

Normalize minimum and maximum values of the valid mappings in the collection.

Overrides base class implementation.

Source code in src/cplus_plugin/models/financial.py
def normalize(self):
    """Normalize minimum and maximum values of the valid mappings in
    the collection.

    Overrides base class implementation.
    """
    self.update_computed_normalization_range()
    _ = self.normalize_npvs()

normalize_npvs

normalize_npvs()

Normalize the NPV values of activity using the specified normalization range.

If the absolute NPV values are less than or greater than the normalization range, then they will be truncated to 0.0 and 1.0 respectively. To avoid such a situation from occurring, it is recommended to make sure that the ranges are synchronized using the latest absolute NPV values by calling update_computed_normalization_range before normalizing the NPVs.

If there is only one NPV mapping, then assign a normalized value of 1.0.

Returns:

Type Description
bool

True if the NPVs were successfully normalized else False due to various reasons such as if the minimum value is greater than the maximum value, if the min/max values are the same, or if there are no NPV mappings.

Source code in src/cplus_plugin/models/financial.py
def normalize_npvs(self) -> bool:
    """Normalize the NPV values of activity using the specified
    normalization range.

    If the absolute NPV values are less than or greater than the
    normalization range, then they will be truncated to 0.0 and 1.0
    respectively. To avoid such a situation from occurring, it is recommended
    to make sure that the ranges are synchronized using the latest absolute
    NPV values by calling `update_computed_normalization_range` before
    normalizing the NPVs.

    If there is only one NPV mapping, then assign a normalized value of 1.0.

    :returns: True if the NPVs were successfully normalized else False due
    to various reasons such as if the minimum value is greater than the
    maximum value, if the min/max values are the same, or if there are no NPV
    mappings.
    """
    valid_npv_mappings = self._valid_npv_mappings()
    if len(valid_npv_mappings) == 0:
        return False

    if len(valid_npv_mappings) == 1:
        activity_npv = self.mappings[0]
        activity_npv.params.normalized = 1.0
        return True

    if self.min_value > self.max_value:
        return False

    norm_range = float(self.max_value - self.min_value)

    if norm_range == 0.0:
        return False

    for activity_npv in valid_npv_mappings:
        absolute_npv = activity_npv.params.absolute
        if not absolute_npv:
            continue

        if absolute_npv <= self.min_value:
            normalized_npv = 0.0
        elif absolute_npv >= self.max_value:
            normalized_npv = 1.0
        else:
            normalized_npv = (absolute_npv - self.min_value) / norm_range

        activity_npv.params.normalized = normalized_npv

    return True

update_computed_normalization_range

update_computed_normalization_range()

Update the minimum and maximum normalization values based on the absolute values of the existing ActivityNpv objects.

Values for disabled activity NPVs will be excluded from the computation.

Returns:

Type Description
bool

True if the min/max values were updated else False if there are no mappings or valid absolute NPV values defined.

Source code in src/cplus_plugin/models/financial.py
def update_computed_normalization_range(self) -> bool:
    """Update the minimum and maximum normalization values
    based on the absolute values of the existing ActivityNpv
    objects.

    Values for disabled activity NPVs will be excluded from
    the computation.

    :returns: True if the min/max values were updated else False if
    there are no mappings or valid absolute NPV values defined.
    """
    if len(self.mappings) == 0:
        return False

    valid_npv_values = [
        activity_npv.params.absolute for activity_npv in self._valid_npv_mappings()
    ]

    if len(valid_npv_values) == 0:
        return False

    self.min_value = min(valid_npv_values)
    self.max_value = max(valid_npv_values)

    return True

NpvParameters dataclass

NpvParameters(normalized=0.0, absolute=0.0, years=0, discount=0.0, yearly_rates=list(), manual_npv=False)

Bases: ConstantRasterInfo

Parameters for computing an activity's NPV.

__post_init__

__post_init__()

Ensure yearly_rates has length equal to years.

Source code in src/cplus_plugin/models/financial.py
def __post_init__(self):
    """Ensure yearly_rates has length equal to years."""
    year_diff = self.years - len(self.yearly_rates)
    if year_diff > 0:
        self.yearly_rates.extend([(None, None, None)] * year_diff)

Last update: December 22, 2025
Back to top