feat: product analytic repo

This commit is contained in:
efrilm 2025-08-18 02:13:11 +07:00
parent b5593d10eb
commit d58198e7f0
17 changed files with 1845 additions and 1 deletions

View File

@ -0,0 +1,49 @@
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/analytic/analytic.dart';
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
part 'product_analytic_loader_event.dart';
part 'product_analytic_loader_state.dart';
part 'product_analytic_loader_bloc.freezed.dart';
@injectable
class ProductAnalyticLoaderBloc
extends Bloc<ProductAnalyticLoaderEvent, ProductAnalyticLoaderState> {
final IAnalyticRepository _repository;
ProductAnalyticLoaderBloc(this._repository)
: super(ProductAnalyticLoaderState.initial()) {
on<ProductAnalyticLoaderEvent>(_onProductAnalyticLoaderEvent);
}
Future<void> _onProductAnalyticLoaderEvent(
ProductAnalyticLoaderEvent event,
Emitter<ProductAnalyticLoaderState> emit,
) {
return event.map(
fetched: (e) async {
emit(
state.copyWith(
isFetching: true,
failureOptionProductAnalytic: none(),
),
);
final result = await _repository.getProduct(
dateFrom: DateTime.now().subtract(const Duration(days: 30)),
dateTo: DateTime.now(),
);
var data = result.fold(
(f) => state.copyWith(failureOptionProductAnalytic: optionOf(f)),
(productAnalytic) => state.copyWith(productAnalytic: productAnalytic),
);
emit(data.copyWith(isFetching: false));
},
);
}
}

View File

