Exemple #1
0
    def get_account_billing_periods(self,
                                    account: Account) -> DateIntervalTree:
        ival_tree = DateIntervalTree()
        for meter in account.meters:
            ival_tree.add(meter.IntervalStart, meter.IntervalEnd)
        ival_tree.merge_overlaps()

        return ival_tree
Exemple #2
0
    def get_account_billing_periods(
            self,
            account: Account,
            max_duration: int = 45) -> DateIntervalTree:
        """Extract the usage periods for a given Urjanet Account object

        Recall that the Account object in Urjanet contains data about a given utility account within a single
        statement. This function takes an Account and attempts to compute the "local" billing timeline according
        to that account. The timeline is represented as a DateIntervalTree. The idea is that this "local" timeline
        will be merged with a "global" timeline representing the aggregated state of all Account objects.

        This function will filter out billing periods that are longer than a certain threshold, according
        to the max_duration argument.
        """
        ival_tree = DateIntervalTree()
        for meter in account.meters:
            for usage in meter.usages:
                if self.consider_usage(usage):
                    usage_start = usage.IntervalStart
                    usage_end = usage.IntervalEnd
                    duration = self.get_duration(usage_start, usage_end)
                    # if the total is a single day, use the Meter date range instead
                    if duration == 0:
                        log.debug(
                            "using meter data range for zero-length usage %s",
                            usage.PK)
                        usage_start = meter.IntervalStart
                        usage_end = meter.IntervalEnd
                        if self.get_duration(usage_start, usage_end) == 0:
                            log.info(
                                "Unable to use meter data range for zero-length usage %s",
                                usage.PK,
                            )
                            continue
                    if max_duration and duration > max_duration:
                        log.debug(
                            "Filtering long usage period: {} to {} ({} days)".
                            format(usage_start, usage_end, duration))
                    ival_tree.add(usage_start, usage_end)
            self.fill_in_usage_gaps(meter, ival_tree)
        ival_tree.merge_overlaps()
        return ival_tree