LCOV - code coverage report
Current view: top level - lib/components/widgets - bill_ytd_chart.dart Coverage Total Hit
Test: lcov.info Lines: 2.0 % 51 1
Test Date: 2026-11-14 15:04:37 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:math';
       5              : 
       6              : import 'package:app_finance/_classes/herald/app_design.dart';
       7              : import 'package:app_finance/_classes/herald/app_locale.dart';
       8              : import 'package:app_finance/_classes/storage/app_data.dart';
       9              : import 'package:app_finance/_classes/structure/bill_app_data.dart';
      10              : import 'package:app_finance/_classes/structure/currency/exchange.dart';
      11              : import 'package:app_finance/_classes/structure/interface_app_data.dart';
      12              : import 'package:app_finance/_configs/theme_helper.dart';
      13              : import 'package:app_finance/_ext/build_context_ext.dart';
      14              : import 'package:app_finance/charts/column_chart.dart';
      15              : import 'package:app_finance/charts/data/data_handler.dart';
      16              : import 'package:app_finance/charts/interface/chart_data.dart';
      17              : import 'package:app_finance/design/wrapper/row_widget.dart';
      18              : import 'package:app_finance/design/wrapper/text_wrapper.dart';
      19              : import 'package:material_ui/material_ui.dart';
      20              : import 'package:provider/provider.dart';
      21              : 
      22              : class BillYtdChart extends StatelessWidget {
      23            2 :   const BillYtdChart({super.key});
      24              : 
      25            0 :   List<ChartData> getData(AppData store) {
      26            0 :     final currentYear = DateTime(DateTime.now().year);
      27            0 :     final prevYear = DateTime(currentYear.year - 1);
      28            0 :     final scope = store.getStream<BillAppData>(AppDataType.bills, filter: (e) => e.createdAt.isBefore(prevYear));
      29              : 
      30            0 :     final exchange = Exchange(store: store);
      31            0 :     return [
      32            0 :       ChartData(
      33            0 :         DataHandler.getAmountGroupedByMonth(
      34            0 :           scope.getTill(0.0 + currentYear.millisecondsSinceEpoch).cast(),
      35              :           exchange: exchange,
      36              :         ),
      37              :         color: Colors.blue,
      38              :       ),
      39            0 :       ChartData(
      40            0 :         DataHandler.getAmountGroupedByMonth(
      41            0 :           scope.toList().cast<InterfaceAppData>().map((e) {
      42            0 :             e.createdAt = e.createdAt.add(const Duration(days: 365));
      43              :             return e;
      44            0 :           }).toList(),
      45              :           exchange: exchange,
      46              :         ),
      47              :         color: Colors.grey,
      48              :       ),
      49              :     ];
      50              :   }
      51              : 
      52            0 :   double getMax(List<ChartData> data) {
      53              :     double yMax = 0;
      54            0 :     if (data.isNotEmpty && data.first.data.isNotEmpty) {
      55            0 :       yMax = data.first.data.reduce((max, current) => current.dy > max.dy ? current : max).dy;
      56            0 :       if (data.last.data.isNotEmpty) {
      57            0 :         double yPrevMax = data.last.data.reduce((max, current) => current.dy > max.dy ? current : max).dy;
      58            0 :         yMax = yMax > yPrevMax ? yMax : yPrevMax;
      59              :       }
      60              :     }
      61              :     return yMax;
      62              :   }
      63              : 
      64            0 :   @override
      65              :   Widget build(BuildContext context) {
      66            0 :     final TextTheme textTheme = context.textTheme;
      67            0 :     final indent = ThemeHelper.getIndent();
      68            0 :     final year = DateTime.now().year;
      69            0 :     return Consumer<AppData>(builder: (context, appState, _) {
      70            0 :       final data = getData(appState);
      71            0 :       return LayoutBuilder(builder: (context, constraints) {
      72            0 :         final width = constraints.maxWidth - indent * 2;
      73            0 :         return Column(
      74            0 :           crossAxisAlignment: AppDesign.getAlignment(),
      75            0 :           children: [
      76            0 :             TextWrapper(
      77            0 :               '${AppLocale.labels.chartYtdExpense}, ${Exchange.defaultCurrency?.code}',
      78            0 :               style: textTheme.bodyLarge,
      79              :             ),
      80            0 :             ColumnChart(
      81              :               width: width,
      82            0 :               height: [constraints.maxHeight - 6 * indent, 200].reduce(min).toDouble(),
      83              :               indent: indent,
      84              :               data: data,
      85            0 :               yMax: getMax(data) * 1.2,
      86              :             ),
      87            0 :             RowWidget(
      88              :               maxWidth: width,
      89              :               indent: indent,
      90              :               chunk: const [null, null],
      91            0 :               children: [
      92            0 :                 [
      93            0 :                   Padding(
      94            0 :                     padding: EdgeInsets.only(left: indent * 2),
      95            0 :                     child: TextWrapper(
      96            0 :                       year.toString(),
      97            0 :                       style: textTheme.bodySmall?.copyWith(color: Colors.blue),
      98              :                     ),
      99              :                   ),
     100              :                 ],
     101            0 :                 [
     102            0 :                   Align(
     103              :                     alignment: Alignment.centerRight,
     104            0 :                     child: TextWrapper(
     105            0 :                       (year - 1).toString(),
     106            0 :                       style: textTheme.bodySmall?.copyWith(color: Colors.grey),
     107              :                     ),
     108              :                   ),
     109              :                 ],
     110              :               ],
     111              :             ),
     112              :           ],
     113              :         );
     114              :       });
     115              :     });
     116              :   }
     117              : }
        

Generated by: LCOV version 2.0-1