From b4a9cf31fcbacd55afc58fdebd7f916044a27a44 Mon Sep 17 00:00:00 2001 From: efrilm Date: Mon, 3 Nov 2025 16:24:11 +0700 Subject: [PATCH] report dashboard --- .../dashboard_analytic_loader_bloc.dart | 53 + ...ashboard_analytic_loader_bloc.freezed.dart | 480 ++++ .../dashboard_analytic_loader_event.dart | 9 + .../dashboard_analytic_loader_state.dart | 16 + lib/application/report/report_state.dart | 4 +- lib/common/extension/datetime_extension.dart | 8 + lib/common/url/api_path.dart | 1 + lib/domain/analytic/analytic.dart | 10 + lib/domain/analytic/analytic.freezed.dart | 1984 +++++++++++++++++ .../analytic/entities/dashboard_entity.dart | 118 + .../analytic/failures/analytic_failure.dart | 9 + .../repositories/i_analytic_repository.dart | 8 + .../analytic/analytic_dtos.dart | 8 + .../analytic/analytic_dtos.freezed.dart | 1747 +++++++++++++++ .../analytic/analytic_dtos.g.dart | 139 ++ .../datasources/remote_data_provider.dart | 50 + .../analytic/dtos/dashboard_dto.dart | 149 ++ .../repositories/analytic_repository.dart | 40 + lib/injection.config.dart | 16 + .../error/analytic_error_state_widget.dart | 43 + .../widgets/report/report_header.dart | 68 + .../widgets/report/report_summary_card.dart | 66 + .../pages/main/pages/report/report_page.dart | 63 +- .../sections/report_dashboard_section.dart | 184 ++ .../dashboard/report_dashboard_order.dart | 138 ++ .../report_dashboard_product_chart.dart | 94 + .../report_dashboard_sales_chart.dart | 170 ++ .../report_dashboard_top_product.dart | 92 + pubspec.lock | 16 + pubspec.yaml | 1 + 30 files changed, 5779 insertions(+), 5 deletions(-) create mode 100644 lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart create mode 100644 lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.freezed.dart create mode 100644 lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_event.dart create mode 100644 lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_state.dart create mode 100644 lib/domain/analytic/analytic.dart create mode 100644 lib/domain/analytic/analytic.freezed.dart create mode 100644 lib/domain/analytic/entities/dashboard_entity.dart create mode 100644 lib/domain/analytic/failures/analytic_failure.dart create mode 100644 lib/domain/analytic/repositories/i_analytic_repository.dart create mode 100644 lib/infrastructure/analytic/analytic_dtos.dart create mode 100644 lib/infrastructure/analytic/analytic_dtos.freezed.dart create mode 100644 lib/infrastructure/analytic/analytic_dtos.g.dart create mode 100644 lib/infrastructure/analytic/datasources/remote_data_provider.dart create mode 100644 lib/infrastructure/analytic/dtos/dashboard_dto.dart create mode 100644 lib/infrastructure/analytic/repositories/analytic_repository.dart create mode 100644 lib/presentation/components/error/analytic_error_state_widget.dart create mode 100644 lib/presentation/components/widgets/report/report_header.dart create mode 100644 lib/presentation/components/widgets/report/report_summary_card.dart create mode 100644 lib/presentation/pages/main/pages/report/sections/report_dashboard_section.dart create mode 100644 lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_order.dart create mode 100644 lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_product_chart.dart create mode 100644 lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_sales_chart.dart create mode 100644 lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_top_product.dart diff --git a/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart new file mode 100644 index 0000000..625aa4a --- /dev/null +++ b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart @@ -0,0 +1,53 @@ +import 'package:bloc/bloc.dart'; +import 'package:dartz/dartz.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../domain/analytic/analytic.dart'; + +part 'dashboard_analytic_loader_event.dart'; +part 'dashboard_analytic_loader_state.dart'; +part 'dashboard_analytic_loader_bloc.freezed.dart'; + +@injectable +class DashboardAnalyticLoaderBloc + extends Bloc { + final IAnalyticRepository _analyticRepository; + + DashboardAnalyticLoaderBloc(this._analyticRepository) + : super(DashboardAnalyticLoaderState.initial()) { + on(_onDashboardAnalyticLoader); + } + + Future _onDashboardAnalyticLoader( + DashboardAnalyticLoaderEvent event, + Emitter emit, + ) { + return event.map( + fetched: (e) async { + emit(state.copyWith(isFetching: true, failureOption: none())); + + final result = await _analyticRepository.getDashboard( + dateFrom: e.startDate, + dateTo: e.endDate, + ); + + await result.fold( + (failure) async { + emit( + state.copyWith( + isFetching: false, + failureOption: optionOf(failure), + ), + ); + }, + (dashboard) async { + emit( + state.copyWith(isFetching: false, dashboardAnalytic: dashboard), + ); + }, + ); + }, + ); + } +} diff --git a/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.freezed.dart b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.freezed.dart new file mode 100644 index 0000000..456ad2d --- /dev/null +++ b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.freezed.dart @@ -0,0 +1,480 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'dashboard_analytic_loader_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +/// @nodoc +mixin _$DashboardAnalyticLoaderEvent { + DateTime get startDate => throw _privateConstructorUsedError; + DateTime get endDate => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult when({ + required TResult Function(DateTime startDate, DateTime endDate) fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(DateTime startDate, DateTime endDate)? fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(DateTime startDate, DateTime endDate)? fetched, + required TResult orElse(), + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Fetched value) fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Fetched value)? fetched, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Fetched value)? fetched, + required TResult orElse(), + }) => throw _privateConstructorUsedError; + + /// Create a copy of DashboardAnalyticLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardAnalyticLoaderEventCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardAnalyticLoaderEventCopyWith<$Res> { + factory $DashboardAnalyticLoaderEventCopyWith( + DashboardAnalyticLoaderEvent value, + $Res Function(DashboardAnalyticLoaderEvent) then, + ) = + _$DashboardAnalyticLoaderEventCopyWithImpl< + $Res, + DashboardAnalyticLoaderEvent + >; + @useResult + $Res call({DateTime startDate, DateTime endDate}); +} + +/// @nodoc +class _$DashboardAnalyticLoaderEventCopyWithImpl< + $Res, + $Val extends DashboardAnalyticLoaderEvent +> + implements $DashboardAnalyticLoaderEventCopyWith<$Res> { + _$DashboardAnalyticLoaderEventCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardAnalyticLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? startDate = null, Object? endDate = null}) { + return _then( + _value.copyWith( + startDate: null == startDate + ? _value.startDate + : startDate // ignore: cast_nullable_to_non_nullable + as DateTime, + endDate: null == endDate + ? _value.endDate + : endDate // ignore: cast_nullable_to_non_nullable + as DateTime, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$FetchedImplCopyWith<$Res> + implements $DashboardAnalyticLoaderEventCopyWith<$Res> { + factory _$$FetchedImplCopyWith( + _$FetchedImpl value, + $Res Function(_$FetchedImpl) then, + ) = __$$FetchedImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({DateTime startDate, DateTime endDate}); +} + +/// @nodoc +class __$$FetchedImplCopyWithImpl<$Res> + extends _$DashboardAnalyticLoaderEventCopyWithImpl<$Res, _$FetchedImpl> + implements _$$FetchedImplCopyWith<$Res> { + __$$FetchedImplCopyWithImpl( + _$FetchedImpl _value, + $Res Function(_$FetchedImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardAnalyticLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? startDate = null, Object? endDate = null}) { + return _then( + _$FetchedImpl( + startDate: null == startDate + ? _value.startDate + : startDate // ignore: cast_nullable_to_non_nullable + as DateTime, + endDate: null == endDate + ? _value.endDate + : endDate // ignore: cast_nullable_to_non_nullable + as DateTime, + ), + ); + } +} + +/// @nodoc + +class _$FetchedImpl implements _Fetched { + const _$FetchedImpl({required this.startDate, required this.endDate}); + + @override + final DateTime startDate; + @override + final DateTime endDate; + + @override + String toString() { + return 'DashboardAnalyticLoaderEvent.fetched(startDate: $startDate, endDate: $endDate)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$FetchedImpl && + (identical(other.startDate, startDate) || + other.startDate == startDate) && + (identical(other.endDate, endDate) || other.endDate == endDate)); + } + + @override + int get hashCode => Object.hash(runtimeType, startDate, endDate); + + /// Create a copy of DashboardAnalyticLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$FetchedImplCopyWith<_$FetchedImpl> get copyWith => + __$$FetchedImplCopyWithImpl<_$FetchedImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(DateTime startDate, DateTime endDate) fetched, + }) { + return fetched(startDate, endDate); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(DateTime startDate, DateTime endDate)? fetched, + }) { + return fetched?.call(startDate, endDate); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(DateTime startDate, DateTime endDate)? fetched, + required TResult orElse(), + }) { + if (fetched != null) { + return fetched(startDate, endDate); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Fetched value) fetched, + }) { + return fetched(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_Fetched value)? fetched, + }) { + return fetched?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Fetched value)? fetched, + required TResult orElse(), + }) { + if (fetched != null) { + return fetched(this); + } + return orElse(); + } +} + +abstract class _Fetched implements DashboardAnalyticLoaderEvent { + const factory _Fetched({ + required final DateTime startDate, + required final DateTime endDate, + }) = _$FetchedImpl; + + @override + DateTime get startDate; + @override + DateTime get endDate; + + /// Create a copy of DashboardAnalyticLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$FetchedImplCopyWith<_$FetchedImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$DashboardAnalyticLoaderState { + DashboardAnalytic get dashboardAnalytic => throw _privateConstructorUsedError; + Option get failureOption => + throw _privateConstructorUsedError; + bool get isFetching => throw _privateConstructorUsedError; + + /// Create a copy of DashboardAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardAnalyticLoaderStateCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardAnalyticLoaderStateCopyWith<$Res> { + factory $DashboardAnalyticLoaderStateCopyWith( + DashboardAnalyticLoaderState value, + $Res Function(DashboardAnalyticLoaderState) then, + ) = + _$DashboardAnalyticLoaderStateCopyWithImpl< + $Res, + DashboardAnalyticLoaderState + >; + @useResult + $Res call({ + DashboardAnalytic dashboardAnalytic, + Option failureOption, + bool isFetching, + }); + + $DashboardAnalyticCopyWith<$Res> get dashboardAnalytic; +} + +/// @nodoc +class _$DashboardAnalyticLoaderStateCopyWithImpl< + $Res, + $Val extends DashboardAnalyticLoaderState +> + implements $DashboardAnalyticLoaderStateCopyWith<$Res> { + _$DashboardAnalyticLoaderStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? dashboardAnalytic = null, + Object? failureOption = null, + Object? isFetching = null, + }) { + return _then( + _value.copyWith( + dashboardAnalytic: null == dashboardAnalytic + ? _value.dashboardAnalytic + : dashboardAnalytic // ignore: cast_nullable_to_non_nullable + as DashboardAnalytic, + failureOption: null == failureOption + ? _value.failureOption + : failureOption // ignore: cast_nullable_to_non_nullable + as Option, + isFetching: null == isFetching + ? _value.isFetching + : isFetching // ignore: cast_nullable_to_non_nullable + as bool, + ) + as $Val, + ); + } + + /// Create a copy of DashboardAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DashboardAnalyticCopyWith<$Res> get dashboardAnalytic { + return $DashboardAnalyticCopyWith<$Res>(_value.dashboardAnalytic, (value) { + return _then(_value.copyWith(dashboardAnalytic: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$DashboardAnalyticLoaderStateImplCopyWith<$Res> + implements $DashboardAnalyticLoaderStateCopyWith<$Res> { + factory _$$DashboardAnalyticLoaderStateImplCopyWith( + _$DashboardAnalyticLoaderStateImpl value, + $Res Function(_$DashboardAnalyticLoaderStateImpl) then, + ) = __$$DashboardAnalyticLoaderStateImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + DashboardAnalytic dashboardAnalytic, + Option failureOption, + bool isFetching, + }); + + @override + $DashboardAnalyticCopyWith<$Res> get dashboardAnalytic; +} + +/// @nodoc +class __$$DashboardAnalyticLoaderStateImplCopyWithImpl<$Res> + extends + _$DashboardAnalyticLoaderStateCopyWithImpl< + $Res, + _$DashboardAnalyticLoaderStateImpl + > + implements _$$DashboardAnalyticLoaderStateImplCopyWith<$Res> { + __$$DashboardAnalyticLoaderStateImplCopyWithImpl( + _$DashboardAnalyticLoaderStateImpl _value, + $Res Function(_$DashboardAnalyticLoaderStateImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? dashboardAnalytic = null, + Object? failureOption = null, + Object? isFetching = null, + }) { + return _then( + _$DashboardAnalyticLoaderStateImpl( + dashboardAnalytic: null == dashboardAnalytic + ? _value.dashboardAnalytic + : dashboardAnalytic // ignore: cast_nullable_to_non_nullable + as DashboardAnalytic, + failureOption: null == failureOption + ? _value.failureOption + : failureOption // ignore: cast_nullable_to_non_nullable + as Option, + isFetching: null == isFetching + ? _value.isFetching + : isFetching // ignore: cast_nullable_to_non_nullable + as bool, + ), + ); + } +} + +/// @nodoc + +class _$DashboardAnalyticLoaderStateImpl + implements _DashboardAnalyticLoaderState { + _$DashboardAnalyticLoaderStateImpl({ + required this.dashboardAnalytic, + required this.failureOption, + this.isFetching = false, + }); + + @override + final DashboardAnalytic dashboardAnalytic; + @override + final Option failureOption; + @override + @JsonKey() + final bool isFetching; + + @override + String toString() { + return 'DashboardAnalyticLoaderState(dashboardAnalytic: $dashboardAnalytic, failureOption: $failureOption, isFetching: $isFetching)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardAnalyticLoaderStateImpl && + (identical(other.dashboardAnalytic, dashboardAnalytic) || + other.dashboardAnalytic == dashboardAnalytic) && + (identical(other.failureOption, failureOption) || + other.failureOption == failureOption) && + (identical(other.isFetching, isFetching) || + other.isFetching == isFetching)); + } + + @override + int get hashCode => + Object.hash(runtimeType, dashboardAnalytic, failureOption, isFetching); + + /// Create a copy of DashboardAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardAnalyticLoaderStateImplCopyWith< + _$DashboardAnalyticLoaderStateImpl + > + get copyWith => + __$$DashboardAnalyticLoaderStateImplCopyWithImpl< + _$DashboardAnalyticLoaderStateImpl + >(this, _$identity); +} + +abstract class _DashboardAnalyticLoaderState + implements DashboardAnalyticLoaderState { + factory _DashboardAnalyticLoaderState({ + required final DashboardAnalytic dashboardAnalytic, + required final Option failureOption, + final bool isFetching, + }) = _$DashboardAnalyticLoaderStateImpl; + + @override + DashboardAnalytic get dashboardAnalytic; + @override + Option get failureOption; + @override + bool get isFetching; + + /// Create a copy of DashboardAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardAnalyticLoaderStateImplCopyWith< + _$DashboardAnalyticLoaderStateImpl + > + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_event.dart b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_event.dart new file mode 100644 index 0000000..f8d2512 --- /dev/null +++ b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_event.dart @@ -0,0 +1,9 @@ +part of 'dashboard_analytic_loader_bloc.dart'; + +@freezed +class DashboardAnalyticLoaderEvent with _$DashboardAnalyticLoaderEvent { + const factory DashboardAnalyticLoaderEvent.fetched({ + required DateTime startDate, + required DateTime endDate, + }) = _Fetched; +} diff --git a/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_state.dart b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_state.dart new file mode 100644 index 0000000..2f1c198 --- /dev/null +++ b/lib/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_state.dart @@ -0,0 +1,16 @@ +part of 'dashboard_analytic_loader_bloc.dart'; + +@freezed +class DashboardAnalyticLoaderState with _$DashboardAnalyticLoaderState { + factory DashboardAnalyticLoaderState({ + required DashboardAnalytic dashboardAnalytic, + required Option failureOption, + @Default(false) bool isFetching, + }) = _DashboardAnalyticLoaderState; + + factory DashboardAnalyticLoaderState.initial() => + DashboardAnalyticLoaderState( + dashboardAnalytic: DashboardAnalytic.empty(), + failureOption: none(), + ); +} diff --git a/lib/application/report/report_state.dart b/lib/application/report/report_state.dart index d4f8e5b..9a4a9c8 100644 --- a/lib/application/report/report_state.dart +++ b/lib/application/report/report_state.dart @@ -12,9 +12,9 @@ class ReportState with _$ReportState { factory ReportState.initial() => ReportState( title: 'Ringkasan Laporan Penjualan', - startDate: DateTime.now(), + startDate: DateTime.now().subtract(const Duration(days: 30)), endDate: DateTime.now(), rangeDateFormatted: - '${DateTime.now().toFormattedDate()} - ${DateTime.now().toFormattedDate()}', + '${DateTime.now().subtract(const Duration(days: 30)).toFormattedDate()} - ${DateTime.now().toFormattedDate()}', ); } diff --git a/lib/common/extension/datetime_extension.dart b/lib/common/extension/datetime_extension.dart index d374907..2ce2834 100644 --- a/lib/common/extension/datetime_extension.dart +++ b/lib/common/extension/datetime_extension.dart @@ -62,4 +62,12 @@ extension DateTimeExt on DateTime { return '$day $month $year, $hour:$minute:$second'; } + + String toServerDate() { + return DateFormat('dd-MM-yyyy').format(this); + } + + String toSimpleMonthDate() { + return DateFormat('dd MMM yyyy').format(this); + } } diff --git a/lib/common/url/api_path.dart b/lib/common/url/api_path.dart index fec0c50..b1e665e 100644 --- a/lib/common/url/api_path.dart +++ b/lib/common/url/api_path.dart @@ -8,4 +8,5 @@ class ApiPath { static const String paymentMethods = '/api/v1/payment-methods'; static const String orders = '/api/v1/orders'; static const String payments = '/api/v1/payments'; + static const String analyticDashboard = '/api/v1/analytics/dashboard'; } diff --git a/lib/domain/analytic/analytic.dart b/lib/domain/analytic/analytic.dart new file mode 100644 index 0000000..230a493 --- /dev/null +++ b/lib/domain/analytic/analytic.dart @@ -0,0 +1,10 @@ +import 'package:dartz/dartz.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../../common/api/api_failure.dart'; + +part 'analytic.freezed.dart'; + +part 'entities/dashboard_entity.dart'; +part 'failures/analytic_failure.dart'; +part 'repositories/i_analytic_repository.dart'; diff --git a/lib/domain/analytic/analytic.freezed.dart b/lib/domain/analytic/analytic.freezed.dart new file mode 100644 index 0000000..02ec136 --- /dev/null +++ b/lib/domain/analytic/analytic.freezed.dart @@ -0,0 +1,1984 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'analytic.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +/// @nodoc +mixin _$DashboardAnalytic { + String get organizationId => throw _privateConstructorUsedError; + String get outletId => throw _privateConstructorUsedError; + String get dateFrom => throw _privateConstructorUsedError; + String get dateTo => throw _privateConstructorUsedError; + DashboardOverview get overview => throw _privateConstructorUsedError; + List get topProducts => + throw _privateConstructorUsedError; + List get paymentMethods => + throw _privateConstructorUsedError; + List get recentSales => + throw _privateConstructorUsedError; + + /// Create a copy of DashboardAnalytic + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardAnalyticCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardAnalyticCopyWith<$Res> { + factory $DashboardAnalyticCopyWith( + DashboardAnalytic value, + $Res Function(DashboardAnalytic) then, + ) = _$DashboardAnalyticCopyWithImpl<$Res, DashboardAnalytic>; + @useResult + $Res call({ + String organizationId, + String outletId, + String dateFrom, + String dateTo, + DashboardOverview overview, + List topProducts, + List paymentMethods, + List recentSales, + }); + + $DashboardOverviewCopyWith<$Res> get overview; +} + +/// @nodoc +class _$DashboardAnalyticCopyWithImpl<$Res, $Val extends DashboardAnalytic> + implements $DashboardAnalyticCopyWith<$Res> { + _$DashboardAnalyticCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardAnalytic + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = null, + Object? outletId = null, + Object? dateFrom = null, + Object? dateTo = null, + Object? overview = null, + Object? topProducts = null, + Object? paymentMethods = null, + Object? recentSales = null, + }) { + return _then( + _value.copyWith( + organizationId: null == organizationId + ? _value.organizationId + : organizationId // ignore: cast_nullable_to_non_nullable + as String, + outletId: null == outletId + ? _value.outletId + : outletId // ignore: cast_nullable_to_non_nullable + as String, + dateFrom: null == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as String, + dateTo: null == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as String, + overview: null == overview + ? _value.overview + : overview // ignore: cast_nullable_to_non_nullable + as DashboardOverview, + topProducts: null == topProducts + ? _value.topProducts + : topProducts // ignore: cast_nullable_to_non_nullable + as List, + paymentMethods: null == paymentMethods + ? _value.paymentMethods + : paymentMethods // ignore: cast_nullable_to_non_nullable + as List, + recentSales: null == recentSales + ? _value.recentSales + : recentSales // ignore: cast_nullable_to_non_nullable + as List, + ) + as $Val, + ); + } + + /// Create a copy of DashboardAnalytic + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DashboardOverviewCopyWith<$Res> get overview { + return $DashboardOverviewCopyWith<$Res>(_value.overview, (value) { + return _then(_value.copyWith(overview: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$DashboardAnalyticImplCopyWith<$Res> + implements $DashboardAnalyticCopyWith<$Res> { + factory _$$DashboardAnalyticImplCopyWith( + _$DashboardAnalyticImpl value, + $Res Function(_$DashboardAnalyticImpl) then, + ) = __$$DashboardAnalyticImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String organizationId, + String outletId, + String dateFrom, + String dateTo, + DashboardOverview overview, + List topProducts, + List paymentMethods, + List recentSales, + }); + + @override + $DashboardOverviewCopyWith<$Res> get overview; +} + +/// @nodoc +class __$$DashboardAnalyticImplCopyWithImpl<$Res> + extends _$DashboardAnalyticCopyWithImpl<$Res, _$DashboardAnalyticImpl> + implements _$$DashboardAnalyticImplCopyWith<$Res> { + __$$DashboardAnalyticImplCopyWithImpl( + _$DashboardAnalyticImpl _value, + $Res Function(_$DashboardAnalyticImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardAnalytic + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = null, + Object? outletId = null, + Object? dateFrom = null, + Object? dateTo = null, + Object? overview = null, + Object? topProducts = null, + Object? paymentMethods = null, + Object? recentSales = null, + }) { + return _then( + _$DashboardAnalyticImpl( + organizationId: null == organizationId + ? _value.organizationId + : organizationId // ignore: cast_nullable_to_non_nullable + as String, + outletId: null == outletId + ? _value.outletId + : outletId // ignore: cast_nullable_to_non_nullable + as String, + dateFrom: null == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as String, + dateTo: null == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as String, + overview: null == overview + ? _value.overview + : overview // ignore: cast_nullable_to_non_nullable + as DashboardOverview, + topProducts: null == topProducts + ? _value._topProducts + : topProducts // ignore: cast_nullable_to_non_nullable + as List, + paymentMethods: null == paymentMethods + ? _value._paymentMethods + : paymentMethods // ignore: cast_nullable_to_non_nullable + as List, + recentSales: null == recentSales + ? _value._recentSales + : recentSales // ignore: cast_nullable_to_non_nullable + as List, + ), + ); + } +} + +/// @nodoc + +class _$DashboardAnalyticImpl implements _DashboardAnalytic { + const _$DashboardAnalyticImpl({ + required this.organizationId, + required this.outletId, + required this.dateFrom, + required this.dateTo, + required this.overview, + required final List topProducts, + required final List paymentMethods, + required final List recentSales, + }) : _topProducts = topProducts, + _paymentMethods = paymentMethods, + _recentSales = recentSales; + + @override + final String organizationId; + @override + final String outletId; + @override + final String dateFrom; + @override + final String dateTo; + @override + final DashboardOverview overview; + final List _topProducts; + @override + List get topProducts { + if (_topProducts is EqualUnmodifiableListView) return _topProducts; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_topProducts); + } + + final List _paymentMethods; + @override + List get paymentMethods { + if (_paymentMethods is EqualUnmodifiableListView) return _paymentMethods; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_paymentMethods); + } + + final List _recentSales; + @override + List get recentSales { + if (_recentSales is EqualUnmodifiableListView) return _recentSales; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_recentSales); + } + + @override + String toString() { + return 'DashboardAnalytic(organizationId: $organizationId, outletId: $outletId, dateFrom: $dateFrom, dateTo: $dateTo, overview: $overview, topProducts: $topProducts, paymentMethods: $paymentMethods, recentSales: $recentSales)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardAnalyticImpl && + (identical(other.organizationId, organizationId) || + other.organizationId == organizationId) && + (identical(other.outletId, outletId) || + other.outletId == outletId) && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo) && + (identical(other.overview, overview) || + other.overview == overview) && + const DeepCollectionEquality().equals( + other._topProducts, + _topProducts, + ) && + const DeepCollectionEquality().equals( + other._paymentMethods, + _paymentMethods, + ) && + const DeepCollectionEquality().equals( + other._recentSales, + _recentSales, + )); + } + + @override + int get hashCode => Object.hash( + runtimeType, + organizationId, + outletId, + dateFrom, + dateTo, + overview, + const DeepCollectionEquality().hash(_topProducts), + const DeepCollectionEquality().hash(_paymentMethods), + const DeepCollectionEquality().hash(_recentSales), + ); + + /// Create a copy of DashboardAnalytic + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardAnalyticImplCopyWith<_$DashboardAnalyticImpl> get copyWith => + __$$DashboardAnalyticImplCopyWithImpl<_$DashboardAnalyticImpl>( + this, + _$identity, + ); +} + +abstract class _DashboardAnalytic implements DashboardAnalytic { + const factory _DashboardAnalytic({ + required final String organizationId, + required final String outletId, + required final String dateFrom, + required final String dateTo, + required final DashboardOverview overview, + required final List topProducts, + required final List paymentMethods, + required final List recentSales, + }) = _$DashboardAnalyticImpl; + + @override + String get organizationId; + @override + String get outletId; + @override + String get dateFrom; + @override + String get dateTo; + @override + DashboardOverview get overview; + @override + List get topProducts; + @override + List get paymentMethods; + @override + List get recentSales; + + /// Create a copy of DashboardAnalytic + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardAnalyticImplCopyWith<_$DashboardAnalyticImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$DashboardOverview { + int get totalSales => throw _privateConstructorUsedError; + int get totalOrders => throw _privateConstructorUsedError; + double get averageOrderValue => throw _privateConstructorUsedError; + int get totalCustomers => throw _privateConstructorUsedError; + int get voidedOrders => throw _privateConstructorUsedError; + int get refundedOrders => throw _privateConstructorUsedError; + + /// Create a copy of DashboardOverview + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardOverviewCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardOverviewCopyWith<$Res> { + factory $DashboardOverviewCopyWith( + DashboardOverview value, + $Res Function(DashboardOverview) then, + ) = _$DashboardOverviewCopyWithImpl<$Res, DashboardOverview>; + @useResult + $Res call({ + int totalSales, + int totalOrders, + double averageOrderValue, + int totalCustomers, + int voidedOrders, + int refundedOrders, + }); +} + +/// @nodoc +class _$DashboardOverviewCopyWithImpl<$Res, $Val extends DashboardOverview> + implements $DashboardOverviewCopyWith<$Res> { + _$DashboardOverviewCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardOverview + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalSales = null, + Object? totalOrders = null, + Object? averageOrderValue = null, + Object? totalCustomers = null, + Object? voidedOrders = null, + Object? refundedOrders = null, + }) { + return _then( + _value.copyWith( + totalSales: null == totalSales + ? _value.totalSales + : totalSales // ignore: cast_nullable_to_non_nullable + as int, + totalOrders: null == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int, + averageOrderValue: null == averageOrderValue + ? _value.averageOrderValue + : averageOrderValue // ignore: cast_nullable_to_non_nullable + as double, + totalCustomers: null == totalCustomers + ? _value.totalCustomers + : totalCustomers // ignore: cast_nullable_to_non_nullable + as int, + voidedOrders: null == voidedOrders + ? _value.voidedOrders + : voidedOrders // ignore: cast_nullable_to_non_nullable + as int, + refundedOrders: null == refundedOrders + ? _value.refundedOrders + : refundedOrders // ignore: cast_nullable_to_non_nullable + as int, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardOverviewImplCopyWith<$Res> + implements $DashboardOverviewCopyWith<$Res> { + factory _$$DashboardOverviewImplCopyWith( + _$DashboardOverviewImpl value, + $Res Function(_$DashboardOverviewImpl) then, + ) = __$$DashboardOverviewImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + int totalSales, + int totalOrders, + double averageOrderValue, + int totalCustomers, + int voidedOrders, + int refundedOrders, + }); +} + +/// @nodoc +class __$$DashboardOverviewImplCopyWithImpl<$Res> + extends _$DashboardOverviewCopyWithImpl<$Res, _$DashboardOverviewImpl> + implements _$$DashboardOverviewImplCopyWith<$Res> { + __$$DashboardOverviewImplCopyWithImpl( + _$DashboardOverviewImpl _value, + $Res Function(_$DashboardOverviewImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardOverview + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalSales = null, + Object? totalOrders = null, + Object? averageOrderValue = null, + Object? totalCustomers = null, + Object? voidedOrders = null, + Object? refundedOrders = null, + }) { + return _then( + _$DashboardOverviewImpl( + totalSales: null == totalSales + ? _value.totalSales + : totalSales // ignore: cast_nullable_to_non_nullable + as int, + totalOrders: null == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int, + averageOrderValue: null == averageOrderValue + ? _value.averageOrderValue + : averageOrderValue // ignore: cast_nullable_to_non_nullable + as double, + totalCustomers: null == totalCustomers + ? _value.totalCustomers + : totalCustomers // ignore: cast_nullable_to_non_nullable + as int, + voidedOrders: null == voidedOrders + ? _value.voidedOrders + : voidedOrders // ignore: cast_nullable_to_non_nullable + as int, + refundedOrders: null == refundedOrders + ? _value.refundedOrders + : refundedOrders // ignore: cast_nullable_to_non_nullable + as int, + ), + ); + } +} + +/// @nodoc + +class _$DashboardOverviewImpl implements _DashboardOverview { + const _$DashboardOverviewImpl({ + required this.totalSales, + required this.totalOrders, + required this.averageOrderValue, + required this.totalCustomers, + required this.voidedOrders, + required this.refundedOrders, + }); + + @override + final int totalSales; + @override + final int totalOrders; + @override + final double averageOrderValue; + @override + final int totalCustomers; + @override + final int voidedOrders; + @override + final int refundedOrders; + + @override + String toString() { + return 'DashboardOverview(totalSales: $totalSales, totalOrders: $totalOrders, averageOrderValue: $averageOrderValue, totalCustomers: $totalCustomers, voidedOrders: $voidedOrders, refundedOrders: $refundedOrders)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardOverviewImpl && + (identical(other.totalSales, totalSales) || + other.totalSales == totalSales) && + (identical(other.totalOrders, totalOrders) || + other.totalOrders == totalOrders) && + (identical(other.averageOrderValue, averageOrderValue) || + other.averageOrderValue == averageOrderValue) && + (identical(other.totalCustomers, totalCustomers) || + other.totalCustomers == totalCustomers) && + (identical(other.voidedOrders, voidedOrders) || + other.voidedOrders == voidedOrders) && + (identical(other.refundedOrders, refundedOrders) || + other.refundedOrders == refundedOrders)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + totalSales, + totalOrders, + averageOrderValue, + totalCustomers, + voidedOrders, + refundedOrders, + ); + + /// Create a copy of DashboardOverview + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardOverviewImplCopyWith<_$DashboardOverviewImpl> get copyWith => + __$$DashboardOverviewImplCopyWithImpl<_$DashboardOverviewImpl>( + this, + _$identity, + ); +} + +abstract class _DashboardOverview implements DashboardOverview { + const factory _DashboardOverview({ + required final int totalSales, + required final int totalOrders, + required final double averageOrderValue, + required final int totalCustomers, + required final int voidedOrders, + required final int refundedOrders, + }) = _$DashboardOverviewImpl; + + @override + int get totalSales; + @override + int get totalOrders; + @override + double get averageOrderValue; + @override + int get totalCustomers; + @override + int get voidedOrders; + @override + int get refundedOrders; + + /// Create a copy of DashboardOverview + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardOverviewImplCopyWith<_$DashboardOverviewImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$DashboardTopProduct { + String get productId => throw _privateConstructorUsedError; + String get productName => throw _privateConstructorUsedError; + String get categoryId => throw _privateConstructorUsedError; + String get categoryName => throw _privateConstructorUsedError; + int get quantitySold => throw _privateConstructorUsedError; + int get revenue => throw _privateConstructorUsedError; + double get averagePrice => throw _privateConstructorUsedError; + int get orderCount => throw _privateConstructorUsedError; + + /// Create a copy of DashboardTopProduct + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardTopProductCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardTopProductCopyWith<$Res> { + factory $DashboardTopProductCopyWith( + DashboardTopProduct value, + $Res Function(DashboardTopProduct) then, + ) = _$DashboardTopProductCopyWithImpl<$Res, DashboardTopProduct>; + @useResult + $Res call({ + String productId, + String productName, + String categoryId, + String categoryName, + int quantitySold, + int revenue, + double averagePrice, + int orderCount, + }); +} + +/// @nodoc +class _$DashboardTopProductCopyWithImpl<$Res, $Val extends DashboardTopProduct> + implements $DashboardTopProductCopyWith<$Res> { + _$DashboardTopProductCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardTopProduct + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? productId = null, + Object? productName = null, + Object? categoryId = null, + Object? categoryName = null, + Object? quantitySold = null, + Object? revenue = null, + Object? averagePrice = null, + Object? orderCount = null, + }) { + return _then( + _value.copyWith( + productId: null == productId + ? _value.productId + : productId // ignore: cast_nullable_to_non_nullable + as String, + productName: null == productName + ? _value.productName + : productName // ignore: cast_nullable_to_non_nullable + as String, + categoryId: null == categoryId + ? _value.categoryId + : categoryId // ignore: cast_nullable_to_non_nullable + as String, + categoryName: null == categoryName + ? _value.categoryName + : categoryName // ignore: cast_nullable_to_non_nullable + as String, + quantitySold: null == quantitySold + ? _value.quantitySold + : quantitySold // ignore: cast_nullable_to_non_nullable + as int, + revenue: null == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int, + averagePrice: null == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as double, + orderCount: null == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardTopProductImplCopyWith<$Res> + implements $DashboardTopProductCopyWith<$Res> { + factory _$$DashboardTopProductImplCopyWith( + _$DashboardTopProductImpl value, + $Res Function(_$DashboardTopProductImpl) then, + ) = __$$DashboardTopProductImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String productId, + String productName, + String categoryId, + String categoryName, + int quantitySold, + int revenue, + double averagePrice, + int orderCount, + }); +} + +/// @nodoc +class __$$DashboardTopProductImplCopyWithImpl<$Res> + extends _$DashboardTopProductCopyWithImpl<$Res, _$DashboardTopProductImpl> + implements _$$DashboardTopProductImplCopyWith<$Res> { + __$$DashboardTopProductImplCopyWithImpl( + _$DashboardTopProductImpl _value, + $Res Function(_$DashboardTopProductImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardTopProduct + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? productId = null, + Object? productName = null, + Object? categoryId = null, + Object? categoryName = null, + Object? quantitySold = null, + Object? revenue = null, + Object? averagePrice = null, + Object? orderCount = null, + }) { + return _then( + _$DashboardTopProductImpl( + productId: null == productId + ? _value.productId + : productId // ignore: cast_nullable_to_non_nullable + as String, + productName: null == productName + ? _value.productName + : productName // ignore: cast_nullable_to_non_nullable + as String, + categoryId: null == categoryId + ? _value.categoryId + : categoryId // ignore: cast_nullable_to_non_nullable + as String, + categoryName: null == categoryName + ? _value.categoryName + : categoryName // ignore: cast_nullable_to_non_nullable + as String, + quantitySold: null == quantitySold + ? _value.quantitySold + : quantitySold // ignore: cast_nullable_to_non_nullable + as int, + revenue: null == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int, + averagePrice: null == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as double, + orderCount: null == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int, + ), + ); + } +} + +/// @nodoc + +class _$DashboardTopProductImpl implements _DashboardTopProduct { + const _$DashboardTopProductImpl({ + required this.productId, + required this.productName, + required this.categoryId, + required this.categoryName, + required this.quantitySold, + required this.revenue, + required this.averagePrice, + required this.orderCount, + }); + + @override + final String productId; + @override + final String productName; + @override + final String categoryId; + @override + final String categoryName; + @override + final int quantitySold; + @override + final int revenue; + @override + final double averagePrice; + @override + final int orderCount; + + @override + String toString() { + return 'DashboardTopProduct(productId: $productId, productName: $productName, categoryId: $categoryId, categoryName: $categoryName, quantitySold: $quantitySold, revenue: $revenue, averagePrice: $averagePrice, orderCount: $orderCount)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardTopProductImpl && + (identical(other.productId, productId) || + other.productId == productId) && + (identical(other.productName, productName) || + other.productName == productName) && + (identical(other.categoryId, categoryId) || + other.categoryId == categoryId) && + (identical(other.categoryName, categoryName) || + other.categoryName == categoryName) && + (identical(other.quantitySold, quantitySold) || + other.quantitySold == quantitySold) && + (identical(other.revenue, revenue) || other.revenue == revenue) && + (identical(other.averagePrice, averagePrice) || + other.averagePrice == averagePrice) && + (identical(other.orderCount, orderCount) || + other.orderCount == orderCount)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + productId, + productName, + categoryId, + categoryName, + quantitySold, + revenue, + averagePrice, + orderCount, + ); + + /// Create a copy of DashboardTopProduct + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardTopProductImplCopyWith<_$DashboardTopProductImpl> get copyWith => + __$$DashboardTopProductImplCopyWithImpl<_$DashboardTopProductImpl>( + this, + _$identity, + ); +} + +abstract class _DashboardTopProduct implements DashboardTopProduct { + const factory _DashboardTopProduct({ + required final String productId, + required final String productName, + required final String categoryId, + required final String categoryName, + required final int quantitySold, + required final int revenue, + required final double averagePrice, + required final int orderCount, + }) = _$DashboardTopProductImpl; + + @override + String get productId; + @override + String get productName; + @override + String get categoryId; + @override + String get categoryName; + @override + int get quantitySold; + @override + int get revenue; + @override + double get averagePrice; + @override + int get orderCount; + + /// Create a copy of DashboardTopProduct + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardTopProductImplCopyWith<_$DashboardTopProductImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$DashboardPaymentMethod { + String get paymentMethodId => throw _privateConstructorUsedError; + String get paymentMethodName => throw _privateConstructorUsedError; + String get paymentMethodType => throw _privateConstructorUsedError; + int get totalAmount => throw _privateConstructorUsedError; + int get orderCount => throw _privateConstructorUsedError; + int get paymentCount => throw _privateConstructorUsedError; + double get percentage => throw _privateConstructorUsedError; + + /// Create a copy of DashboardPaymentMethod + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardPaymentMethodCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardPaymentMethodCopyWith<$Res> { + factory $DashboardPaymentMethodCopyWith( + DashboardPaymentMethod value, + $Res Function(DashboardPaymentMethod) then, + ) = _$DashboardPaymentMethodCopyWithImpl<$Res, DashboardPaymentMethod>; + @useResult + $Res call({ + String paymentMethodId, + String paymentMethodName, + String paymentMethodType, + int totalAmount, + int orderCount, + int paymentCount, + double percentage, + }); +} + +/// @nodoc +class _$DashboardPaymentMethodCopyWithImpl< + $Res, + $Val extends DashboardPaymentMethod +> + implements $DashboardPaymentMethodCopyWith<$Res> { + _$DashboardPaymentMethodCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardPaymentMethod + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paymentMethodId = null, + Object? paymentMethodName = null, + Object? paymentMethodType = null, + Object? totalAmount = null, + Object? orderCount = null, + Object? paymentCount = null, + Object? percentage = null, + }) { + return _then( + _value.copyWith( + paymentMethodId: null == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String, + paymentMethodName: null == paymentMethodName + ? _value.paymentMethodName + : paymentMethodName // ignore: cast_nullable_to_non_nullable + as String, + paymentMethodType: null == paymentMethodType + ? _value.paymentMethodType + : paymentMethodType // ignore: cast_nullable_to_non_nullable + as String, + totalAmount: null == totalAmount + ? _value.totalAmount + : totalAmount // ignore: cast_nullable_to_non_nullable + as int, + orderCount: null == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int, + paymentCount: null == paymentCount + ? _value.paymentCount + : paymentCount // ignore: cast_nullable_to_non_nullable + as int, + percentage: null == percentage + ? _value.percentage + : percentage // ignore: cast_nullable_to_non_nullable + as double, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardPaymentMethodImplCopyWith<$Res> + implements $DashboardPaymentMethodCopyWith<$Res> { + factory _$$DashboardPaymentMethodImplCopyWith( + _$DashboardPaymentMethodImpl value, + $Res Function(_$DashboardPaymentMethodImpl) then, + ) = __$$DashboardPaymentMethodImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String paymentMethodId, + String paymentMethodName, + String paymentMethodType, + int totalAmount, + int orderCount, + int paymentCount, + double percentage, + }); +} + +/// @nodoc +class __$$DashboardPaymentMethodImplCopyWithImpl<$Res> + extends + _$DashboardPaymentMethodCopyWithImpl<$Res, _$DashboardPaymentMethodImpl> + implements _$$DashboardPaymentMethodImplCopyWith<$Res> { + __$$DashboardPaymentMethodImplCopyWithImpl( + _$DashboardPaymentMethodImpl _value, + $Res Function(_$DashboardPaymentMethodImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardPaymentMethod + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paymentMethodId = null, + Object? paymentMethodName = null, + Object? paymentMethodType = null, + Object? totalAmount = null, + Object? orderCount = null, + Object? paymentCount = null, + Object? percentage = null, + }) { + return _then( + _$DashboardPaymentMethodImpl( + paymentMethodId: null == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String, + paymentMethodName: null == paymentMethodName + ? _value.paymentMethodName + : paymentMethodName // ignore: cast_nullable_to_non_nullable + as String, + paymentMethodType: null == paymentMethodType + ? _value.paymentMethodType + : paymentMethodType // ignore: cast_nullable_to_non_nullable + as String, + totalAmount: null == totalAmount + ? _value.totalAmount + : totalAmount // ignore: cast_nullable_to_non_nullable + as int, + orderCount: null == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int, + paymentCount: null == paymentCount + ? _value.paymentCount + : paymentCount // ignore: cast_nullable_to_non_nullable + as int, + percentage: null == percentage + ? _value.percentage + : percentage // ignore: cast_nullable_to_non_nullable + as double, + ), + ); + } +} + +/// @nodoc + +class _$DashboardPaymentMethodImpl implements _DashboardPaymentMethod { + const _$DashboardPaymentMethodImpl({ + required this.paymentMethodId, + required this.paymentMethodName, + required this.paymentMethodType, + required this.totalAmount, + required this.orderCount, + required this.paymentCount, + required this.percentage, + }); + + @override + final String paymentMethodId; + @override + final String paymentMethodName; + @override + final String paymentMethodType; + @override + final int totalAmount; + @override + final int orderCount; + @override + final int paymentCount; + @override + final double percentage; + + @override + String toString() { + return 'DashboardPaymentMethod(paymentMethodId: $paymentMethodId, paymentMethodName: $paymentMethodName, paymentMethodType: $paymentMethodType, totalAmount: $totalAmount, orderCount: $orderCount, paymentCount: $paymentCount, percentage: $percentage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardPaymentMethodImpl && + (identical(other.paymentMethodId, paymentMethodId) || + other.paymentMethodId == paymentMethodId) && + (identical(other.paymentMethodName, paymentMethodName) || + other.paymentMethodName == paymentMethodName) && + (identical(other.paymentMethodType, paymentMethodType) || + other.paymentMethodType == paymentMethodType) && + (identical(other.totalAmount, totalAmount) || + other.totalAmount == totalAmount) && + (identical(other.orderCount, orderCount) || + other.orderCount == orderCount) && + (identical(other.paymentCount, paymentCount) || + other.paymentCount == paymentCount) && + (identical(other.percentage, percentage) || + other.percentage == percentage)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + paymentMethodId, + paymentMethodName, + paymentMethodType, + totalAmount, + orderCount, + paymentCount, + percentage, + ); + + /// Create a copy of DashboardPaymentMethod + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardPaymentMethodImplCopyWith<_$DashboardPaymentMethodImpl> + get copyWith => + __$$DashboardPaymentMethodImplCopyWithImpl<_$DashboardPaymentMethodImpl>( + this, + _$identity, + ); +} + +abstract class _DashboardPaymentMethod implements DashboardPaymentMethod { + const factory _DashboardPaymentMethod({ + required final String paymentMethodId, + required final String paymentMethodName, + required final String paymentMethodType, + required final int totalAmount, + required final int orderCount, + required final int paymentCount, + required final double percentage, + }) = _$DashboardPaymentMethodImpl; + + @override + String get paymentMethodId; + @override + String get paymentMethodName; + @override + String get paymentMethodType; + @override + int get totalAmount; + @override + int get orderCount; + @override + int get paymentCount; + @override + double get percentage; + + /// Create a copy of DashboardPaymentMethod + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardPaymentMethodImplCopyWith<_$DashboardPaymentMethodImpl> + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$DashboardRecentSale { + String get date => throw _privateConstructorUsedError; + int get sales => throw _privateConstructorUsedError; + int get orders => throw _privateConstructorUsedError; + int get items => throw _privateConstructorUsedError; + int get tax => throw _privateConstructorUsedError; + int get discount => throw _privateConstructorUsedError; + int get netSales => throw _privateConstructorUsedError; + + /// Create a copy of DashboardRecentSale + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardRecentSaleCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardRecentSaleCopyWith<$Res> { + factory $DashboardRecentSaleCopyWith( + DashboardRecentSale value, + $Res Function(DashboardRecentSale) then, + ) = _$DashboardRecentSaleCopyWithImpl<$Res, DashboardRecentSale>; + @useResult + $Res call({ + String date, + int sales, + int orders, + int items, + int tax, + int discount, + int netSales, + }); +} + +/// @nodoc +class _$DashboardRecentSaleCopyWithImpl<$Res, $Val extends DashboardRecentSale> + implements $DashboardRecentSaleCopyWith<$Res> { + _$DashboardRecentSaleCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardRecentSale + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = null, + Object? sales = null, + Object? orders = null, + Object? items = null, + Object? tax = null, + Object? discount = null, + Object? netSales = null, + }) { + return _then( + _value.copyWith( + date: null == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String, + sales: null == sales + ? _value.sales + : sales // ignore: cast_nullable_to_non_nullable + as int, + orders: null == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int, + items: null == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as int, + tax: null == tax + ? _value.tax + : tax // ignore: cast_nullable_to_non_nullable + as int, + discount: null == discount + ? _value.discount + : discount // ignore: cast_nullable_to_non_nullable + as int, + netSales: null == netSales + ? _value.netSales + : netSales // ignore: cast_nullable_to_non_nullable + as int, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardRecentSaleImplCopyWith<$Res> + implements $DashboardRecentSaleCopyWith<$Res> { + factory _$$DashboardRecentSaleImplCopyWith( + _$DashboardRecentSaleImpl value, + $Res Function(_$DashboardRecentSaleImpl) then, + ) = __$$DashboardRecentSaleImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String date, + int sales, + int orders, + int items, + int tax, + int discount, + int netSales, + }); +} + +/// @nodoc +class __$$DashboardRecentSaleImplCopyWithImpl<$Res> + extends _$DashboardRecentSaleCopyWithImpl<$Res, _$DashboardRecentSaleImpl> + implements _$$DashboardRecentSaleImplCopyWith<$Res> { + __$$DashboardRecentSaleImplCopyWithImpl( + _$DashboardRecentSaleImpl _value, + $Res Function(_$DashboardRecentSaleImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardRecentSale + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = null, + Object? sales = null, + Object? orders = null, + Object? items = null, + Object? tax = null, + Object? discount = null, + Object? netSales = null, + }) { + return _then( + _$DashboardRecentSaleImpl( + date: null == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String, + sales: null == sales + ? _value.sales + : sales // ignore: cast_nullable_to_non_nullable + as int, + orders: null == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int, + items: null == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as int, + tax: null == tax + ? _value.tax + : tax // ignore: cast_nullable_to_non_nullable + as int, + discount: null == discount + ? _value.discount + : discount // ignore: cast_nullable_to_non_nullable + as int, + netSales: null == netSales + ? _value.netSales + : netSales // ignore: cast_nullable_to_non_nullable + as int, + ), + ); + } +} + +/// @nodoc + +class _$DashboardRecentSaleImpl implements _DashboardRecentSale { + const _$DashboardRecentSaleImpl({ + required this.date, + required this.sales, + required this.orders, + required this.items, + required this.tax, + required this.discount, + required this.netSales, + }); + + @override + final String date; + @override + final int sales; + @override + final int orders; + @override + final int items; + @override + final int tax; + @override + final int discount; + @override + final int netSales; + + @override + String toString() { + return 'DashboardRecentSale(date: $date, sales: $sales, orders: $orders, items: $items, tax: $tax, discount: $discount, netSales: $netSales)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardRecentSaleImpl && + (identical(other.date, date) || other.date == date) && + (identical(other.sales, sales) || other.sales == sales) && + (identical(other.orders, orders) || other.orders == orders) && + (identical(other.items, items) || other.items == items) && + (identical(other.tax, tax) || other.tax == tax) && + (identical(other.discount, discount) || + other.discount == discount) && + (identical(other.netSales, netSales) || + other.netSales == netSales)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + date, + sales, + orders, + items, + tax, + discount, + netSales, + ); + + /// Create a copy of DashboardRecentSale + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardRecentSaleImplCopyWith<_$DashboardRecentSaleImpl> get copyWith => + __$$DashboardRecentSaleImplCopyWithImpl<_$DashboardRecentSaleImpl>( + this, + _$identity, + ); +} + +abstract class _DashboardRecentSale implements DashboardRecentSale { + const factory _DashboardRecentSale({ + required final String date, + required final int sales, + required final int orders, + required final int items, + required final int tax, + required final int discount, + required final int netSales, + }) = _$DashboardRecentSaleImpl; + + @override + String get date; + @override + int get sales; + @override + int get orders; + @override + int get items; + @override + int get tax; + @override + int get discount; + @override + int get netSales; + + /// Create a copy of DashboardRecentSale + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardRecentSaleImplCopyWith<_$DashboardRecentSaleImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$AnalyticFailure { + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $AnalyticFailureCopyWith<$Res> { + factory $AnalyticFailureCopyWith( + AnalyticFailure value, + $Res Function(AnalyticFailure) then, + ) = _$AnalyticFailureCopyWithImpl<$Res, AnalyticFailure>; +} + +/// @nodoc +class _$AnalyticFailureCopyWithImpl<$Res, $Val extends AnalyticFailure> + implements $AnalyticFailureCopyWith<$Res> { + _$AnalyticFailureCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$ServerErrorImplCopyWith<$Res> { + factory _$$ServerErrorImplCopyWith( + _$ServerErrorImpl value, + $Res Function(_$ServerErrorImpl) then, + ) = __$$ServerErrorImplCopyWithImpl<$Res>; + @useResult + $Res call({ApiFailure failure}); + + $ApiFailureCopyWith<$Res> get failure; +} + +/// @nodoc +class __$$ServerErrorImplCopyWithImpl<$Res> + extends _$AnalyticFailureCopyWithImpl<$Res, _$ServerErrorImpl> + implements _$$ServerErrorImplCopyWith<$Res> { + __$$ServerErrorImplCopyWithImpl( + _$ServerErrorImpl _value, + $Res Function(_$ServerErrorImpl) _then, + ) : super(_value, _then); + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? failure = null}) { + return _then( + _$ServerErrorImpl( + null == failure + ? _value.failure + : failure // ignore: cast_nullable_to_non_nullable + as ApiFailure, + ), + ); + } + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ApiFailureCopyWith<$Res> get failure { + return $ApiFailureCopyWith<$Res>(_value.failure, (value) { + return _then(_value.copyWith(failure: value)); + }); + } +} + +/// @nodoc + +class _$ServerErrorImpl implements _ServerError { + const _$ServerErrorImpl(this.failure); + + @override + final ApiFailure failure; + + @override + String toString() { + return 'AnalyticFailure.serverError(failure: $failure)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ServerErrorImpl && + (identical(other.failure, failure) || other.failure == failure)); + } + + @override + int get hashCode => Object.hash(runtimeType, failure); + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith => + __$$ServerErrorImplCopyWithImpl<_$ServerErrorImpl>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) { + return serverError(failure); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) { + return serverError?.call(failure); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (serverError != null) { + return serverError(failure); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) { + return serverError(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) { + return serverError?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (serverError != null) { + return serverError(this); + } + return orElse(); + } +} + +abstract class _ServerError implements AnalyticFailure { + const factory _ServerError(final ApiFailure failure) = _$ServerErrorImpl; + + ApiFailure get failure; + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ServerErrorImplCopyWith<_$ServerErrorImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$UnexpectedErrorImplCopyWith<$Res> { + factory _$$UnexpectedErrorImplCopyWith( + _$UnexpectedErrorImpl value, + $Res Function(_$UnexpectedErrorImpl) then, + ) = __$$UnexpectedErrorImplCopyWithImpl<$Res>; +} + +/// @nodoc +class __$$UnexpectedErrorImplCopyWithImpl<$Res> + extends _$AnalyticFailureCopyWithImpl<$Res, _$UnexpectedErrorImpl> + implements _$$UnexpectedErrorImplCopyWith<$Res> { + __$$UnexpectedErrorImplCopyWithImpl( + _$UnexpectedErrorImpl _value, + $Res Function(_$UnexpectedErrorImpl) _then, + ) : super(_value, _then); + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc + +class _$UnexpectedErrorImpl implements _UnexpectedError { + const _$UnexpectedErrorImpl(); + + @override + String toString() { + return 'AnalyticFailure.unexpectedError()'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$UnexpectedErrorImpl); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) { + return unexpectedError(); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) { + return unexpectedError?.call(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (unexpectedError != null) { + return unexpectedError(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) { + return unexpectedError(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) { + return unexpectedError?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (unexpectedError != null) { + return unexpectedError(this); + } + return orElse(); + } +} + +abstract class _UnexpectedError implements AnalyticFailure { + const factory _UnexpectedError() = _$UnexpectedErrorImpl; +} + +/// @nodoc +abstract class _$$DynamicErrorMessageImplCopyWith<$Res> { + factory _$$DynamicErrorMessageImplCopyWith( + _$DynamicErrorMessageImpl value, + $Res Function(_$DynamicErrorMessageImpl) then, + ) = __$$DynamicErrorMessageImplCopyWithImpl<$Res>; + @useResult + $Res call({String erroMessage}); +} + +/// @nodoc +class __$$DynamicErrorMessageImplCopyWithImpl<$Res> + extends _$AnalyticFailureCopyWithImpl<$Res, _$DynamicErrorMessageImpl> + implements _$$DynamicErrorMessageImplCopyWith<$Res> { + __$$DynamicErrorMessageImplCopyWithImpl( + _$DynamicErrorMessageImpl _value, + $Res Function(_$DynamicErrorMessageImpl) _then, + ) : super(_value, _then); + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? erroMessage = null}) { + return _then( + _$DynamicErrorMessageImpl( + null == erroMessage + ? _value.erroMessage + : erroMessage // ignore: cast_nullable_to_non_nullable + as String, + ), + ); + } +} + +/// @nodoc + +class _$DynamicErrorMessageImpl implements _DynamicErrorMessage { + const _$DynamicErrorMessageImpl(this.erroMessage); + + @override + final String erroMessage; + + @override + String toString() { + return 'AnalyticFailure.dynamicErrorMessage(erroMessage: $erroMessage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DynamicErrorMessageImpl && + (identical(other.erroMessage, erroMessage) || + other.erroMessage == erroMessage)); + } + + @override + int get hashCode => Object.hash(runtimeType, erroMessage); + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith => + __$$DynamicErrorMessageImplCopyWithImpl<_$DynamicErrorMessageImpl>( + this, + _$identity, + ); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(ApiFailure failure) serverError, + required TResult Function() unexpectedError, + required TResult Function(String erroMessage) dynamicErrorMessage, + }) { + return dynamicErrorMessage(erroMessage); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(ApiFailure failure)? serverError, + TResult? Function()? unexpectedError, + TResult? Function(String erroMessage)? dynamicErrorMessage, + }) { + return dynamicErrorMessage?.call(erroMessage); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(ApiFailure failure)? serverError, + TResult Function()? unexpectedError, + TResult Function(String erroMessage)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (dynamicErrorMessage != null) { + return dynamicErrorMessage(erroMessage); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_ServerError value) serverError, + required TResult Function(_UnexpectedError value) unexpectedError, + required TResult Function(_DynamicErrorMessage value) dynamicErrorMessage, + }) { + return dynamicErrorMessage(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_ServerError value)? serverError, + TResult? Function(_UnexpectedError value)? unexpectedError, + TResult? Function(_DynamicErrorMessage value)? dynamicErrorMessage, + }) { + return dynamicErrorMessage?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_ServerError value)? serverError, + TResult Function(_UnexpectedError value)? unexpectedError, + TResult Function(_DynamicErrorMessage value)? dynamicErrorMessage, + required TResult orElse(), + }) { + if (dynamicErrorMessage != null) { + return dynamicErrorMessage(this); + } + return orElse(); + } +} + +abstract class _DynamicErrorMessage implements AnalyticFailure { + const factory _DynamicErrorMessage(final String erroMessage) = + _$DynamicErrorMessageImpl; + + String get erroMessage; + + /// Create a copy of AnalyticFailure + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DynamicErrorMessageImplCopyWith<_$DynamicErrorMessageImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/domain/analytic/entities/dashboard_entity.dart b/lib/domain/analytic/entities/dashboard_entity.dart new file mode 100644 index 0000000..204c85b --- /dev/null +++ b/lib/domain/analytic/entities/dashboard_entity.dart @@ -0,0 +1,118 @@ +part of '../analytic.dart'; + +@freezed +class DashboardAnalytic with _$DashboardAnalytic { + const factory DashboardAnalytic({ + required String organizationId, + required String outletId, + required String dateFrom, + required String dateTo, + required DashboardOverview overview, + required List topProducts, + required List paymentMethods, + required List recentSales, + }) = _DashboardAnalytic; + + factory DashboardAnalytic.empty() => DashboardAnalytic( + organizationId: '', + outletId: '', + dateFrom: '', + dateTo: '', + overview: DashboardOverview.empty(), + topProducts: const [], + paymentMethods: const [], + recentSales: const [], + ); +} + +@freezed +class DashboardOverview with _$DashboardOverview { + const factory DashboardOverview({ + required int totalSales, + required int totalOrders, + required double averageOrderValue, + required int totalCustomers, + required int voidedOrders, + required int refundedOrders, + }) = _DashboardOverview; + + factory DashboardOverview.empty() => const DashboardOverview( + totalSales: 0, + totalOrders: 0, + averageOrderValue: 0.0, + totalCustomers: 0, + voidedOrders: 0, + refundedOrders: 0, + ); +} + +@freezed +class DashboardTopProduct with _$DashboardTopProduct { + const factory DashboardTopProduct({ + required String productId, + required String productName, + required String categoryId, + required String categoryName, + required int quantitySold, + required int revenue, + required double averagePrice, + required int orderCount, + }) = _DashboardTopProduct; + + factory DashboardTopProduct.empty() => const DashboardTopProduct( + productId: '', + productName: '', + categoryId: '', + categoryName: '', + quantitySold: 0, + revenue: 0, + averagePrice: 0.0, + orderCount: 0, + ); +} + +@freezed +class DashboardPaymentMethod with _$DashboardPaymentMethod { + const factory DashboardPaymentMethod({ + required String paymentMethodId, + required String paymentMethodName, + required String paymentMethodType, + required int totalAmount, + required int orderCount, + required int paymentCount, + required double percentage, + }) = _DashboardPaymentMethod; + + factory DashboardPaymentMethod.empty() => const DashboardPaymentMethod( + paymentMethodId: '', + paymentMethodName: '', + paymentMethodType: '', + totalAmount: 0, + orderCount: 0, + paymentCount: 0, + percentage: 0.0, + ); +} + +@freezed +class DashboardRecentSale with _$DashboardRecentSale { + const factory DashboardRecentSale({ + required String date, + required int sales, + required int orders, + required int items, + required int tax, + required int discount, + required int netSales, + }) = _DashboardRecentSale; + + factory DashboardRecentSale.empty() => const DashboardRecentSale( + date: '', + sales: 0, + orders: 0, + items: 0, + tax: 0, + discount: 0, + netSales: 0, + ); +} diff --git a/lib/domain/analytic/failures/analytic_failure.dart b/lib/domain/analytic/failures/analytic_failure.dart new file mode 100644 index 0000000..0f5efb9 --- /dev/null +++ b/lib/domain/analytic/failures/analytic_failure.dart @@ -0,0 +1,9 @@ +part of '../analytic.dart'; + +@freezed +sealed class AnalyticFailure with _$AnalyticFailure { + const factory AnalyticFailure.serverError(ApiFailure failure) = _ServerError; + const factory AnalyticFailure.unexpectedError() = _UnexpectedError; + const factory AnalyticFailure.dynamicErrorMessage(String erroMessage) = + _DynamicErrorMessage; +} diff --git a/lib/domain/analytic/repositories/i_analytic_repository.dart b/lib/domain/analytic/repositories/i_analytic_repository.dart new file mode 100644 index 0000000..68d076c --- /dev/null +++ b/lib/domain/analytic/repositories/i_analytic_repository.dart @@ -0,0 +1,8 @@ +part of '../analytic.dart'; + +abstract class IAnalyticRepository { + Future> getDashboard({ + required DateTime dateFrom, + required DateTime dateTo, + }); +} diff --git a/lib/infrastructure/analytic/analytic_dtos.dart b/lib/infrastructure/analytic/analytic_dtos.dart new file mode 100644 index 0000000..2b3e121 --- /dev/null +++ b/lib/infrastructure/analytic/analytic_dtos.dart @@ -0,0 +1,8 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../../domain/analytic/analytic.dart'; + +part 'analytic_dtos.freezed.dart'; +part 'analytic_dtos.g.dart'; + +part 'dtos/dashboard_dto.dart'; diff --git a/lib/infrastructure/analytic/analytic_dtos.freezed.dart b/lib/infrastructure/analytic/analytic_dtos.freezed.dart new file mode 100644 index 0000000..232f737 --- /dev/null +++ b/lib/infrastructure/analytic/analytic_dtos.freezed.dart @@ -0,0 +1,1747 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'analytic_dtos.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models', +); + +DashboardAnalyticDto _$DashboardAnalyticDtoFromJson(Map json) { + return _DashboardAnalyticDto.fromJson(json); +} + +/// @nodoc +mixin _$DashboardAnalyticDto { + @JsonKey(name: "organization_id") + String? get organizationId => throw _privateConstructorUsedError; + @JsonKey(name: "outlet_id") + String? get outletId => throw _privateConstructorUsedError; + @JsonKey(name: "date_from") + String? get dateFrom => throw _privateConstructorUsedError; + @JsonKey(name: "date_to") + String? get dateTo => throw _privateConstructorUsedError; + @JsonKey(name: "overview") + DashboardOverviewDto? get overview => throw _privateConstructorUsedError; + @JsonKey(name: "top_products") + List? get topProducts => + throw _privateConstructorUsedError; + @JsonKey(name: "payment_methods") + List? get paymentMethods => + throw _privateConstructorUsedError; + @JsonKey(name: "recent_sales") + List? get recentSales => + throw _privateConstructorUsedError; + + /// Serializes this DashboardAnalyticDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DashboardAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardAnalyticDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardAnalyticDtoCopyWith<$Res> { + factory $DashboardAnalyticDtoCopyWith( + DashboardAnalyticDto value, + $Res Function(DashboardAnalyticDto) then, + ) = _$DashboardAnalyticDtoCopyWithImpl<$Res, DashboardAnalyticDto>; + @useResult + $Res call({ + @JsonKey(name: "organization_id") String? organizationId, + @JsonKey(name: "outlet_id") String? outletId, + @JsonKey(name: "date_from") String? dateFrom, + @JsonKey(name: "date_to") String? dateTo, + @JsonKey(name: "overview") DashboardOverviewDto? overview, + @JsonKey(name: "top_products") List? topProducts, + @JsonKey(name: "payment_methods") + List? paymentMethods, + @JsonKey(name: "recent_sales") List? recentSales, + }); + + $DashboardOverviewDtoCopyWith<$Res>? get overview; +} + +/// @nodoc +class _$DashboardAnalyticDtoCopyWithImpl< + $Res, + $Val extends DashboardAnalyticDto +> + implements $DashboardAnalyticDtoCopyWith<$Res> { + _$DashboardAnalyticDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = freezed, + Object? outletId = freezed, + Object? dateFrom = freezed, + Object? dateTo = freezed, + Object? overview = freezed, + Object? topProducts = freezed, + Object? paymentMethods = freezed, + Object? recentSales = freezed, + }) { + return _then( + _value.copyWith( + organizationId: freezed == organizationId + ? _value.organizationId + : organizationId // ignore: cast_nullable_to_non_nullable + as String?, + outletId: freezed == outletId + ? _value.outletId + : outletId // ignore: cast_nullable_to_non_nullable + as String?, + dateFrom: freezed == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as String?, + dateTo: freezed == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as String?, + overview: freezed == overview + ? _value.overview + : overview // ignore: cast_nullable_to_non_nullable + as DashboardOverviewDto?, + topProducts: freezed == topProducts + ? _value.topProducts + : topProducts // ignore: cast_nullable_to_non_nullable + as List?, + paymentMethods: freezed == paymentMethods + ? _value.paymentMethods + : paymentMethods // ignore: cast_nullable_to_non_nullable + as List?, + recentSales: freezed == recentSales + ? _value.recentSales + : recentSales // ignore: cast_nullable_to_non_nullable + as List?, + ) + as $Val, + ); + } + + /// Create a copy of DashboardAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $DashboardOverviewDtoCopyWith<$Res>? get overview { + if (_value.overview == null) { + return null; + } + + return $DashboardOverviewDtoCopyWith<$Res>(_value.overview!, (value) { + return _then(_value.copyWith(overview: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$DashboardAnalyticDtoImplCopyWith<$Res> + implements $DashboardAnalyticDtoCopyWith<$Res> { + factory _$$DashboardAnalyticDtoImplCopyWith( + _$DashboardAnalyticDtoImpl value, + $Res Function(_$DashboardAnalyticDtoImpl) then, + ) = __$$DashboardAnalyticDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "organization_id") String? organizationId, + @JsonKey(name: "outlet_id") String? outletId, + @JsonKey(name: "date_from") String? dateFrom, + @JsonKey(name: "date_to") String? dateTo, + @JsonKey(name: "overview") DashboardOverviewDto? overview, + @JsonKey(name: "top_products") List? topProducts, + @JsonKey(name: "payment_methods") + List? paymentMethods, + @JsonKey(name: "recent_sales") List? recentSales, + }); + + @override + $DashboardOverviewDtoCopyWith<$Res>? get overview; +} + +/// @nodoc +class __$$DashboardAnalyticDtoImplCopyWithImpl<$Res> + extends _$DashboardAnalyticDtoCopyWithImpl<$Res, _$DashboardAnalyticDtoImpl> + implements _$$DashboardAnalyticDtoImplCopyWith<$Res> { + __$$DashboardAnalyticDtoImplCopyWithImpl( + _$DashboardAnalyticDtoImpl _value, + $Res Function(_$DashboardAnalyticDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = freezed, + Object? outletId = freezed, + Object? dateFrom = freezed, + Object? dateTo = freezed, + Object? overview = freezed, + Object? topProducts = freezed, + Object? paymentMethods = freezed, + Object? recentSales = freezed, + }) { + return _then( + _$DashboardAnalyticDtoImpl( + organizationId: freezed == organizationId + ? _value.organizationId + : organizationId // ignore: cast_nullable_to_non_nullable + as String?, + outletId: freezed == outletId + ? _value.outletId + : outletId // ignore: cast_nullable_to_non_nullable + as String?, + dateFrom: freezed == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as String?, + dateTo: freezed == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as String?, + overview: freezed == overview + ? _value.overview + : overview // ignore: cast_nullable_to_non_nullable + as DashboardOverviewDto?, + topProducts: freezed == topProducts + ? _value._topProducts + : topProducts // ignore: cast_nullable_to_non_nullable + as List?, + paymentMethods: freezed == paymentMethods + ? _value._paymentMethods + : paymentMethods // ignore: cast_nullable_to_non_nullable + as List?, + recentSales: freezed == recentSales + ? _value._recentSales + : recentSales // ignore: cast_nullable_to_non_nullable + as List?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$DashboardAnalyticDtoImpl extends _DashboardAnalyticDto { + const _$DashboardAnalyticDtoImpl({ + @JsonKey(name: "organization_id") this.organizationId, + @JsonKey(name: "outlet_id") this.outletId, + @JsonKey(name: "date_from") this.dateFrom, + @JsonKey(name: "date_to") this.dateTo, + @JsonKey(name: "overview") this.overview, + @JsonKey(name: "top_products") + final List? topProducts, + @JsonKey(name: "payment_methods") + final List? paymentMethods, + @JsonKey(name: "recent_sales") + final List? recentSales, + }) : _topProducts = topProducts, + _paymentMethods = paymentMethods, + _recentSales = recentSales, + super._(); + + factory _$DashboardAnalyticDtoImpl.fromJson(Map json) => + _$$DashboardAnalyticDtoImplFromJson(json); + + @override + @JsonKey(name: "organization_id") + final String? organizationId; + @override + @JsonKey(name: "outlet_id") + final String? outletId; + @override + @JsonKey(name: "date_from") + final String? dateFrom; + @override + @JsonKey(name: "date_to") + final String? dateTo; + @override + @JsonKey(name: "overview") + final DashboardOverviewDto? overview; + final List? _topProducts; + @override + @JsonKey(name: "top_products") + List? get topProducts { + final value = _topProducts; + if (value == null) return null; + if (_topProducts is EqualUnmodifiableListView) return _topProducts; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + final List? _paymentMethods; + @override + @JsonKey(name: "payment_methods") + List? get paymentMethods { + final value = _paymentMethods; + if (value == null) return null; + if (_paymentMethods is EqualUnmodifiableListView) return _paymentMethods; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + final List? _recentSales; + @override + @JsonKey(name: "recent_sales") + List? get recentSales { + final value = _recentSales; + if (value == null) return null; + if (_recentSales is EqualUnmodifiableListView) return _recentSales; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @override + String toString() { + return 'DashboardAnalyticDto(organizationId: $organizationId, outletId: $outletId, dateFrom: $dateFrom, dateTo: $dateTo, overview: $overview, topProducts: $topProducts, paymentMethods: $paymentMethods, recentSales: $recentSales)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardAnalyticDtoImpl && + (identical(other.organizationId, organizationId) || + other.organizationId == organizationId) && + (identical(other.outletId, outletId) || + other.outletId == outletId) && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo) && + (identical(other.overview, overview) || + other.overview == overview) && + const DeepCollectionEquality().equals( + other._topProducts, + _topProducts, + ) && + const DeepCollectionEquality().equals( + other._paymentMethods, + _paymentMethods, + ) && + const DeepCollectionEquality().equals( + other._recentSales, + _recentSales, + )); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + organizationId, + outletId, + dateFrom, + dateTo, + overview, + const DeepCollectionEquality().hash(_topProducts), + const DeepCollectionEquality().hash(_paymentMethods), + const DeepCollectionEquality().hash(_recentSales), + ); + + /// Create a copy of DashboardAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardAnalyticDtoImplCopyWith<_$DashboardAnalyticDtoImpl> + get copyWith => + __$$DashboardAnalyticDtoImplCopyWithImpl<_$DashboardAnalyticDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$DashboardAnalyticDtoImplToJson(this); + } +} + +abstract class _DashboardAnalyticDto extends DashboardAnalyticDto { + const factory _DashboardAnalyticDto({ + @JsonKey(name: "organization_id") final String? organizationId, + @JsonKey(name: "outlet_id") final String? outletId, + @JsonKey(name: "date_from") final String? dateFrom, + @JsonKey(name: "date_to") final String? dateTo, + @JsonKey(name: "overview") final DashboardOverviewDto? overview, + @JsonKey(name: "top_products") + final List? topProducts, + @JsonKey(name: "payment_methods") + final List? paymentMethods, + @JsonKey(name: "recent_sales") + final List? recentSales, + }) = _$DashboardAnalyticDtoImpl; + const _DashboardAnalyticDto._() : super._(); + + factory _DashboardAnalyticDto.fromJson(Map json) = + _$DashboardAnalyticDtoImpl.fromJson; + + @override + @JsonKey(name: "organization_id") + String? get organizationId; + @override + @JsonKey(name: "outlet_id") + String? get outletId; + @override + @JsonKey(name: "date_from") + String? get dateFrom; + @override + @JsonKey(name: "date_to") + String? get dateTo; + @override + @JsonKey(name: "overview") + DashboardOverviewDto? get overview; + @override + @JsonKey(name: "top_products") + List? get topProducts; + @override + @JsonKey(name: "payment_methods") + List? get paymentMethods; + @override + @JsonKey(name: "recent_sales") + List? get recentSales; + + /// Create a copy of DashboardAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardAnalyticDtoImplCopyWith<_$DashboardAnalyticDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +DashboardOverviewDto _$DashboardOverviewDtoFromJson(Map json) { + return _DashboardOverviewDto.fromJson(json); +} + +/// @nodoc +mixin _$DashboardOverviewDto { + @JsonKey(name: "total_sales") + int? get totalSales => throw _privateConstructorUsedError; + @JsonKey(name: "total_orders") + int? get totalOrders => throw _privateConstructorUsedError; + @JsonKey(name: "average_order_value") + double? get averageOrderValue => throw _privateConstructorUsedError; + @JsonKey(name: "total_customers") + int? get totalCustomers => throw _privateConstructorUsedError; + @JsonKey(name: "voided_orders") + int? get voidedOrders => throw _privateConstructorUsedError; + @JsonKey(name: "refunded_orders") + int? get refundedOrders => throw _privateConstructorUsedError; + + /// Serializes this DashboardOverviewDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DashboardOverviewDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardOverviewDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardOverviewDtoCopyWith<$Res> { + factory $DashboardOverviewDtoCopyWith( + DashboardOverviewDto value, + $Res Function(DashboardOverviewDto) then, + ) = _$DashboardOverviewDtoCopyWithImpl<$Res, DashboardOverviewDto>; + @useResult + $Res call({ + @JsonKey(name: "total_sales") int? totalSales, + @JsonKey(name: "total_orders") int? totalOrders, + @JsonKey(name: "average_order_value") double? averageOrderValue, + @JsonKey(name: "total_customers") int? totalCustomers, + @JsonKey(name: "voided_orders") int? voidedOrders, + @JsonKey(name: "refunded_orders") int? refundedOrders, + }); +} + +/// @nodoc +class _$DashboardOverviewDtoCopyWithImpl< + $Res, + $Val extends DashboardOverviewDto +> + implements $DashboardOverviewDtoCopyWith<$Res> { + _$DashboardOverviewDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardOverviewDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalSales = freezed, + Object? totalOrders = freezed, + Object? averageOrderValue = freezed, + Object? totalCustomers = freezed, + Object? voidedOrders = freezed, + Object? refundedOrders = freezed, + }) { + return _then( + _value.copyWith( + totalSales: freezed == totalSales + ? _value.totalSales + : totalSales // ignore: cast_nullable_to_non_nullable + as int?, + totalOrders: freezed == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int?, + averageOrderValue: freezed == averageOrderValue + ? _value.averageOrderValue + : averageOrderValue // ignore: cast_nullable_to_non_nullable + as double?, + totalCustomers: freezed == totalCustomers + ? _value.totalCustomers + : totalCustomers // ignore: cast_nullable_to_non_nullable + as int?, + voidedOrders: freezed == voidedOrders + ? _value.voidedOrders + : voidedOrders // ignore: cast_nullable_to_non_nullable + as int?, + refundedOrders: freezed == refundedOrders + ? _value.refundedOrders + : refundedOrders // ignore: cast_nullable_to_non_nullable + as int?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardOverviewDtoImplCopyWith<$Res> + implements $DashboardOverviewDtoCopyWith<$Res> { + factory _$$DashboardOverviewDtoImplCopyWith( + _$DashboardOverviewDtoImpl value, + $Res Function(_$DashboardOverviewDtoImpl) then, + ) = __$$DashboardOverviewDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "total_sales") int? totalSales, + @JsonKey(name: "total_orders") int? totalOrders, + @JsonKey(name: "average_order_value") double? averageOrderValue, + @JsonKey(name: "total_customers") int? totalCustomers, + @JsonKey(name: "voided_orders") int? voidedOrders, + @JsonKey(name: "refunded_orders") int? refundedOrders, + }); +} + +/// @nodoc +class __$$DashboardOverviewDtoImplCopyWithImpl<$Res> + extends _$DashboardOverviewDtoCopyWithImpl<$Res, _$DashboardOverviewDtoImpl> + implements _$$DashboardOverviewDtoImplCopyWith<$Res> { + __$$DashboardOverviewDtoImplCopyWithImpl( + _$DashboardOverviewDtoImpl _value, + $Res Function(_$DashboardOverviewDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardOverviewDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalSales = freezed, + Object? totalOrders = freezed, + Object? averageOrderValue = freezed, + Object? totalCustomers = freezed, + Object? voidedOrders = freezed, + Object? refundedOrders = freezed, + }) { + return _then( + _$DashboardOverviewDtoImpl( + totalSales: freezed == totalSales + ? _value.totalSales + : totalSales // ignore: cast_nullable_to_non_nullable + as int?, + totalOrders: freezed == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int?, + averageOrderValue: freezed == averageOrderValue + ? _value.averageOrderValue + : averageOrderValue // ignore: cast_nullable_to_non_nullable + as double?, + totalCustomers: freezed == totalCustomers + ? _value.totalCustomers + : totalCustomers // ignore: cast_nullable_to_non_nullable + as int?, + voidedOrders: freezed == voidedOrders + ? _value.voidedOrders + : voidedOrders // ignore: cast_nullable_to_non_nullable + as int?, + refundedOrders: freezed == refundedOrders + ? _value.refundedOrders + : refundedOrders // ignore: cast_nullable_to_non_nullable + as int?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$DashboardOverviewDtoImpl extends _DashboardOverviewDto { + const _$DashboardOverviewDtoImpl({ + @JsonKey(name: "total_sales") this.totalSales, + @JsonKey(name: "total_orders") this.totalOrders, + @JsonKey(name: "average_order_value") this.averageOrderValue, + @JsonKey(name: "total_customers") this.totalCustomers, + @JsonKey(name: "voided_orders") this.voidedOrders, + @JsonKey(name: "refunded_orders") this.refundedOrders, + }) : super._(); + + factory _$DashboardOverviewDtoImpl.fromJson(Map json) => + _$$DashboardOverviewDtoImplFromJson(json); + + @override + @JsonKey(name: "total_sales") + final int? totalSales; + @override + @JsonKey(name: "total_orders") + final int? totalOrders; + @override + @JsonKey(name: "average_order_value") + final double? averageOrderValue; + @override + @JsonKey(name: "total_customers") + final int? totalCustomers; + @override + @JsonKey(name: "voided_orders") + final int? voidedOrders; + @override + @JsonKey(name: "refunded_orders") + final int? refundedOrders; + + @override + String toString() { + return 'DashboardOverviewDto(totalSales: $totalSales, totalOrders: $totalOrders, averageOrderValue: $averageOrderValue, totalCustomers: $totalCustomers, voidedOrders: $voidedOrders, refundedOrders: $refundedOrders)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardOverviewDtoImpl && + (identical(other.totalSales, totalSales) || + other.totalSales == totalSales) && + (identical(other.totalOrders, totalOrders) || + other.totalOrders == totalOrders) && + (identical(other.averageOrderValue, averageOrderValue) || + other.averageOrderValue == averageOrderValue) && + (identical(other.totalCustomers, totalCustomers) || + other.totalCustomers == totalCustomers) && + (identical(other.voidedOrders, voidedOrders) || + other.voidedOrders == voidedOrders) && + (identical(other.refundedOrders, refundedOrders) || + other.refundedOrders == refundedOrders)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + totalSales, + totalOrders, + averageOrderValue, + totalCustomers, + voidedOrders, + refundedOrders, + ); + + /// Create a copy of DashboardOverviewDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardOverviewDtoImplCopyWith<_$DashboardOverviewDtoImpl> + get copyWith => + __$$DashboardOverviewDtoImplCopyWithImpl<_$DashboardOverviewDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$DashboardOverviewDtoImplToJson(this); + } +} + +abstract class _DashboardOverviewDto extends DashboardOverviewDto { + const factory _DashboardOverviewDto({ + @JsonKey(name: "total_sales") final int? totalSales, + @JsonKey(name: "total_orders") final int? totalOrders, + @JsonKey(name: "average_order_value") final double? averageOrderValue, + @JsonKey(name: "total_customers") final int? totalCustomers, + @JsonKey(name: "voided_orders") final int? voidedOrders, + @JsonKey(name: "refunded_orders") final int? refundedOrders, + }) = _$DashboardOverviewDtoImpl; + const _DashboardOverviewDto._() : super._(); + + factory _DashboardOverviewDto.fromJson(Map json) = + _$DashboardOverviewDtoImpl.fromJson; + + @override + @JsonKey(name: "total_sales") + int? get totalSales; + @override + @JsonKey(name: "total_orders") + int? get totalOrders; + @override + @JsonKey(name: "average_order_value") + double? get averageOrderValue; + @override + @JsonKey(name: "total_customers") + int? get totalCustomers; + @override + @JsonKey(name: "voided_orders") + int? get voidedOrders; + @override + @JsonKey(name: "refunded_orders") + int? get refundedOrders; + + /// Create a copy of DashboardOverviewDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardOverviewDtoImplCopyWith<_$DashboardOverviewDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +DashboardTopProductDto _$DashboardTopProductDtoFromJson( + Map json, +) { + return _DashboardTopProductDto.fromJson(json); +} + +/// @nodoc +mixin _$DashboardTopProductDto { + @JsonKey(name: "product_id") + String? get productId => throw _privateConstructorUsedError; + @JsonKey(name: "product_name") + String? get productName => throw _privateConstructorUsedError; + @JsonKey(name: "category_id") + String? get categoryId => throw _privateConstructorUsedError; + @JsonKey(name: "category_name") + String? get categoryName => throw _privateConstructorUsedError; + @JsonKey(name: "quantity_sold") + int? get quantitySold => throw _privateConstructorUsedError; + @JsonKey(name: "revenue") + int? get revenue => throw _privateConstructorUsedError; + @JsonKey(name: "average_price") + double? get averagePrice => throw _privateConstructorUsedError; + @JsonKey(name: "order_count") + int? get orderCount => throw _privateConstructorUsedError; + + /// Serializes this DashboardTopProductDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DashboardTopProductDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardTopProductDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardTopProductDtoCopyWith<$Res> { + factory $DashboardTopProductDtoCopyWith( + DashboardTopProductDto value, + $Res Function(DashboardTopProductDto) then, + ) = _$DashboardTopProductDtoCopyWithImpl<$Res, DashboardTopProductDto>; + @useResult + $Res call({ + @JsonKey(name: "product_id") String? productId, + @JsonKey(name: "product_name") String? productName, + @JsonKey(name: "category_id") String? categoryId, + @JsonKey(name: "category_name") String? categoryName, + @JsonKey(name: "quantity_sold") int? quantitySold, + @JsonKey(name: "revenue") int? revenue, + @JsonKey(name: "average_price") double? averagePrice, + @JsonKey(name: "order_count") int? orderCount, + }); +} + +/// @nodoc +class _$DashboardTopProductDtoCopyWithImpl< + $Res, + $Val extends DashboardTopProductDto +> + implements $DashboardTopProductDtoCopyWith<$Res> { + _$DashboardTopProductDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardTopProductDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? productId = freezed, + Object? productName = freezed, + Object? categoryId = freezed, + Object? categoryName = freezed, + Object? quantitySold = freezed, + Object? revenue = freezed, + Object? averagePrice = freezed, + Object? orderCount = freezed, + }) { + return _then( + _value.copyWith( + productId: freezed == productId + ? _value.productId + : productId // ignore: cast_nullable_to_non_nullable + as String?, + productName: freezed == productName + ? _value.productName + : productName // ignore: cast_nullable_to_non_nullable + as String?, + categoryId: freezed == categoryId + ? _value.categoryId + : categoryId // ignore: cast_nullable_to_non_nullable + as String?, + categoryName: freezed == categoryName + ? _value.categoryName + : categoryName // ignore: cast_nullable_to_non_nullable + as String?, + quantitySold: freezed == quantitySold + ? _value.quantitySold + : quantitySold // ignore: cast_nullable_to_non_nullable + as int?, + revenue: freezed == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int?, + averagePrice: freezed == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as double?, + orderCount: freezed == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardTopProductDtoImplCopyWith<$Res> + implements $DashboardTopProductDtoCopyWith<$Res> { + factory _$$DashboardTopProductDtoImplCopyWith( + _$DashboardTopProductDtoImpl value, + $Res Function(_$DashboardTopProductDtoImpl) then, + ) = __$$DashboardTopProductDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "product_id") String? productId, + @JsonKey(name: "product_name") String? productName, + @JsonKey(name: "category_id") String? categoryId, + @JsonKey(name: "category_name") String? categoryName, + @JsonKey(name: "quantity_sold") int? quantitySold, + @JsonKey(name: "revenue") int? revenue, + @JsonKey(name: "average_price") double? averagePrice, + @JsonKey(name: "order_count") int? orderCount, + }); +} + +/// @nodoc +class __$$DashboardTopProductDtoImplCopyWithImpl<$Res> + extends + _$DashboardTopProductDtoCopyWithImpl<$Res, _$DashboardTopProductDtoImpl> + implements _$$DashboardTopProductDtoImplCopyWith<$Res> { + __$$DashboardTopProductDtoImplCopyWithImpl( + _$DashboardTopProductDtoImpl _value, + $Res Function(_$DashboardTopProductDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardTopProductDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? productId = freezed, + Object? productName = freezed, + Object? categoryId = freezed, + Object? categoryName = freezed, + Object? quantitySold = freezed, + Object? revenue = freezed, + Object? averagePrice = freezed, + Object? orderCount = freezed, + }) { + return _then( + _$DashboardTopProductDtoImpl( + productId: freezed == productId + ? _value.productId + : productId // ignore: cast_nullable_to_non_nullable + as String?, + productName: freezed == productName + ? _value.productName + : productName // ignore: cast_nullable_to_non_nullable + as String?, + categoryId: freezed == categoryId + ? _value.categoryId + : categoryId // ignore: cast_nullable_to_non_nullable + as String?, + categoryName: freezed == categoryName + ? _value.categoryName + : categoryName // ignore: cast_nullable_to_non_nullable + as String?, + quantitySold: freezed == quantitySold + ? _value.quantitySold + : quantitySold // ignore: cast_nullable_to_non_nullable + as int?, + revenue: freezed == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int?, + averagePrice: freezed == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as double?, + orderCount: freezed == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$DashboardTopProductDtoImpl extends _DashboardTopProductDto { + const _$DashboardTopProductDtoImpl({ + @JsonKey(name: "product_id") this.productId, + @JsonKey(name: "product_name") this.productName, + @JsonKey(name: "category_id") this.categoryId, + @JsonKey(name: "category_name") this.categoryName, + @JsonKey(name: "quantity_sold") this.quantitySold, + @JsonKey(name: "revenue") this.revenue, + @JsonKey(name: "average_price") this.averagePrice, + @JsonKey(name: "order_count") this.orderCount, + }) : super._(); + + factory _$DashboardTopProductDtoImpl.fromJson(Map json) => + _$$DashboardTopProductDtoImplFromJson(json); + + @override + @JsonKey(name: "product_id") + final String? productId; + @override + @JsonKey(name: "product_name") + final String? productName; + @override + @JsonKey(name: "category_id") + final String? categoryId; + @override + @JsonKey(name: "category_name") + final String? categoryName; + @override + @JsonKey(name: "quantity_sold") + final int? quantitySold; + @override + @JsonKey(name: "revenue") + final int? revenue; + @override + @JsonKey(name: "average_price") + final double? averagePrice; + @override + @JsonKey(name: "order_count") + final int? orderCount; + + @override + String toString() { + return 'DashboardTopProductDto(productId: $productId, productName: $productName, categoryId: $categoryId, categoryName: $categoryName, quantitySold: $quantitySold, revenue: $revenue, averagePrice: $averagePrice, orderCount: $orderCount)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardTopProductDtoImpl && + (identical(other.productId, productId) || + other.productId == productId) && + (identical(other.productName, productName) || + other.productName == productName) && + (identical(other.categoryId, categoryId) || + other.categoryId == categoryId) && + (identical(other.categoryName, categoryName) || + other.categoryName == categoryName) && + (identical(other.quantitySold, quantitySold) || + other.quantitySold == quantitySold) && + (identical(other.revenue, revenue) || other.revenue == revenue) && + (identical(other.averagePrice, averagePrice) || + other.averagePrice == averagePrice) && + (identical(other.orderCount, orderCount) || + other.orderCount == orderCount)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + productId, + productName, + categoryId, + categoryName, + quantitySold, + revenue, + averagePrice, + orderCount, + ); + + /// Create a copy of DashboardTopProductDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardTopProductDtoImplCopyWith<_$DashboardTopProductDtoImpl> + get copyWith => + __$$DashboardTopProductDtoImplCopyWithImpl<_$DashboardTopProductDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$DashboardTopProductDtoImplToJson(this); + } +} + +abstract class _DashboardTopProductDto extends DashboardTopProductDto { + const factory _DashboardTopProductDto({ + @JsonKey(name: "product_id") final String? productId, + @JsonKey(name: "product_name") final String? productName, + @JsonKey(name: "category_id") final String? categoryId, + @JsonKey(name: "category_name") final String? categoryName, + @JsonKey(name: "quantity_sold") final int? quantitySold, + @JsonKey(name: "revenue") final int? revenue, + @JsonKey(name: "average_price") final double? averagePrice, + @JsonKey(name: "order_count") final int? orderCount, + }) = _$DashboardTopProductDtoImpl; + const _DashboardTopProductDto._() : super._(); + + factory _DashboardTopProductDto.fromJson(Map json) = + _$DashboardTopProductDtoImpl.fromJson; + + @override + @JsonKey(name: "product_id") + String? get productId; + @override + @JsonKey(name: "product_name") + String? get productName; + @override + @JsonKey(name: "category_id") + String? get categoryId; + @override + @JsonKey(name: "category_name") + String? get categoryName; + @override + @JsonKey(name: "quantity_sold") + int? get quantitySold; + @override + @JsonKey(name: "revenue") + int? get revenue; + @override + @JsonKey(name: "average_price") + double? get averagePrice; + @override + @JsonKey(name: "order_count") + int? get orderCount; + + /// Create a copy of DashboardTopProductDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardTopProductDtoImplCopyWith<_$DashboardTopProductDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +DashboardPaymentMethodDto _$DashboardPaymentMethodDtoFromJson( + Map json, +) { + return _DashboardPaymentMethodDto.fromJson(json); +} + +/// @nodoc +mixin _$DashboardPaymentMethodDto { + @JsonKey(name: "payment_method_id") + String? get paymentMethodId => throw _privateConstructorUsedError; + @JsonKey(name: "payment_method_name") + String? get paymentMethodName => throw _privateConstructorUsedError; + @JsonKey(name: "payment_method_type") + String? get paymentMethodType => throw _privateConstructorUsedError; + @JsonKey(name: "total_amount") + int? get totalAmount => throw _privateConstructorUsedError; + @JsonKey(name: "order_count") + int? get orderCount => throw _privateConstructorUsedError; + @JsonKey(name: "payment_count") + int? get paymentCount => throw _privateConstructorUsedError; + @JsonKey(name: "percentage") + double? get percentage => throw _privateConstructorUsedError; + + /// Serializes this DashboardPaymentMethodDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DashboardPaymentMethodDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardPaymentMethodDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardPaymentMethodDtoCopyWith<$Res> { + factory $DashboardPaymentMethodDtoCopyWith( + DashboardPaymentMethodDto value, + $Res Function(DashboardPaymentMethodDto) then, + ) = _$DashboardPaymentMethodDtoCopyWithImpl<$Res, DashboardPaymentMethodDto>; + @useResult + $Res call({ + @JsonKey(name: "payment_method_id") String? paymentMethodId, + @JsonKey(name: "payment_method_name") String? paymentMethodName, + @JsonKey(name: "payment_method_type") String? paymentMethodType, + @JsonKey(name: "total_amount") int? totalAmount, + @JsonKey(name: "order_count") int? orderCount, + @JsonKey(name: "payment_count") int? paymentCount, + @JsonKey(name: "percentage") double? percentage, + }); +} + +/// @nodoc +class _$DashboardPaymentMethodDtoCopyWithImpl< + $Res, + $Val extends DashboardPaymentMethodDto +> + implements $DashboardPaymentMethodDtoCopyWith<$Res> { + _$DashboardPaymentMethodDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardPaymentMethodDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paymentMethodId = freezed, + Object? paymentMethodName = freezed, + Object? paymentMethodType = freezed, + Object? totalAmount = freezed, + Object? orderCount = freezed, + Object? paymentCount = freezed, + Object? percentage = freezed, + }) { + return _then( + _value.copyWith( + paymentMethodId: freezed == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String?, + paymentMethodName: freezed == paymentMethodName + ? _value.paymentMethodName + : paymentMethodName // ignore: cast_nullable_to_non_nullable + as String?, + paymentMethodType: freezed == paymentMethodType + ? _value.paymentMethodType + : paymentMethodType // ignore: cast_nullable_to_non_nullable + as String?, + totalAmount: freezed == totalAmount + ? _value.totalAmount + : totalAmount // ignore: cast_nullable_to_non_nullable + as int?, + orderCount: freezed == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int?, + paymentCount: freezed == paymentCount + ? _value.paymentCount + : paymentCount // ignore: cast_nullable_to_non_nullable + as int?, + percentage: freezed == percentage + ? _value.percentage + : percentage // ignore: cast_nullable_to_non_nullable + as double?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardPaymentMethodDtoImplCopyWith<$Res> + implements $DashboardPaymentMethodDtoCopyWith<$Res> { + factory _$$DashboardPaymentMethodDtoImplCopyWith( + _$DashboardPaymentMethodDtoImpl value, + $Res Function(_$DashboardPaymentMethodDtoImpl) then, + ) = __$$DashboardPaymentMethodDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "payment_method_id") String? paymentMethodId, + @JsonKey(name: "payment_method_name") String? paymentMethodName, + @JsonKey(name: "payment_method_type") String? paymentMethodType, + @JsonKey(name: "total_amount") int? totalAmount, + @JsonKey(name: "order_count") int? orderCount, + @JsonKey(name: "payment_count") int? paymentCount, + @JsonKey(name: "percentage") double? percentage, + }); +} + +/// @nodoc +class __$$DashboardPaymentMethodDtoImplCopyWithImpl<$Res> + extends + _$DashboardPaymentMethodDtoCopyWithImpl< + $Res, + _$DashboardPaymentMethodDtoImpl + > + implements _$$DashboardPaymentMethodDtoImplCopyWith<$Res> { + __$$DashboardPaymentMethodDtoImplCopyWithImpl( + _$DashboardPaymentMethodDtoImpl _value, + $Res Function(_$DashboardPaymentMethodDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardPaymentMethodDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paymentMethodId = freezed, + Object? paymentMethodName = freezed, + Object? paymentMethodType = freezed, + Object? totalAmount = freezed, + Object? orderCount = freezed, + Object? paymentCount = freezed, + Object? percentage = freezed, + }) { + return _then( + _$DashboardPaymentMethodDtoImpl( + paymentMethodId: freezed == paymentMethodId + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String?, + paymentMethodName: freezed == paymentMethodName + ? _value.paymentMethodName + : paymentMethodName // ignore: cast_nullable_to_non_nullable + as String?, + paymentMethodType: freezed == paymentMethodType + ? _value.paymentMethodType + : paymentMethodType // ignore: cast_nullable_to_non_nullable + as String?, + totalAmount: freezed == totalAmount + ? _value.totalAmount + : totalAmount // ignore: cast_nullable_to_non_nullable + as int?, + orderCount: freezed == orderCount + ? _value.orderCount + : orderCount // ignore: cast_nullable_to_non_nullable + as int?, + paymentCount: freezed == paymentCount + ? _value.paymentCount + : paymentCount // ignore: cast_nullable_to_non_nullable + as int?, + percentage: freezed == percentage + ? _value.percentage + : percentage // ignore: cast_nullable_to_non_nullable + as double?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$DashboardPaymentMethodDtoImpl extends _DashboardPaymentMethodDto { + const _$DashboardPaymentMethodDtoImpl({ + @JsonKey(name: "payment_method_id") this.paymentMethodId, + @JsonKey(name: "payment_method_name") this.paymentMethodName, + @JsonKey(name: "payment_method_type") this.paymentMethodType, + @JsonKey(name: "total_amount") this.totalAmount, + @JsonKey(name: "order_count") this.orderCount, + @JsonKey(name: "payment_count") this.paymentCount, + @JsonKey(name: "percentage") this.percentage, + }) : super._(); + + factory _$DashboardPaymentMethodDtoImpl.fromJson(Map json) => + _$$DashboardPaymentMethodDtoImplFromJson(json); + + @override + @JsonKey(name: "payment_method_id") + final String? paymentMethodId; + @override + @JsonKey(name: "payment_method_name") + final String? paymentMethodName; + @override + @JsonKey(name: "payment_method_type") + final String? paymentMethodType; + @override + @JsonKey(name: "total_amount") + final int? totalAmount; + @override + @JsonKey(name: "order_count") + final int? orderCount; + @override + @JsonKey(name: "payment_count") + final int? paymentCount; + @override + @JsonKey(name: "percentage") + final double? percentage; + + @override + String toString() { + return 'DashboardPaymentMethodDto(paymentMethodId: $paymentMethodId, paymentMethodName: $paymentMethodName, paymentMethodType: $paymentMethodType, totalAmount: $totalAmount, orderCount: $orderCount, paymentCount: $paymentCount, percentage: $percentage)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardPaymentMethodDtoImpl && + (identical(other.paymentMethodId, paymentMethodId) || + other.paymentMethodId == paymentMethodId) && + (identical(other.paymentMethodName, paymentMethodName) || + other.paymentMethodName == paymentMethodName) && + (identical(other.paymentMethodType, paymentMethodType) || + other.paymentMethodType == paymentMethodType) && + (identical(other.totalAmount, totalAmount) || + other.totalAmount == totalAmount) && + (identical(other.orderCount, orderCount) || + other.orderCount == orderCount) && + (identical(other.paymentCount, paymentCount) || + other.paymentCount == paymentCount) && + (identical(other.percentage, percentage) || + other.percentage == percentage)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + paymentMethodId, + paymentMethodName, + paymentMethodType, + totalAmount, + orderCount, + paymentCount, + percentage, + ); + + /// Create a copy of DashboardPaymentMethodDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardPaymentMethodDtoImplCopyWith<_$DashboardPaymentMethodDtoImpl> + get copyWith => + __$$DashboardPaymentMethodDtoImplCopyWithImpl< + _$DashboardPaymentMethodDtoImpl + >(this, _$identity); + + @override + Map toJson() { + return _$$DashboardPaymentMethodDtoImplToJson(this); + } +} + +abstract class _DashboardPaymentMethodDto extends DashboardPaymentMethodDto { + const factory _DashboardPaymentMethodDto({ + @JsonKey(name: "payment_method_id") final String? paymentMethodId, + @JsonKey(name: "payment_method_name") final String? paymentMethodName, + @JsonKey(name: "payment_method_type") final String? paymentMethodType, + @JsonKey(name: "total_amount") final int? totalAmount, + @JsonKey(name: "order_count") final int? orderCount, + @JsonKey(name: "payment_count") final int? paymentCount, + @JsonKey(name: "percentage") final double? percentage, + }) = _$DashboardPaymentMethodDtoImpl; + const _DashboardPaymentMethodDto._() : super._(); + + factory _DashboardPaymentMethodDto.fromJson(Map json) = + _$DashboardPaymentMethodDtoImpl.fromJson; + + @override + @JsonKey(name: "payment_method_id") + String? get paymentMethodId; + @override + @JsonKey(name: "payment_method_name") + String? get paymentMethodName; + @override + @JsonKey(name: "payment_method_type") + String? get paymentMethodType; + @override + @JsonKey(name: "total_amount") + int? get totalAmount; + @override + @JsonKey(name: "order_count") + int? get orderCount; + @override + @JsonKey(name: "payment_count") + int? get paymentCount; + @override + @JsonKey(name: "percentage") + double? get percentage; + + /// Create a copy of DashboardPaymentMethodDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardPaymentMethodDtoImplCopyWith<_$DashboardPaymentMethodDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +DashboardRecentSaleDto _$DashboardRecentSaleDtoFromJson( + Map json, +) { + return _DashboardRecentSaleDto.fromJson(json); +} + +/// @nodoc +mixin _$DashboardRecentSaleDto { + @JsonKey(name: "date") + String? get date => throw _privateConstructorUsedError; + @JsonKey(name: "sales") + int? get sales => throw _privateConstructorUsedError; + @JsonKey(name: "orders") + int? get orders => throw _privateConstructorUsedError; + @JsonKey(name: "items") + int? get items => throw _privateConstructorUsedError; + @JsonKey(name: "tax") + int? get tax => throw _privateConstructorUsedError; + @JsonKey(name: "discount") + int? get discount => throw _privateConstructorUsedError; + @JsonKey(name: "net_sales") + int? get netSales => throw _privateConstructorUsedError; + + /// Serializes this DashboardRecentSaleDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of DashboardRecentSaleDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $DashboardRecentSaleDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $DashboardRecentSaleDtoCopyWith<$Res> { + factory $DashboardRecentSaleDtoCopyWith( + DashboardRecentSaleDto value, + $Res Function(DashboardRecentSaleDto) then, + ) = _$DashboardRecentSaleDtoCopyWithImpl<$Res, DashboardRecentSaleDto>; + @useResult + $Res call({ + @JsonKey(name: "date") String? date, + @JsonKey(name: "sales") int? sales, + @JsonKey(name: "orders") int? orders, + @JsonKey(name: "items") int? items, + @JsonKey(name: "tax") int? tax, + @JsonKey(name: "discount") int? discount, + @JsonKey(name: "net_sales") int? netSales, + }); +} + +/// @nodoc +class _$DashboardRecentSaleDtoCopyWithImpl< + $Res, + $Val extends DashboardRecentSaleDto +> + implements $DashboardRecentSaleDtoCopyWith<$Res> { + _$DashboardRecentSaleDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of DashboardRecentSaleDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = freezed, + Object? sales = freezed, + Object? orders = freezed, + Object? items = freezed, + Object? tax = freezed, + Object? discount = freezed, + Object? netSales = freezed, + }) { + return _then( + _value.copyWith( + date: freezed == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String?, + sales: freezed == sales + ? _value.sales + : sales // ignore: cast_nullable_to_non_nullable + as int?, + orders: freezed == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int?, + items: freezed == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as int?, + tax: freezed == tax + ? _value.tax + : tax // ignore: cast_nullable_to_non_nullable + as int?, + discount: freezed == discount + ? _value.discount + : discount // ignore: cast_nullable_to_non_nullable + as int?, + netSales: freezed == netSales + ? _value.netSales + : netSales // ignore: cast_nullable_to_non_nullable + as int?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$DashboardRecentSaleDtoImplCopyWith<$Res> + implements $DashboardRecentSaleDtoCopyWith<$Res> { + factory _$$DashboardRecentSaleDtoImplCopyWith( + _$DashboardRecentSaleDtoImpl value, + $Res Function(_$DashboardRecentSaleDtoImpl) then, + ) = __$$DashboardRecentSaleDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "date") String? date, + @JsonKey(name: "sales") int? sales, + @JsonKey(name: "orders") int? orders, + @JsonKey(name: "items") int? items, + @JsonKey(name: "tax") int? tax, + @JsonKey(name: "discount") int? discount, + @JsonKey(name: "net_sales") int? netSales, + }); +} + +/// @nodoc +class __$$DashboardRecentSaleDtoImplCopyWithImpl<$Res> + extends + _$DashboardRecentSaleDtoCopyWithImpl<$Res, _$DashboardRecentSaleDtoImpl> + implements _$$DashboardRecentSaleDtoImplCopyWith<$Res> { + __$$DashboardRecentSaleDtoImplCopyWithImpl( + _$DashboardRecentSaleDtoImpl _value, + $Res Function(_$DashboardRecentSaleDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of DashboardRecentSaleDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = freezed, + Object? sales = freezed, + Object? orders = freezed, + Object? items = freezed, + Object? tax = freezed, + Object? discount = freezed, + Object? netSales = freezed, + }) { + return _then( + _$DashboardRecentSaleDtoImpl( + date: freezed == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String?, + sales: freezed == sales + ? _value.sales + : sales // ignore: cast_nullable_to_non_nullable + as int?, + orders: freezed == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int?, + items: freezed == items + ? _value.items + : items // ignore: cast_nullable_to_non_nullable + as int?, + tax: freezed == tax + ? _value.tax + : tax // ignore: cast_nullable_to_non_nullable + as int?, + discount: freezed == discount + ? _value.discount + : discount // ignore: cast_nullable_to_non_nullable + as int?, + netSales: freezed == netSales + ? _value.netSales + : netSales // ignore: cast_nullable_to_non_nullable + as int?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$DashboardRecentSaleDtoImpl extends _DashboardRecentSaleDto { + const _$DashboardRecentSaleDtoImpl({ + @JsonKey(name: "date") this.date, + @JsonKey(name: "sales") this.sales, + @JsonKey(name: "orders") this.orders, + @JsonKey(name: "items") this.items, + @JsonKey(name: "tax") this.tax, + @JsonKey(name: "discount") this.discount, + @JsonKey(name: "net_sales") this.netSales, + }) : super._(); + + factory _$DashboardRecentSaleDtoImpl.fromJson(Map json) => + _$$DashboardRecentSaleDtoImplFromJson(json); + + @override + @JsonKey(name: "date") + final String? date; + @override + @JsonKey(name: "sales") + final int? sales; + @override + @JsonKey(name: "orders") + final int? orders; + @override + @JsonKey(name: "items") + final int? items; + @override + @JsonKey(name: "tax") + final int? tax; + @override + @JsonKey(name: "discount") + final int? discount; + @override + @JsonKey(name: "net_sales") + final int? netSales; + + @override + String toString() { + return 'DashboardRecentSaleDto(date: $date, sales: $sales, orders: $orders, items: $items, tax: $tax, discount: $discount, netSales: $netSales)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$DashboardRecentSaleDtoImpl && + (identical(other.date, date) || other.date == date) && + (identical(other.sales, sales) || other.sales == sales) && + (identical(other.orders, orders) || other.orders == orders) && + (identical(other.items, items) || other.items == items) && + (identical(other.tax, tax) || other.tax == tax) && + (identical(other.discount, discount) || + other.discount == discount) && + (identical(other.netSales, netSales) || + other.netSales == netSales)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + date, + sales, + orders, + items, + tax, + discount, + netSales, + ); + + /// Create a copy of DashboardRecentSaleDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$DashboardRecentSaleDtoImplCopyWith<_$DashboardRecentSaleDtoImpl> + get copyWith => + __$$DashboardRecentSaleDtoImplCopyWithImpl<_$DashboardRecentSaleDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$DashboardRecentSaleDtoImplToJson(this); + } +} + +abstract class _DashboardRecentSaleDto extends DashboardRecentSaleDto { + const factory _DashboardRecentSaleDto({ + @JsonKey(name: "date") final String? date, + @JsonKey(name: "sales") final int? sales, + @JsonKey(name: "orders") final int? orders, + @JsonKey(name: "items") final int? items, + @JsonKey(name: "tax") final int? tax, + @JsonKey(name: "discount") final int? discount, + @JsonKey(name: "net_sales") final int? netSales, + }) = _$DashboardRecentSaleDtoImpl; + const _DashboardRecentSaleDto._() : super._(); + + factory _DashboardRecentSaleDto.fromJson(Map json) = + _$DashboardRecentSaleDtoImpl.fromJson; + + @override + @JsonKey(name: "date") + String? get date; + @override + @JsonKey(name: "sales") + int? get sales; + @override + @JsonKey(name: "orders") + int? get orders; + @override + @JsonKey(name: "items") + int? get items; + @override + @JsonKey(name: "tax") + int? get tax; + @override + @JsonKey(name: "discount") + int? get discount; + @override + @JsonKey(name: "net_sales") + int? get netSales; + + /// Create a copy of DashboardRecentSaleDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$DashboardRecentSaleDtoImplCopyWith<_$DashboardRecentSaleDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/infrastructure/analytic/analytic_dtos.g.dart b/lib/infrastructure/analytic/analytic_dtos.g.dart new file mode 100644 index 0000000..08c70ef --- /dev/null +++ b/lib/infrastructure/analytic/analytic_dtos.g.dart @@ -0,0 +1,139 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'analytic_dtos.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$DashboardAnalyticDtoImpl _$$DashboardAnalyticDtoImplFromJson( + Map json, +) => _$DashboardAnalyticDtoImpl( + organizationId: json['organization_id'] as String?, + outletId: json['outlet_id'] as String?, + dateFrom: json['date_from'] as String?, + dateTo: json['date_to'] as String?, + overview: json['overview'] == null + ? null + : DashboardOverviewDto.fromJson(json['overview'] as Map), + topProducts: (json['top_products'] as List?) + ?.map((e) => DashboardTopProductDto.fromJson(e as Map)) + .toList(), + paymentMethods: (json['payment_methods'] as List?) + ?.map( + (e) => DashboardPaymentMethodDto.fromJson(e as Map), + ) + .toList(), + recentSales: (json['recent_sales'] as List?) + ?.map((e) => DashboardRecentSaleDto.fromJson(e as Map)) + .toList(), +); + +Map _$$DashboardAnalyticDtoImplToJson( + _$DashboardAnalyticDtoImpl instance, +) => { + 'organization_id': instance.organizationId, + 'outlet_id': instance.outletId, + 'date_from': instance.dateFrom, + 'date_to': instance.dateTo, + 'overview': instance.overview, + 'top_products': instance.topProducts, + 'payment_methods': instance.paymentMethods, + 'recent_sales': instance.recentSales, +}; + +_$DashboardOverviewDtoImpl _$$DashboardOverviewDtoImplFromJson( + Map json, +) => _$DashboardOverviewDtoImpl( + totalSales: (json['total_sales'] as num?)?.toInt(), + totalOrders: (json['total_orders'] as num?)?.toInt(), + averageOrderValue: (json['average_order_value'] as num?)?.toDouble(), + totalCustomers: (json['total_customers'] as num?)?.toInt(), + voidedOrders: (json['voided_orders'] as num?)?.toInt(), + refundedOrders: (json['refunded_orders'] as num?)?.toInt(), +); + +Map _$$DashboardOverviewDtoImplToJson( + _$DashboardOverviewDtoImpl instance, +) => { + 'total_sales': instance.totalSales, + 'total_orders': instance.totalOrders, + 'average_order_value': instance.averageOrderValue, + 'total_customers': instance.totalCustomers, + 'voided_orders': instance.voidedOrders, + 'refunded_orders': instance.refundedOrders, +}; + +_$DashboardTopProductDtoImpl _$$DashboardTopProductDtoImplFromJson( + Map json, +) => _$DashboardTopProductDtoImpl( + productId: json['product_id'] as String?, + productName: json['product_name'] as String?, + categoryId: json['category_id'] as String?, + categoryName: json['category_name'] as String?, + quantitySold: (json['quantity_sold'] as num?)?.toInt(), + revenue: (json['revenue'] as num?)?.toInt(), + averagePrice: (json['average_price'] as num?)?.toDouble(), + orderCount: (json['order_count'] as num?)?.toInt(), +); + +Map _$$DashboardTopProductDtoImplToJson( + _$DashboardTopProductDtoImpl instance, +) => { + 'product_id': instance.productId, + 'product_name': instance.productName, + 'category_id': instance.categoryId, + 'category_name': instance.categoryName, + 'quantity_sold': instance.quantitySold, + 'revenue': instance.revenue, + 'average_price': instance.averagePrice, + 'order_count': instance.orderCount, +}; + +_$DashboardPaymentMethodDtoImpl _$$DashboardPaymentMethodDtoImplFromJson( + Map json, +) => _$DashboardPaymentMethodDtoImpl( + paymentMethodId: json['payment_method_id'] as String?, + paymentMethodName: json['payment_method_name'] as String?, + paymentMethodType: json['payment_method_type'] as String?, + totalAmount: (json['total_amount'] as num?)?.toInt(), + orderCount: (json['order_count'] as num?)?.toInt(), + paymentCount: (json['payment_count'] as num?)?.toInt(), + percentage: (json['percentage'] as num?)?.toDouble(), +); + +Map _$$DashboardPaymentMethodDtoImplToJson( + _$DashboardPaymentMethodDtoImpl instance, +) => { + 'payment_method_id': instance.paymentMethodId, + 'payment_method_name': instance.paymentMethodName, + 'payment_method_type': instance.paymentMethodType, + 'total_amount': instance.totalAmount, + 'order_count': instance.orderCount, + 'payment_count': instance.paymentCount, + 'percentage': instance.percentage, +}; + +_$DashboardRecentSaleDtoImpl _$$DashboardRecentSaleDtoImplFromJson( + Map json, +) => _$DashboardRecentSaleDtoImpl( + date: json['date'] as String?, + sales: (json['sales'] as num?)?.toInt(), + orders: (json['orders'] as num?)?.toInt(), + items: (json['items'] as num?)?.toInt(), + tax: (json['tax'] as num?)?.toInt(), + discount: (json['discount'] as num?)?.toInt(), + netSales: (json['net_sales'] as num?)?.toInt(), +); + +Map _$$DashboardRecentSaleDtoImplToJson( + _$DashboardRecentSaleDtoImpl instance, +) => { + 'date': instance.date, + 'sales': instance.sales, + 'orders': instance.orders, + 'items': instance.items, + 'tax': instance.tax, + 'discount': instance.discount, + 'net_sales': instance.netSales, +}; diff --git a/lib/infrastructure/analytic/datasources/remote_data_provider.dart b/lib/infrastructure/analytic/datasources/remote_data_provider.dart new file mode 100644 index 0000000..1290d44 --- /dev/null +++ b/lib/infrastructure/analytic/datasources/remote_data_provider.dart @@ -0,0 +1,50 @@ +import 'dart:developer'; + +import 'package:data_channel/data_channel.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../common/api/api_client.dart'; +import '../../../common/api/api_failure.dart'; +import '../../../common/extension/extension.dart'; +import '../../../common/function/app_function.dart'; +import '../../../common/url/api_path.dart'; +import '../../../domain/analytic/analytic.dart'; +import '../analytic_dtos.dart'; + +@injectable +class AnalyticRemoteDataProvider { + final ApiClient _apiClient; + + final _logName = 'AnalyticRemoteDataProvider'; + + AnalyticRemoteDataProvider(this._apiClient); + + Future> fetchDashboard({ + required DateTime dateFrom, + required DateTime dateTo, + }) async { + try { + final response = await _apiClient.get( + ApiPath.analyticDashboard, + params: { + 'date_from': dateFrom.toServerDate(), + 'date_to': dateTo.toServerDate(), + }, + headers: getAuthorizationHeader(), + ); + + if (response.data['success'] == false) { + return DC.error(AnalyticFailure.unexpectedError()); + } + + final dashboard = DashboardAnalyticDto.fromJson( + response.data['data'] as Map, + ); + + return DC.data(dashboard); + } on ApiFailure catch (e, s) { + log('fetchDashboard', name: _logName, error: e, stackTrace: s); + return DC.error(AnalyticFailure.serverError(e)); + } + } +} diff --git a/lib/infrastructure/analytic/dtos/dashboard_dto.dart b/lib/infrastructure/analytic/dtos/dashboard_dto.dart new file mode 100644 index 0000000..dccec51 --- /dev/null +++ b/lib/infrastructure/analytic/dtos/dashboard_dto.dart @@ -0,0 +1,149 @@ +part of '../analytic_dtos.dart'; + +@freezed +class DashboardAnalyticDto with _$DashboardAnalyticDto { + const DashboardAnalyticDto._(); + + const factory DashboardAnalyticDto({ + @JsonKey(name: "organization_id") String? organizationId, + @JsonKey(name: "outlet_id") String? outletId, + @JsonKey(name: "date_from") String? dateFrom, + @JsonKey(name: "date_to") String? dateTo, + @JsonKey(name: "overview") DashboardOverviewDto? overview, + @JsonKey(name: "top_products") List? topProducts, + @JsonKey(name: "payment_methods") + List? paymentMethods, + @JsonKey(name: "recent_sales") List? recentSales, + }) = _DashboardAnalyticDto; + + factory DashboardAnalyticDto.fromJson(Map json) => + _$DashboardAnalyticDtoFromJson(json); + + // Optional mapping ke domain + DashboardAnalytic toDomain() => DashboardAnalytic( + organizationId: organizationId ?? '', + outletId: outletId ?? '', + dateFrom: dateFrom ?? '', + dateTo: dateTo ?? '', + overview: overview?.toDomain() ?? DashboardOverview.empty(), + topProducts: topProducts?.map((e) => e.toDomain()).toList() ?? [], + paymentMethods: paymentMethods?.map((e) => e.toDomain()).toList() ?? [], + recentSales: recentSales?.map((e) => e.toDomain()).toList() ?? [], + ); +} + +@freezed +class DashboardOverviewDto with _$DashboardOverviewDto { + const DashboardOverviewDto._(); + + const factory DashboardOverviewDto({ + @JsonKey(name: "total_sales") int? totalSales, + @JsonKey(name: "total_orders") int? totalOrders, + @JsonKey(name: "average_order_value") double? averageOrderValue, + @JsonKey(name: "total_customers") int? totalCustomers, + @JsonKey(name: "voided_orders") int? voidedOrders, + @JsonKey(name: "refunded_orders") int? refundedOrders, + }) = _DashboardOverviewDto; + + factory DashboardOverviewDto.fromJson(Map json) => + _$DashboardOverviewDtoFromJson(json); + + // Optional mapping ke domain + DashboardOverview toDomain() => DashboardOverview( + totalSales: totalSales ?? 0, + totalOrders: totalOrders ?? 0, + averageOrderValue: averageOrderValue ?? 0.0, + totalCustomers: totalCustomers ?? 0, + voidedOrders: voidedOrders ?? 0, + refundedOrders: refundedOrders ?? 0, + ); +} + +@freezed +class DashboardTopProductDto with _$DashboardTopProductDto { + const DashboardTopProductDto._(); + + const factory DashboardTopProductDto({ + @JsonKey(name: "product_id") String? productId, + @JsonKey(name: "product_name") String? productName, + @JsonKey(name: "category_id") String? categoryId, + @JsonKey(name: "category_name") String? categoryName, + @JsonKey(name: "quantity_sold") int? quantitySold, + @JsonKey(name: "revenue") int? revenue, + @JsonKey(name: "average_price") double? averagePrice, + @JsonKey(name: "order_count") int? orderCount, + }) = _DashboardTopProductDto; + + factory DashboardTopProductDto.fromJson(Map json) => + _$DashboardTopProductDtoFromJson(json); + + // Optional mapping ke domain + DashboardTopProduct toDomain() => DashboardTopProduct( + productId: productId ?? '', + productName: productName ?? '', + categoryId: categoryId ?? '', + categoryName: categoryName ?? '', + quantitySold: quantitySold ?? 0, + revenue: revenue ?? 0, + averagePrice: averagePrice ?? 0.0, + orderCount: orderCount ?? 0, + ); +} + +@freezed +class DashboardPaymentMethodDto with _$DashboardPaymentMethodDto { + const DashboardPaymentMethodDto._(); + + const factory DashboardPaymentMethodDto({ + @JsonKey(name: "payment_method_id") String? paymentMethodId, + @JsonKey(name: "payment_method_name") String? paymentMethodName, + @JsonKey(name: "payment_method_type") String? paymentMethodType, + @JsonKey(name: "total_amount") int? totalAmount, + @JsonKey(name: "order_count") int? orderCount, + @JsonKey(name: "payment_count") int? paymentCount, + @JsonKey(name: "percentage") double? percentage, + }) = _DashboardPaymentMethodDto; + + factory DashboardPaymentMethodDto.fromJson(Map json) => + _$DashboardPaymentMethodDtoFromJson(json); + + // Optional mapping ke domain + DashboardPaymentMethod toDomain() => DashboardPaymentMethod( + paymentMethodId: paymentMethodId ?? '', + paymentMethodName: paymentMethodName ?? '', + paymentMethodType: paymentMethodType ?? '', + totalAmount: totalAmount ?? 0, + orderCount: orderCount ?? 0, + paymentCount: paymentCount ?? 0, + percentage: percentage ?? 0.0, + ); +} + +@freezed +class DashboardRecentSaleDto with _$DashboardRecentSaleDto { + const DashboardRecentSaleDto._(); + + const factory DashboardRecentSaleDto({ + @JsonKey(name: "date") String? date, + @JsonKey(name: "sales") int? sales, + @JsonKey(name: "orders") int? orders, + @JsonKey(name: "items") int? items, + @JsonKey(name: "tax") int? tax, + @JsonKey(name: "discount") int? discount, + @JsonKey(name: "net_sales") int? netSales, + }) = _DashboardRecentSaleDto; + + factory DashboardRecentSaleDto.fromJson(Map json) => + _$DashboardRecentSaleDtoFromJson(json); + + // Optional mapping ke domain + DashboardRecentSale toDomain() => DashboardRecentSale( + date: date ?? '', + sales: sales ?? 0, + orders: orders ?? 0, + items: items ?? 0, + tax: tax ?? 0, + discount: discount ?? 0, + netSales: netSales ?? 0, + ); +} diff --git a/lib/infrastructure/analytic/repositories/analytic_repository.dart b/lib/infrastructure/analytic/repositories/analytic_repository.dart new file mode 100644 index 0000000..366b591 --- /dev/null +++ b/lib/infrastructure/analytic/repositories/analytic_repository.dart @@ -0,0 +1,40 @@ +import 'dart:developer'; + +import 'package:dartz/dartz.dart'; +import 'package:injectable/injectable.dart'; + +import '../../../domain/analytic/analytic.dart'; +import '../datasources/remote_data_provider.dart'; + +@Injectable(as: IAnalyticRepository) +class AnalyticRepository implements IAnalyticRepository { + final AnalyticRemoteDataProvider _dataProvider; + + final _logName = 'AnalyticRepository'; + + AnalyticRepository(this._dataProvider); + + @override + Future> getDashboard({ + required DateTime dateFrom, + required DateTime dateTo, + }) async { + try { + final result = await _dataProvider.fetchDashboard( + dateFrom: dateFrom, + dateTo: dateTo, + ); + + if (result.hasError) { + return left(result.error!); + } + + final dashboard = result.data!.toDomain(); + + return right(dashboard); + } catch (e) { + log('getDashboardError', name: _logName, error: e); + return left(const AnalyticFailure.unexpectedError()); + } + } +} diff --git a/lib/injection.config.dart b/lib/injection.config.dart index 56d3d0e..a8efc5e 100644 --- a/lib/injection.config.dart +++ b/lib/injection.config.dart @@ -9,6 +9,8 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:apskel_pos_flutter_v2/application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart' + as _i80; import 'package:apskel_pos_flutter_v2/application/auth/auth_bloc.dart' as _i343; import 'package:apskel_pos_flutter_v2/application/auth/login_form/login_form_bloc.dart' as _i46; @@ -54,6 +56,7 @@ import 'package:apskel_pos_flutter_v2/common/di/di_shared_preferences.dart' as _i135; import 'package:apskel_pos_flutter_v2/common/network/network_client.dart' as _i171; +import 'package:apskel_pos_flutter_v2/domain/analytic/analytic.dart' as _i346; import 'package:apskel_pos_flutter_v2/domain/auth/auth.dart' as _i776; import 'package:apskel_pos_flutter_v2/domain/category/category.dart' as _i502; import 'package:apskel_pos_flutter_v2/domain/customer/customer.dart' as _i143; @@ -64,6 +67,10 @@ import 'package:apskel_pos_flutter_v2/domain/payment_method/payment_method.dart' import 'package:apskel_pos_flutter_v2/domain/product/product.dart' as _i44; import 'package:apskel_pos_flutter_v2/domain/table/table.dart' as _i983; import 'package:apskel_pos_flutter_v2/env.dart' as _i923; +import 'package:apskel_pos_flutter_v2/infrastructure/analytic/datasources/remote_data_provider.dart' + as _i708; +import 'package:apskel_pos_flutter_v2/infrastructure/analytic/repositories/analytic_repository.dart' + as _i288; import 'package:apskel_pos_flutter_v2/infrastructure/auth/datasources/local_data_provider.dart' as _i204; import 'package:apskel_pos_flutter_v2/infrastructure/auth/datasources/remote_data_provider.dart' @@ -182,6 +189,9 @@ extension GetItInjectableX on _i174.GetIt { gh.factory<_i841.CustomerRemoteDataProvider>( () => _i841.CustomerRemoteDataProvider(gh<_i457.ApiClient>()), ); + gh.factory<_i708.AnalyticRemoteDataProvider>( + () => _i708.AnalyticRemoteDataProvider(gh<_i457.ApiClient>()), + ); gh.factory<_i776.IAuthRepository>( () => _i941.AuthRepository( gh<_i370.AuthRemoteDataProvider>(), @@ -256,6 +266,9 @@ extension GetItInjectableX on _i174.GetIt { gh.factory<_i683.CustomerLoaderBloc>( () => _i683.CustomerLoaderBloc(gh<_i143.ICustomerRepository>()), ); + gh.factory<_i346.IAnalyticRepository>( + () => _i288.AnalyticRepository(gh<_i708.AnalyticRemoteDataProvider>()), + ); gh.factory<_i952.PaymentMethodLoaderBloc>( () => _i952.PaymentMethodLoaderBloc(gh<_i297.IPaymentMethodRepository>()), ); @@ -277,6 +290,9 @@ extension GetItInjectableX on _i174.GetIt { gh<_i502.ICategoryRepository>(), ), ); + gh.factory<_i80.DashboardAnalyticLoaderBloc>( + () => _i80.DashboardAnalyticLoaderBloc(gh<_i346.IAnalyticRepository>()), + ); return this; } } diff --git a/lib/presentation/components/error/analytic_error_state_widget.dart b/lib/presentation/components/error/analytic_error_state_widget.dart new file mode 100644 index 0000000..8b2f572 --- /dev/null +++ b/lib/presentation/components/error/analytic_error_state_widget.dart @@ -0,0 +1,43 @@ +import 'package:flutter/widgets.dart'; + +import '../../../common/data/report_menu.dart'; +import '../../../domain/analytic/analytic.dart'; +import '../card/error_card.dart'; + +class AnalyticErrorStateWidget extends StatelessWidget { + final AnalyticFailure failure; + final ReportMenu menu; + final Function() onRefresh; + const AnalyticErrorStateWidget({ + super.key, + required this.failure, + required this.menu, + required this.onRefresh, + }); + + @override + Widget build(BuildContext context) { + return failure.maybeMap( + orElse: () => ErrorCard( + title: menu.title, + message: 'Terjadi kesalahan, Silakan coba lagi!', + onTap: onRefresh, + ), + dynamicErrorMessage: (value) => ErrorCard( + title: menu.title, + message: value.erroMessage, + onTap: onRefresh, + ), + serverError: (value) => ErrorCard( + title: menu.title, + message: 'Server Error, Silakan coba lagi!', + onTap: onRefresh, + ), + unexpectedError: (value) => ErrorCard( + title: menu.title, + message: 'Terjadi kesalahan, Silakan coba lagi!', + onTap: onRefresh, + ), + ); + } +} diff --git a/lib/presentation/components/widgets/report/report_header.dart b/lib/presentation/components/widgets/report/report_header.dart new file mode 100644 index 0000000..367015f --- /dev/null +++ b/lib/presentation/components/widgets/report/report_header.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +import '../../../../common/data/report_menu.dart'; +import '../../../../common/extension/extension.dart'; +import '../../../../common/theme/theme.dart'; +import '../../spaces/space.dart'; + +class ReportHeader extends StatelessWidget { + final ReportMenu menu; + final DateTime endDate; + final DateTime startDate; + const ReportHeader({ + super.key, + required this.menu, + required this.endDate, + required this.startDate, + }); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + menu.title, + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(4), + Text( + menu.subtitle, + style: AppStyle.md.copyWith(color: AppColor.textSecondary), + ), + ], + ), + Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: AppColor.primary, + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.calendar_today, color: Colors.white, size: 16), + const SizedBox(width: 8), + Text( + startDate.toSimpleMonthDate() == endDate.toSimpleMonthDate() + ? startDate.toSimpleMonthDate() + : '${startDate.toSimpleMonthDate()} - ${endDate.toSimpleMonthDate()}', + style: AppStyle.sm.copyWith( + color: Colors.white, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/presentation/components/widgets/report/report_summary_card.dart b/lib/presentation/components/widgets/report/report_summary_card.dart new file mode 100644 index 0000000..398cfac --- /dev/null +++ b/lib/presentation/components/widgets/report/report_summary_card.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +import '../../../../common/theme/theme.dart'; +import '../../spaces/space.dart'; + +class ReportSummaryCard extends StatelessWidget { + final Color color; + final IconData icon; + final String title; + final String value; + const ReportSummaryCard({ + super.key, + required this.color, + required this.icon, + required this.title, + required this.value, + }); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(18), + decoration: BoxDecoration( + color: AppColor.white, + borderRadius: BorderRadius.circular(14), + border: Border.all(color: Colors.grey[200]!), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: color.withOpacity(0.12), + borderRadius: BorderRadius.circular(10), + ), + child: Icon(icon, color: color, size: 22), + ), + SpaceWidth(12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + value, + style: AppStyle.xxl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(4), + Text( + title, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w600, + color: AppColor.textPrimary, + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/report_page.dart b/lib/presentation/pages/main/pages/report/report_page.dart index c5768a5..f1faf28 100644 --- a/lib/presentation/pages/main/pages/report/report_page.dart +++ b/lib/presentation/pages/main/pages/report/report_page.dart @@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import '../../../../../application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart'; import '../../../../../application/report/report_bloc.dart'; import '../../../../../common/data/report_menu.dart'; import '../../../../../common/theme/theme.dart'; @@ -11,6 +12,7 @@ import '../../../../components/page/page_title.dart'; import '../../../../components/picker/date_range_picker.dart'; import '../../../../components/spaces/space.dart'; import '../../../../router/app_router.gr.dart'; +import 'sections/report_dashboard_section.dart'; import 'widgets/report_menu_card.dart'; @RoutePage() @@ -27,6 +29,7 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { return Column( children: [ PageTitle( + isBack: false, title: 'Report', subtitle: state.rangeDateFormatted, actionWidget: [ @@ -51,6 +54,11 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { ), SpaceWidth(8), AppIconButton(icons: Icons.download_outlined, onTap: () {}), + SpaceWidth(8), + AppIconButton( + icons: Icons.refresh_outlined, + onTap: () => onFetched(context, state), + ), ], ), Expanded( @@ -81,6 +89,8 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { title: reportMenus[index].title, ), ); + + onFetched(context, state); } }, ), @@ -94,7 +104,20 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { child: Material( color: AppColor.background, child: switch (state.selectedMenu) { - 0 => Text(state.title), + 0 => + BlocBuilder< + DashboardAnalyticLoaderBloc, + DashboardAnalyticLoaderState + >( + builder: (context, dashboard) { + return ReportDashboardSection( + menu: reportMenus[state.selectedMenu], + state: dashboard, + startDate: state.startDate, + endDate: state.endDate, + ); + }, + ), 1 => Text(state.title), 2 => Text(state.title), 3 => Text(state.title), @@ -117,7 +140,41 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { ); } + void onFetched(BuildContext context, ReportState state) { + switch (state.selectedMenu) { + case 0: + return context.read().add( + DashboardAnalyticLoaderEvent.fetched( + startDate: state.startDate, + endDate: state.endDate, + ), + ); + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + default: + return; + } + } + @override - Widget wrappedRoute(BuildContext context) => - BlocProvider(create: (context) => getIt(), child: this); + Widget wrappedRoute(BuildContext context) => MultiBlocProvider( + providers: [ + BlocProvider(create: (context) => getIt()), + BlocProvider( + create: (context) => getIt() + ..add( + DashboardAnalyticLoaderEvent.fetched( + startDate: DateTime.now().subtract(const Duration(days: 30)), + endDate: DateTime.now(), + ), + ), + ), + ], + child: this, + ); } diff --git a/lib/presentation/pages/main/pages/report/sections/report_dashboard_section.dart b/lib/presentation/pages/main/pages/report/sections/report_dashboard_section.dart new file mode 100644 index 0000000..be3257d --- /dev/null +++ b/lib/presentation/pages/main/pages/report/sections/report_dashboard_section.dart @@ -0,0 +1,184 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../../application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart'; +import '../../../../../../common/data/report_menu.dart'; +import '../../../../../../common/extension/extension.dart'; +import '../../../../../../common/theme/theme.dart'; +import '../../../../../components/error/analytic_error_state_widget.dart'; +import '../../../../../components/loader/loader_with_text.dart'; +import '../../../../../components/spaces/space.dart'; +import '../../../../../components/widgets/report/report_header.dart'; +import '../../../../../components/widgets/report/report_summary_card.dart'; +import '../widgets/dashboard/report_dashboard_order.dart'; +import '../widgets/dashboard/report_dashboard_product_chart.dart'; +import '../widgets/dashboard/report_dashboard_sales_chart.dart'; +import '../widgets/dashboard/report_dashboard_top_product.dart'; + +class ReportDashboardSection extends StatelessWidget { + final ReportMenu menu; + final DashboardAnalyticLoaderState state; + final DateTime startDate; + final DateTime endDate; + + const ReportDashboardSection({ + super.key, + required this.menu, + required this.state, + required this.startDate, + required this.endDate, + }); + + @override + Widget build(BuildContext context) { + if (state.isFetching) { + return const Center(child: LoaderWithText()); + } + + return state.failureOption.fold( + () => RefreshIndicator( + backgroundColor: AppColor.white, + color: AppColor.primary, + onRefresh: () { + context.read().add( + DashboardAnalyticLoaderEvent.fetched( + startDate: startDate, + endDate: endDate, + ), + ); + + return Future.value(); + }, + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + ReportHeader(menu: menu, startDate: startDate, endDate: endDate), + _buildSummary(), + Padding( + padding: const EdgeInsets.only(top: 16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 2, + child: ReportDashboardSalesChart( + sales: List.of(state.dashboardAnalytic.recentSales) + ..sort( + (a, b) => DateTime.parse( + a.date, + ).compareTo(DateTime.parse(b.date)), + ), + ), + ), + SpaceWidth(12), + Expanded( + flex: 1, + child: ReportDashboardProductChart( + data: state.dashboardAnalytic.topProducts, + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(top: 16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 2, + child: ReportDashboardTopProduct( + data: state.dashboardAnalytic.topProducts, + ), + ), + SpaceWidth(12), + Expanded( + flex: 1, + child: ReportDashboardOrder(data: state.dashboardAnalytic), + ), + ], + ), + ), + ], + ), + ), + (f) => AnalyticErrorStateWidget( + failure: f, + menu: menu, + onRefresh: () => context.read().add( + DashboardAnalyticLoaderEvent.fetched( + startDate: startDate, + endDate: endDate, + ), + ), + ), + ); + } + + Padding _buildSummary() { + final successfulOrders = + state.dashboardAnalytic.overview.totalOrders - + state.dashboardAnalytic.overview.voidedOrders - + state.dashboardAnalytic.overview.refundedOrders; + + return Padding( + padding: const EdgeInsets.only(top: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: ReportSummaryCard( + color: AppColor.success, + icon: Icons.trending_up, + title: 'Total Penjualan', + value: state + .dashboardAnalytic + .overview + .totalSales + .currencyFormatRpV2, + ), + ), + SpaceWidth(12), + Expanded( + child: ReportSummaryCard( + color: AppColor.info, + icon: Icons.shopping_cart_outlined, + title: 'Total Pesanan', + value: state.dashboardAnalytic.overview.totalOrders + .toString(), + ), + ), + ], + ), + SpaceHeight(12), + Row( + children: [ + Expanded( + child: ReportSummaryCard( + color: AppColor.warning, + icon: Icons.attach_money, + title: 'Rata-rata Pesanan', + value: state + .dashboardAnalytic + .overview + .averageOrderValue + .currencyFormatRpV2, + ), + ), + SpaceWidth(12), + Expanded( + child: ReportSummaryCard( + color: AppColor.primary, + icon: Icons.check_circle_outline, + title: 'Pesanan Sukses', + value: successfulOrders.toString(), + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_order.dart b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_order.dart new file mode 100644 index 0000000..8f4f83a --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_order.dart @@ -0,0 +1,138 @@ +import 'package:flutter/material.dart'; + +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportDashboardOrder extends StatelessWidget { + final DashboardAnalytic data; + const ReportDashboardOrder({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + final successfulOrders = + data.overview.totalOrders - + data.overview.voidedOrders - + data.overview.refundedOrders; + + return Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Ringkasan Pesanan', + style: AppStyle.xl.copyWith( + fontSize: 18, + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(20), + _buildSummaryItem( + 'Total Pesanan', + '${data.overview.totalOrders}', + Icons.shopping_cart, + AppColor.info, + ), + _buildSummaryItem( + 'Pesanan Sukses', + '$successfulOrders', + Icons.check_circle, + AppColor.success, + ), + _buildSummaryItem( + 'Pesanan Dibatalkan', + '${data.overview.voidedOrders}', + Icons.cancel, + AppColor.error, + ), + _buildSummaryItem( + 'Pesanan Refund', + '${data.overview.refundedOrders}', + Icons.refresh, + AppColor.warning, + ), + const SpaceHeight(20), + // Payment Methods + if (data.paymentMethods.isNotEmpty) + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + Text( + 'Metode Pembayaran', + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w500, + color: AppColor.textPrimary, + ), + ), + const SpaceHeight(8), + ...data.paymentMethods.map( + (method) => Padding( + padding: const EdgeInsets.only(bottom: 4), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + method.paymentMethodType == 'cash' + ? Icons.payments + : Icons.credit_card, + color: AppColor.primary, + size: 16, + ), + const SpaceWidth(8), + Text( + method.paymentMethodName, + style: AppStyle.md.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.primary, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildSummaryItem( + String title, + String value, + IconData icon, + Color color, + ) { + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Row( + children: [ + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, color: color, size: 16), + ), + const SizedBox(width: 12), + Expanded(child: Text(title, style: const TextStyle(fontSize: 12))), + Text(value, style: AppStyle.md.copyWith(fontWeight: FontWeight.w600)), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_product_chart.dart b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_product_chart.dart new file mode 100644 index 0000000..49db1b9 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_product_chart.dart @@ -0,0 +1,94 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportDashboardProductChart extends StatelessWidget { + final List data; + const ReportDashboardProductChart({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + final colors = [ + AppColor.primary, + AppColor.secondary, + AppColor.info, + AppColor.warning, + AppColor.success, + ]; + + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Distribusi Produk', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(12), + SizedBox( + height: 160, + child: PieChart( + PieChartData( + sectionsSpace: 2, + centerSpaceRadius: 40, + sections: data.asMap().entries.map((entry) { + return PieChartSectionData( + color: colors[entry.key % colors.length], + value: entry.value.quantitySold.toDouble(), + title: '${entry.value.quantitySold}', + radius: 40, + titleStyle: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ); + }).toList(), + ), + ), + ), + SpaceHeight(16), + Column( + children: data.take(3).map((product) { + final index = data.indexOf(product); + + return Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Row( + children: [ + Container( + width: 8, + height: 8, + decoration: BoxDecoration( + color: colors[index % colors.length], + shape: BoxShape.circle, + ), + ), + const SizedBox(width: 8), + Expanded( + child: Text(product.productName, style: AppStyle.sm), + ), + Text( + '${product.quantitySold}', + style: AppStyle.sm.copyWith(fontWeight: FontWeight.w500), + ), + ], + ), + ); + }).toList(), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_sales_chart.dart b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_sales_chart.dart new file mode 100644 index 0000000..00487b5 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_sales_chart.dart @@ -0,0 +1,170 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '../../../../../../../common/extension/extension.dart'; +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportDashboardSalesChart extends StatelessWidget { + final List sales; + const ReportDashboardSalesChart({super.key, required this.sales}); + + @override + Widget build(BuildContext context) { + if (sales.isEmpty) { + return const Center(child: Text('Tidak ada data penjualan')); + } + + // Sort agar tanggal berurutan + final sortedSales = List.of( + sales, + )..sort((a, b) => DateTime.parse(a.date).compareTo(DateTime.parse(b.date))); + + // Convert ke FlSpot berdasarkan tanggal + final spots = sortedSales.map((sale) { + final date = DateTime.parse(sale.date); + return FlSpot( + date.millisecondsSinceEpoch.toDouble(), + sale.sales.toDouble(), + ); + }).toList(); + + // Batas min & max untuk X axis + final minX = spots.first.x; + final maxX = spots.last.x; + + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Tren Penjualan Harian', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(12), + SizedBox( + height: 220, + child: LineChart( + LineChartData( + minX: minX, + maxX: maxX, + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + fitInsideHorizontally: true, + fitInsideVertically: true, + getTooltipColor: (touchedSpot) => AppColor.primary, + getTooltipItems: (touchedSpots) { + return touchedSpots.map((spot) { + final date = DateTime.fromMillisecondsSinceEpoch( + spot.x.toInt(), + ); + final sale = spot.y.toInt(); + + return LineTooltipItem( + '${date.toFormattedDate()}\n ${sale.currencyFormatRpV2}', + AppStyle.xs.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ); + }).toList(); + }, + ), + ), + gridData: FlGridData( + show: true, + drawHorizontalLine: true, + drawVerticalLine: false, + horizontalInterval: 200000, + getDrawingHorizontalLine: (value) { + return FlLine(color: Colors.grey[200]!, strokeWidth: 1); + }, + ), + titlesData: FlTitlesData( + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 60, + getTitlesWidget: (value, meta) { + return Text( + '${(value / 1000).toInt()}K', + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontSize: 10, + ), + ); + }, + ), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: + (maxX - minX) / + (sortedSales.length > 6 ? 6 : sortedSales.length), + getTitlesWidget: (value, meta) { + final date = DateTime.fromMillisecondsSinceEpoch( + value.toInt(), + ); + final formatter = DateFormat('dd MMM'); + + // tampilkan hanya jika tanggal cocok dengan titik data sebenarnya + final match = sortedSales.any((s) { + final d = DateTime.parse(s.date); + return d.difference(date).inDays.abs() < 1; + }); + + if (!match) return const SizedBox(); + + return Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + formatter.format(date), + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontSize: 10, + ), + ), + ); + }, + ), + ), + rightTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + ), + borderData: FlBorderData(show: false), + + lineBarsData: [ + LineChartBarData( + spots: spots, + isCurved: true, + color: AppColor.primary, + dotData: const FlDotData(show: true), + belowBarData: BarAreaData( + show: true, + color: AppColor.primary.withOpacity(0.1), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_top_product.dart b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_top_product.dart new file mode 100644 index 0000000..e310fd4 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/dashboard/report_dashboard_top_product.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; + +import '../../../../../../../common/extension/extension.dart'; +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportDashboardTopProduct extends StatelessWidget { + final List data; + const ReportDashboardTopProduct({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Produk Terlaris', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(16), + Column( + children: data.map((product) { + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: const Color(0xFFF8FAFC), + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.border), + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + product.productName, + style: AppStyle.md.copyWith( + fontWeight: FontWeight.w600, + ), + ), + SpaceHeight(2), + Text( + product.categoryName, + style: AppStyle.sm.copyWith( + fontSize: 12, + color: AppColor.textSecondary, + ), + ), + ], + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + '${product.quantitySold} unit', + style: AppStyle.md.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const SpaceHeight(2), + Text( + product.revenue.currencyFormatRpV2, + style: AppStyle.sm.copyWith( + fontSize: 12, + color: AppColor.textSecondary, + ), + ), + ], + ), + ], + ), + ); + }).toList(), + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 9a30be7..36367cf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -353,6 +353,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.6" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" fake_async: dependency: transitive description: @@ -425,6 +433,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: "7ca9a40f4eb85949190e54087be8b4d6ac09dc4c54238d782a34cf1f7c011de9" + url: "https://pub.dev" + source: hosted + version: "1.1.1" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 17fc9a9..2435083 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: shimmer: ^3.0.0 dropdown_search: ^5.0.6 syncfusion_flutter_datepicker: ^31.2.3 + fl_chart: ^1.1.1 dev_dependencies: flutter_test: