Esempio n. 1
0
    def production_ci_na5_gwp(self, party, _group, _periods):
        """
            The HFC baseline includes a % of the HCFC baseline
            computed in CO2-equivalent tonnes
            The HCFC baseline formula contains in its turn a percentage of
            the CFC production/consumption
        """
        cfc_group = self.groups.get('AI')
        hcfc_group = self.groups.get('CI')

        # Note that the consumption of EU member states SHOULD BE included!
        # Also, these should be unrounded values!
        hcfc_prod = self._prod_cons_gwp(party, hcfc_group, '1989', 'PROD')
        cfc_prod = self._prod_cons_gwp(party, cfc_group, '1989', 'PROD')
        hcfc_cons = self._prod_cons_gwp(party, hcfc_group, '1989', 'CONS')
        cfc_cons = self._prod_cons_gwp(party, cfc_group, '1989', 'CONS')

        if any(x is None for x in (hcfc_prod, cfc_prod, hcfc_cons, cfc_cons)):
            return None

        rounded_average = round_decimal_half_up(
            sum((
                round_decimal_half_up(hcfc_prod, 0),
                round_decimal_half_up(cfc_prod, 0) * Decimal('0.028'),
                round_decimal_half_up(hcfc_cons, 0),
                round_decimal_half_up(cfc_cons, 0) * Decimal('0.028'),
            )) / 2,
            0,
        )
        return rounded_average if rounded_average > 0 else Decimal('0')
Esempio n. 2
0
def get_row(data, precision):
    return (
        data[0],
        sm_r(format_decimal(round_decimal_half_up(data[1], precision))),
        sm_r(format_decimal(round_decimal_half_up(data[2], precision))),
        sm_r(format_decimal(round_decimal_half_up(data[3], precision))),
        sm_r(format_decimal(round_decimal_half_up(data[4], precision))),
    )
Esempio n. 3
0
    def average_production_gwp(self, party, group, periods):
        total_prod = Decimal('0.0')
        for period in periods:
            prod = self._prod_cons_gwp(party, group, period, 'PROD')
            if prod is None:
                # Don't compute if party has not reported for a baseline period
                return None
            total_prod += round_decimal_half_up(prod, 0)

        rounded_average = round_decimal_half_up(total_prod / len(periods), 0)
        return rounded_average if rounded_average > 0 else Decimal('0')
Esempio n. 4
0
    def get_limit(self, limit_type, group, party, party_type, is_eu_member,
                  period):

        if party.abbr == 'EU' and limit_type in (LimitTypes.BDN.value,
                                                 LimitTypes.PRODUCTION.value):
            # No BDN or Prod limits for EU/ECE(European Union)
            return None

        if is_eu_member and limit_type == LimitTypes.CONSUMPTION.value:
            # No consumption baseline for EU member states
            return None

        # Get the control measure objects for these limits
        key = (group.group_id, party_type.name, limit_type)
        cm_objects = self.control_measures[key]
        cm_objects = [
            o for o in cm_objects if (o.start_date <= period.end_date and (
                o.end_date == None or o.end_date >= period.start_date))
        ]

        cm_count = len(cm_objects)
        if cm_count == 0:
            # No control measures here
            return None
        elif cm_count == 1:
            cm = cm_objects[0]
            baseline = self._get_baseline(party, group, cm.baseline_type)
            if baseline is None:
                return Decimal('0')
            else:
                return round_decimal_half_up(
                    baseline * cm.allowed,
                    self._get_decimals_for_limits(group, party))
        elif cm_count == 2:
            # This happens for NA5 BDN limits, AI/BI/EI
            # because control measure becomes applicable in July 28, 2000
            cm1 = cm_objects[0]
            cm2 = cm_objects[1]
            baseline1 = self._get_baseline(party, group, cm1.baseline_type)
            baseline2 = self._get_baseline(party, group, cm2.baseline_type)
            if baseline1 is None or baseline2 is None:
                return Decimal('0')
            days1 = (cm1.end_date - period.start_date).days + 1
            days2 = (period.end_date - cm2.start_date).days + 1
            limit = sum((
                cm1.allowed * days1 * baseline1,
                cm2.allowed * days2 * baseline2,
            )) / ((period.end_date - period.start_date).days + 1)
            return round_decimal_half_up(
                limit, self._get_decimals_for_limits(group, party))
