LCOV - code coverage report
Current view: top level - lib/charts/data - data_handler.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 31 56 55.4 %
Date: 2024-10-04 11:09:33 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 The terCAD team. All rights reserved.
       2             : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
       3             : 
       4             : import 'dart:collection';
       5             : 
       6             : import 'package:app_finance/_classes/structure/bill_app_data.dart';
       7             : import 'package:app_finance/_classes/structure/budget_app_data.dart';
       8             : import 'package:app_finance/_classes/structure/currency/exchange.dart';
       9             : import 'package:app_finance/_classes/structure/interface_app_data.dart';
      10             : import 'package:app_finance/_classes/structure/transaction_log_data.dart';
      11             : import 'package:app_finance/charts/interface/ohlc_data.dart';
      12             : import 'package:flutter/material.dart';
      13             : 
      14             : typedef DateCallback = double Function(InterfaceAppData item);
      15             : 
      16             : class DataHandler {
      17           0 :   static double countBudgetTotal(List<InterfaceAppData> scope, {required Exchange exchange}) {
      18           0 :     final currency = exchange.getDefaultCurrency();
      19           0 :     return scope.fold(0.0, (v, e) => v + exchange.reform((e as BudgetAppData).amountLimit, e.currency, currency));
      20             :   }
      21             : 
      22           0 :   static List<Offset> getAmountGroupedByCategory(List<BillAppData> scope, List<BudgetAppData> budgets,
      23             :       {required Exchange exchange}) {
      24           0 :     final idx = budgets.map((e) => e.uuid).toList();
      25           0 :     fn(item) => idx.indexWhere((uuid) => uuid == item.category).toDouble();
      26           0 :     return _getGroupedAmount(scope, fn, exchange: exchange);
      27             :   }
      28             : 
      29           0 :   static List<Offset> getAmountGroupedByMonth(List<InterfaceAppData> scope, {required Exchange exchange}) {
      30           0 :     fn(item) => DateTime(item.createdAt.year, item.createdAt.month).millisecondsSinceEpoch.toDouble();
      31           0 :     return _getGroupedAmount(scope, fn, exchange: exchange);
      32             :   }
      33             : 
      34           0 :   static List<Offset> getAmountGroupedByDate(List<InterfaceAppData> scope, {required Exchange exchange}) {
      35           0 :     fn(item) =>
      36           0 :         DateTime(item.createdAt.year, item.createdAt.month, item.createdAt.day).millisecondsSinceEpoch.toDouble();
      37           0 :     return _getGroupedAmount(scope, fn, exchange: exchange);
      38             :   }
      39             : 
      40           0 :   static List<Offset> _getGroupedAmount(List<InterfaceAppData> scope, DateCallback fn, {required Exchange exchange}) {
      41           0 :     final data = SplayTreeMap<dynamic, List<double>>();
      42           0 :     final currency = exchange.getDefaultCurrency();
      43           0 :     for (final item in scope) {
      44           0 :       final actual = fn(item);
      45           0 :       if (actual == -1) {
      46             :         continue;
      47             :       }
      48           0 :       if (data[actual] == null) {
      49           0 :         data[actual] = [];
      50             :       }
      51           0 :       data[actual]!.add(exchange.reform(item.details, item.currency, currency));
      52             :     }
      53           0 :     final List<Offset> result = [];
      54           0 :     data.forEach((key, value) => result.add(Offset(key, value.fold(0.0, (v, e) => v + e))));
      55             :     return result;
      56             :   }
      57             : 
      58           1 :   static List<OhlcData> generateOhlcSummary(List<List<TransactionLogData>?> scope,
      59             :       {required Exchange exchange, DateTime? cut}) {
      60           1 :     final data = scope.firstOrNull;
      61           3 :     for (int i = 1; i < scope.length; i++) {
      62           1 :       if (scope[i] == null || data == null) {
      63             :         continue;
      64             :       }
      65           4 :       data.addAll(scope[i]!.where((e) => cut == null || e.timestamp.isAfter(cut)));
      66             :     }
      67           1 :     if (data != null && data.isNotEmpty) {
      68           5 :       data.sort((a, b) => a.timestamp.compareTo(b.timestamp));
      69           1 :       return _generateOhlc(data, exchange);
      70             :     }
      71           1 :     return [];
      72             :   }
      73             : 
      74           1 :   static List<OhlcData> _generateOhlc(List<TransactionLogData> scope, Exchange exchange) {
      75           1 :     final currency = exchange.getDefaultCurrency();
      76           1 :     final result = SplayTreeMap<DateTime, OhlcData>();
      77             :     double min = 0;
      78             :     double close = 0;
      79           3 :     for (int i = 0; i < scope.length; i++) {
      80          13 :       final key = DateTime(scope[i].timestamp.year, scope[i].timestamp.month, (scope[i].timestamp.day / 7).floor() * 6);
      81           5 :       final value = exchange.reform(scope[i].delta, scope[i].currency, currency);
      82           1 :       if (!result.containsKey(key)) {
      83           5 :         result[key] = OhlcData(date: key, open: close, close: value + close, high: value + close, low: value + close);
      84             :       } else {
      85           3 :         result[key]!.close += value;
      86             :       }
      87           5 :       if (result[key]!.close > result[key]!.high) {
      88           4 :         result[key]!.high = result[key]!.close;
      89             :       }
      90           5 :       if (result[key]!.close < result[key]!.low) {
      91           4 :         result[key]!.low = result[key]!.close;
      92             :       }
      93           3 :       if (min > result[key]!.close) {
      94           2 :         min = result[key]!.close;
      95             :       }
      96           2 :       close = result[key]!.close;
      97             :     }
      98           2 :     for (OhlcData data in result.values) {
      99           2 :       data.open -= min;
     100           2 :       data.close -= min;
     101           2 :       data.high -= min;
     102           2 :       data.low -= min;
     103             :     }
     104           2 :     return result.values.toList();
     105             :   }
     106             : }

Generated by: LCOV version 1.14