diff --git a/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.dart b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.dart new file mode 100644 index 0000000..a00ae56 --- /dev/null +++ b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.dart @@ -0,0 +1,52 @@ +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 'profit_loss_analytic_loader_event.dart'; +part 'profit_loss_analytic_loader_state.dart'; +part 'profit_loss_analytic_loader_bloc.freezed.dart'; + +@injectable +class ProfitLossAnalyticLoaderBloc + extends Bloc { + final IAnalyticRepository _analyticRepository; + ProfitLossAnalyticLoaderBloc(this._analyticRepository) + : super(ProfitLossAnalyticLoaderState.initial()) { + on(_onProfitLossAnalyticLoaderEvent); + } + + Future _onProfitLossAnalyticLoaderEvent( + ProfitLossAnalyticLoaderEvent event, + Emitter emit, + ) { + return event.map( + fetched: (e) async { + emit(state.copyWith(isFetching: true, failureOption: none())); + + final result = await _analyticRepository.getProfitLoss( + dateFrom: e.startDate, + dateTo: e.endDate, + ); + + await result.fold( + (failure) async { + emit( + state.copyWith( + isFetching: false, + failureOption: optionOf(failure), + ), + ); + }, + (profitLoss) async { + emit( + state.copyWith(isFetching: false, profitLossAnalytic: profitLoss), + ); + }, + ); + }, + ); + } +} diff --git a/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.freezed.dart b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.freezed.dart new file mode 100644 index 0000000..8d41005 --- /dev/null +++ b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.freezed.dart @@ -0,0 +1,483 @@ +// 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 'profit_loss_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 _$ProfitLossAnalyticLoaderEvent { + 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 ProfitLossAnalyticLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticLoaderEventCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticLoaderEventCopyWith<$Res> { + factory $ProfitLossAnalyticLoaderEventCopyWith( + ProfitLossAnalyticLoaderEvent value, + $Res Function(ProfitLossAnalyticLoaderEvent) then, + ) = + _$ProfitLossAnalyticLoaderEventCopyWithImpl< + $Res, + ProfitLossAnalyticLoaderEvent + >; + @useResult + $Res call({DateTime startDate, DateTime endDate}); +} + +/// @nodoc +class _$ProfitLossAnalyticLoaderEventCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticLoaderEvent +> + implements $ProfitLossAnalyticLoaderEventCopyWith<$Res> { + _$ProfitLossAnalyticLoaderEventCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticLoaderEvent + /// 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 $ProfitLossAnalyticLoaderEventCopyWith<$Res> { + factory _$$FetchedImplCopyWith( + _$FetchedImpl value, + $Res Function(_$FetchedImpl) then, + ) = __$$FetchedImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({DateTime startDate, DateTime endDate}); +} + +/// @nodoc +class __$$FetchedImplCopyWithImpl<$Res> + extends _$ProfitLossAnalyticLoaderEventCopyWithImpl<$Res, _$FetchedImpl> + implements _$$FetchedImplCopyWith<$Res> { + __$$FetchedImplCopyWithImpl( + _$FetchedImpl _value, + $Res Function(_$FetchedImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticLoaderEvent + /// 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 'ProfitLossAnalyticLoaderEvent.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 ProfitLossAnalyticLoaderEvent + /// 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 ProfitLossAnalyticLoaderEvent { + const factory _Fetched({ + required final DateTime startDate, + required final DateTime endDate, + }) = _$FetchedImpl; + + @override + DateTime get startDate; + @override + DateTime get endDate; + + /// Create a copy of ProfitLossAnalyticLoaderEvent + /// 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 _$ProfitLossAnalyticLoaderState { + ProfitLossAnalytic get profitLossAnalytic => + throw _privateConstructorUsedError; + Option get failureOption => + throw _privateConstructorUsedError; + bool get isFetching => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticLoaderStateCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticLoaderStateCopyWith<$Res> { + factory $ProfitLossAnalyticLoaderStateCopyWith( + ProfitLossAnalyticLoaderState value, + $Res Function(ProfitLossAnalyticLoaderState) then, + ) = + _$ProfitLossAnalyticLoaderStateCopyWithImpl< + $Res, + ProfitLossAnalyticLoaderState + >; + @useResult + $Res call({ + ProfitLossAnalytic profitLossAnalytic, + Option failureOption, + bool isFetching, + }); + + $ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic; +} + +/// @nodoc +class _$ProfitLossAnalyticLoaderStateCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticLoaderState +> + implements $ProfitLossAnalyticLoaderStateCopyWith<$Res> { + _$ProfitLossAnalyticLoaderStateCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? profitLossAnalytic = null, + Object? failureOption = null, + Object? isFetching = null, + }) { + return _then( + _value.copyWith( + profitLossAnalytic: null == profitLossAnalytic + ? _value.profitLossAnalytic + : profitLossAnalytic // ignore: cast_nullable_to_non_nullable + as ProfitLossAnalytic, + 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 ProfitLossAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic { + return $ProfitLossAnalyticCopyWith<$Res>(_value.profitLossAnalytic, ( + value, + ) { + return _then(_value.copyWith(profitLossAnalytic: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticLoaderStateImplCopyWith<$Res> + implements $ProfitLossAnalyticLoaderStateCopyWith<$Res> { + factory _$$ProfitLossAnalyticLoaderStateImplCopyWith( + _$ProfitLossAnalyticLoaderStateImpl value, + $Res Function(_$ProfitLossAnalyticLoaderStateImpl) then, + ) = __$$ProfitLossAnalyticLoaderStateImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + ProfitLossAnalytic profitLossAnalytic, + Option failureOption, + bool isFetching, + }); + + @override + $ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic; +} + +/// @nodoc +class __$$ProfitLossAnalyticLoaderStateImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticLoaderStateCopyWithImpl< + $Res, + _$ProfitLossAnalyticLoaderStateImpl + > + implements _$$ProfitLossAnalyticLoaderStateImplCopyWith<$Res> { + __$$ProfitLossAnalyticLoaderStateImplCopyWithImpl( + _$ProfitLossAnalyticLoaderStateImpl _value, + $Res Function(_$ProfitLossAnalyticLoaderStateImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? profitLossAnalytic = null, + Object? failureOption = null, + Object? isFetching = null, + }) { + return _then( + _$ProfitLossAnalyticLoaderStateImpl( + profitLossAnalytic: null == profitLossAnalytic + ? _value.profitLossAnalytic + : profitLossAnalytic // ignore: cast_nullable_to_non_nullable + as ProfitLossAnalytic, + 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 _$ProfitLossAnalyticLoaderStateImpl + implements _ProfitLossAnalyticLoaderState { + _$ProfitLossAnalyticLoaderStateImpl({ + required this.profitLossAnalytic, + required this.failureOption, + this.isFetching = false, + }); + + @override + final ProfitLossAnalytic profitLossAnalytic; + @override + final Option failureOption; + @override + @JsonKey() + final bool isFetching; + + @override + String toString() { + return 'ProfitLossAnalyticLoaderState(profitLossAnalytic: $profitLossAnalytic, failureOption: $failureOption, isFetching: $isFetching)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticLoaderStateImpl && + (identical(other.profitLossAnalytic, profitLossAnalytic) || + other.profitLossAnalytic == profitLossAnalytic) && + (identical(other.failureOption, failureOption) || + other.failureOption == failureOption) && + (identical(other.isFetching, isFetching) || + other.isFetching == isFetching)); + } + + @override + int get hashCode => + Object.hash(runtimeType, profitLossAnalytic, failureOption, isFetching); + + /// Create a copy of ProfitLossAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticLoaderStateImplCopyWith< + _$ProfitLossAnalyticLoaderStateImpl + > + get copyWith => + __$$ProfitLossAnalyticLoaderStateImplCopyWithImpl< + _$ProfitLossAnalyticLoaderStateImpl + >(this, _$identity); +} + +abstract class _ProfitLossAnalyticLoaderState + implements ProfitLossAnalyticLoaderState { + factory _ProfitLossAnalyticLoaderState({ + required final ProfitLossAnalytic profitLossAnalytic, + required final Option failureOption, + final bool isFetching, + }) = _$ProfitLossAnalyticLoaderStateImpl; + + @override + ProfitLossAnalytic get profitLossAnalytic; + @override + Option get failureOption; + @override + bool get isFetching; + + /// Create a copy of ProfitLossAnalyticLoaderState + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticLoaderStateImplCopyWith< + _$ProfitLossAnalyticLoaderStateImpl + > + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_event.dart b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_event.dart new file mode 100644 index 0000000..1814e6c --- /dev/null +++ b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_event.dart @@ -0,0 +1,9 @@ +part of 'profit_loss_analytic_loader_bloc.dart'; + +@freezed +class ProfitLossAnalyticLoaderEvent with _$ProfitLossAnalyticLoaderEvent { + const factory ProfitLossAnalyticLoaderEvent.fetched({ + required DateTime startDate, + required DateTime endDate, + }) = _Fetched; +} diff --git a/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_state.dart b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_state.dart new file mode 100644 index 0000000..213b976 --- /dev/null +++ b/lib/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_state.dart @@ -0,0 +1,16 @@ +part of 'profit_loss_analytic_loader_bloc.dart'; + +@freezed +class ProfitLossAnalyticLoaderState with _$ProfitLossAnalyticLoaderState { + factory ProfitLossAnalyticLoaderState({ + required ProfitLossAnalytic profitLossAnalytic, + required Option failureOption, + @Default(false) bool isFetching, + }) = _ProfitLossAnalyticLoaderState; + + factory ProfitLossAnalyticLoaderState.initial() => + ProfitLossAnalyticLoaderState( + profitLossAnalytic: ProfitLossAnalytic.empty(), + failureOption: none(), + ); +} diff --git a/lib/common/function/app_function.dart b/lib/common/function/app_function.dart index f346d32..35862e6 100644 --- a/lib/common/function/app_function.dart +++ b/lib/common/function/app_function.dart @@ -44,3 +44,13 @@ Map getChairDistribution(int capacity) { return {'top': side, 'bottom': side, 'left': 1, 'right': 1}; } } + +double safeDouble(double value) { + if (value.isNaN || value.isInfinite) return 0.0; + return value; +} + +int safeRound(double value) { + if (value.isNaN || value.isInfinite) return 0; + return value.round(); +} diff --git a/lib/common/url/api_path.dart b/lib/common/url/api_path.dart index 53a622f..1f56b0a 100644 --- a/lib/common/url/api_path.dart +++ b/lib/common/url/api_path.dart @@ -13,4 +13,5 @@ class ApiPath { static const String analyticProducts = '/api/v1/analytics/products'; static const String analyticPaymentMethods = '/api/v1/analytics/payment-methods'; + static const String analyticProfitLoss = '/api/v1/analytics/profit-loss'; } diff --git a/lib/domain/analytic/analytic.dart b/lib/domain/analytic/analytic.dart index e7ea3bf..3653bc9 100644 --- a/lib/domain/analytic/analytic.dart +++ b/lib/domain/analytic/analytic.dart @@ -9,5 +9,6 @@ part 'entities/dashboard_entity.dart'; part 'entities/sales_entity.dart'; part 'entities/product_analytic_entity.dart'; part 'entities/payment_method_analytic_entity.dart'; +part 'entities/profit_loss_analytic_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 index f391dd7..00b2356 100644 --- a/lib/domain/analytic/analytic.freezed.dart +++ b/lib/domain/analytic/analytic.freezed.dart @@ -3923,6 +3923,1440 @@ abstract class _PaymentMethodAnalyticSummary get copyWith => throw _privateConstructorUsedError; } +/// @nodoc +mixin _$ProfitLossAnalytic { + String get organizationId => throw _privateConstructorUsedError; + String get dateFrom => throw _privateConstructorUsedError; + String get dateTo => throw _privateConstructorUsedError; + String get groupBy => throw _privateConstructorUsedError; + ProfitLossAnalyticSummary get summary => throw _privateConstructorUsedError; + List get data => throw _privateConstructorUsedError; + List get productData => + throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalytic + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticCopyWith<$Res> { + factory $ProfitLossAnalyticCopyWith( + ProfitLossAnalytic value, + $Res Function(ProfitLossAnalytic) then, + ) = _$ProfitLossAnalyticCopyWithImpl<$Res, ProfitLossAnalytic>; + @useResult + $Res call({ + String organizationId, + String dateFrom, + String dateTo, + String groupBy, + ProfitLossAnalyticSummary summary, + List data, + List productData, + }); + + $ProfitLossAnalyticSummaryCopyWith<$Res> get summary; +} + +/// @nodoc +class _$ProfitLossAnalyticCopyWithImpl<$Res, $Val extends ProfitLossAnalytic> + implements $ProfitLossAnalyticCopyWith<$Res> { + _$ProfitLossAnalyticCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalytic + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = null, + Object? dateFrom = null, + Object? dateTo = null, + Object? groupBy = null, + Object? summary = null, + Object? data = null, + Object? productData = null, + }) { + return _then( + _value.copyWith( + organizationId: null == organizationId + ? _value.organizationId + : organizationId // 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, + groupBy: null == groupBy + ? _value.groupBy + : groupBy // ignore: cast_nullable_to_non_nullable + as String, + summary: null == summary + ? _value.summary + : summary // ignore: cast_nullable_to_non_nullable + as ProfitLossAnalyticSummary, + data: null == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as List, + productData: null == productData + ? _value.productData + : productData // ignore: cast_nullable_to_non_nullable + as List, + ) + as $Val, + ); + } + + /// Create a copy of ProfitLossAnalytic + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ProfitLossAnalyticSummaryCopyWith<$Res> get summary { + return $ProfitLossAnalyticSummaryCopyWith<$Res>(_value.summary, (value) { + return _then(_value.copyWith(summary: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticImplCopyWith<$Res> + implements $ProfitLossAnalyticCopyWith<$Res> { + factory _$$ProfitLossAnalyticImplCopyWith( + _$ProfitLossAnalyticImpl value, + $Res Function(_$ProfitLossAnalyticImpl) then, + ) = __$$ProfitLossAnalyticImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String organizationId, + String dateFrom, + String dateTo, + String groupBy, + ProfitLossAnalyticSummary summary, + List data, + List productData, + }); + + @override + $ProfitLossAnalyticSummaryCopyWith<$Res> get summary; +} + +/// @nodoc +class __$$ProfitLossAnalyticImplCopyWithImpl<$Res> + extends _$ProfitLossAnalyticCopyWithImpl<$Res, _$ProfitLossAnalyticImpl> + implements _$$ProfitLossAnalyticImplCopyWith<$Res> { + __$$ProfitLossAnalyticImplCopyWithImpl( + _$ProfitLossAnalyticImpl _value, + $Res Function(_$ProfitLossAnalyticImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalytic + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = null, + Object? dateFrom = null, + Object? dateTo = null, + Object? groupBy = null, + Object? summary = null, + Object? data = null, + Object? productData = null, + }) { + return _then( + _$ProfitLossAnalyticImpl( + organizationId: null == organizationId + ? _value.organizationId + : organizationId // 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, + groupBy: null == groupBy + ? _value.groupBy + : groupBy // ignore: cast_nullable_to_non_nullable + as String, + summary: null == summary + ? _value.summary + : summary // ignore: cast_nullable_to_non_nullable + as ProfitLossAnalyticSummary, + data: null == data + ? _value._data + : data // ignore: cast_nullable_to_non_nullable + as List, + productData: null == productData + ? _value._productData + : productData // ignore: cast_nullable_to_non_nullable + as List, + ), + ); + } +} + +/// @nodoc + +class _$ProfitLossAnalyticImpl implements _ProfitLossAnalytic { + const _$ProfitLossAnalyticImpl({ + required this.organizationId, + required this.dateFrom, + required this.dateTo, + required this.groupBy, + required this.summary, + required final List data, + required final List productData, + }) : _data = data, + _productData = productData; + + @override + final String organizationId; + @override + final String dateFrom; + @override + final String dateTo; + @override + final String groupBy; + @override + final ProfitLossAnalyticSummary summary; + final List _data; + @override + List get data { + if (_data is EqualUnmodifiableListView) return _data; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_data); + } + + final List _productData; + @override + List get productData { + if (_productData is EqualUnmodifiableListView) return _productData; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_productData); + } + + @override + String toString() { + return 'ProfitLossAnalytic(organizationId: $organizationId, dateFrom: $dateFrom, dateTo: $dateTo, groupBy: $groupBy, summary: $summary, data: $data, productData: $productData)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticImpl && + (identical(other.organizationId, organizationId) || + other.organizationId == organizationId) && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo) && + (identical(other.groupBy, groupBy) || other.groupBy == groupBy) && + (identical(other.summary, summary) || other.summary == summary) && + const DeepCollectionEquality().equals(other._data, _data) && + const DeepCollectionEquality().equals( + other._productData, + _productData, + )); + } + + @override + int get hashCode => Object.hash( + runtimeType, + organizationId, + dateFrom, + dateTo, + groupBy, + summary, + const DeepCollectionEquality().hash(_data), + const DeepCollectionEquality().hash(_productData), + ); + + /// Create a copy of ProfitLossAnalytic + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticImplCopyWith<_$ProfitLossAnalyticImpl> get copyWith => + __$$ProfitLossAnalyticImplCopyWithImpl<_$ProfitLossAnalyticImpl>( + this, + _$identity, + ); +} + +abstract class _ProfitLossAnalytic implements ProfitLossAnalytic { + const factory _ProfitLossAnalytic({ + required final String organizationId, + required final String dateFrom, + required final String dateTo, + required final String groupBy, + required final ProfitLossAnalyticSummary summary, + required final List data, + required final List productData, + }) = _$ProfitLossAnalyticImpl; + + @override + String get organizationId; + @override + String get dateFrom; + @override + String get dateTo; + @override + String get groupBy; + @override + ProfitLossAnalyticSummary get summary; + @override + List get data; + @override + List get productData; + + /// Create a copy of ProfitLossAnalytic + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticImplCopyWith<_$ProfitLossAnalyticImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$ProfitLossAnalyticSummary { + int get totalRevenue => throw _privateConstructorUsedError; + num get totalCost => throw _privateConstructorUsedError; + num get grossProfit => throw _privateConstructorUsedError; + double get grossProfitMargin => throw _privateConstructorUsedError; + int get totalTax => throw _privateConstructorUsedError; + int get totalDiscount => throw _privateConstructorUsedError; + num get netProfit => throw _privateConstructorUsedError; + double get netProfitMargin => throw _privateConstructorUsedError; + int get totalOrders => throw _privateConstructorUsedError; + double get averageProfit => throw _privateConstructorUsedError; + double get profitabilityRatio => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticSummary + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticSummaryCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticSummaryCopyWith<$Res> { + factory $ProfitLossAnalyticSummaryCopyWith( + ProfitLossAnalyticSummary value, + $Res Function(ProfitLossAnalyticSummary) then, + ) = _$ProfitLossAnalyticSummaryCopyWithImpl<$Res, ProfitLossAnalyticSummary>; + @useResult + $Res call({ + int totalRevenue, + num totalCost, + num grossProfit, + double grossProfitMargin, + int totalTax, + int totalDiscount, + num netProfit, + double netProfitMargin, + int totalOrders, + double averageProfit, + double profitabilityRatio, + }); +} + +/// @nodoc +class _$ProfitLossAnalyticSummaryCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticSummary +> + implements $ProfitLossAnalyticSummaryCopyWith<$Res> { + _$ProfitLossAnalyticSummaryCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticSummary + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalRevenue = null, + Object? totalCost = null, + Object? grossProfit = null, + Object? grossProfitMargin = null, + Object? totalTax = null, + Object? totalDiscount = null, + Object? netProfit = null, + Object? netProfitMargin = null, + Object? totalOrders = null, + Object? averageProfit = null, + Object? profitabilityRatio = null, + }) { + return _then( + _value.copyWith( + totalRevenue: null == totalRevenue + ? _value.totalRevenue + : totalRevenue // ignore: cast_nullable_to_non_nullable + as int, + totalCost: null == totalCost + ? _value.totalCost + : totalCost // ignore: cast_nullable_to_non_nullable + as num, + grossProfit: null == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num, + grossProfitMargin: null == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + totalTax: null == totalTax + ? _value.totalTax + : totalTax // ignore: cast_nullable_to_non_nullable + as int, + totalDiscount: null == totalDiscount + ? _value.totalDiscount + : totalDiscount // ignore: cast_nullable_to_non_nullable + as int, + netProfit: null == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num, + netProfitMargin: null == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + totalOrders: null == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int, + averageProfit: null == averageProfit + ? _value.averageProfit + : averageProfit // ignore: cast_nullable_to_non_nullable + as double, + profitabilityRatio: null == profitabilityRatio + ? _value.profitabilityRatio + : profitabilityRatio // ignore: cast_nullable_to_non_nullable + as double, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticSummaryImplCopyWith<$Res> + implements $ProfitLossAnalyticSummaryCopyWith<$Res> { + factory _$$ProfitLossAnalyticSummaryImplCopyWith( + _$ProfitLossAnalyticSummaryImpl value, + $Res Function(_$ProfitLossAnalyticSummaryImpl) then, + ) = __$$ProfitLossAnalyticSummaryImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + int totalRevenue, + num totalCost, + num grossProfit, + double grossProfitMargin, + int totalTax, + int totalDiscount, + num netProfit, + double netProfitMargin, + int totalOrders, + double averageProfit, + double profitabilityRatio, + }); +} + +/// @nodoc +class __$$ProfitLossAnalyticSummaryImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticSummaryCopyWithImpl< + $Res, + _$ProfitLossAnalyticSummaryImpl + > + implements _$$ProfitLossAnalyticSummaryImplCopyWith<$Res> { + __$$ProfitLossAnalyticSummaryImplCopyWithImpl( + _$ProfitLossAnalyticSummaryImpl _value, + $Res Function(_$ProfitLossAnalyticSummaryImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticSummary + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalRevenue = null, + Object? totalCost = null, + Object? grossProfit = null, + Object? grossProfitMargin = null, + Object? totalTax = null, + Object? totalDiscount = null, + Object? netProfit = null, + Object? netProfitMargin = null, + Object? totalOrders = null, + Object? averageProfit = null, + Object? profitabilityRatio = null, + }) { + return _then( + _$ProfitLossAnalyticSummaryImpl( + totalRevenue: null == totalRevenue + ? _value.totalRevenue + : totalRevenue // ignore: cast_nullable_to_non_nullable + as int, + totalCost: null == totalCost + ? _value.totalCost + : totalCost // ignore: cast_nullable_to_non_nullable + as num, + grossProfit: null == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num, + grossProfitMargin: null == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + totalTax: null == totalTax + ? _value.totalTax + : totalTax // ignore: cast_nullable_to_non_nullable + as int, + totalDiscount: null == totalDiscount + ? _value.totalDiscount + : totalDiscount // ignore: cast_nullable_to_non_nullable + as int, + netProfit: null == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num, + netProfitMargin: null == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + totalOrders: null == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int, + averageProfit: null == averageProfit + ? _value.averageProfit + : averageProfit // ignore: cast_nullable_to_non_nullable + as double, + profitabilityRatio: null == profitabilityRatio + ? _value.profitabilityRatio + : profitabilityRatio // ignore: cast_nullable_to_non_nullable + as double, + ), + ); + } +} + +/// @nodoc + +class _$ProfitLossAnalyticSummaryImpl implements _ProfitLossAnalyticSummary { + const _$ProfitLossAnalyticSummaryImpl({ + required this.totalRevenue, + required this.totalCost, + required this.grossProfit, + required this.grossProfitMargin, + required this.totalTax, + required this.totalDiscount, + required this.netProfit, + required this.netProfitMargin, + required this.totalOrders, + required this.averageProfit, + required this.profitabilityRatio, + }); + + @override + final int totalRevenue; + @override + final num totalCost; + @override + final num grossProfit; + @override + final double grossProfitMargin; + @override + final int totalTax; + @override + final int totalDiscount; + @override + final num netProfit; + @override + final double netProfitMargin; + @override + final int totalOrders; + @override + final double averageProfit; + @override + final double profitabilityRatio; + + @override + String toString() { + return 'ProfitLossAnalyticSummary(totalRevenue: $totalRevenue, totalCost: $totalCost, grossProfit: $grossProfit, grossProfitMargin: $grossProfitMargin, totalTax: $totalTax, totalDiscount: $totalDiscount, netProfit: $netProfit, netProfitMargin: $netProfitMargin, totalOrders: $totalOrders, averageProfit: $averageProfit, profitabilityRatio: $profitabilityRatio)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticSummaryImpl && + (identical(other.totalRevenue, totalRevenue) || + other.totalRevenue == totalRevenue) && + (identical(other.totalCost, totalCost) || + other.totalCost == totalCost) && + (identical(other.grossProfit, grossProfit) || + other.grossProfit == grossProfit) && + (identical(other.grossProfitMargin, grossProfitMargin) || + other.grossProfitMargin == grossProfitMargin) && + (identical(other.totalTax, totalTax) || + other.totalTax == totalTax) && + (identical(other.totalDiscount, totalDiscount) || + other.totalDiscount == totalDiscount) && + (identical(other.netProfit, netProfit) || + other.netProfit == netProfit) && + (identical(other.netProfitMargin, netProfitMargin) || + other.netProfitMargin == netProfitMargin) && + (identical(other.totalOrders, totalOrders) || + other.totalOrders == totalOrders) && + (identical(other.averageProfit, averageProfit) || + other.averageProfit == averageProfit) && + (identical(other.profitabilityRatio, profitabilityRatio) || + other.profitabilityRatio == profitabilityRatio)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + totalRevenue, + totalCost, + grossProfit, + grossProfitMargin, + totalTax, + totalDiscount, + netProfit, + netProfitMargin, + totalOrders, + averageProfit, + profitabilityRatio, + ); + + /// Create a copy of ProfitLossAnalyticSummary + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticSummaryImplCopyWith<_$ProfitLossAnalyticSummaryImpl> + get copyWith => + __$$ProfitLossAnalyticSummaryImplCopyWithImpl< + _$ProfitLossAnalyticSummaryImpl + >(this, _$identity); +} + +abstract class _ProfitLossAnalyticSummary implements ProfitLossAnalyticSummary { + const factory _ProfitLossAnalyticSummary({ + required final int totalRevenue, + required final num totalCost, + required final num grossProfit, + required final double grossProfitMargin, + required final int totalTax, + required final int totalDiscount, + required final num netProfit, + required final double netProfitMargin, + required final int totalOrders, + required final double averageProfit, + required final double profitabilityRatio, + }) = _$ProfitLossAnalyticSummaryImpl; + + @override + int get totalRevenue; + @override + num get totalCost; + @override + num get grossProfit; + @override + double get grossProfitMargin; + @override + int get totalTax; + @override + int get totalDiscount; + @override + num get netProfit; + @override + double get netProfitMargin; + @override + int get totalOrders; + @override + double get averageProfit; + @override + double get profitabilityRatio; + + /// Create a copy of ProfitLossAnalyticSummary + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticSummaryImplCopyWith<_$ProfitLossAnalyticSummaryImpl> + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$ProfitLossAnalyticItem { + String get date => throw _privateConstructorUsedError; + int get revenue => throw _privateConstructorUsedError; + num get cost => throw _privateConstructorUsedError; + num get grossProfit => throw _privateConstructorUsedError; + double get grossProfitMargin => throw _privateConstructorUsedError; + int get tax => throw _privateConstructorUsedError; + int get discount => throw _privateConstructorUsedError; + num get netProfit => throw _privateConstructorUsedError; + double get netProfitMargin => throw _privateConstructorUsedError; + int get orders => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticItem + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticItemCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticItemCopyWith<$Res> { + factory $ProfitLossAnalyticItemCopyWith( + ProfitLossAnalyticItem value, + $Res Function(ProfitLossAnalyticItem) then, + ) = _$ProfitLossAnalyticItemCopyWithImpl<$Res, ProfitLossAnalyticItem>; + @useResult + $Res call({ + String date, + int revenue, + num cost, + num grossProfit, + double grossProfitMargin, + int tax, + int discount, + num netProfit, + double netProfitMargin, + int orders, + }); +} + +/// @nodoc +class _$ProfitLossAnalyticItemCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticItem +> + implements $ProfitLossAnalyticItemCopyWith<$Res> { + _$ProfitLossAnalyticItemCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticItem + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = null, + Object? revenue = null, + Object? cost = null, + Object? grossProfit = null, + Object? grossProfitMargin = null, + Object? tax = null, + Object? discount = null, + Object? netProfit = null, + Object? netProfitMargin = null, + Object? orders = null, + }) { + return _then( + _value.copyWith( + date: null == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String, + revenue: null == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int, + cost: null == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num, + grossProfit: null == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num, + grossProfitMargin: null == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + 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, + netProfit: null == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num, + netProfitMargin: null == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + orders: null == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticItemImplCopyWith<$Res> + implements $ProfitLossAnalyticItemCopyWith<$Res> { + factory _$$ProfitLossAnalyticItemImplCopyWith( + _$ProfitLossAnalyticItemImpl value, + $Res Function(_$ProfitLossAnalyticItemImpl) then, + ) = __$$ProfitLossAnalyticItemImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String date, + int revenue, + num cost, + num grossProfit, + double grossProfitMargin, + int tax, + int discount, + num netProfit, + double netProfitMargin, + int orders, + }); +} + +/// @nodoc +class __$$ProfitLossAnalyticItemImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticItemCopyWithImpl<$Res, _$ProfitLossAnalyticItemImpl> + implements _$$ProfitLossAnalyticItemImplCopyWith<$Res> { + __$$ProfitLossAnalyticItemImplCopyWithImpl( + _$ProfitLossAnalyticItemImpl _value, + $Res Function(_$ProfitLossAnalyticItemImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticItem + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = null, + Object? revenue = null, + Object? cost = null, + Object? grossProfit = null, + Object? grossProfitMargin = null, + Object? tax = null, + Object? discount = null, + Object? netProfit = null, + Object? netProfitMargin = null, + Object? orders = null, + }) { + return _then( + _$ProfitLossAnalyticItemImpl( + date: null == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String, + revenue: null == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int, + cost: null == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num, + grossProfit: null == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num, + grossProfitMargin: null == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + 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, + netProfit: null == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num, + netProfitMargin: null == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + orders: null == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int, + ), + ); + } +} + +/// @nodoc + +class _$ProfitLossAnalyticItemImpl implements _ProfitLossAnalyticItem { + const _$ProfitLossAnalyticItemImpl({ + required this.date, + required this.revenue, + required this.cost, + required this.grossProfit, + required this.grossProfitMargin, + required this.tax, + required this.discount, + required this.netProfit, + required this.netProfitMargin, + required this.orders, + }); + + @override + final String date; + @override + final int revenue; + @override + final num cost; + @override + final num grossProfit; + @override + final double grossProfitMargin; + @override + final int tax; + @override + final int discount; + @override + final num netProfit; + @override + final double netProfitMargin; + @override + final int orders; + + @override + String toString() { + return 'ProfitLossAnalyticItem(date: $date, revenue: $revenue, cost: $cost, grossProfit: $grossProfit, grossProfitMargin: $grossProfitMargin, tax: $tax, discount: $discount, netProfit: $netProfit, netProfitMargin: $netProfitMargin, orders: $orders)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticItemImpl && + (identical(other.date, date) || other.date == date) && + (identical(other.revenue, revenue) || other.revenue == revenue) && + (identical(other.cost, cost) || other.cost == cost) && + (identical(other.grossProfit, grossProfit) || + other.grossProfit == grossProfit) && + (identical(other.grossProfitMargin, grossProfitMargin) || + other.grossProfitMargin == grossProfitMargin) && + (identical(other.tax, tax) || other.tax == tax) && + (identical(other.discount, discount) || + other.discount == discount) && + (identical(other.netProfit, netProfit) || + other.netProfit == netProfit) && + (identical(other.netProfitMargin, netProfitMargin) || + other.netProfitMargin == netProfitMargin) && + (identical(other.orders, orders) || other.orders == orders)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + date, + revenue, + cost, + grossProfit, + grossProfitMargin, + tax, + discount, + netProfit, + netProfitMargin, + orders, + ); + + /// Create a copy of ProfitLossAnalyticItem + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticItemImplCopyWith<_$ProfitLossAnalyticItemImpl> + get copyWith => + __$$ProfitLossAnalyticItemImplCopyWithImpl<_$ProfitLossAnalyticItemImpl>( + this, + _$identity, + ); +} + +abstract class _ProfitLossAnalyticItem implements ProfitLossAnalyticItem { + const factory _ProfitLossAnalyticItem({ + required final String date, + required final int revenue, + required final num cost, + required final num grossProfit, + required final double grossProfitMargin, + required final int tax, + required final int discount, + required final num netProfit, + required final double netProfitMargin, + required final int orders, + }) = _$ProfitLossAnalyticItemImpl; + + @override + String get date; + @override + int get revenue; + @override + num get cost; + @override + num get grossProfit; + @override + double get grossProfitMargin; + @override + int get tax; + @override + int get discount; + @override + num get netProfit; + @override + double get netProfitMargin; + @override + int get orders; + + /// Create a copy of ProfitLossAnalyticItem + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticItemImplCopyWith<_$ProfitLossAnalyticItemImpl> + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +mixin _$ProfitLossAnalyticProduct { + 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; + num get cost => throw _privateConstructorUsedError; + num get grossProfit => throw _privateConstructorUsedError; + double get grossProfitMargin => throw _privateConstructorUsedError; + int get averagePrice => throw _privateConstructorUsedError; + num get averageCost => throw _privateConstructorUsedError; + num get profitPerUnit => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticProduct + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticProductCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticProductCopyWith<$Res> { + factory $ProfitLossAnalyticProductCopyWith( + ProfitLossAnalyticProduct value, + $Res Function(ProfitLossAnalyticProduct) then, + ) = _$ProfitLossAnalyticProductCopyWithImpl<$Res, ProfitLossAnalyticProduct>; + @useResult + $Res call({ + String productId, + String productName, + String categoryId, + String categoryName, + int quantitySold, + int revenue, + num cost, + num grossProfit, + double grossProfitMargin, + int averagePrice, + num averageCost, + num profitPerUnit, + }); +} + +/// @nodoc +class _$ProfitLossAnalyticProductCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticProduct +> + implements $ProfitLossAnalyticProductCopyWith<$Res> { + _$ProfitLossAnalyticProductCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticProduct + /// 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? cost = null, + Object? grossProfit = null, + Object? grossProfitMargin = null, + Object? averagePrice = null, + Object? averageCost = null, + Object? profitPerUnit = 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, + cost: null == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num, + grossProfit: null == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num, + grossProfitMargin: null == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + averagePrice: null == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as int, + averageCost: null == averageCost + ? _value.averageCost + : averageCost // ignore: cast_nullable_to_non_nullable + as num, + profitPerUnit: null == profitPerUnit + ? _value.profitPerUnit + : profitPerUnit // ignore: cast_nullable_to_non_nullable + as num, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticProductImplCopyWith<$Res> + implements $ProfitLossAnalyticProductCopyWith<$Res> { + factory _$$ProfitLossAnalyticProductImplCopyWith( + _$ProfitLossAnalyticProductImpl value, + $Res Function(_$ProfitLossAnalyticProductImpl) then, + ) = __$$ProfitLossAnalyticProductImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + String productId, + String productName, + String categoryId, + String categoryName, + int quantitySold, + int revenue, + num cost, + num grossProfit, + double grossProfitMargin, + int averagePrice, + num averageCost, + num profitPerUnit, + }); +} + +/// @nodoc +class __$$ProfitLossAnalyticProductImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticProductCopyWithImpl< + $Res, + _$ProfitLossAnalyticProductImpl + > + implements _$$ProfitLossAnalyticProductImplCopyWith<$Res> { + __$$ProfitLossAnalyticProductImplCopyWithImpl( + _$ProfitLossAnalyticProductImpl _value, + $Res Function(_$ProfitLossAnalyticProductImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticProduct + /// 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? cost = null, + Object? grossProfit = null, + Object? grossProfitMargin = null, + Object? averagePrice = null, + Object? averageCost = null, + Object? profitPerUnit = null, + }) { + return _then( + _$ProfitLossAnalyticProductImpl( + 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, + cost: null == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num, + grossProfit: null == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num, + grossProfitMargin: null == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double, + averagePrice: null == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as int, + averageCost: null == averageCost + ? _value.averageCost + : averageCost // ignore: cast_nullable_to_non_nullable + as num, + profitPerUnit: null == profitPerUnit + ? _value.profitPerUnit + : profitPerUnit // ignore: cast_nullable_to_non_nullable + as num, + ), + ); + } +} + +/// @nodoc + +class _$ProfitLossAnalyticProductImpl implements _ProfitLossAnalyticProduct { + const _$ProfitLossAnalyticProductImpl({ + required this.productId, + required this.productName, + required this.categoryId, + required this.categoryName, + required this.quantitySold, + required this.revenue, + required this.cost, + required this.grossProfit, + required this.grossProfitMargin, + required this.averagePrice, + required this.averageCost, + required this.profitPerUnit, + }); + + @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 num cost; + @override + final num grossProfit; + @override + final double grossProfitMargin; + @override + final int averagePrice; + @override + final num averageCost; + @override + final num profitPerUnit; + + @override + String toString() { + return 'ProfitLossAnalyticProduct(productId: $productId, productName: $productName, categoryId: $categoryId, categoryName: $categoryName, quantitySold: $quantitySold, revenue: $revenue, cost: $cost, grossProfit: $grossProfit, grossProfitMargin: $grossProfitMargin, averagePrice: $averagePrice, averageCost: $averageCost, profitPerUnit: $profitPerUnit)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticProductImpl && + (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.cost, cost) || other.cost == cost) && + (identical(other.grossProfit, grossProfit) || + other.grossProfit == grossProfit) && + (identical(other.grossProfitMargin, grossProfitMargin) || + other.grossProfitMargin == grossProfitMargin) && + (identical(other.averagePrice, averagePrice) || + other.averagePrice == averagePrice) && + (identical(other.averageCost, averageCost) || + other.averageCost == averageCost) && + (identical(other.profitPerUnit, profitPerUnit) || + other.profitPerUnit == profitPerUnit)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + productId, + productName, + categoryId, + categoryName, + quantitySold, + revenue, + cost, + grossProfit, + grossProfitMargin, + averagePrice, + averageCost, + profitPerUnit, + ); + + /// Create a copy of ProfitLossAnalyticProduct + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticProductImplCopyWith<_$ProfitLossAnalyticProductImpl> + get copyWith => + __$$ProfitLossAnalyticProductImplCopyWithImpl< + _$ProfitLossAnalyticProductImpl + >(this, _$identity); +} + +abstract class _ProfitLossAnalyticProduct implements ProfitLossAnalyticProduct { + const factory _ProfitLossAnalyticProduct({ + 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 num cost, + required final num grossProfit, + required final double grossProfitMargin, + required final int averagePrice, + required final num averageCost, + required final num profitPerUnit, + }) = _$ProfitLossAnalyticProductImpl; + + @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 + num get cost; + @override + num get grossProfit; + @override + double get grossProfitMargin; + @override + int get averagePrice; + @override + num get averageCost; + @override + num get profitPerUnit; + + /// Create a copy of ProfitLossAnalyticProduct + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticProductImplCopyWith<_$ProfitLossAnalyticProductImpl> + get copyWith => throw _privateConstructorUsedError; +} + /// @nodoc mixin _$AnalyticFailure { @optionalTypeArgs diff --git a/lib/domain/analytic/entities/profit_loss_analytic_entity.dart b/lib/domain/analytic/entities/profit_loss_analytic_entity.dart new file mode 100644 index 0000000..36d6a8d --- /dev/null +++ b/lib/domain/analytic/entities/profit_loss_analytic_entity.dart @@ -0,0 +1,117 @@ +part of '../analytic.dart'; + +@freezed +class ProfitLossAnalytic with _$ProfitLossAnalytic { + const factory ProfitLossAnalytic({ + required String organizationId, + required String dateFrom, + required String dateTo, + required String groupBy, + required ProfitLossAnalyticSummary summary, + required List data, + required List productData, + }) = _ProfitLossAnalytic; + + factory ProfitLossAnalytic.empty() => ProfitLossAnalytic( + organizationId: '', + dateFrom: '', + dateTo: '', + groupBy: 'day', + summary: ProfitLossAnalyticSummary.empty(), + data: const [], + productData: const [], + ); +} + +@freezed +class ProfitLossAnalyticSummary with _$ProfitLossAnalyticSummary { + const factory ProfitLossAnalyticSummary({ + required int totalRevenue, + required num totalCost, + required num grossProfit, + required double grossProfitMargin, + required int totalTax, + required int totalDiscount, + required num netProfit, + required double netProfitMargin, + required int totalOrders, + required double averageProfit, + required double profitabilityRatio, + }) = _ProfitLossAnalyticSummary; + + factory ProfitLossAnalyticSummary.empty() => const ProfitLossAnalyticSummary( + totalRevenue: 0, + totalCost: 0, + grossProfit: 0, + grossProfitMargin: 0.0, + totalTax: 0, + totalDiscount: 0, + netProfit: 0, + netProfitMargin: 0.0, + totalOrders: 0, + averageProfit: 0.0, + profitabilityRatio: 0.0, + ); +} + +@freezed +class ProfitLossAnalyticItem with _$ProfitLossAnalyticItem { + const factory ProfitLossAnalyticItem({ + required String date, + required int revenue, + required num cost, + required num grossProfit, + required double grossProfitMargin, + required int tax, + required int discount, + required num netProfit, + required double netProfitMargin, + required int orders, + }) = _ProfitLossAnalyticItem; + + factory ProfitLossAnalyticItem.empty() => const ProfitLossAnalyticItem( + date: '', + revenue: 0, + cost: 0, + grossProfit: 0, + grossProfitMargin: 0.0, + tax: 0, + discount: 0, + netProfit: 0, + netProfitMargin: 0.0, + orders: 0, + ); +} + +@freezed +class ProfitLossAnalyticProduct with _$ProfitLossAnalyticProduct { + const factory ProfitLossAnalyticProduct({ + required String productId, + required String productName, + required String categoryId, + required String categoryName, + required int quantitySold, + required int revenue, + required num cost, + required num grossProfit, + required double grossProfitMargin, + required int averagePrice, + required num averageCost, + required num profitPerUnit, + }) = _ProfitLossAnalyticProduct; + + factory ProfitLossAnalyticProduct.empty() => const ProfitLossAnalyticProduct( + productId: '', + productName: '', + categoryId: '', + categoryName: '', + quantitySold: 0, + revenue: 0, + cost: 0, + grossProfit: 0, + grossProfitMargin: 0.0, + averagePrice: 0, + averageCost: 0, + profitPerUnit: 0, + ); +} diff --git a/lib/domain/analytic/repositories/i_analytic_repository.dart b/lib/domain/analytic/repositories/i_analytic_repository.dart index 10a3dad..3bbd636 100644 --- a/lib/domain/analytic/repositories/i_analytic_repository.dart +++ b/lib/domain/analytic/repositories/i_analytic_repository.dart @@ -17,4 +17,8 @@ abstract class IAnalyticRepository { required DateTime dateFrom, required DateTime dateTo, }); + Future> getProfitLoss({ + required DateTime dateFrom, + required DateTime dateTo, + }); } diff --git a/lib/infrastructure/analytic/analytic_dtos.dart b/lib/infrastructure/analytic/analytic_dtos.dart index 6d7fc76..fdb6476 100644 --- a/lib/infrastructure/analytic/analytic_dtos.dart +++ b/lib/infrastructure/analytic/analytic_dtos.dart @@ -9,3 +9,4 @@ part 'dtos/dashboard_dto.dart'; part 'dtos/sales_dto.dart'; part 'dtos/product_analytic_dto.dart'; part 'dtos/payment_method_analytic_dto.dart'; +part 'dtos/profit_loss_analytic_dto.dart'; diff --git a/lib/infrastructure/analytic/analytic_dtos.freezed.dart b/lib/infrastructure/analytic/analytic_dtos.freezed.dart index cfdf56e..373381b 100644 --- a/lib/infrastructure/analytic/analytic_dtos.freezed.dart +++ b/lib/infrastructure/analytic/analytic_dtos.freezed.dart @@ -4346,3 +4346,1689 @@ abstract class _PaymentMethodAnalyticSummaryDto > get copyWith => throw _privateConstructorUsedError; } + +ProfitLossAnalyticDto _$ProfitLossAnalyticDtoFromJson( + Map json, +) { + return _ProfitLossAnalyticDto.fromJson(json); +} + +/// @nodoc +mixin _$ProfitLossAnalyticDto { + @JsonKey(name: "organization_id") + String? get organizationId => throw _privateConstructorUsedError; + @JsonKey(name: "date_from") + String? get dateFrom => throw _privateConstructorUsedError; + @JsonKey(name: "date_to") + String? get dateTo => throw _privateConstructorUsedError; + @JsonKey(name: "group_by") + String? get groupBy => throw _privateConstructorUsedError; + @JsonKey(name: "summary") + ProfitLossAnalyticSummaryDto? get summary => + throw _privateConstructorUsedError; + @JsonKey(name: "data") + List? get data => + throw _privateConstructorUsedError; + @JsonKey(name: "product_data") + List? get productData => + throw _privateConstructorUsedError; + + /// Serializes this ProfitLossAnalyticDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticDtoCopyWith<$Res> { + factory $ProfitLossAnalyticDtoCopyWith( + ProfitLossAnalyticDto value, + $Res Function(ProfitLossAnalyticDto) then, + ) = _$ProfitLossAnalyticDtoCopyWithImpl<$Res, ProfitLossAnalyticDto>; + @useResult + $Res call({ + @JsonKey(name: "organization_id") String? organizationId, + @JsonKey(name: "date_from") String? dateFrom, + @JsonKey(name: "date_to") String? dateTo, + @JsonKey(name: "group_by") String? groupBy, + @JsonKey(name: "summary") ProfitLossAnalyticSummaryDto? summary, + @JsonKey(name: "data") List? data, + @JsonKey(name: "product_data") + List? productData, + }); + + $ProfitLossAnalyticSummaryDtoCopyWith<$Res>? get summary; +} + +/// @nodoc +class _$ProfitLossAnalyticDtoCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticDto +> + implements $ProfitLossAnalyticDtoCopyWith<$Res> { + _$ProfitLossAnalyticDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = freezed, + Object? dateFrom = freezed, + Object? dateTo = freezed, + Object? groupBy = freezed, + Object? summary = freezed, + Object? data = freezed, + Object? productData = freezed, + }) { + return _then( + _value.copyWith( + organizationId: freezed == organizationId + ? _value.organizationId + : organizationId // 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?, + groupBy: freezed == groupBy + ? _value.groupBy + : groupBy // ignore: cast_nullable_to_non_nullable + as String?, + summary: freezed == summary + ? _value.summary + : summary // ignore: cast_nullable_to_non_nullable + as ProfitLossAnalyticSummaryDto?, + data: freezed == data + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as List?, + productData: freezed == productData + ? _value.productData + : productData // ignore: cast_nullable_to_non_nullable + as List?, + ) + as $Val, + ); + } + + /// Create a copy of ProfitLossAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ProfitLossAnalyticSummaryDtoCopyWith<$Res>? get summary { + if (_value.summary == null) { + return null; + } + + return $ProfitLossAnalyticSummaryDtoCopyWith<$Res>(_value.summary!, ( + value, + ) { + return _then(_value.copyWith(summary: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticDtoImplCopyWith<$Res> + implements $ProfitLossAnalyticDtoCopyWith<$Res> { + factory _$$ProfitLossAnalyticDtoImplCopyWith( + _$ProfitLossAnalyticDtoImpl value, + $Res Function(_$ProfitLossAnalyticDtoImpl) then, + ) = __$$ProfitLossAnalyticDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "organization_id") String? organizationId, + @JsonKey(name: "date_from") String? dateFrom, + @JsonKey(name: "date_to") String? dateTo, + @JsonKey(name: "group_by") String? groupBy, + @JsonKey(name: "summary") ProfitLossAnalyticSummaryDto? summary, + @JsonKey(name: "data") List? data, + @JsonKey(name: "product_data") + List? productData, + }); + + @override + $ProfitLossAnalyticSummaryDtoCopyWith<$Res>? get summary; +} + +/// @nodoc +class __$$ProfitLossAnalyticDtoImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticDtoCopyWithImpl<$Res, _$ProfitLossAnalyticDtoImpl> + implements _$$ProfitLossAnalyticDtoImplCopyWith<$Res> { + __$$ProfitLossAnalyticDtoImplCopyWithImpl( + _$ProfitLossAnalyticDtoImpl _value, + $Res Function(_$ProfitLossAnalyticDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? organizationId = freezed, + Object? dateFrom = freezed, + Object? dateTo = freezed, + Object? groupBy = freezed, + Object? summary = freezed, + Object? data = freezed, + Object? productData = freezed, + }) { + return _then( + _$ProfitLossAnalyticDtoImpl( + organizationId: freezed == organizationId + ? _value.organizationId + : organizationId // 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?, + groupBy: freezed == groupBy + ? _value.groupBy + : groupBy // ignore: cast_nullable_to_non_nullable + as String?, + summary: freezed == summary + ? _value.summary + : summary // ignore: cast_nullable_to_non_nullable + as ProfitLossAnalyticSummaryDto?, + data: freezed == data + ? _value._data + : data // ignore: cast_nullable_to_non_nullable + as List?, + productData: freezed == productData + ? _value._productData + : productData // ignore: cast_nullable_to_non_nullable + as List?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$ProfitLossAnalyticDtoImpl extends _ProfitLossAnalyticDto { + const _$ProfitLossAnalyticDtoImpl({ + @JsonKey(name: "organization_id") this.organizationId, + @JsonKey(name: "date_from") this.dateFrom, + @JsonKey(name: "date_to") this.dateTo, + @JsonKey(name: "group_by") this.groupBy, + @JsonKey(name: "summary") this.summary, + @JsonKey(name: "data") final List? data, + @JsonKey(name: "product_data") + final List? productData, + }) : _data = data, + _productData = productData, + super._(); + + factory _$ProfitLossAnalyticDtoImpl.fromJson(Map json) => + _$$ProfitLossAnalyticDtoImplFromJson(json); + + @override + @JsonKey(name: "organization_id") + final String? organizationId; + @override + @JsonKey(name: "date_from") + final String? dateFrom; + @override + @JsonKey(name: "date_to") + final String? dateTo; + @override + @JsonKey(name: "group_by") + final String? groupBy; + @override + @JsonKey(name: "summary") + final ProfitLossAnalyticSummaryDto? summary; + final List? _data; + @override + @JsonKey(name: "data") + List? get data { + final value = _data; + if (value == null) return null; + if (_data is EqualUnmodifiableListView) return _data; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + final List? _productData; + @override + @JsonKey(name: "product_data") + List? get productData { + final value = _productData; + if (value == null) return null; + if (_productData is EqualUnmodifiableListView) return _productData; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @override + String toString() { + return 'ProfitLossAnalyticDto(organizationId: $organizationId, dateFrom: $dateFrom, dateTo: $dateTo, groupBy: $groupBy, summary: $summary, data: $data, productData: $productData)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticDtoImpl && + (identical(other.organizationId, organizationId) || + other.organizationId == organizationId) && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo) && + (identical(other.groupBy, groupBy) || other.groupBy == groupBy) && + (identical(other.summary, summary) || other.summary == summary) && + const DeepCollectionEquality().equals(other._data, _data) && + const DeepCollectionEquality().equals( + other._productData, + _productData, + )); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + organizationId, + dateFrom, + dateTo, + groupBy, + summary, + const DeepCollectionEquality().hash(_data), + const DeepCollectionEquality().hash(_productData), + ); + + /// Create a copy of ProfitLossAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticDtoImplCopyWith<_$ProfitLossAnalyticDtoImpl> + get copyWith => + __$$ProfitLossAnalyticDtoImplCopyWithImpl<_$ProfitLossAnalyticDtoImpl>( + this, + _$identity, + ); + + @override + Map toJson() { + return _$$ProfitLossAnalyticDtoImplToJson(this); + } +} + +abstract class _ProfitLossAnalyticDto extends ProfitLossAnalyticDto { + const factory _ProfitLossAnalyticDto({ + @JsonKey(name: "organization_id") final String? organizationId, + @JsonKey(name: "date_from") final String? dateFrom, + @JsonKey(name: "date_to") final String? dateTo, + @JsonKey(name: "group_by") final String? groupBy, + @JsonKey(name: "summary") final ProfitLossAnalyticSummaryDto? summary, + @JsonKey(name: "data") final List? data, + @JsonKey(name: "product_data") + final List? productData, + }) = _$ProfitLossAnalyticDtoImpl; + const _ProfitLossAnalyticDto._() : super._(); + + factory _ProfitLossAnalyticDto.fromJson(Map json) = + _$ProfitLossAnalyticDtoImpl.fromJson; + + @override + @JsonKey(name: "organization_id") + String? get organizationId; + @override + @JsonKey(name: "date_from") + String? get dateFrom; + @override + @JsonKey(name: "date_to") + String? get dateTo; + @override + @JsonKey(name: "group_by") + String? get groupBy; + @override + @JsonKey(name: "summary") + ProfitLossAnalyticSummaryDto? get summary; + @override + @JsonKey(name: "data") + List? get data; + @override + @JsonKey(name: "product_data") + List? get productData; + + /// Create a copy of ProfitLossAnalyticDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticDtoImplCopyWith<_$ProfitLossAnalyticDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +ProfitLossAnalyticSummaryDto _$ProfitLossAnalyticSummaryDtoFromJson( + Map json, +) { + return _ProfitLossAnalyticSummaryDto.fromJson(json); +} + +/// @nodoc +mixin _$ProfitLossAnalyticSummaryDto { + @JsonKey(name: "total_revenue") + int? get totalRevenue => throw _privateConstructorUsedError; + @JsonKey(name: "total_cost") + num? get totalCost => throw _privateConstructorUsedError; + @JsonKey(name: "gross_profit") + num? get grossProfit => throw _privateConstructorUsedError; + @JsonKey(name: "gross_profit_margin") + double? get grossProfitMargin => throw _privateConstructorUsedError; + @JsonKey(name: "total_tax") + int? get totalTax => throw _privateConstructorUsedError; + @JsonKey(name: "total_discount") + int? get totalDiscount => throw _privateConstructorUsedError; + @JsonKey(name: "net_profit") + num? get netProfit => throw _privateConstructorUsedError; + @JsonKey(name: "net_profit_margin") + double? get netProfitMargin => throw _privateConstructorUsedError; + @JsonKey(name: "total_orders") + int? get totalOrders => throw _privateConstructorUsedError; + @JsonKey(name: "average_profit") + double? get averageProfit => throw _privateConstructorUsedError; + @JsonKey(name: "profitability_ratio") + double? get profitabilityRatio => throw _privateConstructorUsedError; + + /// Serializes this ProfitLossAnalyticSummaryDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticSummaryDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticSummaryDtoCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticSummaryDtoCopyWith<$Res> { + factory $ProfitLossAnalyticSummaryDtoCopyWith( + ProfitLossAnalyticSummaryDto value, + $Res Function(ProfitLossAnalyticSummaryDto) then, + ) = + _$ProfitLossAnalyticSummaryDtoCopyWithImpl< + $Res, + ProfitLossAnalyticSummaryDto + >; + @useResult + $Res call({ + @JsonKey(name: "total_revenue") int? totalRevenue, + @JsonKey(name: "total_cost") num? totalCost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "total_tax") int? totalTax, + @JsonKey(name: "total_discount") int? totalDiscount, + @JsonKey(name: "net_profit") num? netProfit, + @JsonKey(name: "net_profit_margin") double? netProfitMargin, + @JsonKey(name: "total_orders") int? totalOrders, + @JsonKey(name: "average_profit") double? averageProfit, + @JsonKey(name: "profitability_ratio") double? profitabilityRatio, + }); +} + +/// @nodoc +class _$ProfitLossAnalyticSummaryDtoCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticSummaryDto +> + implements $ProfitLossAnalyticSummaryDtoCopyWith<$Res> { + _$ProfitLossAnalyticSummaryDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticSummaryDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalRevenue = freezed, + Object? totalCost = freezed, + Object? grossProfit = freezed, + Object? grossProfitMargin = freezed, + Object? totalTax = freezed, + Object? totalDiscount = freezed, + Object? netProfit = freezed, + Object? netProfitMargin = freezed, + Object? totalOrders = freezed, + Object? averageProfit = freezed, + Object? profitabilityRatio = freezed, + }) { + return _then( + _value.copyWith( + totalRevenue: freezed == totalRevenue + ? _value.totalRevenue + : totalRevenue // ignore: cast_nullable_to_non_nullable + as int?, + totalCost: freezed == totalCost + ? _value.totalCost + : totalCost // ignore: cast_nullable_to_non_nullable + as num?, + grossProfit: freezed == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num?, + grossProfitMargin: freezed == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + totalTax: freezed == totalTax + ? _value.totalTax + : totalTax // ignore: cast_nullable_to_non_nullable + as int?, + totalDiscount: freezed == totalDiscount + ? _value.totalDiscount + : totalDiscount // ignore: cast_nullable_to_non_nullable + as int?, + netProfit: freezed == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num?, + netProfitMargin: freezed == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + totalOrders: freezed == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int?, + averageProfit: freezed == averageProfit + ? _value.averageProfit + : averageProfit // ignore: cast_nullable_to_non_nullable + as double?, + profitabilityRatio: freezed == profitabilityRatio + ? _value.profitabilityRatio + : profitabilityRatio // ignore: cast_nullable_to_non_nullable + as double?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticSummaryDtoImplCopyWith<$Res> + implements $ProfitLossAnalyticSummaryDtoCopyWith<$Res> { + factory _$$ProfitLossAnalyticSummaryDtoImplCopyWith( + _$ProfitLossAnalyticSummaryDtoImpl value, + $Res Function(_$ProfitLossAnalyticSummaryDtoImpl) then, + ) = __$$ProfitLossAnalyticSummaryDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "total_revenue") int? totalRevenue, + @JsonKey(name: "total_cost") num? totalCost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "total_tax") int? totalTax, + @JsonKey(name: "total_discount") int? totalDiscount, + @JsonKey(name: "net_profit") num? netProfit, + @JsonKey(name: "net_profit_margin") double? netProfitMargin, + @JsonKey(name: "total_orders") int? totalOrders, + @JsonKey(name: "average_profit") double? averageProfit, + @JsonKey(name: "profitability_ratio") double? profitabilityRatio, + }); +} + +/// @nodoc +class __$$ProfitLossAnalyticSummaryDtoImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticSummaryDtoCopyWithImpl< + $Res, + _$ProfitLossAnalyticSummaryDtoImpl + > + implements _$$ProfitLossAnalyticSummaryDtoImplCopyWith<$Res> { + __$$ProfitLossAnalyticSummaryDtoImplCopyWithImpl( + _$ProfitLossAnalyticSummaryDtoImpl _value, + $Res Function(_$ProfitLossAnalyticSummaryDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticSummaryDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? totalRevenue = freezed, + Object? totalCost = freezed, + Object? grossProfit = freezed, + Object? grossProfitMargin = freezed, + Object? totalTax = freezed, + Object? totalDiscount = freezed, + Object? netProfit = freezed, + Object? netProfitMargin = freezed, + Object? totalOrders = freezed, + Object? averageProfit = freezed, + Object? profitabilityRatio = freezed, + }) { + return _then( + _$ProfitLossAnalyticSummaryDtoImpl( + totalRevenue: freezed == totalRevenue + ? _value.totalRevenue + : totalRevenue // ignore: cast_nullable_to_non_nullable + as int?, + totalCost: freezed == totalCost + ? _value.totalCost + : totalCost // ignore: cast_nullable_to_non_nullable + as num?, + grossProfit: freezed == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num?, + grossProfitMargin: freezed == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + totalTax: freezed == totalTax + ? _value.totalTax + : totalTax // ignore: cast_nullable_to_non_nullable + as int?, + totalDiscount: freezed == totalDiscount + ? _value.totalDiscount + : totalDiscount // ignore: cast_nullable_to_non_nullable + as int?, + netProfit: freezed == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num?, + netProfitMargin: freezed == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + totalOrders: freezed == totalOrders + ? _value.totalOrders + : totalOrders // ignore: cast_nullable_to_non_nullable + as int?, + averageProfit: freezed == averageProfit + ? _value.averageProfit + : averageProfit // ignore: cast_nullable_to_non_nullable + as double?, + profitabilityRatio: freezed == profitabilityRatio + ? _value.profitabilityRatio + : profitabilityRatio // ignore: cast_nullable_to_non_nullable + as double?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$ProfitLossAnalyticSummaryDtoImpl extends _ProfitLossAnalyticSummaryDto { + const _$ProfitLossAnalyticSummaryDtoImpl({ + @JsonKey(name: "total_revenue") this.totalRevenue, + @JsonKey(name: "total_cost") this.totalCost, + @JsonKey(name: "gross_profit") this.grossProfit, + @JsonKey(name: "gross_profit_margin") this.grossProfitMargin, + @JsonKey(name: "total_tax") this.totalTax, + @JsonKey(name: "total_discount") this.totalDiscount, + @JsonKey(name: "net_profit") this.netProfit, + @JsonKey(name: "net_profit_margin") this.netProfitMargin, + @JsonKey(name: "total_orders") this.totalOrders, + @JsonKey(name: "average_profit") this.averageProfit, + @JsonKey(name: "profitability_ratio") this.profitabilityRatio, + }) : super._(); + + factory _$ProfitLossAnalyticSummaryDtoImpl.fromJson( + Map json, + ) => _$$ProfitLossAnalyticSummaryDtoImplFromJson(json); + + @override + @JsonKey(name: "total_revenue") + final int? totalRevenue; + @override + @JsonKey(name: "total_cost") + final num? totalCost; + @override + @JsonKey(name: "gross_profit") + final num? grossProfit; + @override + @JsonKey(name: "gross_profit_margin") + final double? grossProfitMargin; + @override + @JsonKey(name: "total_tax") + final int? totalTax; + @override + @JsonKey(name: "total_discount") + final int? totalDiscount; + @override + @JsonKey(name: "net_profit") + final num? netProfit; + @override + @JsonKey(name: "net_profit_margin") + final double? netProfitMargin; + @override + @JsonKey(name: "total_orders") + final int? totalOrders; + @override + @JsonKey(name: "average_profit") + final double? averageProfit; + @override + @JsonKey(name: "profitability_ratio") + final double? profitabilityRatio; + + @override + String toString() { + return 'ProfitLossAnalyticSummaryDto(totalRevenue: $totalRevenue, totalCost: $totalCost, grossProfit: $grossProfit, grossProfitMargin: $grossProfitMargin, totalTax: $totalTax, totalDiscount: $totalDiscount, netProfit: $netProfit, netProfitMargin: $netProfitMargin, totalOrders: $totalOrders, averageProfit: $averageProfit, profitabilityRatio: $profitabilityRatio)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticSummaryDtoImpl && + (identical(other.totalRevenue, totalRevenue) || + other.totalRevenue == totalRevenue) && + (identical(other.totalCost, totalCost) || + other.totalCost == totalCost) && + (identical(other.grossProfit, grossProfit) || + other.grossProfit == grossProfit) && + (identical(other.grossProfitMargin, grossProfitMargin) || + other.grossProfitMargin == grossProfitMargin) && + (identical(other.totalTax, totalTax) || + other.totalTax == totalTax) && + (identical(other.totalDiscount, totalDiscount) || + other.totalDiscount == totalDiscount) && + (identical(other.netProfit, netProfit) || + other.netProfit == netProfit) && + (identical(other.netProfitMargin, netProfitMargin) || + other.netProfitMargin == netProfitMargin) && + (identical(other.totalOrders, totalOrders) || + other.totalOrders == totalOrders) && + (identical(other.averageProfit, averageProfit) || + other.averageProfit == averageProfit) && + (identical(other.profitabilityRatio, profitabilityRatio) || + other.profitabilityRatio == profitabilityRatio)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + totalRevenue, + totalCost, + grossProfit, + grossProfitMargin, + totalTax, + totalDiscount, + netProfit, + netProfitMargin, + totalOrders, + averageProfit, + profitabilityRatio, + ); + + /// Create a copy of ProfitLossAnalyticSummaryDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticSummaryDtoImplCopyWith< + _$ProfitLossAnalyticSummaryDtoImpl + > + get copyWith => + __$$ProfitLossAnalyticSummaryDtoImplCopyWithImpl< + _$ProfitLossAnalyticSummaryDtoImpl + >(this, _$identity); + + @override + Map toJson() { + return _$$ProfitLossAnalyticSummaryDtoImplToJson(this); + } +} + +abstract class _ProfitLossAnalyticSummaryDto + extends ProfitLossAnalyticSummaryDto { + const factory _ProfitLossAnalyticSummaryDto({ + @JsonKey(name: "total_revenue") final int? totalRevenue, + @JsonKey(name: "total_cost") final num? totalCost, + @JsonKey(name: "gross_profit") final num? grossProfit, + @JsonKey(name: "gross_profit_margin") final double? grossProfitMargin, + @JsonKey(name: "total_tax") final int? totalTax, + @JsonKey(name: "total_discount") final int? totalDiscount, + @JsonKey(name: "net_profit") final num? netProfit, + @JsonKey(name: "net_profit_margin") final double? netProfitMargin, + @JsonKey(name: "total_orders") final int? totalOrders, + @JsonKey(name: "average_profit") final double? averageProfit, + @JsonKey(name: "profitability_ratio") final double? profitabilityRatio, + }) = _$ProfitLossAnalyticSummaryDtoImpl; + const _ProfitLossAnalyticSummaryDto._() : super._(); + + factory _ProfitLossAnalyticSummaryDto.fromJson(Map json) = + _$ProfitLossAnalyticSummaryDtoImpl.fromJson; + + @override + @JsonKey(name: "total_revenue") + int? get totalRevenue; + @override + @JsonKey(name: "total_cost") + num? get totalCost; + @override + @JsonKey(name: "gross_profit") + num? get grossProfit; + @override + @JsonKey(name: "gross_profit_margin") + double? get grossProfitMargin; + @override + @JsonKey(name: "total_tax") + int? get totalTax; + @override + @JsonKey(name: "total_discount") + int? get totalDiscount; + @override + @JsonKey(name: "net_profit") + num? get netProfit; + @override + @JsonKey(name: "net_profit_margin") + double? get netProfitMargin; + @override + @JsonKey(name: "total_orders") + int? get totalOrders; + @override + @JsonKey(name: "average_profit") + double? get averageProfit; + @override + @JsonKey(name: "profitability_ratio") + double? get profitabilityRatio; + + /// Create a copy of ProfitLossAnalyticSummaryDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticSummaryDtoImplCopyWith< + _$ProfitLossAnalyticSummaryDtoImpl + > + get copyWith => throw _privateConstructorUsedError; +} + +ProfitLossAnalyticItemDto _$ProfitLossAnalyticItemDtoFromJson( + Map json, +) { + return _ProfitLossAnalyticItemDto.fromJson(json); +} + +/// @nodoc +mixin _$ProfitLossAnalyticItemDto { + @JsonKey(name: "date") + String? get date => throw _privateConstructorUsedError; + @JsonKey(name: "revenue") + int? get revenue => throw _privateConstructorUsedError; + @JsonKey(name: "cost") + num? get cost => throw _privateConstructorUsedError; + @JsonKey(name: "gross_profit") + num? get grossProfit => throw _privateConstructorUsedError; + @JsonKey(name: "gross_profit_margin") + double? get grossProfitMargin => throw _privateConstructorUsedError; + @JsonKey(name: "tax") + int? get tax => throw _privateConstructorUsedError; + @JsonKey(name: "discount") + int? get discount => throw _privateConstructorUsedError; + @JsonKey(name: "net_profit") + num? get netProfit => throw _privateConstructorUsedError; + @JsonKey(name: "net_profit_margin") + double? get netProfitMargin => throw _privateConstructorUsedError; + @JsonKey(name: "orders") + int? get orders => throw _privateConstructorUsedError; + + /// Serializes this ProfitLossAnalyticItemDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticItemDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticItemDtoCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticItemDtoCopyWith<$Res> { + factory $ProfitLossAnalyticItemDtoCopyWith( + ProfitLossAnalyticItemDto value, + $Res Function(ProfitLossAnalyticItemDto) then, + ) = _$ProfitLossAnalyticItemDtoCopyWithImpl<$Res, ProfitLossAnalyticItemDto>; + @useResult + $Res call({ + @JsonKey(name: "date") String? date, + @JsonKey(name: "revenue") int? revenue, + @JsonKey(name: "cost") num? cost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "tax") int? tax, + @JsonKey(name: "discount") int? discount, + @JsonKey(name: "net_profit") num? netProfit, + @JsonKey(name: "net_profit_margin") double? netProfitMargin, + @JsonKey(name: "orders") int? orders, + }); +} + +/// @nodoc +class _$ProfitLossAnalyticItemDtoCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticItemDto +> + implements $ProfitLossAnalyticItemDtoCopyWith<$Res> { + _$ProfitLossAnalyticItemDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticItemDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = freezed, + Object? revenue = freezed, + Object? cost = freezed, + Object? grossProfit = freezed, + Object? grossProfitMargin = freezed, + Object? tax = freezed, + Object? discount = freezed, + Object? netProfit = freezed, + Object? netProfitMargin = freezed, + Object? orders = freezed, + }) { + return _then( + _value.copyWith( + date: freezed == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String?, + revenue: freezed == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int?, + cost: freezed == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num?, + grossProfit: freezed == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num?, + grossProfitMargin: freezed == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + 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?, + netProfit: freezed == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num?, + netProfitMargin: freezed == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + orders: freezed == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticItemDtoImplCopyWith<$Res> + implements $ProfitLossAnalyticItemDtoCopyWith<$Res> { + factory _$$ProfitLossAnalyticItemDtoImplCopyWith( + _$ProfitLossAnalyticItemDtoImpl value, + $Res Function(_$ProfitLossAnalyticItemDtoImpl) then, + ) = __$$ProfitLossAnalyticItemDtoImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({ + @JsonKey(name: "date") String? date, + @JsonKey(name: "revenue") int? revenue, + @JsonKey(name: "cost") num? cost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "tax") int? tax, + @JsonKey(name: "discount") int? discount, + @JsonKey(name: "net_profit") num? netProfit, + @JsonKey(name: "net_profit_margin") double? netProfitMargin, + @JsonKey(name: "orders") int? orders, + }); +} + +/// @nodoc +class __$$ProfitLossAnalyticItemDtoImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticItemDtoCopyWithImpl< + $Res, + _$ProfitLossAnalyticItemDtoImpl + > + implements _$$ProfitLossAnalyticItemDtoImplCopyWith<$Res> { + __$$ProfitLossAnalyticItemDtoImplCopyWithImpl( + _$ProfitLossAnalyticItemDtoImpl _value, + $Res Function(_$ProfitLossAnalyticItemDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticItemDto + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? date = freezed, + Object? revenue = freezed, + Object? cost = freezed, + Object? grossProfit = freezed, + Object? grossProfitMargin = freezed, + Object? tax = freezed, + Object? discount = freezed, + Object? netProfit = freezed, + Object? netProfitMargin = freezed, + Object? orders = freezed, + }) { + return _then( + _$ProfitLossAnalyticItemDtoImpl( + date: freezed == date + ? _value.date + : date // ignore: cast_nullable_to_non_nullable + as String?, + revenue: freezed == revenue + ? _value.revenue + : revenue // ignore: cast_nullable_to_non_nullable + as int?, + cost: freezed == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num?, + grossProfit: freezed == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num?, + grossProfitMargin: freezed == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + 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?, + netProfit: freezed == netProfit + ? _value.netProfit + : netProfit // ignore: cast_nullable_to_non_nullable + as num?, + netProfitMargin: freezed == netProfitMargin + ? _value.netProfitMargin + : netProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + orders: freezed == orders + ? _value.orders + : orders // ignore: cast_nullable_to_non_nullable + as int?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$ProfitLossAnalyticItemDtoImpl extends _ProfitLossAnalyticItemDto { + const _$ProfitLossAnalyticItemDtoImpl({ + @JsonKey(name: "date") this.date, + @JsonKey(name: "revenue") this.revenue, + @JsonKey(name: "cost") this.cost, + @JsonKey(name: "gross_profit") this.grossProfit, + @JsonKey(name: "gross_profit_margin") this.grossProfitMargin, + @JsonKey(name: "tax") this.tax, + @JsonKey(name: "discount") this.discount, + @JsonKey(name: "net_profit") this.netProfit, + @JsonKey(name: "net_profit_margin") this.netProfitMargin, + @JsonKey(name: "orders") this.orders, + }) : super._(); + + factory _$ProfitLossAnalyticItemDtoImpl.fromJson(Map json) => + _$$ProfitLossAnalyticItemDtoImplFromJson(json); + + @override + @JsonKey(name: "date") + final String? date; + @override + @JsonKey(name: "revenue") + final int? revenue; + @override + @JsonKey(name: "cost") + final num? cost; + @override + @JsonKey(name: "gross_profit") + final num? grossProfit; + @override + @JsonKey(name: "gross_profit_margin") + final double? grossProfitMargin; + @override + @JsonKey(name: "tax") + final int? tax; + @override + @JsonKey(name: "discount") + final int? discount; + @override + @JsonKey(name: "net_profit") + final num? netProfit; + @override + @JsonKey(name: "net_profit_margin") + final double? netProfitMargin; + @override + @JsonKey(name: "orders") + final int? orders; + + @override + String toString() { + return 'ProfitLossAnalyticItemDto(date: $date, revenue: $revenue, cost: $cost, grossProfit: $grossProfit, grossProfitMargin: $grossProfitMargin, tax: $tax, discount: $discount, netProfit: $netProfit, netProfitMargin: $netProfitMargin, orders: $orders)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticItemDtoImpl && + (identical(other.date, date) || other.date == date) && + (identical(other.revenue, revenue) || other.revenue == revenue) && + (identical(other.cost, cost) || other.cost == cost) && + (identical(other.grossProfit, grossProfit) || + other.grossProfit == grossProfit) && + (identical(other.grossProfitMargin, grossProfitMargin) || + other.grossProfitMargin == grossProfitMargin) && + (identical(other.tax, tax) || other.tax == tax) && + (identical(other.discount, discount) || + other.discount == discount) && + (identical(other.netProfit, netProfit) || + other.netProfit == netProfit) && + (identical(other.netProfitMargin, netProfitMargin) || + other.netProfitMargin == netProfitMargin) && + (identical(other.orders, orders) || other.orders == orders)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + date, + revenue, + cost, + grossProfit, + grossProfitMargin, + tax, + discount, + netProfit, + netProfitMargin, + orders, + ); + + /// Create a copy of ProfitLossAnalyticItemDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticItemDtoImplCopyWith<_$ProfitLossAnalyticItemDtoImpl> + get copyWith => + __$$ProfitLossAnalyticItemDtoImplCopyWithImpl< + _$ProfitLossAnalyticItemDtoImpl + >(this, _$identity); + + @override + Map toJson() { + return _$$ProfitLossAnalyticItemDtoImplToJson(this); + } +} + +abstract class _ProfitLossAnalyticItemDto extends ProfitLossAnalyticItemDto { + const factory _ProfitLossAnalyticItemDto({ + @JsonKey(name: "date") final String? date, + @JsonKey(name: "revenue") final int? revenue, + @JsonKey(name: "cost") final num? cost, + @JsonKey(name: "gross_profit") final num? grossProfit, + @JsonKey(name: "gross_profit_margin") final double? grossProfitMargin, + @JsonKey(name: "tax") final int? tax, + @JsonKey(name: "discount") final int? discount, + @JsonKey(name: "net_profit") final num? netProfit, + @JsonKey(name: "net_profit_margin") final double? netProfitMargin, + @JsonKey(name: "orders") final int? orders, + }) = _$ProfitLossAnalyticItemDtoImpl; + const _ProfitLossAnalyticItemDto._() : super._(); + + factory _ProfitLossAnalyticItemDto.fromJson(Map json) = + _$ProfitLossAnalyticItemDtoImpl.fromJson; + + @override + @JsonKey(name: "date") + String? get date; + @override + @JsonKey(name: "revenue") + int? get revenue; + @override + @JsonKey(name: "cost") + num? get cost; + @override + @JsonKey(name: "gross_profit") + num? get grossProfit; + @override + @JsonKey(name: "gross_profit_margin") + double? get grossProfitMargin; + @override + @JsonKey(name: "tax") + int? get tax; + @override + @JsonKey(name: "discount") + int? get discount; + @override + @JsonKey(name: "net_profit") + num? get netProfit; + @override + @JsonKey(name: "net_profit_margin") + double? get netProfitMargin; + @override + @JsonKey(name: "orders") + int? get orders; + + /// Create a copy of ProfitLossAnalyticItemDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticItemDtoImplCopyWith<_$ProfitLossAnalyticItemDtoImpl> + get copyWith => throw _privateConstructorUsedError; +} + +ProfitLossAnalyticProductDto _$ProfitLossAnalyticProductDtoFromJson( + Map json, +) { + return _ProfitLossAnalyticProductDto.fromJson(json); +} + +/// @nodoc +mixin _$ProfitLossAnalyticProductDto { + @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: "cost") + num? get cost => throw _privateConstructorUsedError; + @JsonKey(name: "gross_profit") + num? get grossProfit => throw _privateConstructorUsedError; + @JsonKey(name: "gross_profit_margin") + double? get grossProfitMargin => throw _privateConstructorUsedError; + @JsonKey(name: "average_price") + int? get averagePrice => throw _privateConstructorUsedError; + @JsonKey(name: "average_cost") + num? get averageCost => throw _privateConstructorUsedError; + @JsonKey(name: "profit_per_unit") + num? get profitPerUnit => throw _privateConstructorUsedError; + + /// Serializes this ProfitLossAnalyticProductDto to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ProfitLossAnalyticProductDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ProfitLossAnalyticProductDtoCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ProfitLossAnalyticProductDtoCopyWith<$Res> { + factory $ProfitLossAnalyticProductDtoCopyWith( + ProfitLossAnalyticProductDto value, + $Res Function(ProfitLossAnalyticProductDto) then, + ) = + _$ProfitLossAnalyticProductDtoCopyWithImpl< + $Res, + ProfitLossAnalyticProductDto + >; + @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: "cost") num? cost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "average_price") int? averagePrice, + @JsonKey(name: "average_cost") num? averageCost, + @JsonKey(name: "profit_per_unit") num? profitPerUnit, + }); +} + +/// @nodoc +class _$ProfitLossAnalyticProductDtoCopyWithImpl< + $Res, + $Val extends ProfitLossAnalyticProductDto +> + implements $ProfitLossAnalyticProductDtoCopyWith<$Res> { + _$ProfitLossAnalyticProductDtoCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ProfitLossAnalyticProductDto + /// 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? cost = freezed, + Object? grossProfit = freezed, + Object? grossProfitMargin = freezed, + Object? averagePrice = freezed, + Object? averageCost = freezed, + Object? profitPerUnit = 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?, + cost: freezed == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num?, + grossProfit: freezed == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num?, + grossProfitMargin: freezed == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + averagePrice: freezed == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as int?, + averageCost: freezed == averageCost + ? _value.averageCost + : averageCost // ignore: cast_nullable_to_non_nullable + as num?, + profitPerUnit: freezed == profitPerUnit + ? _value.profitPerUnit + : profitPerUnit // ignore: cast_nullable_to_non_nullable + as num?, + ) + as $Val, + ); + } +} + +/// @nodoc +abstract class _$$ProfitLossAnalyticProductDtoImplCopyWith<$Res> + implements $ProfitLossAnalyticProductDtoCopyWith<$Res> { + factory _$$ProfitLossAnalyticProductDtoImplCopyWith( + _$ProfitLossAnalyticProductDtoImpl value, + $Res Function(_$ProfitLossAnalyticProductDtoImpl) then, + ) = __$$ProfitLossAnalyticProductDtoImplCopyWithImpl<$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: "cost") num? cost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "average_price") int? averagePrice, + @JsonKey(name: "average_cost") num? averageCost, + @JsonKey(name: "profit_per_unit") num? profitPerUnit, + }); +} + +/// @nodoc +class __$$ProfitLossAnalyticProductDtoImplCopyWithImpl<$Res> + extends + _$ProfitLossAnalyticProductDtoCopyWithImpl< + $Res, + _$ProfitLossAnalyticProductDtoImpl + > + implements _$$ProfitLossAnalyticProductDtoImplCopyWith<$Res> { + __$$ProfitLossAnalyticProductDtoImplCopyWithImpl( + _$ProfitLossAnalyticProductDtoImpl _value, + $Res Function(_$ProfitLossAnalyticProductDtoImpl) _then, + ) : super(_value, _then); + + /// Create a copy of ProfitLossAnalyticProductDto + /// 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? cost = freezed, + Object? grossProfit = freezed, + Object? grossProfitMargin = freezed, + Object? averagePrice = freezed, + Object? averageCost = freezed, + Object? profitPerUnit = freezed, + }) { + return _then( + _$ProfitLossAnalyticProductDtoImpl( + 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?, + cost: freezed == cost + ? _value.cost + : cost // ignore: cast_nullable_to_non_nullable + as num?, + grossProfit: freezed == grossProfit + ? _value.grossProfit + : grossProfit // ignore: cast_nullable_to_non_nullable + as num?, + grossProfitMargin: freezed == grossProfitMargin + ? _value.grossProfitMargin + : grossProfitMargin // ignore: cast_nullable_to_non_nullable + as double?, + averagePrice: freezed == averagePrice + ? _value.averagePrice + : averagePrice // ignore: cast_nullable_to_non_nullable + as int?, + averageCost: freezed == averageCost + ? _value.averageCost + : averageCost // ignore: cast_nullable_to_non_nullable + as num?, + profitPerUnit: freezed == profitPerUnit + ? _value.profitPerUnit + : profitPerUnit // ignore: cast_nullable_to_non_nullable + as num?, + ), + ); + } +} + +/// @nodoc +@JsonSerializable() +class _$ProfitLossAnalyticProductDtoImpl extends _ProfitLossAnalyticProductDto { + const _$ProfitLossAnalyticProductDtoImpl({ + @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: "cost") this.cost, + @JsonKey(name: "gross_profit") this.grossProfit, + @JsonKey(name: "gross_profit_margin") this.grossProfitMargin, + @JsonKey(name: "average_price") this.averagePrice, + @JsonKey(name: "average_cost") this.averageCost, + @JsonKey(name: "profit_per_unit") this.profitPerUnit, + }) : super._(); + + factory _$ProfitLossAnalyticProductDtoImpl.fromJson( + Map json, + ) => _$$ProfitLossAnalyticProductDtoImplFromJson(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: "cost") + final num? cost; + @override + @JsonKey(name: "gross_profit") + final num? grossProfit; + @override + @JsonKey(name: "gross_profit_margin") + final double? grossProfitMargin; + @override + @JsonKey(name: "average_price") + final int? averagePrice; + @override + @JsonKey(name: "average_cost") + final num? averageCost; + @override + @JsonKey(name: "profit_per_unit") + final num? profitPerUnit; + + @override + String toString() { + return 'ProfitLossAnalyticProductDto(productId: $productId, productName: $productName, categoryId: $categoryId, categoryName: $categoryName, quantitySold: $quantitySold, revenue: $revenue, cost: $cost, grossProfit: $grossProfit, grossProfitMargin: $grossProfitMargin, averagePrice: $averagePrice, averageCost: $averageCost, profitPerUnit: $profitPerUnit)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ProfitLossAnalyticProductDtoImpl && + (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.cost, cost) || other.cost == cost) && + (identical(other.grossProfit, grossProfit) || + other.grossProfit == grossProfit) && + (identical(other.grossProfitMargin, grossProfitMargin) || + other.grossProfitMargin == grossProfitMargin) && + (identical(other.averagePrice, averagePrice) || + other.averagePrice == averagePrice) && + (identical(other.averageCost, averageCost) || + other.averageCost == averageCost) && + (identical(other.profitPerUnit, profitPerUnit) || + other.profitPerUnit == profitPerUnit)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + productId, + productName, + categoryId, + categoryName, + quantitySold, + revenue, + cost, + grossProfit, + grossProfitMargin, + averagePrice, + averageCost, + profitPerUnit, + ); + + /// Create a copy of ProfitLossAnalyticProductDto + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ProfitLossAnalyticProductDtoImplCopyWith< + _$ProfitLossAnalyticProductDtoImpl + > + get copyWith => + __$$ProfitLossAnalyticProductDtoImplCopyWithImpl< + _$ProfitLossAnalyticProductDtoImpl + >(this, _$identity); + + @override + Map toJson() { + return _$$ProfitLossAnalyticProductDtoImplToJson(this); + } +} + +abstract class _ProfitLossAnalyticProductDto + extends ProfitLossAnalyticProductDto { + const factory _ProfitLossAnalyticProductDto({ + @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: "cost") final num? cost, + @JsonKey(name: "gross_profit") final num? grossProfit, + @JsonKey(name: "gross_profit_margin") final double? grossProfitMargin, + @JsonKey(name: "average_price") final int? averagePrice, + @JsonKey(name: "average_cost") final num? averageCost, + @JsonKey(name: "profit_per_unit") final num? profitPerUnit, + }) = _$ProfitLossAnalyticProductDtoImpl; + const _ProfitLossAnalyticProductDto._() : super._(); + + factory _ProfitLossAnalyticProductDto.fromJson(Map json) = + _$ProfitLossAnalyticProductDtoImpl.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: "cost") + num? get cost; + @override + @JsonKey(name: "gross_profit") + num? get grossProfit; + @override + @JsonKey(name: "gross_profit_margin") + double? get grossProfitMargin; + @override + @JsonKey(name: "average_price") + int? get averagePrice; + @override + @JsonKey(name: "average_cost") + num? get averageCost; + @override + @JsonKey(name: "profit_per_unit") + num? get profitPerUnit; + + /// Create a copy of ProfitLossAnalyticProductDto + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ProfitLossAnalyticProductDtoImplCopyWith< + _$ProfitLossAnalyticProductDtoImpl + > + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/infrastructure/analytic/analytic_dtos.g.dart b/lib/infrastructure/analytic/analytic_dtos.g.dart index f937fa1..398b4e5 100644 --- a/lib/infrastructure/analytic/analytic_dtos.g.dart +++ b/lib/infrastructure/analytic/analytic_dtos.g.dart @@ -347,3 +347,135 @@ Map _$$PaymentMethodAnalyticSummaryDtoImplToJson( 'total_payments': instance.totalPayments, 'average_order_value': instance.averageOrderValue, }; + +_$ProfitLossAnalyticDtoImpl _$$ProfitLossAnalyticDtoImplFromJson( + Map json, +) => _$ProfitLossAnalyticDtoImpl( + organizationId: json['organization_id'] as String?, + dateFrom: json['date_from'] as String?, + dateTo: json['date_to'] as String?, + groupBy: json['group_by'] as String?, + summary: json['summary'] == null + ? null + : ProfitLossAnalyticSummaryDto.fromJson( + json['summary'] as Map, + ), + data: (json['data'] as List?) + ?.map( + (e) => ProfitLossAnalyticItemDto.fromJson(e as Map), + ) + .toList(), + productData: (json['product_data'] as List?) + ?.map( + (e) => ProfitLossAnalyticProductDto.fromJson(e as Map), + ) + .toList(), +); + +Map _$$ProfitLossAnalyticDtoImplToJson( + _$ProfitLossAnalyticDtoImpl instance, +) => { + 'organization_id': instance.organizationId, + 'date_from': instance.dateFrom, + 'date_to': instance.dateTo, + 'group_by': instance.groupBy, + 'summary': instance.summary, + 'data': instance.data, + 'product_data': instance.productData, +}; + +_$ProfitLossAnalyticSummaryDtoImpl _$$ProfitLossAnalyticSummaryDtoImplFromJson( + Map json, +) => _$ProfitLossAnalyticSummaryDtoImpl( + totalRevenue: (json['total_revenue'] as num?)?.toInt(), + totalCost: json['total_cost'] as num?, + grossProfit: json['gross_profit'] as num?, + grossProfitMargin: (json['gross_profit_margin'] as num?)?.toDouble(), + totalTax: (json['total_tax'] as num?)?.toInt(), + totalDiscount: (json['total_discount'] as num?)?.toInt(), + netProfit: json['net_profit'] as num?, + netProfitMargin: (json['net_profit_margin'] as num?)?.toDouble(), + totalOrders: (json['total_orders'] as num?)?.toInt(), + averageProfit: (json['average_profit'] as num?)?.toDouble(), + profitabilityRatio: (json['profitability_ratio'] as num?)?.toDouble(), +); + +Map _$$ProfitLossAnalyticSummaryDtoImplToJson( + _$ProfitLossAnalyticSummaryDtoImpl instance, +) => { + 'total_revenue': instance.totalRevenue, + 'total_cost': instance.totalCost, + 'gross_profit': instance.grossProfit, + 'gross_profit_margin': instance.grossProfitMargin, + 'total_tax': instance.totalTax, + 'total_discount': instance.totalDiscount, + 'net_profit': instance.netProfit, + 'net_profit_margin': instance.netProfitMargin, + 'total_orders': instance.totalOrders, + 'average_profit': instance.averageProfit, + 'profitability_ratio': instance.profitabilityRatio, +}; + +_$ProfitLossAnalyticItemDtoImpl _$$ProfitLossAnalyticItemDtoImplFromJson( + Map json, +) => _$ProfitLossAnalyticItemDtoImpl( + date: json['date'] as String?, + revenue: (json['revenue'] as num?)?.toInt(), + cost: json['cost'] as num?, + grossProfit: json['gross_profit'] as num?, + grossProfitMargin: (json['gross_profit_margin'] as num?)?.toDouble(), + tax: (json['tax'] as num?)?.toInt(), + discount: (json['discount'] as num?)?.toInt(), + netProfit: json['net_profit'] as num?, + netProfitMargin: (json['net_profit_margin'] as num?)?.toDouble(), + orders: (json['orders'] as num?)?.toInt(), +); + +Map _$$ProfitLossAnalyticItemDtoImplToJson( + _$ProfitLossAnalyticItemDtoImpl instance, +) => { + 'date': instance.date, + 'revenue': instance.revenue, + 'cost': instance.cost, + 'gross_profit': instance.grossProfit, + 'gross_profit_margin': instance.grossProfitMargin, + 'tax': instance.tax, + 'discount': instance.discount, + 'net_profit': instance.netProfit, + 'net_profit_margin': instance.netProfitMargin, + 'orders': instance.orders, +}; + +_$ProfitLossAnalyticProductDtoImpl _$$ProfitLossAnalyticProductDtoImplFromJson( + Map json, +) => _$ProfitLossAnalyticProductDtoImpl( + 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(), + cost: json['cost'] as num?, + grossProfit: json['gross_profit'] as num?, + grossProfitMargin: (json['gross_profit_margin'] as num?)?.toDouble(), + averagePrice: (json['average_price'] as num?)?.toInt(), + averageCost: json['average_cost'] as num?, + profitPerUnit: json['profit_per_unit'] as num?, +); + +Map _$$ProfitLossAnalyticProductDtoImplToJson( + _$ProfitLossAnalyticProductDtoImpl instance, +) => { + 'product_id': instance.productId, + 'product_name': instance.productName, + 'category_id': instance.categoryId, + 'category_name': instance.categoryName, + 'quantity_sold': instance.quantitySold, + 'revenue': instance.revenue, + 'cost': instance.cost, + 'gross_profit': instance.grossProfit, + 'gross_profit_margin': instance.grossProfitMargin, + 'average_price': instance.averagePrice, + 'average_cost': instance.averageCost, + 'profit_per_unit': instance.profitPerUnit, +}; diff --git a/lib/infrastructure/analytic/datasources/remote_data_provider.dart b/lib/infrastructure/analytic/datasources/remote_data_provider.dart index b6a9d83..c775827 100644 --- a/lib/infrastructure/analytic/datasources/remote_data_provider.dart +++ b/lib/infrastructure/analytic/datasources/remote_data_provider.dart @@ -134,4 +134,33 @@ class AnalyticRemoteDataProvider { return DC.error(AnalyticFailure.serverError(e)); } } + + Future> fetchProfitLoss({ + required DateTime dateFrom, + required DateTime dateTo, + }) async { + try { + final response = await _apiClient.get( + ApiPath.analyticProfitLoss, + params: { + 'date_from': dateFrom.toServerDate(), + 'date_to': dateTo.toServerDate(), + }, + headers: getAuthorizationHeader(), + ); + + if (response.data['success'] == false) { + return DC.error(AnalyticFailure.unexpectedError()); + } + + final profitLoss = ProfitLossAnalyticDto.fromJson( + response.data['data'] as Map, + ); + + return DC.data(profitLoss); + } on ApiFailure catch (e, s) { + log('fetchProfitLoss', name: _logName, error: e, stackTrace: s); + return DC.error(AnalyticFailure.serverError(e)); + } + } } diff --git a/lib/infrastructure/analytic/dtos/profit_loss_analytic_dto.dart b/lib/infrastructure/analytic/dtos/profit_loss_analytic_dto.dart new file mode 100644 index 0000000..7517525 --- /dev/null +++ b/lib/infrastructure/analytic/dtos/profit_loss_analytic_dto.dart @@ -0,0 +1,142 @@ +part of '../analytic_dtos.dart'; + +@freezed +class ProfitLossAnalyticDto with _$ProfitLossAnalyticDto { + const ProfitLossAnalyticDto._(); + + const factory ProfitLossAnalyticDto({ + @JsonKey(name: "organization_id") String? organizationId, + @JsonKey(name: "date_from") String? dateFrom, + @JsonKey(name: "date_to") String? dateTo, + @JsonKey(name: "group_by") String? groupBy, + @JsonKey(name: "summary") ProfitLossAnalyticSummaryDto? summary, + @JsonKey(name: "data") List? data, + @JsonKey(name: "product_data") + List? productData, + }) = _ProfitLossAnalyticDto; + + factory ProfitLossAnalyticDto.fromJson(Map json) => + _$ProfitLossAnalyticDtoFromJson(json); + + // Optional: mapper ke domain entity + ProfitLossAnalytic toDomain() => ProfitLossAnalytic( + organizationId: organizationId ?? '', + dateFrom: dateFrom ?? '', + dateTo: dateTo ?? '', + groupBy: groupBy ?? 'day', + summary: summary?.toDomain() ?? ProfitLossAnalyticSummary.empty(), + data: data?.map((e) => e.toDomain()).toList() ?? [], + productData: productData?.map((e) => e.toDomain()).toList() ?? [], + ); +} + +@freezed +class ProfitLossAnalyticSummaryDto with _$ProfitLossAnalyticSummaryDto { + const ProfitLossAnalyticSummaryDto._(); + + const factory ProfitLossAnalyticSummaryDto({ + @JsonKey(name: "total_revenue") int? totalRevenue, + @JsonKey(name: "total_cost") num? totalCost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "total_tax") int? totalTax, + @JsonKey(name: "total_discount") int? totalDiscount, + @JsonKey(name: "net_profit") num? netProfit, + @JsonKey(name: "net_profit_margin") double? netProfitMargin, + @JsonKey(name: "total_orders") int? totalOrders, + @JsonKey(name: "average_profit") double? averageProfit, + @JsonKey(name: "profitability_ratio") double? profitabilityRatio, + }) = _ProfitLossAnalyticSummaryDto; + + factory ProfitLossAnalyticSummaryDto.fromJson(Map json) => + _$ProfitLossAnalyticSummaryDtoFromJson(json); + + // Optional mapper ke domain + ProfitLossAnalyticSummary toDomain() => ProfitLossAnalyticSummary( + totalRevenue: totalRevenue ?? 0, + totalCost: totalCost ?? 0, + grossProfit: grossProfit ?? 0, + grossProfitMargin: grossProfitMargin ?? 0.0, + totalTax: totalTax ?? 0, + totalDiscount: totalDiscount ?? 0, + netProfit: netProfit ?? 0, + netProfitMargin: netProfitMargin ?? 0.0, + totalOrders: totalOrders ?? 0, + averageProfit: averageProfit ?? 0.0, + profitabilityRatio: profitabilityRatio ?? 0.0, + ); +} + +@freezed +class ProfitLossAnalyticItemDto with _$ProfitLossAnalyticItemDto { + const ProfitLossAnalyticItemDto._(); + + const factory ProfitLossAnalyticItemDto({ + @JsonKey(name: "date") String? date, + @JsonKey(name: "revenue") int? revenue, + @JsonKey(name: "cost") num? cost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "tax") int? tax, + @JsonKey(name: "discount") int? discount, + @JsonKey(name: "net_profit") num? netProfit, + @JsonKey(name: "net_profit_margin") double? netProfitMargin, + @JsonKey(name: "orders") int? orders, + }) = _ProfitLossAnalyticItemDto; + + factory ProfitLossAnalyticItemDto.fromJson(Map json) => + _$ProfitLossAnalyticItemDtoFromJson(json); + + // Optional mapper ke domain + ProfitLossAnalyticItem toDomain() => ProfitLossAnalyticItem( + date: date ?? '', + revenue: revenue ?? 0, + cost: cost ?? 0, + grossProfit: grossProfit ?? 0, + grossProfitMargin: grossProfitMargin ?? 0.0, + tax: tax ?? 0, + discount: discount ?? 0, + netProfit: netProfit ?? 0, + netProfitMargin: netProfitMargin ?? 0.0, + orders: orders ?? 0, + ); +} + +@freezed +class ProfitLossAnalyticProductDto with _$ProfitLossAnalyticProductDto { + const ProfitLossAnalyticProductDto._(); + + const factory ProfitLossAnalyticProductDto({ + @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: "cost") num? cost, + @JsonKey(name: "gross_profit") num? grossProfit, + @JsonKey(name: "gross_profit_margin") double? grossProfitMargin, + @JsonKey(name: "average_price") int? averagePrice, + @JsonKey(name: "average_cost") num? averageCost, + @JsonKey(name: "profit_per_unit") num? profitPerUnit, + }) = _ProfitLossAnalyticProductDto; + + factory ProfitLossAnalyticProductDto.fromJson(Map json) => + _$ProfitLossAnalyticProductDtoFromJson(json); + + // Optional mapper ke domain + ProfitLossAnalyticProduct toDomain() => ProfitLossAnalyticProduct( + productId: productId ?? '', + productName: productName ?? '', + categoryId: categoryId ?? '', + categoryName: categoryName ?? '', + quantitySold: quantitySold ?? 0, + revenue: revenue ?? 0, + cost: cost ?? 0, + grossProfit: grossProfit ?? 0, + grossProfitMargin: grossProfitMargin ?? 0.0, + averagePrice: averagePrice ?? 0, + averageCost: averageCost ?? 0, + profitPerUnit: profitPerUnit ?? 0, + ); +} diff --git a/lib/infrastructure/analytic/repositories/analytic_repository.dart b/lib/infrastructure/analytic/repositories/analytic_repository.dart index cad51b0..365ed72 100644 --- a/lib/infrastructure/analytic/repositories/analytic_repository.dart +++ b/lib/infrastructure/analytic/repositories/analytic_repository.dart @@ -109,4 +109,28 @@ class AnalyticRepository implements IAnalyticRepository { return left(const AnalyticFailure.unexpectedError()); } } + + @override + Future> getProfitLoss({ + required DateTime dateFrom, + required DateTime dateTo, + }) async { + try { + final result = await _dataProvider.fetchProfitLoss( + dateFrom: dateFrom, + dateTo: dateTo, + ); + + if (result.hasError) { + return left(result.error!); + } + + final profitLoss = result.data!.toDomain(); + + return right(profitLoss); + } catch (e) { + log('getProfitLossError', name: _logName, error: e); + return left(const AnalyticFailure.unexpectedError()); + } + } } diff --git a/lib/injection.config.dart b/lib/injection.config.dart index 218a3f2..aef938e 100644 --- a/lib/injection.config.dart +++ b/lib/injection.config.dart @@ -15,6 +15,8 @@ import 'package:apskel_pos_flutter_v2/application/analytic/payment_method_analyt as _i733; import 'package:apskel_pos_flutter_v2/application/analytic/product_analytic_loader/product_analytic_loader_bloc.dart' as _i268; +import 'package:apskel_pos_flutter_v2/application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.dart' + as _i741; import 'package:apskel_pos_flutter_v2/application/analytic/sales_analytic_loader/sales_analytic_loader_bloc.dart' as _i413; import 'package:apskel_pos_flutter_v2/application/auth/auth_bloc.dart' as _i343; @@ -310,6 +312,9 @@ extension GetItInjectableX on _i174.GetIt { gh<_i346.IAnalyticRepository>(), ), ); + gh.factory<_i741.ProfitLossAnalyticLoaderBloc>( + () => _i741.ProfitLossAnalyticLoaderBloc(gh<_i346.IAnalyticRepository>()), + ); return this; } } diff --git a/lib/presentation/pages/main/pages/report/report_page.dart b/lib/presentation/pages/main/pages/report/report_page.dart index 8644f23..5bd1939 100644 --- a/lib/presentation/pages/main/pages/report/report_page.dart +++ b/lib/presentation/pages/main/pages/report/report_page.dart @@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../../application/analytic/dashboard_analytic_loader/dashboard_analytic_loader_bloc.dart'; import '../../../../../application/analytic/payment_method_analytic_loader/payment_method_analytic_loader_bloc.dart'; import '../../../../../application/analytic/product_analytic_loader/product_analytic_loader_bloc.dart'; +import '../../../../../application/analytic/profit_loss_analytic_loader/profit_loss_analytic_loader_bloc.dart'; import '../../../../../application/analytic/sales_analytic_loader/sales_analytic_loader_bloc.dart'; import '../../../../../application/report/report_bloc.dart'; import '../../../../../common/data/report_menu.dart'; @@ -18,6 +19,7 @@ import '../../../../router/app_router.gr.dart'; import 'sections/report_dashboard_section.dart'; import 'sections/report_payment_method_section.dart'; import 'sections/report_product_section.dart'; +import 'sections/report_profit_loss_section.dart'; import 'sections/report_sales_section.dart'; import 'widgets/report_menu_card.dart'; @@ -167,7 +169,20 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { ); }, ), - 5 => Text(state.title), + 5 => + BlocBuilder< + ProfitLossAnalyticLoaderBloc, + ProfitLossAnalyticLoaderState + >( + builder: (context, profitLoss) { + return ReportProfitLossSection( + menu: reportMenus[state.selectedMenu], + state: profitLoss, + startDate: state.startDate, + endDate: state.endDate, + ); + }, + ), 6 => Text(state.title), 7 => Text(state.title), _ => Container(), @@ -218,6 +233,12 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { ); case 5: + return context.read().add( + ProfitLossAnalyticLoaderEvent.fetched( + startDate: state.startDate, + endDate: state.endDate, + ), + ); case 6: case 7: default: @@ -265,6 +286,15 @@ class ReportPage extends StatelessWidget implements AutoRouteWrapper { ), ), ), + BlocProvider( + create: (context) => getIt() + ..add( + ProfitLossAnalyticLoaderEvent.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_profit_loss_section.dart b/lib/presentation/pages/main/pages/report/sections/report_profit_loss_section.dart new file mode 100644 index 0000000..04a973b --- /dev/null +++ b/lib/presentation/pages/main/pages/report/sections/report_profit_loss_section.dart @@ -0,0 +1,157 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../../application/analytic/profit_loss_analytic_loader/profit_loss_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/profit_loss/report_profit_loss_breakdown.dart'; +import '../widgets/profit_loss/report_profit_loss_metric.dart'; +import '../widgets/profit_loss/report_profit_loss_product_profitability.dart'; +import '../widgets/profit_loss/report_profit_loss_trend_chart.dart'; + +class ReportProfitLossSection extends StatelessWidget { + final ReportMenu menu; + final ProfitLossAnalyticLoaderState state; + final DateTime startDate; + final DateTime endDate; + + const ReportProfitLossSection({ + 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( + onRefresh: () { + context.read().add( + ProfitLossAnalyticLoaderEvent.fetched( + startDate: startDate, + endDate: endDate, + ), + ); + return Future.value(); + }, + child: ListView( + padding: EdgeInsets.all(16), + children: [ + ReportHeader(menu: menu, endDate: endDate, startDate: startDate), + _buildSummary(), + ReportProfitLossTrendChart(data: state.profitLossAnalytic.data), + Padding( + padding: const EdgeInsets.only(top: 16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 3, + child: ReportProfitLossProductProfitability( + data: state.profitLossAnalytic.productData, + ), + ), + SpaceWidth(12), + Expanded( + flex: 2, + child: ReportProfitLossBreakdown( + data: state.profitLossAnalytic, + ), + ), + ], + ), + ), + ReportProfitLossMetric(data: state.profitLossAnalytic), + ], + ), + ), + (f) => AnalyticErrorStateWidget( + failure: f, + menu: menu, + onRefresh: () { + context.read().add( + ProfitLossAnalyticLoaderEvent.fetched( + startDate: startDate, + endDate: endDate, + ), + ); + }, + ), + ); + } + + Padding _buildSummary() { + return Padding( + padding: const EdgeInsets.only(top: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: ReportSummaryCard( + color: AppColor.success, + icon: Icons.attach_money, + title: 'Jumlah Pendapatan', + value: state + .profitLossAnalytic + .summary + .totalRevenue + .currencyFormatRpV2, + ), + ), + SpaceWidth(12), + Expanded( + child: ReportSummaryCard( + color: AppColor.info, + icon: Icons.receipt_outlined, + title: 'Jumlah Biaya', + value: state.profitLossAnalytic.summary.totalCost + .toDouble() + .currencyFormatRpV2, + ), + ), + ], + ), + SpaceHeight(12), + Row( + children: [ + Expanded( + child: ReportSummaryCard( + color: AppColor.warning, + icon: Icons.trending_up_outlined, + title: 'Laba Kotor', + value: state.profitLossAnalytic.summary.grossProfit + .toDouble() + .currencyFormatRpV2, + ), + ), + SpaceWidth(12), + Expanded( + child: ReportSummaryCard( + color: AppColor.primary, + icon: Icons.account_balance_outlined, + title: 'Laba Bersih', + value: state.profitLossAnalytic.summary.netProfit + .toString() + .currencyFormatRpV2, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_breakdown.dart b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_breakdown.dart new file mode 100644 index 0000000..a545f94 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_breakdown.dart @@ -0,0 +1,185 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../../../common/extension/extension.dart'; +import '../../../../../../../common/function/app_function.dart'; +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportProfitLossBreakdown extends StatelessWidget { + final ProfitLossAnalytic data; + const ReportProfitLossBreakdown({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + final breakdownData = [ + { + 'label': 'Laba Kotor', + 'value': data.summary.grossProfit, + 'color': AppColor.success, + }, + { + 'label': 'Pajak', + 'value': data.summary.totalTax, + 'color': AppColor.warning, + }, + { + 'label': 'Diskon', + 'value': data.summary.totalDiscount, + 'color': AppColor.info, + }, + { + 'label': 'Laba Bersih', + 'value': data.summary.netProfit, + 'color': AppColor.primary, + }, + ]; + + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Rincian Keuntungan', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(4), + Text( + 'Komponen pembentuk profit', + style: AppStyle.sm.copyWith(color: AppColor.textSecondary), + ), + SpaceHeight(20), + + // Grafik Donut + SizedBox( + height: 160, + child: PieChart( + PieChartData( + sectionsSpace: 3, + centerSpaceRadius: 50, + startDegreeOffset: -90, + sections: breakdownData.asMap().entries.map((entry) { + final item = entry.value; + final grossProfit = data.summary.grossProfit; + final value = item['value'] as num; + + // Handle division by zero + final percentage = grossProfit > 0 + ? (value / grossProfit * 100) + : 0.0; + + return PieChartSectionData( + color: item['color'] as Color, + value: value.toDouble(), + title: '${safeRound(percentage)}%', + radius: 40, + titleStyle: AppStyle.xs.copyWith( + fontSize: 10, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ); + }).toList(), + ), + ), + ), + + SpaceHeight(16), + + // Legenda + Column( + children: breakdownData.map((item) { + return Padding( + padding: const EdgeInsets.only(bottom: 12), + child: Row( + children: [ + Container( + width: 12, + height: 12, + decoration: BoxDecoration( + color: item['color'] as Color, + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(width: 8), + Expanded( + child: Text( + item['label'] as String, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w500, + ), + ), + ), + Text( + (item['value'] as num).toString().currencyFormatRpV2, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ], + ), + ); + }).toList(), + ), + + SpaceHeight(16), + + // Rasio Profitabilitas + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + AppColor.primary.withOpacity(0.1), + AppColor.secondary.withOpacity(0.1), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + children: [ + Text( + 'Rasio Profitabilitas', + style: AppStyle.sm.copyWith( + fontSize: 12, + fontWeight: FontWeight.w600, + color: AppColor.textSecondary, + ), + ), + SpaceHeight(8), + Text( + '${safeRound(data.summary.profitabilityRatio)}%', + style: AppStyle.h5.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.primary, + ), + ), + SpaceHeight(4), + Text( + 'Tingkat Pengembalian Pendapatan', + style: AppStyle.xs.copyWith( + fontSize: 10, + color: AppColor.textSecondary, + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_metric.dart b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_metric.dart new file mode 100644 index 0000000..a7a0337 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_metric.dart @@ -0,0 +1,300 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '../../../../../../../common/extension/extension.dart'; +import '../../../../../../../common/function/app_function.dart'; +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportProfitLossMetric extends StatelessWidget { + final ProfitLossAnalytic data; + const ReportProfitLossMetric({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(12), + margin: EdgeInsets.only(top: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Metrik Kinerja Terperinci', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(16), + + Row( + children: [ + Expanded( + child: _buildMetricCard( + 'Nilai Rata-rata Pesanan', + _safeCalculateAverageOrder().currencyFormatRpV2, + 'Per transaksi', + Icons.shopping_cart_outlined, + AppColor.info, + ), + ), + SpaceWidth(12), + Expanded( + child: _buildMetricCard( + 'Keuntungan Rata-rata', + "${data.summary.averageProfit.round()}%", + 'Per pesanan', + Icons.trending_up, + AppColor.success, + ), + ), + SpaceWidth(12), + Expanded( + child: _buildMetricCard( + 'Rasio Biaya', + '${_safeCalculateCostRatio()}%', + 'Dari total pendapatan', + Icons.pie_chart, + AppColor.error, + ), + ), + ], + ), + + SpaceHeight(16), + + // Tabel rincian harian + Container( + decoration: BoxDecoration( + color: const Color(0xFFF8FAFC), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey[100]!), + ), + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.primary.withOpacity(0.05), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(12), + topRight: Radius.circular(12), + ), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + 'Tanggal', + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + Expanded( + child: Text( + 'Pendapatan', + textAlign: TextAlign.center, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + Expanded( + child: Text( + 'Biaya', + textAlign: TextAlign.center, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + Expanded( + child: Text( + 'Laba Bersih', + textAlign: TextAlign.center, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + Expanded( + child: Text( + 'Margin', + textAlign: TextAlign.center, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + ), + ], + ), + ), + ...data.data.map((item) { + final date = DateTime.parse(item.date); + final dateStr = DateFormat('dd MMM').format(date); + + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: Colors.grey[100]!), + ), + ), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + dateStr, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w600, + color: AppColor.textPrimary, + ), + ), + ), + Expanded( + child: Text( + item.revenue.currencyFormatRpV2, + textAlign: TextAlign.center, + style: AppStyle.xs.copyWith( + fontWeight: FontWeight.w500, + color: AppColor.info, + ), + ), + ), + Expanded( + child: Text( + item.cost.toString().currencyFormatRpV2, + textAlign: TextAlign.center, + style: AppStyle.xs.copyWith( + fontWeight: FontWeight.w500, + color: AppColor.error, + ), + ), + ), + Expanded( + child: Text( + item.netProfit.toString().currencyFormatRpV2, + textAlign: TextAlign.center, + style: AppStyle.xs.copyWith( + fontWeight: FontWeight.w600, + color: AppColor.success, + ), + ), + ), + Expanded( + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 3, + ), + decoration: BoxDecoration( + color: _getMarginColor( + item.netProfitMargin, + ).withOpacity(0.1), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + '${safeRound(item.netProfitMargin)}%', + textAlign: TextAlign.center, + style: AppStyle.xs.copyWith( + fontSize: 10, + fontWeight: FontWeight.bold, + color: _getMarginColor(item.netProfitMargin), + ), + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ], + ), + ); + } + + Widget _buildMetricCard( + String title, + String value, + String subtitle, + IconData icon, + Color color, + ) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: color.withOpacity(0.06), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: color.withOpacity(0.2)), + ), + child: Column( + children: [ + Icon(icon, color: color, size: 24), + SpaceHeight(8), + Text( + value, + style: AppStyle.lg.copyWith( + fontWeight: FontWeight.bold, + color: color, + ), + ), + SpaceHeight(4), + Text( + title, + textAlign: TextAlign.center, + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.w600, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(2), + Text( + subtitle, + textAlign: TextAlign.center, + style: AppStyle.xs.copyWith( + fontSize: 10, + color: AppColor.textSecondary, + ), + ), + ], + ), + ); + } + + int _safeCalculateAverageOrder() { + if (data.summary.totalOrders == 0) return 0; + final average = data.summary.totalRevenue / data.summary.totalOrders; + if (average.isNaN || average.isInfinite) return 0; + return average.round(); + } + + int _safeCalculateCostRatio() { + if (data.summary.totalRevenue == 0) return 0; + final ratio = (data.summary.totalCost / data.summary.totalRevenue) * 100; + if (ratio.isNaN || ratio.isInfinite) return 0; + return ratio.round(); + } + + Color _getMarginColor(double margin) { + final safeMargin = safeDouble(margin); + if (safeMargin >= 25) return AppColor.success; + if (safeMargin >= 15) return AppColor.warning; + return AppColor.error; + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_product_profitability.dart b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_product_profitability.dart new file mode 100644 index 0000000..8156340 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_product_profitability.dart @@ -0,0 +1,184 @@ +import 'package:flutter/material.dart'; + +import '../../../../../../../common/extension/extension.dart'; +import '../../../../../../../common/function/app_function.dart'; +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; +import '../../../../../../components/spaces/space.dart'; + +class ReportProfitLossProductProfitability extends StatelessWidget { + final List data; + const ReportProfitLossProductProfitability({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Profitabilitas Produk', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + SpaceHeight(4), + Text( + 'Analisis margin keuntungan per produk', + style: AppStyle.sm.copyWith(color: AppColor.textSecondary), + ), + SpaceHeight(12), + Column( + children: data.take(4).map((product) { + return _buildProductItem(product); + }).toList(), + ), + ], + ), + ); + } + + Widget _buildProductItem(ProfitLossAnalyticProduct product) { + final profitMargin = safeDouble(product.grossProfitMargin); + final profitColor = profitMargin >= 35 + ? AppColor.success + : profitMargin >= 25 + ? AppColor.warning + : AppColor.error; + + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: const Color(0xFFF8FAFC), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey[100]!), + ), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + product.productName, + style: AppStyle.md.copyWith( + fontWeight: FontWeight.w600, + color: Color(0xFF0F172A), + ), + ), + SpaceHeight(2), + Text( + '${product.quantitySold} unit • ${product.categoryName}', + style: AppStyle.sm.copyWith( + color: AppColor.textSecondary, + ), + ), + ], + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + color: profitColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(6), + ), + child: Text( + '${safeRound(profitMargin)}%', + style: AppStyle.sm.copyWith( + fontWeight: FontWeight.bold, + color: profitColor, + ), + ), + ), + SpaceHeight(4), + Text( + product.grossProfit.toString().currencyFormatRpV2, + style: AppStyle.md.copyWith( + fontSize: 14, + fontWeight: FontWeight.w600, + color: AppColor.primary, + ), + ), + ], + ), + ], + ), + SpaceHeight(12), + Row( + children: [ + Expanded( + child: _buildProductMetric( + 'Pendapatan', + product.revenue, + AppColor.info, + ), + ), + SpaceWidth(8), + Expanded( + child: _buildProductMetric( + 'Biaya', + product.cost, + AppColor.error, + ), + ), + SpaceWidth(8), + Expanded( + child: _buildProductMetric( + 'Laba/Unit', + product.profitPerUnit, + AppColor.success, + ), + ), + ], + ), + ], + ), + ); + } + + Widget _buildProductMetric(String label, num value, Color color) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: color.withOpacity(0.08), + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + Text( + label, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + color: Colors.grey[600], + ), + ), + SpaceHeight(2), + Text( + value.toString().currencyFormatRpV2, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.bold, + color: color, + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_trend_chart.dart b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_trend_chart.dart new file mode 100644 index 0000000..e355428 --- /dev/null +++ b/lib/presentation/pages/main/pages/report/widgets/profit_loss/report_profit_loss_trend_chart.dart @@ -0,0 +1,185 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../../../common/theme/theme.dart'; +import '../../../../../../../domain/analytic/analytic.dart'; + +class ReportProfitLossTrendChart extends StatelessWidget { + final List data; + const ReportProfitLossTrendChart({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(12), + margin: EdgeInsets.only(top: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Analisis Tren Keuntungan', + style: AppStyle.xl.copyWith( + fontWeight: FontWeight.bold, + color: AppColor.textPrimary, + ), + ), + Row( + children: [ + _buildLegendItem('Pendapatan', AppColor.info), + const SizedBox(width: 16), + _buildLegendItem('Biaya', AppColor.error), + const SizedBox(width: 16), + _buildLegendItem('Laba Bersih', AppColor.success), + ], + ), + ], + ), + const SizedBox(height: 20), + SizedBox( + height: 220, + child: LineChart( + LineChartData( + gridData: FlGridData( + show: true, + drawHorizontalLine: true, + drawVerticalLine: false, + horizontalInterval: 100000, + getDrawingHorizontalLine: (value) { + return FlLine(color: Colors.grey[100]!, strokeWidth: 1); + }, + ), + titlesData: FlTitlesData( + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 50, + getTitlesWidget: (value, meta) { + final kValue = (value / 1000); + if (kValue.isFinite) { + return Text( + '${kValue.toInt()}K', + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontSize: 10, + ), + ); + } + return const SizedBox(); + }, + ), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, meta) { + final index = value.toInt(); + if (index >= 0 && index < data.length) { + final date = DateTime.parse(data[index].date); + return Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + '${date.day}/${date.month}', + style: AppStyle.xs.copyWith( + color: AppColor.textSecondary, + fontSize: 10, + ), + ), + ); + } + return const SizedBox(); + }, + ), + ), + rightTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: const AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + ), + borderData: FlBorderData(show: false), + lineBarsData: [ + // Garis Pendapatan + LineChartBarData( + spots: data.asMap().entries.map((entry) { + final revenue = entry.value.revenue.toDouble(); + return FlSpot( + entry.key.toDouble(), + revenue.isFinite ? revenue : 0, + ); + }).toList(), + isCurved: true, + color: AppColor.info, + dotData: const FlDotData(show: false), + ), + // Garis Biaya + LineChartBarData( + spots: data.asMap().entries.map((entry) { + final cost = entry.value.cost.toDouble(); + return FlSpot( + entry.key.toDouble(), + cost.isFinite ? cost : 0, + ); + }).toList(), + isCurved: true, + color: AppColor.error, + dotData: const FlDotData(show: false), + ), + // Garis Laba Bersih + LineChartBarData( + spots: data.asMap().entries.map((entry) { + final netProfit = entry.value.netProfit.toDouble(); + return FlSpot( + entry.key.toDouble(), + netProfit.isFinite ? netProfit : 0, + ); + }).toList(), + isCurved: true, + color: AppColor.success, + dotData: const FlDotData(show: true), + belowBarData: BarAreaData( + show: true, + color: AppColor.success.withOpacity(0.1), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildLegendItem(String label, Color color) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 12, + height: 12, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(width: 6), + Text( + label, + style: AppStyle.sm.copyWith( + fontSize: 12, + fontWeight: FontWeight.w500, + color: AppColor.textPrimary, + ), + ), + ], + ); + } +}