Esempio n. 5
0
    def consumption_ci_na5(self, party, _group, _periods):
        """
            1989 HCFC consumption + 2.8 per cent of 1989 CFC consumption
        """
        hcfc_group = self.groups.get('CI')
        cfc_group = self.groups.get('AI')
        hcfc_1989 = self._get_prodcons(party, hcfc_group, '1989')
        cfc_1989 = self._get_prodcons(party, cfc_group, '1989')
        if hcfc_1989 and cfc_1989:
            if hcfc_1989.is_eu_member:
                # hcfc_1989.calculated_consumption = round_decimal_half_up(
                #     hcfc_1989.get_calc_consumption(),
                #     1  # always 1 decimal for 1989
                # )
                # cfc_1989.calculated_consumption = round_decimal_half_up(
                #     cfc_1989.get_calc_consumption(),
                #     1  # always 1 decimal for 1989
                # )
                # TODO: but is it correct to use unrounded values for EU members
                # and rounded values for non-EU?
                hcfc_1989.calculated_consumption = hcfc_1989.get_calc_consumption(
                )
                cfc_1989.calculated_consumption = cfc_1989.get_calc_consumption(
                )

            # Use already rounded values for calculated consumption
            c1_baseline_cons = round_decimal_half_up(
                sum((
                    hcfc_1989.calculated_consumption,
                    cfc_1989.calculated_consumption * Decimal('0.028'),
                )),
                1,  # always 1 decimal for 1989
            )
            return c1_baseline_cons if c1_baseline_cons > 0 else Decimal('0')
        return None
Esempio n. 6
0
    def production_ci_na5(self, party, _group, _periods):
        """ Average of
            1989 HCFC production + 2.8 per cent of 1989 CFC production
            and
            1989 HCFC consumption + 2.8 per cent of 1989 CFC consumption
        """

        hcfc_group = self.groups.get('CI')
        cfc_group = self.groups.get('AI')
        hcfc_1989 = self._get_prodcons(party, hcfc_group, '1989')
        cfc_1989 = self._get_prodcons(party, cfc_group, '1989')
        if hcfc_1989 and cfc_1989:
            # Note: For EU members, real consumption is included in the formula
            # even if they have NULL calculated_consumption

            average_prod = sum_decimals(
                hcfc_1989.calculated_production,
                decimal_zero_if_none(cfc_1989.calculated_production) *
                Decimal('0.028'),
                hcfc_1989.get_calc_consumption(),
                cfc_1989.get_calc_consumption() * Decimal('0.028'),
            )
            average_prod = round_decimal_half_up(
                average_prod / 2,
                1  # always 1 decimal for 1989
            )
            return average_prod if average_prod > 0 else Decimal('0')
        return None
Esempio n. 7
0
    def per_capita(self, cons, population):
        if cons in [None, value_missing, value_not_required]:
            return '-'

        if not population:
            return '-'

        return format_decimal(round_decimal_half_up(cons / population, 4))
Esempio n. 8
0
    def average_consumption_gwp(self, party, group, periods):
        total_cons = Decimal('0.0')
        for period in periods:
            cons = self._prod_cons_gwp(party, group, period, 'CONS')
            if cons is None:
                # Don't compute if party has not reported for a baseline period
                return None
            total_cons += round_decimal_half_up(cons, 0)

            if party.abbr == 'EU':
                # Must add consumption of EU member states
                # which were not member states in 1989
                for _ms in self.new_eu_member_states_since[period]:
                    cons_ms = self._prod_cons_gwp(_ms, group, period, 'CONS')
                    if cons_ms is not None:
                        total_cons += round_decimal_half_up(cons_ms, 0)

        rounded_average = round_decimal_half_up(total_cons / len(periods), 0)
        return rounded_average if rounded_average > 0 else Decimal('0')
Esempio n. 9
0
    def prodcons(self, value):
        if value is value_not_required:
            return '-'

        if value is value_missing:
            return 'N.R.'

        if self.round_baseline is not None:
            value = round_decimal_half_up(value, self.round_prodcons)

        return format_decimal(value)
