Пример #1
0
    def compute_daily_data(
        self,
        all_time_count,
        all_time_sum,
        days,
        days_names,
        timescales,
        timescale_names,
    ):
        """Compute the “daily data” table."""
        timescale_rows = {num: [name] for num, name in timescale_names.items()}

        for day_count_name in days_names:
            day_count: int = days[day_count_name]
            for num, row in timescale_rows.items():
                current_count = all_time_count * num / day_count
                current_sum = all_time_sum * num / day_count
                row.extend(
                    [round(current_count, 2),
                     format_money(current_sum)])

        daily_data = [timescale_rows[timescale] for timescale in timescales]
        all_time_row = [int(all_time_count), format_money(all_time_sum)]
        daily_data.append([_("All time")] + all_time_row + all_time_row)

        return daily_data
Пример #2
0
    def compute_category_data(self,
                              cat_data,
                              user_categories,
                              days,
                              days_names,
                              timescales,
                              timescale_names,
                              is_html=True):
        cat_totals: typing.Dict[int, typing.Union[float, decimal.Decimal]] = {}

        if is_html:
            cat_tables_headings = [
                format_html(
                    _("Category spending per expense-day (<var>d<sub>E</sub></var> = {})"
                      ), days["expense_days"]),
                format_html(
                    _("Category spending per day (<var>d<sub>A</sub></var> = {})"
                      ), days["all_days"]),
            ]
        else:
            cat_tables_headings = [
                f"{_('Category spending per expense-day dE =')} {days['expense_days']}",
                f"{_('Category spending per day dA =')} {days['all_days']}",
            ]

        cat_tables_contents = []

        # Just in case not all categories have expenses
        cat_data_per_id = {
            cat_id: (cat_count, cat_sum)
            for cat_id, cat_count, cat_sum in cat_data
        }
        user_category_ids = [cat.pk for cat in user_categories]

        for day_count_name in days_names:
            day_count: int = days[day_count_name]
            rows = []
            for timescale in timescales:
                row = [timescale_names[timescale]]
                for category in user_category_ids:
                    cat_count, cat_sum = cat_data_per_id.get(category, (0, 0))
                    current_count = cat_count * timescale / day_count
                    current_sum = cat_sum * timescale / day_count
                    row.extend(
                        [round(current_count, 2),
                         format_money(current_sum)])
                rows.append(row)
            all_time_row = [_("All time")]
            for category in user_category_ids:
                cat_count, cat_sum = cat_data_per_id.get(category, (0, 0))
                all_time_row.extend([cat_count, format_money(cat_sum)])
            rows.append(all_time_row)
            cat_tables_contents.append(rows)

        cat_tables = zip(cat_tables_headings, cat_tables_contents)

        return cat_tables
Пример #3
0
 def display_amount(self):
     """A displayable version of the amount."""
     if self.type == "menu":
         return "—"
     if self.type == "count":
         # Translators: Used to display amounts of count templates
         return format_html(_("×{amount}"),
                            amount=format_money(self.amount))
     return format_money(self.amount)
Пример #4
0
    def preprocess_rows(self, results: typing.Iterable) -> typing.Iterable:
        total_count = 0
        total_amount = 0
        for vendor, count, amount, avg in results:
            url = (
                reverse("expenses:search") +
                "?for=expenses&include=expenses&include=bills&category_all=true&q="
                + urllib.parse.quote_plus(vendor))
            vendor_link = format_html('<a href="{}">{}</a>', url, vendor)
            total_count += count
            total_amount += amount
            yield vendor_link, count, format_money(amount), format_money(avg)

        if total_count > 0:
            yield _("Grand Total"), total_count, format_money(
                total_amount), format_money(total_amount / total_count)
Пример #5
0
    def preprocess_rows(self, results: typing.Iterable) -> typing.Iterable:
        if self.query_type == "month_category":
            user_categories: typing.Iterable[Category] = Category.user_objects(
                self.request)
            user_category_ids: typing.Dict[int, int] = {}
            cat_totals: typing.Dict[int, typing.Union[float,
                                                      decimal.Decimal]] = {}
            for n, cat in enumerate(user_categories, 1):
                user_category_ids[cat.pk] = n
                cat_totals[cat.pk] = 0
            cat_count = len(user_category_ids)
            for yearmonth, items in itertools.groupby(results,
                                                      operator.itemgetter(0)):
                row = [format_yearmonth(yearmonth)
                       ] + [format_money(0)] * cat_count
                row_total = 0
                for _ym, category_id, value in items:
                    row[user_category_ids[category_id]] = format_money(value)
                    row_total += value
                    cat_totals[category_id] += value
                row.append(format_money(row_total))
                yield row

            cat_totals_values = list(cat_totals.values())
            yield [_("Grand Total")] + [
                format_money(i) for i in cat_totals_values
            ] + [format_money(sum(cat_totals_values))]

        elif self.query_type == "month":
            total = 0
            for yearmonth, value in results:
                yield format_yearmonth(yearmonth), format_money(value)
                total += value

            yield _("Grand Total"), format_money(total)
        else:
            # category
            user_categories: typing.Dict[int, Category] = {
                c.pk: c
                for c in Category.user_objects(self.request)
            }
            total = 0
            for category, value in results:
                yield (user_categories[category].html_link(),
                       format_money(value))
                total += value

            yield _("Grand Total"), format_money(total)
Пример #6
0
 def format_money(self, amount: typing.Union[int, float,
                                             decimal.Decimal]) -> str:
     return format_money(amount)