report category

This commit is contained in:
efrilm
2025-11-03 23:24:16 +07:00
parent 13941d4881
commit 2a44ce023e
18 changed files with 2163 additions and 1 deletions
@@ -10,3 +10,4 @@ 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';
part 'dtos/category_analytic_dto.dart';
@@ -6032,3 +6032,588 @@ abstract class _ProfitLossAnalyticProductDto
>
get copyWith => throw _privateConstructorUsedError;
}
CategoryAnalyticDto _$CategoryAnalyticDtoFromJson(Map<String, dynamic> json) {
return _CategoryAnalyticDto.fromJson(json);
}
/// @nodoc
mixin _$CategoryAnalyticDto {
@JsonKey(name: "organization_id")
String? get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: "outlet_id")
String? get outletId => throw _privateConstructorUsedError;
@JsonKey(name: "date_from")
DateTime? get dateFrom => throw _privateConstructorUsedError;
@JsonKey(name: "date_to")
DateTime? get dateTo => throw _privateConstructorUsedError;
List<CategoryAnalyticItemDto>? get data => throw _privateConstructorUsedError;
/// Serializes this CategoryAnalyticDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of CategoryAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$CategoryAnalyticDtoCopyWith<CategoryAnalyticDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $CategoryAnalyticDtoCopyWith<$Res> {
factory $CategoryAnalyticDtoCopyWith(
CategoryAnalyticDto value,
$Res Function(CategoryAnalyticDto) then,
) = _$CategoryAnalyticDtoCopyWithImpl<$Res, CategoryAnalyticDto>;
@useResult
$Res call({
@JsonKey(name: "organization_id") String? organizationId,
@JsonKey(name: "outlet_id") String? outletId,
@JsonKey(name: "date_from") DateTime? dateFrom,
@JsonKey(name: "date_to") DateTime? dateTo,
List<CategoryAnalyticItemDto>? data,
});
}
/// @nodoc
class _$CategoryAnalyticDtoCopyWithImpl<$Res, $Val extends CategoryAnalyticDto>
implements $CategoryAnalyticDtoCopyWith<$Res> {
_$CategoryAnalyticDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of CategoryAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? organizationId = freezed,
Object? outletId = freezed,
Object? dateFrom = freezed,
Object? dateTo = freezed,
Object? data = freezed,
}) {
return _then(
_value.copyWith(
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
dateFrom: freezed == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as DateTime?,
dateTo: freezed == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as DateTime?,
data: freezed == data
? _value.data
: data // ignore: cast_nullable_to_non_nullable
as List<CategoryAnalyticItemDto>?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$CategoryAnalyticDtoImplCopyWith<$Res>
implements $CategoryAnalyticDtoCopyWith<$Res> {
factory _$$CategoryAnalyticDtoImplCopyWith(
_$CategoryAnalyticDtoImpl value,
$Res Function(_$CategoryAnalyticDtoImpl) then,
) = __$$CategoryAnalyticDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: "organization_id") String? organizationId,
@JsonKey(name: "outlet_id") String? outletId,
@JsonKey(name: "date_from") DateTime? dateFrom,
@JsonKey(name: "date_to") DateTime? dateTo,
List<CategoryAnalyticItemDto>? data,
});
}
/// @nodoc
class __$$CategoryAnalyticDtoImplCopyWithImpl<$Res>
extends _$CategoryAnalyticDtoCopyWithImpl<$Res, _$CategoryAnalyticDtoImpl>
implements _$$CategoryAnalyticDtoImplCopyWith<$Res> {
__$$CategoryAnalyticDtoImplCopyWithImpl(
_$CategoryAnalyticDtoImpl _value,
$Res Function(_$CategoryAnalyticDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of CategoryAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? organizationId = freezed,
Object? outletId = freezed,
Object? dateFrom = freezed,
Object? dateTo = freezed,
Object? data = freezed,
}) {
return _then(
_$CategoryAnalyticDtoImpl(
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
dateFrom: freezed == dateFrom
? _value.dateFrom
: dateFrom // ignore: cast_nullable_to_non_nullable
as DateTime?,
dateTo: freezed == dateTo
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as DateTime?,
data: freezed == data
? _value._data
: data // ignore: cast_nullable_to_non_nullable
as List<CategoryAnalyticItemDto>?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$CategoryAnalyticDtoImpl extends _CategoryAnalyticDto {
const _$CategoryAnalyticDtoImpl({
@JsonKey(name: "organization_id") this.organizationId,
@JsonKey(name: "outlet_id") this.outletId,
@JsonKey(name: "date_from") this.dateFrom,
@JsonKey(name: "date_to") this.dateTo,
final List<CategoryAnalyticItemDto>? data,
}) : _data = data,
super._();
factory _$CategoryAnalyticDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$CategoryAnalyticDtoImplFromJson(json);
@override
@JsonKey(name: "organization_id")
final String? organizationId;
@override
@JsonKey(name: "outlet_id")
final String? outletId;
@override
@JsonKey(name: "date_from")
final DateTime? dateFrom;
@override
@JsonKey(name: "date_to")
final DateTime? dateTo;
final List<CategoryAnalyticItemDto>? _data;
@override
List<CategoryAnalyticItemDto>? get data {
final value = _data;
if (value == null) return null;
if (_data is EqualUnmodifiableListView) return _data;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value);
}
@override
String toString() {
return 'CategoryAnalyticDto(organizationId: $organizationId, outletId: $outletId, dateFrom: $dateFrom, dateTo: $dateTo, data: $data)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CategoryAnalyticDtoImpl &&
(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 CategoryAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CategoryAnalyticDtoImplCopyWith<_$CategoryAnalyticDtoImpl> get copyWith =>
__$$CategoryAnalyticDtoImplCopyWithImpl<_$CategoryAnalyticDtoImpl>(
this,
_$identity,
);
@override
Map<String, dynamic> toJson() {
return _$$CategoryAnalyticDtoImplToJson(this);
}
}
abstract class _CategoryAnalyticDto extends CategoryAnalyticDto {
const factory _CategoryAnalyticDto({
@JsonKey(name: "organization_id") final String? organizationId,
@JsonKey(name: "outlet_id") final String? outletId,
@JsonKey(name: "date_from") final DateTime? dateFrom,
@JsonKey(name: "date_to") final DateTime? dateTo,
final List<CategoryAnalyticItemDto>? data,
}) = _$CategoryAnalyticDtoImpl;
const _CategoryAnalyticDto._() : super._();
factory _CategoryAnalyticDto.fromJson(Map<String, dynamic> json) =
_$CategoryAnalyticDtoImpl.fromJson;
@override
@JsonKey(name: "organization_id")
String? get organizationId;
@override
@JsonKey(name: "outlet_id")
String? get outletId;
@override
@JsonKey(name: "date_from")
DateTime? get dateFrom;
@override
@JsonKey(name: "date_to")
DateTime? get dateTo;
@override
List<CategoryAnalyticItemDto>? get data;
/// Create a copy of CategoryAnalyticDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CategoryAnalyticDtoImplCopyWith<_$CategoryAnalyticDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
CategoryAnalyticItemDto _$CategoryAnalyticItemDtoFromJson(
Map<String, dynamic> json,
) {
return _CategoryAnalyticItemDto.fromJson(json);
}
/// @nodoc
mixin _$CategoryAnalyticItemDto {
@JsonKey(name: "category_id")
String? get categoryId => throw _privateConstructorUsedError;
@JsonKey(name: "category_name")
String? get categoryName => throw _privateConstructorUsedError;
@JsonKey(name: "total_revenue")
int? get totalRevenue => throw _privateConstructorUsedError;
@JsonKey(name: "total_quantity")
int? get totalQuantity => throw _privateConstructorUsedError;
@JsonKey(name: "product_count")
int? get productCount => throw _privateConstructorUsedError;
@JsonKey(name: "order_count")
int? get orderCount => throw _privateConstructorUsedError;
/// Serializes this CategoryAnalyticItemDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of CategoryAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$CategoryAnalyticItemDtoCopyWith<CategoryAnalyticItemDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $CategoryAnalyticItemDtoCopyWith<$Res> {
factory $CategoryAnalyticItemDtoCopyWith(
CategoryAnalyticItemDto value,
$Res Function(CategoryAnalyticItemDto) then,
) = _$CategoryAnalyticItemDtoCopyWithImpl<$Res, CategoryAnalyticItemDto>;
@useResult
$Res call({
@JsonKey(name: "category_id") String? categoryId,
@JsonKey(name: "category_name") String? categoryName,
@JsonKey(name: "total_revenue") int? totalRevenue,
@JsonKey(name: "total_quantity") int? totalQuantity,
@JsonKey(name: "product_count") int? productCount,
@JsonKey(name: "order_count") int? orderCount,
});
}
/// @nodoc
class _$CategoryAnalyticItemDtoCopyWithImpl<
$Res,
$Val extends CategoryAnalyticItemDto
>
implements $CategoryAnalyticItemDtoCopyWith<$Res> {
_$CategoryAnalyticItemDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of CategoryAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? categoryId = freezed,
Object? categoryName = freezed,
Object? totalRevenue = freezed,
Object? totalQuantity = freezed,
Object? productCount = freezed,
Object? orderCount = freezed,
}) {
return _then(
_value.copyWith(
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?,
totalRevenue: freezed == totalRevenue
? _value.totalRevenue
: totalRevenue // ignore: cast_nullable_to_non_nullable
as int?,
totalQuantity: freezed == totalQuantity
? _value.totalQuantity
: totalQuantity // ignore: cast_nullable_to_non_nullable
as int?,
productCount: freezed == productCount
? _value.productCount
: productCount // ignore: cast_nullable_to_non_nullable
as int?,
orderCount: freezed == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$CategoryAnalyticItemDtoImplCopyWith<$Res>
implements $CategoryAnalyticItemDtoCopyWith<$Res> {
factory _$$CategoryAnalyticItemDtoImplCopyWith(
_$CategoryAnalyticItemDtoImpl value,
$Res Function(_$CategoryAnalyticItemDtoImpl) then,
) = __$$CategoryAnalyticItemDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: "category_id") String? categoryId,
@JsonKey(name: "category_name") String? categoryName,
@JsonKey(name: "total_revenue") int? totalRevenue,
@JsonKey(name: "total_quantity") int? totalQuantity,
@JsonKey(name: "product_count") int? productCount,
@JsonKey(name: "order_count") int? orderCount,
});
}
/// @nodoc
class __$$CategoryAnalyticItemDtoImplCopyWithImpl<$Res>
extends
_$CategoryAnalyticItemDtoCopyWithImpl<
$Res,
_$CategoryAnalyticItemDtoImpl
>
implements _$$CategoryAnalyticItemDtoImplCopyWith<$Res> {
__$$CategoryAnalyticItemDtoImplCopyWithImpl(
_$CategoryAnalyticItemDtoImpl _value,
$Res Function(_$CategoryAnalyticItemDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of CategoryAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? categoryId = freezed,
Object? categoryName = freezed,
Object? totalRevenue = freezed,
Object? totalQuantity = freezed,
Object? productCount = freezed,
Object? orderCount = freezed,
}) {
return _then(
_$CategoryAnalyticItemDtoImpl(
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?,
totalRevenue: freezed == totalRevenue
? _value.totalRevenue
: totalRevenue // ignore: cast_nullable_to_non_nullable
as int?,
totalQuantity: freezed == totalQuantity
? _value.totalQuantity
: totalQuantity // ignore: cast_nullable_to_non_nullable
as int?,
productCount: freezed == productCount
? _value.productCount
: productCount // ignore: cast_nullable_to_non_nullable
as int?,
orderCount: freezed == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$CategoryAnalyticItemDtoImpl extends _CategoryAnalyticItemDto {
const _$CategoryAnalyticItemDtoImpl({
@JsonKey(name: "category_id") this.categoryId,
@JsonKey(name: "category_name") this.categoryName,
@JsonKey(name: "total_revenue") this.totalRevenue,
@JsonKey(name: "total_quantity") this.totalQuantity,
@JsonKey(name: "product_count") this.productCount,
@JsonKey(name: "order_count") this.orderCount,
}) : super._();
factory _$CategoryAnalyticItemDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$CategoryAnalyticItemDtoImplFromJson(json);
@override
@JsonKey(name: "category_id")
final String? categoryId;
@override
@JsonKey(name: "category_name")
final String? categoryName;
@override
@JsonKey(name: "total_revenue")
final int? totalRevenue;
@override
@JsonKey(name: "total_quantity")
final int? totalQuantity;
@override
@JsonKey(name: "product_count")
final int? productCount;
@override
@JsonKey(name: "order_count")
final int? orderCount;
@override
String toString() {
return 'CategoryAnalyticItemDto(categoryId: $categoryId, categoryName: $categoryName, totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, productCount: $productCount, orderCount: $orderCount)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CategoryAnalyticItemDtoImpl &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId) &&
(identical(other.categoryName, categoryName) ||
other.categoryName == categoryName) &&
(identical(other.totalRevenue, totalRevenue) ||
other.totalRevenue == totalRevenue) &&
(identical(other.totalQuantity, totalQuantity) ||
other.totalQuantity == totalQuantity) &&
(identical(other.productCount, productCount) ||
other.productCount == productCount) &&
(identical(other.orderCount, orderCount) ||
other.orderCount == orderCount));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
categoryId,
categoryName,
totalRevenue,
totalQuantity,
productCount,
orderCount,
);
/// Create a copy of CategoryAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CategoryAnalyticItemDtoImplCopyWith<_$CategoryAnalyticItemDtoImpl>
get copyWith =>
__$$CategoryAnalyticItemDtoImplCopyWithImpl<
_$CategoryAnalyticItemDtoImpl
>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$CategoryAnalyticItemDtoImplToJson(this);
}
}
abstract class _CategoryAnalyticItemDto extends CategoryAnalyticItemDto {
const factory _CategoryAnalyticItemDto({
@JsonKey(name: "category_id") final String? categoryId,
@JsonKey(name: "category_name") final String? categoryName,
@JsonKey(name: "total_revenue") final int? totalRevenue,
@JsonKey(name: "total_quantity") final int? totalQuantity,
@JsonKey(name: "product_count") final int? productCount,
@JsonKey(name: "order_count") final int? orderCount,
}) = _$CategoryAnalyticItemDtoImpl;
const _CategoryAnalyticItemDto._() : super._();
factory _CategoryAnalyticItemDto.fromJson(Map<String, dynamic> json) =
_$CategoryAnalyticItemDtoImpl.fromJson;
@override
@JsonKey(name: "category_id")
String? get categoryId;
@override
@JsonKey(name: "category_name")
String? get categoryName;
@override
@JsonKey(name: "total_revenue")
int? get totalRevenue;
@override
@JsonKey(name: "total_quantity")
int? get totalQuantity;
@override
@JsonKey(name: "product_count")
int? get productCount;
@override
@JsonKey(name: "order_count")
int? get orderCount;
/// Create a copy of CategoryAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CategoryAnalyticItemDtoImplCopyWith<_$CategoryAnalyticItemDtoImpl>
get copyWith => throw _privateConstructorUsedError;
}
@@ -479,3 +479,51 @@ Map<String, dynamic> _$$ProfitLossAnalyticProductDtoImplToJson(
'average_cost': instance.averageCost,
'profit_per_unit': instance.profitPerUnit,
};
_$CategoryAnalyticDtoImpl _$$CategoryAnalyticDtoImplFromJson(
Map<String, dynamic> json,
) => _$CategoryAnalyticDtoImpl(
organizationId: json['organization_id'] as String?,
outletId: json['outlet_id'] as String?,
dateFrom: json['date_from'] == null
? null
: DateTime.parse(json['date_from'] as String),
dateTo: json['date_to'] == null
? null
: DateTime.parse(json['date_to'] as String),
data: (json['data'] as List<dynamic>?)
?.map((e) => CategoryAnalyticItemDto.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$CategoryAnalyticDtoImplToJson(
_$CategoryAnalyticDtoImpl instance,
) => <String, dynamic>{
'organization_id': instance.organizationId,
'outlet_id': instance.outletId,
'date_from': instance.dateFrom?.toIso8601String(),
'date_to': instance.dateTo?.toIso8601String(),
'data': instance.data,
};
_$CategoryAnalyticItemDtoImpl _$$CategoryAnalyticItemDtoImplFromJson(
Map<String, dynamic> json,
) => _$CategoryAnalyticItemDtoImpl(
categoryId: json['category_id'] as String?,
categoryName: json['category_name'] as String?,
totalRevenue: (json['total_revenue'] as num?)?.toInt(),
totalQuantity: (json['total_quantity'] as num?)?.toInt(),
productCount: (json['product_count'] as num?)?.toInt(),
orderCount: (json['order_count'] as num?)?.toInt(),
);
Map<String, dynamic> _$$CategoryAnalyticItemDtoImplToJson(
_$CategoryAnalyticItemDtoImpl instance,
) => <String, dynamic>{
'category_id': instance.categoryId,
'category_name': instance.categoryName,
'total_revenue': instance.totalRevenue,
'total_quantity': instance.totalQuantity,
'product_count': instance.productCount,
'order_count': instance.orderCount,
};
@@ -163,4 +163,33 @@ class AnalyticRemoteDataProvider {
return DC.error(AnalyticFailure.serverError(e));
}
}
Future<DC<AnalyticFailure, CategoryAnalyticDto>> fetchCategories({
required DateTime dateFrom,
required DateTime dateTo,
}) async {
try {
final response = await _apiClient.get(
ApiPath.analyticCategories,
params: {
'date_from': dateFrom.toServerDate(),
'date_to': dateTo.toServerDate(),
},
headers: getAuthorizationHeader(),
);
if (response.data['success'] == false) {
return DC.error(AnalyticFailure.unexpectedError());
}
final categories = CategoryAnalyticDto.fromJson(
response.data['data'] as Map<String, dynamic>,
);
return DC.data(categories);
} on ApiFailure catch (e, s) {
log('fetchCategories', name: _logName, error: e, stackTrace: s);
return DC.error(AnalyticFailure.serverError(e));
}
}
}
@@ -0,0 +1,53 @@
part of '../analytic_dtos.dart';
@freezed
class CategoryAnalyticDto with _$CategoryAnalyticDto {
const CategoryAnalyticDto._();
const factory CategoryAnalyticDto({
@JsonKey(name: "organization_id") String? organizationId,
@JsonKey(name: "outlet_id") String? outletId,
@JsonKey(name: "date_from") DateTime? dateFrom,
@JsonKey(name: "date_to") DateTime? dateTo,
List<CategoryAnalyticItemDto>? data,
}) = _CategoryAnalyticDto;
factory CategoryAnalyticDto.fromJson(Map<String, dynamic> json) =>
_$CategoryAnalyticDtoFromJson(json);
// Optional mapper ke entity
CategoryAnalytic toDomain() => CategoryAnalytic(
organizationId: organizationId ?? '',
outletId: outletId ?? '',
dateFrom: dateFrom ?? DateTime.now(),
dateTo: dateTo ?? DateTime.now(),
data: data?.map((e) => e.toDomain()).toList() ?? [],
);
}
@freezed
class CategoryAnalyticItemDto with _$CategoryAnalyticItemDto {
const CategoryAnalyticItemDto._();
const factory CategoryAnalyticItemDto({
@JsonKey(name: "category_id") String? categoryId,
@JsonKey(name: "category_name") String? categoryName,
@JsonKey(name: "total_revenue") int? totalRevenue,
@JsonKey(name: "total_quantity") int? totalQuantity,
@JsonKey(name: "product_count") int? productCount,
@JsonKey(name: "order_count") int? orderCount,
}) = _CategoryAnalyticItemDto;
factory CategoryAnalyticItemDto.fromJson(Map<String, dynamic> json) =>
_$CategoryAnalyticItemDtoFromJson(json);
// Optional mapper ke entity
CategoryAnalyticItem toDomain() => CategoryAnalyticItem(
categoryId: categoryId ?? '',
categoryName: categoryName ?? '',
totalRevenue: totalRevenue ?? 0,
totalQuantity: totalQuantity ?? 0,
productCount: productCount ?? 0,
orderCount: orderCount ?? 0,
);
}
@@ -133,4 +133,28 @@ class AnalyticRepository implements IAnalyticRepository {
return left(const AnalyticFailure.unexpectedError());
}
}
@override
Future<Either<AnalyticFailure, CategoryAnalytic>> getCategories({
required DateTime dateFrom,
required DateTime dateTo,
}) async {
try {
final result = await _dataProvider.fetchCategories(
dateFrom: dateFrom,
dateTo: dateTo,
);
if (result.hasError) {
return left(result.error!);
}
final categories = result.data!.toDomain();
return right(categories);
} catch (e) {
log('getCategoriesError', name: _logName, error: e);
return left(const AnalyticFailure.unexpectedError());
}
}
}