Esempio n. 10
0
    def average_consumption(self, party, group, periods):
        total_cons = Decimal('0.0')
        rounding_digits = 0
        for period in periods:
            prodcons = self._get_prodcons(party, group, period)
            if not prodcons:
                return None
            if prodcons.is_eu_member:
                total_cons += round_decimal_half_up(
                    prodcons.get_calc_consumption(), prodcons.decimals)
            else:
                total_cons += prodcons.calculated_consumption
            if group.group_id in ('AI', 'AII', 'BI', 'BII', 'BIII'):
                # Add ImpRecov and subtract ExpRecov
                total_cons += prodcons.import_recovered - prodcons.export_recovered
            rounding_digits = max(rounding_digits, prodcons.decimals)

        average_cons = round_decimal_half_up(total_cons / len(periods),
                                             rounding_digits)
        return average_cons if average_cons > 0 else Decimal('0')
Esempio n. 11
0
    def average_production_bdn(self, party, group, periods):
        total_prod = Decimal('0.0')
        for period in periods:
            prodcons = self._get_prodcons(party, group, period)
            if not prodcons:
                return None
            total_prod += prodcons.production_article_5
            if total_prod > 0:
                # Special case, e.g. France/AI (no production, only transfers)
                total_prod += self._get_bdn_transfer(party, group, period)

        average_prod = round_decimal_half_up(total_prod / len(periods), 5)
        return average_prod if average_prod > 0 else Decimal('0')
Esempio n. 12
0
    def average_production(self, party, group, periods):
        total_prod = Decimal('0.0')
        rounding_digits = 0
        for period in periods:
            prodcons = self._get_prodcons(party, group, period)
            if not prodcons:
                return None
            total_prod += prodcons.calculated_production
            rounding_digits = max(rounding_digits, prodcons.decimals)

        average_prod = round_decimal_half_up(total_prod / len(periods),
                                             rounding_digits)
        return average_prod if average_prod > 0 else Decimal('0')
Esempio n. 13
0
    def baseline(self, baseline, actual):
        # actual is format.value(production/consumption)
        if baseline is value_missing:
            return 'N.R.'

        if baseline is value_not_required:
            return '-'

        if actual is value_not_required:
            return '-'

        if self.round_baseline is not None:
            baseline = round_decimal_half_up(baseline, self.round_baseline)
        return format_decimal(baseline)
Esempio n. 14
0
    def consumption_ci_na5_gwp(self, party, _group, _periods):
        """
            The HFC baseline includes a % of the HCFC baseline
            computed in CO2-equivalent tonnes
            The HCFC baseline formula contains in its turn a percentage of
            the CFC production/consumption
        """
        cfc_group = self.groups.get('AI')
        hcfc_group = self.groups.get('CI')
        hcfc_cons = self._prod_cons_gwp(party, hcfc_group, '1989', 'CONS')
        cfc_cons = self._prod_cons_gwp(party, cfc_group, '1989', 'CONS')
        if hcfc_cons is None or cfc_cons is None:
            return None

        if party.abbr == 'EU':
            # Must add consumption of EU member states
            # which were not member states in 1989
            for _ms in self.new_eu_member_states_since['1989']:
                hcfc_cons_ms = self._prod_cons_gwp(_ms, hcfc_group, '1989',
                                                   'CONS')
                if hcfc_cons_ms is not None and hcfc_cons_ms > 0:
                    hcfc_cons += hcfc_cons_ms
                cfc_cons_ms = self._prod_cons_gwp(_ms, cfc_group, '1989',
                                                  'CONS')
                if cfc_cons_ms is not None and cfc_cons_ms > 0:
                    cfc_cons += cfc_cons_ms
                logger.debug(
                    f"{_ms.abbr} cfc={cfc_cons_ms} hcfc={hcfc_cons_ms}")

        rounded_average = round_decimal_half_up(
            sum((
                round_decimal_half_up(hcfc_cons, 0),
                round_decimal_half_up(cfc_cons, 0) * Decimal('0.028'),
            )),
            0,
        )
        return rounded_average if rounded_average > 0 else Decimal('0')
Esempio n. 15
0
    def consumption(self, party, group, periods):
        if len(periods) != 1:
            raise CalculationError(
                f"Consumption func should have only one period parameter,"
                "got {periods}")
        prodcons = self._get_prodcons(party, group, periods[0])
        if not prodcons:
            return None

        if prodcons.is_eu_member:
            # TODO: re-calculate real consumption
            consumption = round_decimal_half_up(
                prodcons.get_calc_consumption(), prodcons.decimals)
        else:
            consumption = prodcons.calculated_consumption
        return consumption if consumption > 0 else Decimal('0')
