report product

This commit is contained in:
efrilm
2025-11-03 19:34:46 +07:00
parent 3bb6bd653e
commit 14c3c69ad6
19 changed files with 2557 additions and 2 deletions
@@ -7,3 +7,4 @@ part 'analytic_dtos.g.dart';
part 'dtos/dashboard_dto.dart';
part 'dtos/sales_dto.dart';
part 'dtos/product_analytic_dto.dart';
@@ -2739,3 +2739,638 @@ abstract class _SalesAnalyticItemDto extends SalesAnalyticItemDto {
_$$SalesAnalyticItemDtoImplCopyWith<_$SalesAnalyticItemDtoImpl>
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")
DateTime? get dateFrom => throw _privateConstructorUsedError;
@JsonKey(name: "date_to")
DateTime? get dateTo => throw _privateConstructorUsedError;
@JsonKey(name: "data")
List<ProductAnalyticItemDto>? 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") DateTime? dateFrom,
@JsonKey(name: "date_to") DateTime? dateTo,
@JsonKey(name: "data") List<ProductAnalyticItemDto>? 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 = 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<ProductAnalyticItemDto>?,
)
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") DateTime? dateFrom,
@JsonKey(name: "date_to") DateTime? dateTo,
@JsonKey(name: "data") List<ProductAnalyticItemDto>? 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 = freezed,
Object? outletId = freezed,
Object? dateFrom = freezed,
Object? dateTo = freezed,
Object? data = freezed,
}) {
return _then(
_$ProductAnalyticDtoImpl(
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<ProductAnalyticItemDto>?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$ProductAnalyticDtoImpl extends _ProductAnalyticDto {
const _$ProductAnalyticDtoImpl({
@JsonKey(name: "organization_id") this.organizationId,
@JsonKey(name: "outlet_id") this.outletId,
@JsonKey(name: "date_from") this.dateFrom,
@JsonKey(name: "date_to") this.dateTo,
@JsonKey(name: "data") final List<ProductAnalyticItemDto>? 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 DateTime? dateFrom;
@override
@JsonKey(name: "date_to")
final DateTime? dateTo;
final List<ProductAnalyticItemDto>? _data;
@override
@JsonKey(name: "data")
List<ProductAnalyticItemDto>? 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 '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") final String? organizationId,
@JsonKey(name: "outlet_id") final String? outletId,
@JsonKey(name: "date_from") final DateTime? dateFrom,
@JsonKey(name: "date_to") final DateTime? dateTo,
@JsonKey(name: "data") final List<ProductAnalyticItemDto>? 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")
DateTime? get dateFrom;
@override
@JsonKey(name: "date_to")
DateTime? get dateTo;
@override
@JsonKey(name: "data")
List<ProductAnalyticItemDto>? 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;
}
ProductAnalyticItemDto _$ProductAnalyticItemDtoFromJson(
Map<String, dynamic> json,
) {
return _ProductAnalyticItemDto.fromJson(json);
}
/// @nodoc
mixin _$ProductAnalyticItemDto {
@JsonKey(name: "product_id")
String? get productId => throw _privateConstructorUsedError;
@JsonKey(name: "product_name")
String? get productName => throw _privateConstructorUsedError;
@JsonKey(name: "category_id")
String? get categoryId => throw _privateConstructorUsedError;
@JsonKey(name: "category_name")
String? get categoryName => throw _privateConstructorUsedError;
@JsonKey(name: "quantity_sold")
int? get quantitySold => throw _privateConstructorUsedError;
@JsonKey(name: "revenue")
int? get revenue => throw _privateConstructorUsedError;
@JsonKey(name: "average_price")
double? get averagePrice => throw _privateConstructorUsedError;
@JsonKey(name: "order_count")
int? get orderCount => throw _privateConstructorUsedError;
/// Serializes this ProductAnalyticItemDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of ProductAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProductAnalyticItemDtoCopyWith<ProductAnalyticItemDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProductAnalyticItemDtoCopyWith<$Res> {
factory $ProductAnalyticItemDtoCopyWith(
ProductAnalyticItemDto value,
$Res Function(ProductAnalyticItemDto) then,
) = _$ProductAnalyticItemDtoCopyWithImpl<$Res, ProductAnalyticItemDto>;
@useResult
$Res call({
@JsonKey(name: "product_id") String? productId,
@JsonKey(name: "product_name") String? productName,
@JsonKey(name: "category_id") String? categoryId,
@JsonKey(name: "category_name") String? categoryName,
@JsonKey(name: "quantity_sold") int? quantitySold,
@JsonKey(name: "revenue") int? revenue,
@JsonKey(name: "average_price") double? averagePrice,
@JsonKey(name: "order_count") int? orderCount,
});
}
/// @nodoc
class _$ProductAnalyticItemDtoCopyWithImpl<
$Res,
$Val extends ProductAnalyticItemDto
>
implements $ProductAnalyticItemDtoCopyWith<$Res> {
_$ProductAnalyticItemDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProductAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = freezed,
Object? productName = freezed,
Object? categoryId = freezed,
Object? categoryName = freezed,
Object? quantitySold = freezed,
Object? revenue = freezed,
Object? averagePrice = freezed,
Object? orderCount = freezed,
}) {
return _then(
_value.copyWith(
productId: freezed == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String?,
productName: freezed == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String?,
categoryId: freezed == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String?,
categoryName: freezed == categoryName
? _value.categoryName
: categoryName // ignore: cast_nullable_to_non_nullable
as String?,
quantitySold: freezed == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as int?,
revenue: freezed == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as int?,
averagePrice: freezed == averagePrice
? _value.averagePrice
: averagePrice // ignore: cast_nullable_to_non_nullable
as double?,
orderCount: freezed == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProductAnalyticItemDtoImplCopyWith<$Res>
implements $ProductAnalyticItemDtoCopyWith<$Res> {
factory _$$ProductAnalyticItemDtoImplCopyWith(
_$ProductAnalyticItemDtoImpl value,
$Res Function(_$ProductAnalyticItemDtoImpl) then,
) = __$$ProductAnalyticItemDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: "product_id") String? productId,
@JsonKey(name: "product_name") String? productName,
@JsonKey(name: "category_id") String? categoryId,
@JsonKey(name: "category_name") String? categoryName,
@JsonKey(name: "quantity_sold") int? quantitySold,
@JsonKey(name: "revenue") int? revenue,
@JsonKey(name: "average_price") double? averagePrice,
@JsonKey(name: "order_count") int? orderCount,
});
}
/// @nodoc
class __$$ProductAnalyticItemDtoImplCopyWithImpl<$Res>
extends
_$ProductAnalyticItemDtoCopyWithImpl<$Res, _$ProductAnalyticItemDtoImpl>
implements _$$ProductAnalyticItemDtoImplCopyWith<$Res> {
__$$ProductAnalyticItemDtoImplCopyWithImpl(
_$ProductAnalyticItemDtoImpl _value,
$Res Function(_$ProductAnalyticItemDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of ProductAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = freezed,
Object? productName = freezed,
Object? categoryId = freezed,
Object? categoryName = freezed,
Object? quantitySold = freezed,
Object? revenue = freezed,
Object? averagePrice = freezed,
Object? orderCount = freezed,
}) {
return _then(
_$ProductAnalyticItemDtoImpl(
productId: freezed == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String?,
productName: freezed == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String?,
categoryId: freezed == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String?,
categoryName: freezed == categoryName
? _value.categoryName
: categoryName // ignore: cast_nullable_to_non_nullable
as String?,
quantitySold: freezed == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as int?,
revenue: freezed == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as int?,
averagePrice: freezed == averagePrice
? _value.averagePrice
: averagePrice // ignore: cast_nullable_to_non_nullable
as double?,
orderCount: freezed == orderCount
? _value.orderCount
: orderCount // ignore: cast_nullable_to_non_nullable
as int?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$ProductAnalyticItemDtoImpl extends _ProductAnalyticItemDto {
const _$ProductAnalyticItemDtoImpl({
@JsonKey(name: "product_id") this.productId,
@JsonKey(name: "product_name") this.productName,
@JsonKey(name: "category_id") this.categoryId,
@JsonKey(name: "category_name") this.categoryName,
@JsonKey(name: "quantity_sold") this.quantitySold,
@JsonKey(name: "revenue") this.revenue,
@JsonKey(name: "average_price") this.averagePrice,
@JsonKey(name: "order_count") this.orderCount,
}) : super._();
factory _$ProductAnalyticItemDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$ProductAnalyticItemDtoImplFromJson(json);
@override
@JsonKey(name: "product_id")
final String? productId;
@override
@JsonKey(name: "product_name")
final String? productName;
@override
@JsonKey(name: "category_id")
final String? categoryId;
@override
@JsonKey(name: "category_name")
final String? categoryName;
@override
@JsonKey(name: "quantity_sold")
final int? quantitySold;
@override
@JsonKey(name: "revenue")
final int? revenue;
@override
@JsonKey(name: "average_price")
final double? averagePrice;
@override
@JsonKey(name: "order_count")
final int? orderCount;
@override
String toString() {
return 'ProductAnalyticItemDto(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 _$ProductAnalyticItemDtoImpl &&
(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 ProductAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProductAnalyticItemDtoImplCopyWith<_$ProductAnalyticItemDtoImpl>
get copyWith =>
__$$ProductAnalyticItemDtoImplCopyWithImpl<_$ProductAnalyticItemDtoImpl>(
this,
_$identity,
);
@override
Map<String, dynamic> toJson() {
return _$$ProductAnalyticItemDtoImplToJson(this);
}
}
abstract class _ProductAnalyticItemDto extends ProductAnalyticItemDto {
const factory _ProductAnalyticItemDto({
@JsonKey(name: "product_id") final String? productId,
@JsonKey(name: "product_name") final String? productName,
@JsonKey(name: "category_id") final String? categoryId,
@JsonKey(name: "category_name") final String? categoryName,
@JsonKey(name: "quantity_sold") final int? quantitySold,
@JsonKey(name: "revenue") final int? revenue,
@JsonKey(name: "average_price") final double? averagePrice,
@JsonKey(name: "order_count") final int? orderCount,
}) = _$ProductAnalyticItemDtoImpl;
const _ProductAnalyticItemDto._() : super._();
factory _ProductAnalyticItemDto.fromJson(Map<String, dynamic> json) =
_$ProductAnalyticItemDtoImpl.fromJson;
@override
@JsonKey(name: "product_id")
String? get productId;
@override
@JsonKey(name: "product_name")
String? get productName;
@override
@JsonKey(name: "category_id")
String? get categoryId;
@override
@JsonKey(name: "category_name")
String? get categoryName;
@override
@JsonKey(name: "quantity_sold")
int? get quantitySold;
@override
@JsonKey(name: "revenue")
int? get revenue;
@override
@JsonKey(name: "average_price")
double? get averagePrice;
@override
@JsonKey(name: "order_count")
int? get orderCount;
/// Create a copy of ProductAnalyticItemDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProductAnalyticItemDtoImplCopyWith<_$ProductAnalyticItemDtoImpl>
get copyWith => throw _privateConstructorUsedError;
}
@@ -217,3 +217,55 @@ Map<String, dynamic> _$$SalesAnalyticItemDtoImplToJson(
'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'] == 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) => ProductAnalyticItemDto.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?.toIso8601String(),
'date_to': instance.dateTo?.toIso8601String(),
'data': instance.data,
};
_$ProductAnalyticItemDtoImpl _$$ProductAnalyticItemDtoImplFromJson(
Map<String, dynamic> json,
) => _$ProductAnalyticItemDtoImpl(
productId: json['product_id'] as String?,
productName: json['product_name'] as String?,
categoryId: json['category_id'] as String?,
categoryName: json['category_name'] as String?,
quantitySold: (json['quantity_sold'] as num?)?.toInt(),
revenue: (json['revenue'] as num?)?.toInt(),
averagePrice: (json['average_price'] as num?)?.toDouble(),
orderCount: (json['order_count'] as num?)?.toInt(),
);
Map<String, dynamic> _$$ProductAnalyticItemDtoImplToJson(
_$ProductAnalyticItemDtoImpl 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,
};
@@ -76,4 +76,33 @@ class AnalyticRemoteDataProvider {
return DC.error(AnalyticFailure.serverError(e));
}
}
Future<DC<AnalyticFailure, ProductAnalyticDto>> fetchProducts({
required DateTime dateFrom,
required DateTime dateTo,
}) async {
try {
final response = await _apiClient.get(
ApiPath.analyticProducts,
params: {
'date_from': dateFrom.toServerDate(),
'date_to': dateTo.toServerDate(),
},
headers: getAuthorizationHeader(),
);
if (response.data['success'] == false) {
return DC.error(AnalyticFailure.unexpectedError());
}
final products = ProductAnalyticDto.fromJson(
response.data['data'] as Map<String, dynamic>,
);
return DC.data(products);
} on ApiFailure catch (e, s) {
log('fetchProducts', name: _logName, error: e, stackTrace: s);
return DC.error(AnalyticFailure.serverError(e));
}
}
}
@@ -0,0 +1,57 @@
part of '../analytic_dtos.dart';
@freezed
class ProductAnalyticDto with _$ProductAnalyticDto {
const ProductAnalyticDto._();
const factory ProductAnalyticDto({
@JsonKey(name: "organization_id") String? organizationId,
@JsonKey(name: "outlet_id") String? outletId,
@JsonKey(name: "date_from") DateTime? dateFrom,
@JsonKey(name: "date_to") DateTime? dateTo,
@JsonKey(name: "data") List<ProductAnalyticItemDto>? data,
}) = _ProductAnalyticDto;
factory ProductAnalyticDto.fromJson(Map<String, dynamic> json) =>
_$ProductAnalyticDtoFromJson(json);
// Optional mapping ke domain entity
ProductAnalytic toDomain() => ProductAnalytic(
organizationId: organizationId ?? '',
outletId: outletId ?? '',
dateFrom: dateFrom ?? DateTime.now(),
dateTo: dateTo ?? DateTime.now(),
data: data?.map((e) => e.toDomain()).toList() ?? [],
);
}
@freezed
class ProductAnalyticItemDto with _$ProductAnalyticItemDto {
const ProductAnalyticItemDto._();
const factory ProductAnalyticItemDto({
@JsonKey(name: "product_id") String? productId,
@JsonKey(name: "product_name") String? productName,
@JsonKey(name: "category_id") String? categoryId,
@JsonKey(name: "category_name") String? categoryName,
@JsonKey(name: "quantity_sold") int? quantitySold,
@JsonKey(name: "revenue") int? revenue,
@JsonKey(name: "average_price") double? averagePrice,
@JsonKey(name: "order_count") int? orderCount,
}) = _ProductAnalyticItemDto;
factory ProductAnalyticItemDto.fromJson(Map<String, dynamic> json) =>
_$ProductAnalyticItemDtoFromJson(json);
// Optional mapping ke domain entity
ProductAnalyticItem toDomain() => ProductAnalyticItem(
productId: productId ?? '',
productName: productName ?? '',
categoryId: categoryId ?? '',
categoryName: categoryName ?? '',
quantitySold: quantitySold ?? 0,
revenue: revenue ?? 0,
averagePrice: averagePrice ?? 0.0,
orderCount: orderCount ?? 0,
);
}
@@ -61,4 +61,28 @@ class AnalyticRepository implements IAnalyticRepository {
return left(const AnalyticFailure.unexpectedError());
}
}
@override
Future<Either<AnalyticFailure, ProductAnalytic>> getProducts({
required DateTime dateFrom,
required DateTime dateTo,
}) async {
try {
final result = await _dataProvider.fetchProducts(
dateFrom: dateFrom,
dateTo: dateTo,
);
if (result.hasError) {
return left(result.error!);
}
final products = result.data!.toDomain();
return right(products);
} catch (e) {
log('getProductsError', name: _logName, error: e);
return left(const AnalyticFailure.unexpectedError());
}
}
}