LCOV - code coverage report
Current view: top level - _classes/math - total_recalculation.dart Coverage Total Hit
Test: lcov.info Lines: 94.4 % 36 34
Test Date: 2026-11-14 15:03:01 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/storage/app_data.dart';
       7              : import 'package:app_finance/_classes/math/abstract_recalculation.dart';
       8              : import 'package:app_finance/_classes/structure/currency/exchange.dart';
       9              : import 'package:app_finance/_classes/structure/summary_app_data.dart';
      10              : 
      11              : class TotalRecalculation extends AbstractRecalculation {
      12              :   @override
      13              :   // ignore: overridden_fields
      14              :   Exchange exchange;
      15              :   bool isBudgetPositive;
      16              : 
      17            1 :   TotalRecalculation({
      18              :     required this.exchange,
      19              :     this.isBudgetPositive = false,
      20              :   });
      21              : 
      22            1 :   @override
      23              :   double getDelta() {
      24            1 :     throw UnimplementedError();
      25              :   }
      26              : 
      27            1 :   double updateTotalMap(AppDataType type, String uuid, HashMap<String, dynamic> hashTable) {
      28            1 :     final item = hashTable[uuid];
      29            2 :     if (item == null || item.hidden || item.skip) {
      30              :       return 0.0;
      31              :     }
      32            4 :     double total = exchange.reform(item.details, item.currency, Exchange.defaultCurrency);
      33            3 :     if (type == AppDataType.budgets && total < 0 && isBudgetPositive) {
      34              :       total = 0.0;
      35              :     }
      36            1 :     if (type == AppDataType.goals) {
      37            3 :       total *= (1 - item.progress);
      38              :     }
      39              :     return total;
      40              :   }
      41              : 
      42            1 :   List<String> getSummaryList(AppDataType type, SummaryAppData? summary) {
      43              :     if (summary == null) {
      44            0 :       return [];
      45              :     }
      46            4 :     return [AppDataType.bills, AppDataType.invoice].contains(type) ? summary.listActual : summary.list;
      47              :   }
      48              : 
      49            1 :   Future<void> updateTotal(AppDataType type, SummaryAppData? summary, HashMap<String, dynamic> hashTable) async {
      50            1 :     final list = getSummaryList(type, summary);
      51            2 :     summary?.total = list.isEmpty
      52              :         ? 0.0
      53              :         : list
      54            3 :             .map<double>((String uuid) => updateTotalMap(type, uuid, hashTable))
      55            3 :             .reduce((value, details) => value + details);
      56              :   }
      57              : 
      58            1 :   void updateGoals(dynamic goalList, double initTotal, double total) {
      59            1 :     double delta = total - initTotal;
      60            1 :     if (goalList.isNotEmpty) {
      61              :       int index = 0;
      62            2 :       delta /= goalList.length;
      63            2 :       goalList.forEach((dynamic goal) {
      64            1 :         index++;
      65              :         double convDelta = 0;
      66            3 :         if (delta > 0 && total <= goal.initial) {
      67            0 :           convDelta = exchange.reform(total, Exchange.defaultCurrency, goal.currency) - goal.initial;
      68              :         } else {
      69            3 :           convDelta = exchange.reform(delta, Exchange.defaultCurrency, goal.currency);
      70              :         }
      71            3 :         double progress = getProgress(goal.details, goal.progress, convDelta);
      72            1 :         if (progress > 1.0) {
      73            2 :           if (index < goalList.length) {
      74            8 :             delta += exchange.reform(goal.details * (progress - 1.0), goal.currency, Exchange.defaultCurrency) /
      75            2 :                 (goalList.length - index);
      76              :           }
      77              :           progress = 1.0;
      78              :         }
      79            7 :         if (progress < 1.0 && goal.progress == 1.0 && goal.initial + goal.details < total) {
      80              :           progress = 1.0;
      81            4 :           delta += delta / (goalList.length - index);
      82              :         }
      83            1 :         if (progress < 0.0) {
      84              :           progress = 0.0;
      85              :         }
      86            1 :         goal.progress = progress;
      87              :       });
      88              :     }
      89              :   }
      90              : }
        

Generated by: LCOV version 2.0-1