@ -0,0 +1,385 @@
// 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 'product_analytic_loader_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(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 _$ProductAnalyticLoaderEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetched,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Fetched value) fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Fetched value)? fetched,
}) => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Fetched value)? fetched,
required TResult orElse(),
}) => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticLoaderEventCopyWith<$Res> {
factory $ProductAnalyticLoaderEventCopyWith(
ProductAnalyticLoaderEvent value,
$Res Function(ProductAnalyticLoaderEvent) then,
) =
_$ProductAnalyticLoaderEventCopyWithImpl<
$Res,
ProductAnalyticLoaderEvent
>;
}
/// @nodoc
class _$ProductAnalyticLoaderEventCopyWithImpl<
$Res,
$Val extends ProductAnalyticLoaderEvent
>
implements $ProductAnalyticLoaderEventCopyWith<$Res> {
_$ProductAnalyticLoaderEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalyticLoaderEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$FetchedImplCopyWith<$Res> {
factory _$$FetchedImplCopyWith(
_$FetchedImpl value,
$Res Function(_$FetchedImpl) then,
) = __$$FetchedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$FetchedImplCopyWithImpl<$Res>
extends _$ProductAnalyticLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
implements _$$FetchedImplCopyWith<$Res> {
__$$FetchedImplCopyWithImpl(
_$FetchedImpl _value,
$Res Function(_$FetchedImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalyticLoaderEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$FetchedImpl implements _Fetched {
const _$FetchedImpl();
@override
String toString() {
return 'ProductAnalyticLoaderEvent.fetched()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$FetchedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({required TResult Function() fetched}) {
return fetched();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
return fetched?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetched,
required TResult orElse(),
}) {
if (fetched != null) {
return fetched();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Fetched value) fetched,
}) {
return fetched(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Fetched value)? fetched,
}) {
return fetched?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Fetched value)? fetched,
required TResult orElse(),
}) {
if (fetched != null) {
return fetched(this);
}
return orElse();
}
}
abstract class _Fetched implements ProductAnalyticLoaderEvent {
const factory _Fetched() = _$FetchedImpl;
}
/// @nodoc
mixin _$ProductAnalyticLoaderState {
ProductAnalytic get productAnalytic => throw _privateConstructorUsedError;
dynamic get failureOptionProductAnalytic =>
throw _privateConstructorUsedError;
bool get isFetching => throw _privateConstructorUsedError;
/// Create a copy of ProductAnalyticLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProductAnalyticLoaderStateCopyWith<ProductAnalyticLoaderState>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticLoaderStateCopyWith<$Res> {
factory $ProductAnalyticLoaderStateCopyWith(
ProductAnalyticLoaderState value,
$Res Function(ProductAnalyticLoaderState) then,
) =
_$ProductAnalyticLoaderStateCopyWithImpl<
$Res,
ProductAnalyticLoaderState
>;
@useResult
$Res call({
ProductAnalytic productAnalytic,
dynamic failureOptionProductAnalytic,
bool isFetching,
});
}
/// @nodoc
class _$ProductAnalyticLoaderStateCopyWithImpl<
$Res,
$Val extends ProductAnalyticLoaderState
>
implements $ProductAnalyticLoaderStateCopyWith<$Res> {
_$ProductAnalyticLoaderStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalyticLoaderState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productAnalytic = freezed,
Object? failureOptionProductAnalytic = freezed,
Object? isFetching = null,
}) {
return _then(
_value.copyWith(
productAnalytic: freezed == productAnalytic
? _value.productAnalytic
: productAnalytic // ignore: cast_nullable_to_non_nullable
as ProductAnalytic,
failureOptionProductAnalytic:
freezed == failureOptionProductAnalytic
? _value.failureOptionProductAnalytic
: failureOptionProductAnalytic // ignore: cast_nullable_to_non_nullable
as dynamic,
isFetching: null == isFetching
? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable
as bool,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProductAnalyticLoaderStateImplCopyWith<$Res>
implements $ProductAnalyticLoaderStateCopyWith<$Res> {
factory _$$ProductAnalyticLoaderStateImplCopyWith(
_$ProductAnalyticLoaderStateImpl value,
$Res Function(_$ProductAnalyticLoaderStateImpl) then,
) = __$$ProductAnalyticLoaderStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
ProductAnalytic productAnalytic,
dynamic failureOptionProductAnalytic,
bool isFetching,
});
}
/// @nodoc
class __$$ProductAnalyticLoaderStateImplCopyWithImpl<$Res>
extends
_$ProductAnalyticLoaderStateCopyWithImpl<
$Res,
_$ProductAnalyticLoaderStateImpl
>
implements _$$ProductAnalyticLoaderStateImplCopyWith<$Res> {
__$$ProductAnalyticLoaderStateImplCopyWithImpl(
_$ProductAnalyticLoaderStateImpl _value,
$Res Function(_$ProductAnalyticLoaderStateImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalyticLoaderState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productAnalytic = freezed,
Object? failureOptionProductAnalytic = freezed,
Object? isFetching = null,
}) {
return _then(
_$ProductAnalyticLoaderStateImpl(
productAnalytic: freezed == productAnalytic
? _value.productAnalytic
: productAnalytic // ignore: cast_nullable_to_non_nullable
as ProductAnalytic,
failureOptionProductAnalytic: freezed == failureOptionProductAnalytic
? _value.failureOptionProductAnalytic!
: failureOptionProductAnalytic,
isFetching: null == isFetching
? _value.isFetching
: isFetching // ignore: cast_nullable_to_non_nullable
as bool,
),
);
}
}
/// @nodoc
class _$ProductAnalyticLoaderStateImpl implements _ProductAnalyticLoaderState {
const _$ProductAnalyticLoaderStateImpl({
required this.productAnalytic,
required this.failureOptionProductAnalytic,
this.isFetching = false,
});
@override
final ProductAnalytic productAnalytic;
@override
final dynamic failureOptionProductAnalytic;
@override
@JsonKey()
final bool isFetching;
@override
String toString() {
return 'ProductAnalyticLoaderState(productAnalytic: $productAnalytic, failureOptionProductAnalytic: $failureOptionProductAnalytic, isFetching: $isFetching)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProductAnalyticLoaderStateImpl &&
const DeepCollectionEquality().equals(
other.productAnalytic,
productAnalytic,
) &&
const DeepCollectionEquality().equals(
other.failureOptionProductAnalytic,
failureOptionProductAnalytic,
) &&
(identical(other.isFetching, isFetching) ||
other.isFetching == isFetching));
}
@override
int get hashCode => Object.hash(
runtimeType,
const DeepCollectionEquality().hash(productAnalytic),
const DeepCollectionEquality().hash(failureOptionProductAnalytic),
isFetching,
);
/// Create a copy of ProductAnalyticLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProductAnalyticLoaderStateImplCopyWith<_$ProductAnalyticLoaderStateImpl>
get copyWith =>
__$$ProductAnalyticLoaderStateImplCopyWithImpl<
_$ProductAnalyticLoaderStateImpl
>(this, _$identity);
}
abstract class _ProductAnalyticLoaderState
implements ProductAnalyticLoaderState {
const factory _ProductAnalyticLoaderState({
required final ProductAnalytic productAnalytic,
required final dynamic failureOptionProductAnalytic,
final bool isFetching,
}) = _$ProductAnalyticLoaderStateImpl;
@override
ProductAnalytic get productAnalytic;
@override
dynamic get failureOptionProductAnalytic;
@override
bool get isFetching;
/// Create a copy of ProductAnalyticLoaderState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProductAnalyticLoaderStateImplCopyWith<_$ProductAnalyticLoaderStateImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,6 @@
part of 'product_analytic_loader_bloc.dart';
@freezed
class ProductAnalyticLoaderEvent with _$ProductAnalyticLoaderEvent {
const factory ProductAnalyticLoaderEvent.fetched() = _Fetched;
}

View File

@ -0,0 +1,15 @@
part of 'product_analytic_loader_bloc.dart';
@freezed
class ProductAnalyticLoaderState with _$ProductAnalyticLoaderState {
const factory ProductAnalyticLoaderState({
required ProductAnalytic productAnalytic,
required Option<AnalyticFailure> failureOptionProductAnalytic,
@Default(false) bool isFetching,
}) = _ProductAnalyticLoaderState;
factory ProductAnalyticLoaderState.initial() => ProductAnalyticLoaderState(
productAnalytic: ProductAnalytic.empty(),
failureOptionProductAnalytic: none(),
);
}

View File

@ -8,6 +8,7 @@ class ApiPath {
static const String profitLossAnalytic = '/api/v1/analytics/profit-loss';
static const String categoryAnalytic = '/api/v1/analytics/categories';
static const String dashboardAnalytic = '/api/v1/analytics/dashboard';
static const String productAnalytic = '/api/v1/analytics/products';
// Inventory
static const String inventoryReportDetail =

View File

@ -9,4 +9,5 @@ part 'entities/profit_loss_analytic_entity.dart';
part 'entities/category_analytic_entity.dart';
part 'entities/inventory_analytic_entity.dart';
part 'entities/dashboard_analytic_entity.dart';
part 'entities/product_analytic_entity.dart';
part 'failures/analytic_failure.dart';

View File

@ -5723,6 +5723,552 @@ abstract class _DashboardRecentSale implements DashboardRecentSale {
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$ProductAnalytic {
String get organizationId => throw _privateConstructorUsedError;
String get outletId => throw _privateConstructorUsedError;
String get dateFrom => throw _privateConstructorUsedError;
String get dateTo => throw _privateConstructorUsedError;
List<ProductAnalyticData> get data => throw _privateConstructorUsedError;
/// Create a copy of ProductAnalytic
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProductAnalyticCopyWith<ProductAnalytic> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticCopyWith<$Res> {
factory $ProductAnalyticCopyWith(
ProductAnalytic value,
$Res Function(ProductAnalytic) then,
) = _$ProductAnalyticCopyWithImpl<$Res, ProductAnalytic>;
@useResult
$Res call({
String organizationId,
String outletId,
String dateFrom,
String dateTo,
List<ProductAnalyticData> data,
});
}
/// @nodoc
class _$ProductAnalyticCopyWithImpl<$Res, $Val extends ProductAnalytic>
implements $ProductAnalyticCopyWith<$Res> {
_$ProductAnalyticCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalytic
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? organizationId = null,
Object? outletId = null,
Object? dateFrom = null,
Object? dateTo = null,
Object? data = null,
}) {
return _then(
_value.copyWith(
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
dateFrom: null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as String,
dateTo: null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as String,
data: null == data
? _value.data
: data // ignore: cast_nullable_to_non_nullable
as List<ProductAnalyticData>,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProductAnalyticImplCopyWith<$Res>
implements $ProductAnalyticCopyWith<$Res> {
factory _$$ProductAnalyticImplCopyWith(
_$ProductAnalyticImpl value,
$Res Function(_$ProductAnalyticImpl) then,
) = __$$ProductAnalyticImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String organizationId,
String outletId,
String dateFrom,
String dateTo,
List<ProductAnalyticData> data,
});
}
/// @nodoc
class __$$ProductAnalyticImplCopyWithImpl<$Res>
extends _$ProductAnalyticCopyWithImpl<$Res, _$ProductAnalyticImpl>
implements _$$ProductAnalyticImplCopyWith<$Res> {
__$$ProductAnalyticImplCopyWithImpl(
_$ProductAnalyticImpl _value,
$Res Function(_$ProductAnalyticImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalytic
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? organizationId = null,
Object? outletId = null,
Object? dateFrom = null,
Object? dateTo = null,
Object? data = null,
}) {
return _then(
_$ProductAnalyticImpl(
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
dateFrom: null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as String,
dateTo: null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as String,
data: null == data
? _value._data
: data // ignore: cast_nullable_to_non_nullable
as List<ProductAnalyticData>,
),
);
}
}
/// @nodoc
class _$ProductAnalyticImpl implements _ProductAnalytic {
const _$ProductAnalyticImpl({
required this.organizationId,
required this.outletId,
required this.dateFrom,
required this.dateTo,
required final List<ProductAnalyticData> data,
}) : _data = data;
@override
final String organizationId;
@override
final String outletId;
@override
final String dateFrom;
@override
final String dateTo;
final List<ProductAnalyticData> _data;
@override
List<ProductAnalyticData> get data {
if (_data is EqualUnmodifiableListView) return _data;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_data);
}
@override
String toString() {
return 'ProductAnalytic(organizationId: $organizationId, outletId: $outletId, dateFrom: $dateFrom, dateTo: $dateTo, data: $data)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProductAnalyticImpl &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.dateFrom, dateFrom) ||
other.dateFrom == dateFrom) &&
(identical(other.dateTo, dateTo) || other.dateTo == dateTo) &&
const DeepCollectionEquality().equals(other._data, _data));
}
@override
int get hashCode => Object.hash(
runtimeType,
organizationId,
outletId,
dateFrom,
dateTo,
const DeepCollectionEquality().hash(_data),
);
/// Create a copy of ProductAnalytic
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProductAnalyticImplCopyWith<_$ProductAnalyticImpl> get copyWith =>
__$$ProductAnalyticImplCopyWithImpl<_$ProductAnalyticImpl>(
this,
_$identity,
);
}
abstract class _ProductAnalytic implements ProductAnalytic {
const factory _ProductAnalytic({
required final String organizationId,
required final String outletId,
required final String dateFrom,
required final String dateTo,
required final List<ProductAnalyticData> data,
}) = _$ProductAnalyticImpl;
@override
String get organizationId;
@override
String get outletId;
@override
String get dateFrom;
@override
String get dateTo;
@override
List<ProductAnalyticData> get data;
/// Create a copy of ProductAnalytic
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProductAnalyticImplCopyWith<_$ProductAnalyticImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$ProductAnalyticData {
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;
double get revenue => throw _privateConstructorUsedError;
double get averagePrice => throw _privateConstructorUsedError;
int get orderCount => throw _privateConstructorUsedError;
/// Create a copy of ProductAnalyticData
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProductAnalyticDataCopyWith<ProductAnalyticData> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticDataCopyWith<$Res> {
factory $ProductAnalyticDataCopyWith(
ProductAnalyticData value,
$Res Function(ProductAnalyticData) then,
) = _$ProductAnalyticDataCopyWithImpl<$Res, ProductAnalyticData>;
@useResult
$Res call({
String productId,
String productName,
String categoryId,
String categoryName,
int quantitySold,
double revenue,
double averagePrice,
int orderCount,
});
}
/// @nodoc
class _$ProductAnalyticDataCopyWithImpl<$Res, $Val extends ProductAnalyticData>
implements $ProductAnalyticDataCopyWith<$Res> {
_$ProductAnalyticDataCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalyticData
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = null,
Object? productName = null,
Object? categoryId = null,
Object? categoryName = null,
Object? quantitySold = null,
Object? revenue = null,
Object? averagePrice = null,
Object? orderCount = null,
}) {
return _then(
_value.copyWith(
productId: null == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String,
productName: null == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String,
categoryId: null == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String,
categoryName: null == categoryName
? _value.categoryName
: categoryName // ignore: cast_nullable_to_non_nullable
as String,
quantitySold: null == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as int,
revenue: null == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as double,
averagePrice: null == averagePrice
? _value.averagePrice
: averagePrice // ignore: cast_nullable_to_non_nullable
as double,
orderCount: null == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProductAnalyticDataImplCopyWith<$Res>
implements $ProductAnalyticDataCopyWith<$Res> {
factory _$$ProductAnalyticDataImplCopyWith(
_$ProductAnalyticDataImpl value,
$Res Function(_$ProductAnalyticDataImpl) then,
) = __$$ProductAnalyticDataImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String productId,
String productName,
String categoryId,
String categoryName,
int quantitySold,
double revenue,
double averagePrice,
int orderCount,
});
}
/// @nodoc
class __$$ProductAnalyticDataImplCopyWithImpl<$Res>
extends _$ProductAnalyticDataCopyWithImpl<$Res, _$ProductAnalyticDataImpl>
implements _$$ProductAnalyticDataImplCopyWith<$Res> {
__$$ProductAnalyticDataImplCopyWithImpl(
_$ProductAnalyticDataImpl _value,
$Res Function(_$ProductAnalyticDataImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalyticData
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = null,
Object? productName = null,
Object? categoryId = null,
Object? categoryName = null,
Object? quantitySold = null,
Object? revenue = null,
Object? averagePrice = null,
Object? orderCount = null,
}) {
return _then(
_$ProductAnalyticDataImpl(
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 double,
averagePrice: null == averagePrice
? _value.averagePrice
: averagePrice // ignore: cast_nullable_to_non_nullable
as double,
orderCount: null == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int,
),
);
}
}
/// @nodoc
class _$ProductAnalyticDataImpl implements _ProductAnalyticData {
const _$ProductAnalyticDataImpl({
required this.productId,
required this.productName,
required this.categoryId,
required this.categoryName,
required this.quantitySold,
required this.revenue,
required this.averagePrice,
required this.orderCount,
});
@override
final String productId;
@override
final String productName;
@override
final String categoryId;
@override
final String categoryName;
@override
final int quantitySold;
@override
final double revenue;
@override
final double averagePrice;
@override
final int orderCount;
@override
String toString() {
return 'ProductAnalyticData(productId: $productId, productName: $productName, categoryId: $categoryId, categoryName: $categoryName, quantitySold: $quantitySold, revenue: $revenue, averagePrice: $averagePrice, orderCount: $orderCount)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProductAnalyticDataImpl &&
(identical(other.productId, productId) ||
other.productId == productId) &&
(identical(other.productName, productName) ||
other.productName == productName) &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId) &&
(identical(other.categoryName, categoryName) ||
other.categoryName == categoryName) &&
(identical(other.quantitySold, quantitySold) ||
other.quantitySold == quantitySold) &&
(identical(other.revenue, revenue) || other.revenue == revenue) &&
(identical(other.averagePrice, averagePrice) ||
other.averagePrice == averagePrice) &&
(identical(other.orderCount, orderCount) ||
other.orderCount == orderCount));
}
@override
int get hashCode => Object.hash(
runtimeType,
productId,
productName,
categoryId,
categoryName,
quantitySold,
revenue,
averagePrice,
orderCount,
);
/// Create a copy of ProductAnalyticData
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProductAnalyticDataImplCopyWith<_$ProductAnalyticDataImpl> get copyWith =>
__$$ProductAnalyticDataImplCopyWithImpl<_$ProductAnalyticDataImpl>(
this,
_$identity,
);
}
abstract class _ProductAnalyticData implements ProductAnalyticData {
const factory _ProductAnalyticData({
required final String productId,
required final String productName,
required final String categoryId,
required final String categoryName,
required final int quantitySold,
required final double revenue,
required final double averagePrice,
required final int orderCount,
}) = _$ProductAnalyticDataImpl;
@override
String get productId;
@override
String get productName;
@override
String get categoryId;
@override
String get categoryName;
@override
int get quantitySold;
@override
double get revenue;
@override
double get averagePrice;
@override
int get orderCount;
/// Create a copy of ProductAnalyticData
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProductAnalyticDataImplCopyWith<_$ProductAnalyticDataImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$AnalyticFailure {
@optionalTypeArgs

View File

@ -0,0 +1,45 @@
part of '../analytic.dart';
@freezed
class ProductAnalytic with _$ProductAnalytic {
const factory ProductAnalytic({
required String organizationId,
required String outletId,
required String dateFrom,
required String dateTo,
required List<ProductAnalyticData> data,
}) = _ProductAnalytic;
factory ProductAnalytic.empty() => const ProductAnalytic(
organizationId: '',
outletId: '',
dateFrom: '',
dateTo: '',
data: [],
);
}
@freezed
class ProductAnalyticData with _$ProductAnalyticData {
const factory ProductAnalyticData({
required String productId,
required String productName,
required String categoryId,
required String categoryName,
required int quantitySold,
required double revenue,
required double averagePrice,
required int orderCount,
}) = _ProductAnalyticData;
factory ProductAnalyticData.empty() => const ProductAnalyticData(
productId: '',
productName: '',
categoryId: '',
categoryName: '',
quantitySold: 0,
revenue: 0.0,
averagePrice: 0.0,
orderCount: 0,
);
}

View File

@ -27,4 +27,9 @@ abstract class IAnalyticRepository {
required DateTime dateFrom,
required DateTime dateTo,
});
Future<Either<AnalyticFailure, ProductAnalytic>> getProduct({
required DateTime dateFrom,
required DateTime dateTo,
});
}

View File

@ -10,3 +10,4 @@ part 'dto/profit_loss_analytic_dto.dart';
part 'dto/category_analytic_dto.dart';
part 'dto/inventory_analytic_dto.dart';
part 'dto/dashboard_analytic_dto.dart';
part 'dto/product_analytic_dto.dart';

View File

@ -6653,3 +6653,630 @@ abstract class _DashboardRecentSaleDto extends DashboardRecentSaleDto {
_$$DashboardRecentSaleDtoImplCopyWith<_$DashboardRecentSaleDtoImpl>
get copyWith => throw _privateConstructorUsedError;
}
ProductAnalyticDto _$ProductAnalyticDtoFromJson(Map<String, dynamic> json) {
return _ProductAnalyticDto.fromJson(json);
}
/// @nodoc
mixin _$ProductAnalyticDto {
@JsonKey(name: 'organization_id')
String get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: 'outlet_id')
String get outletId => throw _privateConstructorUsedError;
@JsonKey(name: 'date_from')
String get dateFrom => throw _privateConstructorUsedError;
@JsonKey(name: 'date_to')
String get dateTo => throw _privateConstructorUsedError;
List<ProductAnalyticDataDto> get data => throw _privateConstructorUsedError;
/// Serializes this ProductAnalyticDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of ProductAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProductAnalyticDtoCopyWith<ProductAnalyticDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticDtoCopyWith<$Res> {
factory $ProductAnalyticDtoCopyWith(
ProductAnalyticDto value,
$Res Function(ProductAnalyticDto) then,
) = _$ProductAnalyticDtoCopyWithImpl<$Res, ProductAnalyticDto>;
@useResult
$Res call({
@JsonKey(name: 'organization_id') String organizationId,
@JsonKey(name: 'outlet_id') String outletId,
@JsonKey(name: 'date_from') String dateFrom,
@JsonKey(name: 'date_to') String dateTo,
List<ProductAnalyticDataDto> data,
});
}
/// @nodoc
class _$ProductAnalyticDtoCopyWithImpl<$Res, $Val extends ProductAnalyticDto>
implements $ProductAnalyticDtoCopyWith<$Res> {
_$ProductAnalyticDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? organizationId = null,
Object? outletId = null,
Object? dateFrom = null,
Object? dateTo = null,
Object? data = null,
}) {
return _then(
_value.copyWith(
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
dateFrom: null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as String,
dateTo: null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as String,
data: null == data
? _value.data
: data // ignore: cast_nullable_to_non_nullable
as List<ProductAnalyticDataDto>,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProductAnalyticDtoImplCopyWith<$Res>
implements $ProductAnalyticDtoCopyWith<$Res> {
factory _$$ProductAnalyticDtoImplCopyWith(
_$ProductAnalyticDtoImpl value,
$Res Function(_$ProductAnalyticDtoImpl) then,
) = __$$ProductAnalyticDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'organization_id') String organizationId,
@JsonKey(name: 'outlet_id') String outletId,
@JsonKey(name: 'date_from') String dateFrom,
@JsonKey(name: 'date_to') String dateTo,
List<ProductAnalyticDataDto> data,
});
}
/// @nodoc
class __$$ProductAnalyticDtoImplCopyWithImpl<$Res>
extends _$ProductAnalyticDtoCopyWithImpl<$Res, _$ProductAnalyticDtoImpl>
implements _$$ProductAnalyticDtoImplCopyWith<$Res> {
__$$ProductAnalyticDtoImplCopyWithImpl(
_$ProductAnalyticDtoImpl _value,
$Res Function(_$ProductAnalyticDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? organizationId = null,
Object? outletId = null,
Object? dateFrom = null,
Object? dateTo = null,
Object? data = null,
}) {
return _then(
_$ProductAnalyticDtoImpl(
organizationId: null == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String,
outletId: null == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String,
dateFrom: null == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as String,
dateTo: null == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as String,
data: null == data
? _value._data
: data // ignore: cast_nullable_to_non_nullable
as List<ProductAnalyticDataDto>,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$ProductAnalyticDtoImpl extends _ProductAnalyticDto {
const _$ProductAnalyticDtoImpl({
@JsonKey(name: 'organization_id') required this.organizationId,
@JsonKey(name: 'outlet_id') required this.outletId,
@JsonKey(name: 'date_from') required this.dateFrom,
@JsonKey(name: 'date_to') required this.dateTo,
required final List<ProductAnalyticDataDto> data,
}) : _data = data,
super._();
factory _$ProductAnalyticDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$ProductAnalyticDtoImplFromJson(json);
@override
@JsonKey(name: 'organization_id')
final String organizationId;
@override
@JsonKey(name: 'outlet_id')
final String outletId;
@override
@JsonKey(name: 'date_from')
final String dateFrom;
@override
@JsonKey(name: 'date_to')
final String dateTo;
final List<ProductAnalyticDataDto> _data;
@override
List<ProductAnalyticDataDto> get data {
if (_data is EqualUnmodifiableListView) return _data;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_data);
}
@override
String toString() {
return 'ProductAnalyticDto(organizationId: $organizationId, outletId: $outletId, dateFrom: $dateFrom, dateTo: $dateTo, data: $data)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProductAnalyticDtoImpl &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.dateFrom, dateFrom) ||
other.dateFrom == dateFrom) &&
(identical(other.dateTo, dateTo) || other.dateTo == dateTo) &&
const DeepCollectionEquality().equals(other._data, _data));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
organizationId,
outletId,
dateFrom,
dateTo,
const DeepCollectionEquality().hash(_data),
);
/// Create a copy of ProductAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProductAnalyticDtoImplCopyWith<_$ProductAnalyticDtoImpl> get copyWith =>
__$$ProductAnalyticDtoImplCopyWithImpl<_$ProductAnalyticDtoImpl>(
this,
_$identity,
);
@override
Map<String, dynamic> toJson() {
return _$$ProductAnalyticDtoImplToJson(this);
}
}
abstract class _ProductAnalyticDto extends ProductAnalyticDto {
const factory _ProductAnalyticDto({
@JsonKey(name: 'organization_id') required final String organizationId,
@JsonKey(name: 'outlet_id') required final String outletId,
@JsonKey(name: 'date_from') required final String dateFrom,
@JsonKey(name: 'date_to') required final String dateTo,
required final List<ProductAnalyticDataDto> data,
}) = _$ProductAnalyticDtoImpl;
const _ProductAnalyticDto._() : super._();
factory _ProductAnalyticDto.fromJson(Map<String, dynamic> json) =
_$ProductAnalyticDtoImpl.fromJson;
@override
@JsonKey(name: 'organization_id')
String get organizationId;
@override
@JsonKey(name: 'outlet_id')
String get outletId;
@override
@JsonKey(name: 'date_from')
String get dateFrom;
@override
@JsonKey(name: 'date_to')
String get dateTo;
@override
List<ProductAnalyticDataDto> get data;
/// Create a copy of ProductAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProductAnalyticDtoImplCopyWith<_$ProductAnalyticDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
ProductAnalyticDataDto _$ProductAnalyticDataDtoFromJson(
Map<String, dynamic> json,
) {
return _ProductAnalyticDataDto.fromJson(json);
}
/// @nodoc
mixin _$ProductAnalyticDataDto {
@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;
double get revenue => throw _privateConstructorUsedError;
@JsonKey(name: 'average_price')
double get averagePrice => throw _privateConstructorUsedError;
@JsonKey(name: 'order_count')
int get orderCount => throw _privateConstructorUsedError;
/// Serializes this ProductAnalyticDataDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of ProductAnalyticDataDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProductAnalyticDataDtoCopyWith<ProductAnalyticDataDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticDataDtoCopyWith<$Res> {
factory $ProductAnalyticDataDtoCopyWith(
ProductAnalyticDataDto value,
$Res Function(ProductAnalyticDataDto) then,
) = _$ProductAnalyticDataDtoCopyWithImpl<$Res, ProductAnalyticDataDto>;
@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,
double revenue,
@JsonKey(name: 'average_price') double averagePrice,
@JsonKey(name: 'order_count') int orderCount,
});
}
/// @nodoc
class _$ProductAnalyticDataDtoCopyWithImpl<
$Res,
$Val extends ProductAnalyticDataDto
>
implements $ProductAnalyticDataDtoCopyWith<$Res> {
_$ProductAnalyticDataDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalyticDataDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = null,
Object? productName = null,
Object? categoryId = null,
Object? categoryName = null,
Object? quantitySold = null,
Object? revenue = null,
Object? averagePrice = null,
Object? orderCount = null,
}) {
return _then(
_value.copyWith(
productId: null == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String,
productName: null == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String,
categoryId: null == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String,
categoryName: null == categoryName
? _value.categoryName
: categoryName // ignore: cast_nullable_to_non_nullable
as String,
quantitySold: null == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as int,
revenue: null == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as double,
averagePrice: null == averagePrice
? _value.averagePrice
: averagePrice // ignore: cast_nullable_to_non_nullable
as double,
orderCount: null == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProductAnalyticDataDtoImplCopyWith<$Res>
implements $ProductAnalyticDataDtoCopyWith<$Res> {
factory _$$ProductAnalyticDataDtoImplCopyWith(
_$ProductAnalyticDataDtoImpl value,
$Res Function(_$ProductAnalyticDataDtoImpl) then,
) = __$$ProductAnalyticDataDtoImplCopyWithImpl<$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,
double revenue,
@JsonKey(name: 'average_price') double averagePrice,
@JsonKey(name: 'order_count') int orderCount,
});
}
/// @nodoc
class __$$ProductAnalyticDataDtoImplCopyWithImpl<$Res>
extends
_$ProductAnalyticDataDtoCopyWithImpl<$Res, _$ProductAnalyticDataDtoImpl>
implements _$$ProductAnalyticDataDtoImplCopyWith<$Res> {
__$$ProductAnalyticDataDtoImplCopyWithImpl(
_$ProductAnalyticDataDtoImpl _value,
$Res Function(_$ProductAnalyticDataDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalyticDataDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = null,
Object? productName = null,
Object? categoryId = null,
Object? categoryName = null,
Object? quantitySold = null,
Object? revenue = null,
Object? averagePrice = null,
Object? orderCount = null,
}) {
return _then(
_$ProductAnalyticDataDtoImpl(
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 double,
averagePrice: null == averagePrice
? _value.averagePrice
: averagePrice // ignore: cast_nullable_to_non_nullable
as double,
orderCount: null == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$ProductAnalyticDataDtoImpl extends _ProductAnalyticDataDto {
const _$ProductAnalyticDataDtoImpl({
@JsonKey(name: 'product_id') required this.productId,
@JsonKey(name: 'product_name') required this.productName,
@JsonKey(name: 'category_id') required this.categoryId,
@JsonKey(name: 'category_name') required this.categoryName,
@JsonKey(name: 'quantity_sold') required this.quantitySold,
required this.revenue,
@JsonKey(name: 'average_price') required this.averagePrice,
@JsonKey(name: 'order_count') required this.orderCount,
}) : super._();
factory _$ProductAnalyticDataDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$ProductAnalyticDataDtoImplFromJson(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
final double revenue;
@override
@JsonKey(name: 'average_price')
final double averagePrice;
@override
@JsonKey(name: 'order_count')
final int orderCount;
@override
String toString() {
return 'ProductAnalyticDataDto(productId: $productId, productName: $productName, categoryId: $categoryId, categoryName: $categoryName, quantitySold: $quantitySold, revenue: $revenue, averagePrice: $averagePrice, orderCount: $orderCount)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProductAnalyticDataDtoImpl &&
(identical(other.productId, productId) ||
other.productId == productId) &&
(identical(other.productName, productName) ||
other.productName == productName) &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId) &&
(identical(other.categoryName, categoryName) ||
other.categoryName == categoryName) &&
(identical(other.quantitySold, quantitySold) ||
other.quantitySold == quantitySold) &&
(identical(other.revenue, revenue) || other.revenue == revenue) &&
(identical(other.averagePrice, averagePrice) ||
other.averagePrice == averagePrice) &&
(identical(other.orderCount, orderCount) ||
other.orderCount == orderCount));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
productId,
productName,
categoryId,
categoryName,
quantitySold,
revenue,
averagePrice,
orderCount,
);
/// Create a copy of ProductAnalyticDataDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProductAnalyticDataDtoImplCopyWith<_$ProductAnalyticDataDtoImpl>
get copyWith =>
__$$ProductAnalyticDataDtoImplCopyWithImpl<_$ProductAnalyticDataDtoImpl>(
this,
_$identity,
);
@override
Map<String, dynamic> toJson() {
return _$$ProductAnalyticDataDtoImplToJson(this);
}
}
abstract class _ProductAnalyticDataDto extends ProductAnalyticDataDto {
const factory _ProductAnalyticDataDto({
@JsonKey(name: 'product_id') required final String productId,
@JsonKey(name: 'product_name') required final String productName,
@JsonKey(name: 'category_id') required final String categoryId,
@JsonKey(name: 'category_name') required final String categoryName,
@JsonKey(name: 'quantity_sold') required final int quantitySold,
required final double revenue,
@JsonKey(name: 'average_price') required final double averagePrice,
@JsonKey(name: 'order_count') required final int orderCount,
}) = _$ProductAnalyticDataDtoImpl;
const _ProductAnalyticDataDto._() : super._();
factory _ProductAnalyticDataDto.fromJson(Map<String, dynamic> json) =
_$ProductAnalyticDataDtoImpl.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
double get revenue;
@override
@JsonKey(name: 'average_price')
double get averagePrice;
@override
@JsonKey(name: 'order_count')
int get orderCount;
/// Create a copy of ProductAnalyticDataDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProductAnalyticDataDtoImplCopyWith<_$ProductAnalyticDataDtoImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@ -517,3 +517,51 @@ Map<String, dynamic> _$$DashboardRecentSaleDtoImplToJson(
'discount': instance.discount,
'net_sales': instance.netSales,
};
_$ProductAnalyticDtoImpl _$$ProductAnalyticDtoImplFromJson(
Map<String, dynamic> json,
) => _$ProductAnalyticDtoImpl(
organizationId: json['organization_id'] as String,
outletId: json['outlet_id'] as String,
dateFrom: json['date_from'] as String,
dateTo: json['date_to'] as String,
data: (json['data'] as List<dynamic>)
.map((e) => ProductAnalyticDataDto.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$ProductAnalyticDtoImplToJson(
_$ProductAnalyticDtoImpl instance,
) => <String, dynamic>{
'organization_id': instance.organizationId,
'outlet_id': instance.outletId,
'date_from': instance.dateFrom,
'date_to': instance.dateTo,
'data': instance.data,
};
_$ProductAnalyticDataDtoImpl _$$ProductAnalyticDataDtoImplFromJson(
Map<String, dynamic> json,
) => _$ProductAnalyticDataDtoImpl(
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).toDouble(),
averagePrice: (json['average_price'] as num).toDouble(),
orderCount: (json['order_count'] as num).toInt(),
);
Map<String, dynamic> _$$ProductAnalyticDataDtoImplToJson(
_$ProductAnalyticDataDtoImpl instance,
) => <String, dynamic>{
'product_id': instance.productId,
'product_name': instance.productName,
'category_id': instance.categoryId,
'category_name': instance.categoryName,
'quantity_sold': instance.quantitySold,
'revenue': instance.revenue,
'average_price': instance.averagePrice,
'order_count': instance.orderCount,
};

View File

@ -154,4 +154,32 @@ class AnalyticRemoteDataProvider {
return DC.error(AnalyticFailure.serverError(e));
}
}
Future<DC<AnalyticFailure, ProductAnalyticDto>> fetchProduct({
required String outletId,
required DateTime dateFrom,
required DateTime dateTo,
}) async {
try {
final response = await _apiClient.get(
ApiPath.productAnalytic,
params: {
'date_from': dateFrom.toServerDate,
'date_to': dateTo.toServerDate,
},
headers: getAuthorizationHeader(),
);
if (response.data['data'] == null) {
return DC.error(AnalyticFailure.empty());
}
final dto = ProductAnalyticDto.fromJson(response.data['data']);
return DC.data(dto);
} on ApiFailure catch (e, s) {
log('fetchProductError', name: _logName, error: e, stackTrace: s);
return DC.error(AnalyticFailure.serverError(e));
}
}
}

View File

@ -0,0 +1,55 @@
part of '../analytic_dtos.dart';
@freezed
class ProductAnalyticDto with _$ProductAnalyticDto {
const ProductAnalyticDto._();
const factory ProductAnalyticDto({
@JsonKey(name: 'organization_id') required String organizationId,
@JsonKey(name: 'outlet_id') required String outletId,
@JsonKey(name: 'date_from') required String dateFrom,
@JsonKey(name: 'date_to') required String dateTo,
required List<ProductAnalyticDataDto> data,
}) = _ProductAnalyticDto;
factory ProductAnalyticDto.fromJson(Map<String, dynamic> json) =>
_$ProductAnalyticDtoFromJson(json);
ProductAnalytic toDomain() => ProductAnalytic(
organizationId: organizationId,
outletId: outletId,
dateFrom: dateFrom,
dateTo: dateTo,
data: data.map((e) => e.toDomain()).toList(),
);
}
@freezed
class ProductAnalyticDataDto with _$ProductAnalyticDataDto {
const ProductAnalyticDataDto._();
const factory ProductAnalyticDataDto({
@JsonKey(name: 'product_id') required String productId,
@JsonKey(name: 'product_name') required String productName,
@JsonKey(name: 'category_id') required String categoryId,
@JsonKey(name: 'category_name') required String categoryName,
@JsonKey(name: 'quantity_sold') required int quantitySold,
required double revenue,
@JsonKey(name: 'average_price') required double averagePrice,
@JsonKey(name: 'order_count') required int orderCount,
}) = _ProductAnalyticDataDto;
factory ProductAnalyticDataDto.fromJson(Map<String, dynamic> json) =>
_$ProductAnalyticDataDtoFromJson(json);
ProductAnalyticData toDomain() => ProductAnalyticData(
productId: productId,
productName: productName,
categoryId: categoryId,
categoryName: categoryName,
quantitySold: quantitySold,
revenue: revenue,
averagePrice: averagePrice,
orderCount: orderCount,
);
}

View File

@ -142,4 +142,31 @@ class AnalyticRepository implements IAnalyticRepository {
return left(const AnalyticFailure.unexpectedError());
}
}
@override
Future<Either<AnalyticFailure, ProductAnalytic>> getProduct({
required DateTime dateFrom,
required DateTime dateTo,
}) async {
try {
User currentUser = await _authLocalDataProvider.currentUser();
final result = await _dataProvider.fetchProduct(
outletId: currentUser.outletId,
dateFrom: dateFrom,
dateTo: dateTo,
);
if (result.hasError) {
return left(result.error!);
}
final auth = result.data!.toDomain();
return right(auth);
} catch (e, s) {
log('getProductError', name: _logName, error: e, stackTrace: s);
return left(const AnalyticFailure.unexpectedError());
}
}
}

View File

@ -15,6 +15,8 @@ import 'package:apskel_owner_flutter/application/analytic/dashboard_analytic_loa
as _i516;
import 'package:apskel_owner_flutter/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.dart'
as _i785;
import 'package:apskel_owner_flutter/application/analytic/product_analytic_loader/product_analytic_loader_bloc.dart'
as _i221;
import 'package:apskel_owner_flutter/application/analytic/profit_loss_loader/profit_loss_loader_bloc.dart'
as _i11;
import 'package:apskel_owner_flutter/application/analytic/sales_loader/sales_loader_bloc.dart'
@ -179,6 +181,9 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i516.DashboardAnalyticLoaderBloc>(
() => _i516.DashboardAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i221.ProductAnalyticLoaderBloc>(
() => _i221.ProductAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i775.LoginFormBloc>(
() => _i775.LoginFormBloc(gh<_i49.IAuthRepository>()),
);

View File

@ -311,7 +311,7 @@ class ReportRoute extends _i18.PageRouteInfo<void> {
static _i18.PageInfo page = _i18.PageInfo(
name,
builder: (data) {
return const _i13.ReportPage();
return _i18.WrappedRoute(child: const _i13.ReportPage());
},
);
}