Esempio n. 16
0
 def get_entry(self, idx, party, period, group, limit_type, limit):
     return {
         'pk': idx,
         'model': 'core.limit',
         'fields': {
             'party':
             party.pk,
             'reporting_period':
             period.pk,
             'group':
             group.pk,
             'limit_type':
             limit_type,
             'limit':
             round_decimal_half_up(
                 limit, 1 if limit_type == LimitTypes.BDN.value else
                 ProdCons.get_decimals(period, group, party))
         }
     }
Esempio n. 17
0
    def change(self, actual_value, baseline):
        if actual_value in [value_not_required, value_missing]:
            return '-'

        if baseline in [value_not_required, value_missing]:
            return '-'

        if baseline is None:
            return '-'

        if actual_value <= 0:
            # even when baseline was not reported
            return -100

        if baseline == 0:
            return 100

        the_value = actual_value / baseline * 100 - 100
        return format_decimal(round_decimal_half_up(the_value, 2))
Esempio n. 18
0
 def format_value(self, value):
     return format_decimal(round_decimal_half_up(value))
Esempio n. 19
0
    def _prod_cons_f(self, party, _group, _periods, prod_cons,
                     base_party_type):  # noqa: C901
        """
            HFC baseline actually depends on the party group:

            NA5 Group 1: Average HFC for 2011-2013 + 15% of HCFC baseline
            NA5 Group 2: Average HFC for 2011-2013 + 25% of HCFC baseline
             A5 Group 1: Average HFC for 2020–2022 + 65% of HCFC baseline
             A5 Group 2: Average HFC for 2024–2026 + 65% of HCFC baseline
        """

        party_type = self.party_types.get(party.abbr, None)
        if party_type is None:
            # can happen for Palestine or new states
            logger.warning(
                f"No party history for {party.abbr}/{self.current_period.name}"
            )
            return None

        if not party_type.startswith(base_party_type):
            return None

        base_periods = {
            'NA5G1': ('2011', '2012', '2013'),
            'NA5G2': ('2011', '2012', '2013'),
            'A5G1': ('2020', '2021', '2022'),
            'A5G2': ('2024', '2025', '2026'),
        }.get(party_type)

        hfc_group = self.groups.get('F')
        total_amount = Decimal('0.0')
        for period in base_periods:
            prodcons = self._get_prodcons(party, hfc_group, period)
            if not prodcons:
                # If data not reported, no baseline is computed
                return None
            if prod_cons == 'PROD':
                total_amount += prodcons.calculated_production
            elif prod_cons == 'CONS':
                # Check EU membership
                if party in Party.get_eu_members_at(
                        self.reporting_periods[period]):
                    return None
                total_amount += (prodcons.calculated_consumption
                                 if prodcons.calculated_consumption else
                                 Decimal('0'))
        if total_amount < 0:
            total_amount = Decimal('0')

        hcfc_group = self.groups.get('CI')
        hcfc_baseline_type = {
            ('PROD', 'NA5G1'): 'NA5ProdGWP',
            ('PROD', 'NA5G2'): 'NA5ProdGWP',
            ('PROD', 'A5G1'): 'A5ProdGWP',
            ('PROD', 'A5G2'): 'A5ProdGWP',
            ('CONS', 'NA5G1'): 'NA5ConsGWP',
            ('CONS', 'NA5G2'): 'NA5ConsGWP',
            ('CONS', 'A5G1'): 'A5ConsGWP',
            ('CONS', 'A5G2'): 'A5ConsGWP',
        }.get((prod_cons, party_type))
        hcfc_baseline = self.get_baseline(hcfc_baseline_type, hcfc_group,
                                          party)
        if hcfc_baseline is None:
            return None

        rounded_average = round_decimal_half_up(
            sum((
                total_amount / len(base_periods),
                self._get_hcfc_percentage(party) * hcfc_baseline,
            )), 0)
        return rounded_average if rounded_average > 0 else Decimal('0')
Esempio n. 20
0
 def to_cell(x, precision):
     return b_r(format_decimal(round_decimal_half_up(x, precision)))