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 : 16 1 : TotalRecalculation({ 17 : required this.exchange, 18 : }); 19 : 20 1 : @override 21 : double getDelta() { 22 1 : throw UnimplementedError(); 23 : } 24 : 25 1 : double updateTotalMap(AppDataType type, String uuid, HashMap<String, dynamic> hashTable) { 26 1 : final item = hashTable[uuid]; 27 1 : if (item == null || item.hidden) { 28 : return 0.0; 29 : } 30 4 : double total = exchange.reform(item.details, item.currency, Exchange.defaultCurrency); 31 1 : if (type == AppDataType.goals) { 32 3 : total *= (1 - item.progress); 33 : } 34 : return total; 35 : } 36 : 37 1 : List<String> getSummaryList(AppDataType type, SummaryAppData? summary) { 38 : if (summary == null) { 39 0 : return []; 40 : } 41 2 : return [AppDataType.bills, AppDataType.budgets, AppDataType.invoice].contains(type) 42 1 : ? summary.listActual 43 1 : : summary.list; 44 : } 45 : 46 1 : Future<void> updateTotal(AppDataType type, SummaryAppData? summary, HashMap<String, dynamic> hashTable) async { 47 1 : final list = getSummaryList(type, summary); 48 2 : summary?.total = list.isEmpty 49 : ? 0.0 50 : : list 51 3 : .map<double>((String uuid) => updateTotalMap(type, uuid, hashTable)) 52 3 : .reduce((value, details) => value + details); 53 : } 54 : 55 1 : void updateGoals(dynamic goalList, double initTotal, double total) { 56 1 : double delta = total - initTotal; 57 1 : if (goalList.isNotEmpty) { 58 : int index = 0; 59 2 : delta /= goalList.length; 60 2 : goalList.forEach((dynamic goal) { 61 1 : index++; 62 : double convDelta = 0; 63 3 : if (delta > 0 && total <= goal.initial) { 64 0 : convDelta = exchange.reform(total, Exchange.defaultCurrency, goal.currency) - goal.initial; 65 : } else { 66 3 : convDelta = exchange.reform(delta, Exchange.defaultCurrency, goal.currency); 67 : } 68 3 : double progress = getProgress(goal.details, goal.progress, convDelta); 69 1 : if (progress > 1.0) { 70 2 : if (index < goalList.length) { 71 8 : delta += exchange.reform(goal.details * (progress - 1.0), goal.currency, Exchange.defaultCurrency) / 72 2 : (goalList.length - index); 73 : } 74 : progress = 1.0; 75 : } 76 7 : if (progress < 1.0 && goal.progress == 1.0 && goal.initial + goal.details < total) { 77 : progress = 1.0; 78 4 : delta += delta / (goalList.length - index); 79 : } 80 1 : if (progress < 0.0) { 81 : progress = 0.0; 82 : } 83 1 : goal.progress = progress; 84 : }); 85 : } 86 : } 87 : }