feat: transaction report
This commit is contained in:
parent
1aa65d1732
commit
f07d07b3a8
@ -0,0 +1,91 @@
|
|||||||
|
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';
|
||||||
|
import '../../../domain/outlet/outlet.dart';
|
||||||
|
|
||||||
|
part 'transaction_report_event.dart';
|
||||||
|
part 'transaction_report_state.dart';
|
||||||
|
part 'transaction_report_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class TransactionReportBloc
|
||||||
|
extends Bloc<TransactionReportEvent, TransactionReportState> {
|
||||||
|
final IAnalyticRepository _analyticRepository;
|
||||||
|
final IOutletRepository _outletRepository;
|
||||||
|
|
||||||
|
TransactionReportBloc(this._analyticRepository, this._outletRepository)
|
||||||
|
: super(TransactionReportState.initial()) {
|
||||||
|
on<TransactionReportEvent>(_onTransactionReportEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onTransactionReportEvent(
|
||||||
|
TransactionReportEvent event,
|
||||||
|
Emitter<TransactionReportState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
fetchedOutlet: (e) async {
|
||||||
|
emit(
|
||||||
|
state.copyWith(isFetchingOutlet: true, failureOptionOutlet: none()),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _outletRepository.currentOutlet();
|
||||||
|
|
||||||
|
var data = result.fold(
|
||||||
|
(f) => state.copyWith(failureOptionOutlet: optionOf(f)),
|
||||||
|
(currentOutlet) => state.copyWith(outlet: currentOutlet),
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(data.copyWith(isFetchingOutlet: false));
|
||||||
|
},
|
||||||
|
fetchedTransaction: (e) async {
|
||||||
|
emit(state.copyWith(isFetching: true, failureOptionAnalytic: none()));
|
||||||
|
|
||||||
|
var newState = state;
|
||||||
|
|
||||||
|
final category = await _analyticRepository.getCategory(
|
||||||
|
dateFrom: e.dateFrom,
|
||||||
|
dateTo: e.dateTo,
|
||||||
|
);
|
||||||
|
final profitLoss = await _analyticRepository.getProfitLoss(
|
||||||
|
dateFrom: e.dateFrom,
|
||||||
|
dateTo: e.dateTo,
|
||||||
|
);
|
||||||
|
final paymentMethod = await _analyticRepository.getPaymentMethod(
|
||||||
|
dateFrom: e.dateFrom,
|
||||||
|
dateTo: e.dateTo,
|
||||||
|
);
|
||||||
|
final product = await _analyticRepository.getProduct(
|
||||||
|
dateFrom: e.dateFrom,
|
||||||
|
dateTo: e.dateTo,
|
||||||
|
);
|
||||||
|
|
||||||
|
newState = category.fold(
|
||||||
|
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
|
||||||
|
(categoryAnalytic) =>
|
||||||
|
newState.copyWith(categoryAnalytic: categoryAnalytic),
|
||||||
|
);
|
||||||
|
newState = profitLoss.fold(
|
||||||
|
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
|
||||||
|
(profitLossAnalytic) =>
|
||||||
|
newState.copyWith(profitLossAnalytic: profitLossAnalytic),
|
||||||
|
);
|
||||||
|
newState = paymentMethod.fold(
|
||||||
|
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
|
||||||
|
(paymentMethodAnalytic) =>
|
||||||
|
newState.copyWith(paymentMethodAnalytic: paymentMethodAnalytic),
|
||||||
|
);
|
||||||
|
newState = product.fold(
|
||||||
|
(f) => newState.copyWith(failureOptionAnalytic: optionOf(f)),
|
||||||
|
(productAnalytic) =>
|
||||||
|
newState.copyWith(productAnalytic: productAnalytic),
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(newState.copyWith(isFetching: false));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,752 @@
|
|||||||
|
// 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 'transaction_report_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 _$TransactionReportEvent {
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() fetchedOutlet,
|
||||||
|
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||||
|
fetchedTransaction,
|
||||||
|
}) => throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? fetchedOutlet,
|
||||||
|
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
|
||||||
|
}) => throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? fetchedOutlet,
|
||||||
|
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) => throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_FetchedOutlet value) fetchedOutlet,
|
||||||
|
required TResult Function(_FetchedTransaction value) fetchedTransaction,
|
||||||
|
}) => throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
|
||||||
|
TResult? Function(_FetchedTransaction value)? fetchedTransaction,
|
||||||
|
}) => throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_FetchedOutlet value)? fetchedOutlet,
|
||||||
|
TResult Function(_FetchedTransaction value)? fetchedTransaction,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $TransactionReportEventCopyWith<$Res> {
|
||||||
|
factory $TransactionReportEventCopyWith(
|
||||||
|
TransactionReportEvent value,
|
||||||
|
$Res Function(TransactionReportEvent) then,
|
||||||
|
) = _$TransactionReportEventCopyWithImpl<$Res, TransactionReportEvent>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$TransactionReportEventCopyWithImpl<
|
||||||
|
$Res,
|
||||||
|
$Val extends TransactionReportEvent
|
||||||
|
>
|
||||||
|
implements $TransactionReportEventCopyWith<$Res> {
|
||||||
|
_$TransactionReportEventCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$FetchedOutletImplCopyWith<$Res> {
|
||||||
|
factory _$$FetchedOutletImplCopyWith(
|
||||||
|
_$FetchedOutletImpl value,
|
||||||
|
$Res Function(_$FetchedOutletImpl) then,
|
||||||
|
) = __$$FetchedOutletImplCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$FetchedOutletImplCopyWithImpl<$Res>
|
||||||
|
extends _$TransactionReportEventCopyWithImpl<$Res, _$FetchedOutletImpl>
|
||||||
|
implements _$$FetchedOutletImplCopyWith<$Res> {
|
||||||
|
__$$FetchedOutletImplCopyWithImpl(
|
||||||
|
_$FetchedOutletImpl _value,
|
||||||
|
$Res Function(_$FetchedOutletImpl) _then,
|
||||||
|
) : super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$FetchedOutletImpl implements _FetchedOutlet {
|
||||||
|
const _$FetchedOutletImpl();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransactionReportEvent.fetchedOutlet()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$FetchedOutletImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() fetchedOutlet,
|
||||||
|
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||||
|
fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedOutlet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? fetchedOutlet,
|
||||||
|
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedOutlet?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? fetchedOutlet,
|
||||||
|
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fetchedOutlet != null) {
|
||||||
|
return fetchedOutlet();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_FetchedOutlet value) fetchedOutlet,
|
||||||
|
required TResult Function(_FetchedTransaction value) fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedOutlet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
|
||||||
|
TResult? Function(_FetchedTransaction value)? fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedOutlet?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_FetchedOutlet value)? fetchedOutlet,
|
||||||
|
TResult Function(_FetchedTransaction value)? fetchedTransaction,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fetchedOutlet != null) {
|
||||||
|
return fetchedOutlet(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _FetchedOutlet implements TransactionReportEvent {
|
||||||
|
const factory _FetchedOutlet() = _$FetchedOutletImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$FetchedTransactionImplCopyWith<$Res> {
|
||||||
|
factory _$$FetchedTransactionImplCopyWith(
|
||||||
|
_$FetchedTransactionImpl value,
|
||||||
|
$Res Function(_$FetchedTransactionImpl) then,
|
||||||
|
) = __$$FetchedTransactionImplCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({DateTime dateFrom, DateTime dateTo});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$FetchedTransactionImplCopyWithImpl<$Res>
|
||||||
|
extends _$TransactionReportEventCopyWithImpl<$Res, _$FetchedTransactionImpl>
|
||||||
|
implements _$$FetchedTransactionImplCopyWith<$Res> {
|
||||||
|
__$$FetchedTransactionImplCopyWithImpl(
|
||||||
|
_$FetchedTransactionImpl _value,
|
||||||
|
$Res Function(_$FetchedTransactionImpl) _then,
|
||||||
|
) : super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({Object? dateFrom = null, Object? dateTo = null}) {
|
||||||
|
return _then(
|
||||||
|
_$FetchedTransactionImpl(
|
||||||
|
null == dateFrom
|
||||||
|
? _value.dateFrom
|
||||||
|
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
null == dateTo
|
||||||
|
? _value.dateTo
|
||||||
|
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$FetchedTransactionImpl implements _FetchedTransaction {
|
||||||
|
const _$FetchedTransactionImpl(this.dateFrom, this.dateTo);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final DateTime dateFrom;
|
||||||
|
@override
|
||||||
|
final DateTime dateTo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransactionReportEvent.fetchedTransaction(dateFrom: $dateFrom, dateTo: $dateTo)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$FetchedTransactionImpl &&
|
||||||
|
(identical(other.dateFrom, dateFrom) ||
|
||||||
|
other.dateFrom == dateFrom) &&
|
||||||
|
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, dateFrom, dateTo);
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$FetchedTransactionImplCopyWith<_$FetchedTransactionImpl> get copyWith =>
|
||||||
|
__$$FetchedTransactionImplCopyWithImpl<_$FetchedTransactionImpl>(
|
||||||
|
this,
|
||||||
|
_$identity,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() fetchedOutlet,
|
||||||
|
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||||
|
fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedTransaction(dateFrom, dateTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? fetchedOutlet,
|
||||||
|
TResult? Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedTransaction?.call(dateFrom, dateTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? fetchedOutlet,
|
||||||
|
TResult Function(DateTime dateFrom, DateTime dateTo)? fetchedTransaction,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fetchedTransaction != null) {
|
||||||
|
return fetchedTransaction(dateFrom, dateTo);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_FetchedOutlet value) fetchedOutlet,
|
||||||
|
required TResult Function(_FetchedTransaction value) fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedTransaction(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(_FetchedOutlet value)? fetchedOutlet,
|
||||||
|
TResult? Function(_FetchedTransaction value)? fetchedTransaction,
|
||||||
|
}) {
|
||||||
|
return fetchedTransaction?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_FetchedOutlet value)? fetchedOutlet,
|
||||||
|
TResult Function(_FetchedTransaction value)? fetchedTransaction,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fetchedTransaction != null) {
|
||||||
|
return fetchedTransaction(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _FetchedTransaction implements TransactionReportEvent {
|
||||||
|
const factory _FetchedTransaction(
|
||||||
|
final DateTime dateFrom,
|
||||||
|
final DateTime dateTo,
|
||||||
|
) = _$FetchedTransactionImpl;
|
||||||
|
|
||||||
|
DateTime get dateFrom;
|
||||||
|
DateTime get dateTo;
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$FetchedTransactionImplCopyWith<_$FetchedTransactionImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TransactionReportState {
|
||||||
|
CategoryAnalytic get categoryAnalytic => throw _privateConstructorUsedError;
|
||||||
|
ProfitLossAnalytic get profitLossAnalytic =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
PaymentMethodAnalytic get paymentMethodAnalytic =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
ProductAnalytic get productAnalytic => throw _privateConstructorUsedError;
|
||||||
|
Option<AnalyticFailure> get failureOptionAnalytic =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
Outlet get outlet => throw _privateConstructorUsedError;
|
||||||
|
Option<OutletFailure> get failureOptionOutlet =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
bool get isFetching => throw _privateConstructorUsedError;
|
||||||
|
bool get isFetchingOutlet => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$TransactionReportStateCopyWith<TransactionReportState> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $TransactionReportStateCopyWith<$Res> {
|
||||||
|
factory $TransactionReportStateCopyWith(
|
||||||
|
TransactionReportState value,
|
||||||
|
$Res Function(TransactionReportState) then,
|
||||||
|
) = _$TransactionReportStateCopyWithImpl<$Res, TransactionReportState>;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
CategoryAnalytic categoryAnalytic,
|
||||||
|
ProfitLossAnalytic profitLossAnalytic,
|
||||||
|
PaymentMethodAnalytic paymentMethodAnalytic,
|
||||||
|
ProductAnalytic productAnalytic,
|
||||||
|
Option<AnalyticFailure> failureOptionAnalytic,
|
||||||
|
Outlet outlet,
|
||||||
|
Option<OutletFailure> failureOptionOutlet,
|
||||||
|
bool isFetching,
|
||||||
|
bool isFetchingOutlet,
|
||||||
|
});
|
||||||
|
|
||||||
|
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic;
|
||||||
|
$ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic;
|
||||||
|
$PaymentMethodAnalyticCopyWith<$Res> get paymentMethodAnalytic;
|
||||||
|
$ProductAnalyticCopyWith<$Res> get productAnalytic;
|
||||||
|
$OutletCopyWith<$Res> get outlet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$TransactionReportStateCopyWithImpl<
|
||||||
|
$Res,
|
||||||
|
$Val extends TransactionReportState
|
||||||
|
>
|
||||||
|
implements $TransactionReportStateCopyWith<$Res> {
|
||||||
|
_$TransactionReportStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? categoryAnalytic = null,
|
||||||
|
Object? profitLossAnalytic = null,
|
||||||
|
Object? paymentMethodAnalytic = null,
|
||||||
|
Object? productAnalytic = null,
|
||||||
|
Object? failureOptionAnalytic = null,
|
||||||
|
Object? outlet = null,
|
||||||
|
Object? failureOptionOutlet = null,
|
||||||
|
Object? isFetching = null,
|
||||||
|
Object? isFetchingOutlet = null,
|
||||||
|
}) {
|
||||||
|
return _then(
|
||||||
|
_value.copyWith(
|
||||||
|
categoryAnalytic: null == categoryAnalytic
|
||||||
|
? _value.categoryAnalytic
|
||||||
|
: categoryAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as CategoryAnalytic,
|
||||||
|
profitLossAnalytic: null == profitLossAnalytic
|
||||||
|
? _value.profitLossAnalytic
|
||||||
|
: profitLossAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ProfitLossAnalytic,
|
||||||
|
paymentMethodAnalytic: null == paymentMethodAnalytic
|
||||||
|
? _value.paymentMethodAnalytic
|
||||||
|
: paymentMethodAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PaymentMethodAnalytic,
|
||||||
|
productAnalytic: null == productAnalytic
|
||||||
|
? _value.productAnalytic
|
||||||
|
: productAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ProductAnalytic,
|
||||||
|
failureOptionAnalytic: null == failureOptionAnalytic
|
||||||
|
? _value.failureOptionAnalytic
|
||||||
|
: failureOptionAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<AnalyticFailure>,
|
||||||
|
outlet: null == outlet
|
||||||
|
? _value.outlet
|
||||||
|
: outlet // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Outlet,
|
||||||
|
failureOptionOutlet: null == failureOptionOutlet
|
||||||
|
? _value.failureOptionOutlet
|
||||||
|
: failureOptionOutlet // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<OutletFailure>,
|
||||||
|
isFetching: null == isFetching
|
||||||
|
? _value.isFetching
|
||||||
|
: isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
isFetchingOutlet: null == isFetchingOutlet
|
||||||
|
? _value.isFetchingOutlet
|
||||||
|
: isFetchingOutlet // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
)
|
||||||
|
as $Val,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic {
|
||||||
|
return $CategoryAnalyticCopyWith<$Res>(_value.categoryAnalytic, (value) {
|
||||||
|
return _then(_value.copyWith(categoryAnalytic: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic {
|
||||||
|
return $ProfitLossAnalyticCopyWith<$Res>(_value.profitLossAnalytic, (
|
||||||
|
value,
|
||||||
|
) {
|
||||||
|
return _then(_value.copyWith(profitLossAnalytic: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$PaymentMethodAnalyticCopyWith<$Res> get paymentMethodAnalytic {
|
||||||
|
return $PaymentMethodAnalyticCopyWith<$Res>(_value.paymentMethodAnalytic, (
|
||||||
|
value,
|
||||||
|
) {
|
||||||
|
return _then(_value.copyWith(paymentMethodAnalytic: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ProductAnalyticCopyWith<$Res> get productAnalytic {
|
||||||
|
return $ProductAnalyticCopyWith<$Res>(_value.productAnalytic, (value) {
|
||||||
|
return _then(_value.copyWith(productAnalytic: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$OutletCopyWith<$Res> get outlet {
|
||||||
|
return $OutletCopyWith<$Res>(_value.outlet, (value) {
|
||||||
|
return _then(_value.copyWith(outlet: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$TransactionReportStateImplCopyWith<$Res>
|
||||||
|
implements $TransactionReportStateCopyWith<$Res> {
|
||||||
|
factory _$$TransactionReportStateImplCopyWith(
|
||||||
|
_$TransactionReportStateImpl value,
|
||||||
|
$Res Function(_$TransactionReportStateImpl) then,
|
||||||
|
) = __$$TransactionReportStateImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
CategoryAnalytic categoryAnalytic,
|
||||||
|
ProfitLossAnalytic profitLossAnalytic,
|
||||||
|
PaymentMethodAnalytic paymentMethodAnalytic,
|
||||||
|
ProductAnalytic productAnalytic,
|
||||||
|
Option<AnalyticFailure> failureOptionAnalytic,
|
||||||
|
Outlet outlet,
|
||||||
|
Option<OutletFailure> failureOptionOutlet,
|
||||||
|
bool isFetching,
|
||||||
|
bool isFetchingOutlet,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
$CategoryAnalyticCopyWith<$Res> get categoryAnalytic;
|
||||||
|
@override
|
||||||
|
$ProfitLossAnalyticCopyWith<$Res> get profitLossAnalytic;
|
||||||
|
@override
|
||||||
|
$PaymentMethodAnalyticCopyWith<$Res> get paymentMethodAnalytic;
|
||||||
|
@override
|
||||||
|
$ProductAnalyticCopyWith<$Res> get productAnalytic;
|
||||||
|
@override
|
||||||
|
$OutletCopyWith<$Res> get outlet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$TransactionReportStateImplCopyWithImpl<$Res>
|
||||||
|
extends
|
||||||
|
_$TransactionReportStateCopyWithImpl<$Res, _$TransactionReportStateImpl>
|
||||||
|
implements _$$TransactionReportStateImplCopyWith<$Res> {
|
||||||
|
__$$TransactionReportStateImplCopyWithImpl(
|
||||||
|
_$TransactionReportStateImpl _value,
|
||||||
|
$Res Function(_$TransactionReportStateImpl) _then,
|
||||||
|
) : super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? categoryAnalytic = null,
|
||||||
|
Object? profitLossAnalytic = null,
|
||||||
|
Object? paymentMethodAnalytic = null,
|
||||||
|
Object? productAnalytic = null,
|
||||||
|
Object? failureOptionAnalytic = null,
|
||||||
|
Object? outlet = null,
|
||||||
|
Object? failureOptionOutlet = null,
|
||||||
|
Object? isFetching = null,
|
||||||
|
Object? isFetchingOutlet = null,
|
||||||
|
}) {
|
||||||
|
return _then(
|
||||||
|
_$TransactionReportStateImpl(
|
||||||
|
categoryAnalytic: null == categoryAnalytic
|
||||||
|
? _value.categoryAnalytic
|
||||||
|
: categoryAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as CategoryAnalytic,
|
||||||
|
profitLossAnalytic: null == profitLossAnalytic
|
||||||
|
? _value.profitLossAnalytic
|
||||||
|
: profitLossAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ProfitLossAnalytic,
|
||||||
|
paymentMethodAnalytic: null == paymentMethodAnalytic
|
||||||
|
? _value.paymentMethodAnalytic
|
||||||
|
: paymentMethodAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PaymentMethodAnalytic,
|
||||||
|
productAnalytic: null == productAnalytic
|
||||||
|
? _value.productAnalytic
|
||||||
|
: productAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ProductAnalytic,
|
||||||
|
failureOptionAnalytic: null == failureOptionAnalytic
|
||||||
|
? _value.failureOptionAnalytic
|
||||||
|
: failureOptionAnalytic // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<AnalyticFailure>,
|
||||||
|
outlet: null == outlet
|
||||||
|
? _value.outlet
|
||||||
|
: outlet // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Outlet,
|
||||||
|
failureOptionOutlet: null == failureOptionOutlet
|
||||||
|
? _value.failureOptionOutlet
|
||||||
|
: failureOptionOutlet // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<OutletFailure>,
|
||||||
|
isFetching: null == isFetching
|
||||||
|
? _value.isFetching
|
||||||
|
: isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
isFetchingOutlet: null == isFetchingOutlet
|
||||||
|
? _value.isFetchingOutlet
|
||||||
|
: isFetchingOutlet // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$TransactionReportStateImpl implements _TransactionReportState {
|
||||||
|
const _$TransactionReportStateImpl({
|
||||||
|
required this.categoryAnalytic,
|
||||||
|
required this.profitLossAnalytic,
|
||||||
|
required this.paymentMethodAnalytic,
|
||||||
|
required this.productAnalytic,
|
||||||
|
required this.failureOptionAnalytic,
|
||||||
|
required this.outlet,
|
||||||
|
required this.failureOptionOutlet,
|
||||||
|
this.isFetching = false,
|
||||||
|
this.isFetchingOutlet = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
final CategoryAnalytic categoryAnalytic;
|
||||||
|
@override
|
||||||
|
final ProfitLossAnalytic profitLossAnalytic;
|
||||||
|
@override
|
||||||
|
final PaymentMethodAnalytic paymentMethodAnalytic;
|
||||||
|
@override
|
||||||
|
final ProductAnalytic productAnalytic;
|
||||||
|
@override
|
||||||
|
final Option<AnalyticFailure> failureOptionAnalytic;
|
||||||
|
@override
|
||||||
|
final Outlet outlet;
|
||||||
|
@override
|
||||||
|
final Option<OutletFailure> failureOptionOutlet;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool isFetching;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool isFetchingOutlet;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransactionReportState(categoryAnalytic: $categoryAnalytic, profitLossAnalytic: $profitLossAnalytic, paymentMethodAnalytic: $paymentMethodAnalytic, productAnalytic: $productAnalytic, failureOptionAnalytic: $failureOptionAnalytic, outlet: $outlet, failureOptionOutlet: $failureOptionOutlet, isFetching: $isFetching, isFetchingOutlet: $isFetchingOutlet)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$TransactionReportStateImpl &&
|
||||||
|
(identical(other.categoryAnalytic, categoryAnalytic) ||
|
||||||
|
other.categoryAnalytic == categoryAnalytic) &&
|
||||||
|
(identical(other.profitLossAnalytic, profitLossAnalytic) ||
|
||||||
|
other.profitLossAnalytic == profitLossAnalytic) &&
|
||||||
|
(identical(other.paymentMethodAnalytic, paymentMethodAnalytic) ||
|
||||||
|
other.paymentMethodAnalytic == paymentMethodAnalytic) &&
|
||||||
|
(identical(other.productAnalytic, productAnalytic) ||
|
||||||
|
other.productAnalytic == productAnalytic) &&
|
||||||
|
(identical(other.failureOptionAnalytic, failureOptionAnalytic) ||
|
||||||
|
other.failureOptionAnalytic == failureOptionAnalytic) &&
|
||||||
|
(identical(other.outlet, outlet) || other.outlet == outlet) &&
|
||||||
|
(identical(other.failureOptionOutlet, failureOptionOutlet) ||
|
||||||
|
other.failureOptionOutlet == failureOptionOutlet) &&
|
||||||
|
(identical(other.isFetching, isFetching) ||
|
||||||
|
other.isFetching == isFetching) &&
|
||||||
|
(identical(other.isFetchingOutlet, isFetchingOutlet) ||
|
||||||
|
other.isFetchingOutlet == isFetchingOutlet));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
categoryAnalytic,
|
||||||
|
profitLossAnalytic,
|
||||||
|
paymentMethodAnalytic,
|
||||||
|
productAnalytic,
|
||||||
|
failureOptionAnalytic,
|
||||||
|
outlet,
|
||||||
|
failureOptionOutlet,
|
||||||
|
isFetching,
|
||||||
|
isFetchingOutlet,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$TransactionReportStateImplCopyWith<_$TransactionReportStateImpl>
|
||||||
|
get copyWith =>
|
||||||
|
__$$TransactionReportStateImplCopyWithImpl<_$TransactionReportStateImpl>(
|
||||||
|
this,
|
||||||
|
_$identity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _TransactionReportState implements TransactionReportState {
|
||||||
|
const factory _TransactionReportState({
|
||||||
|
required final CategoryAnalytic categoryAnalytic,
|
||||||
|
required final ProfitLossAnalytic profitLossAnalytic,
|
||||||
|
required final PaymentMethodAnalytic paymentMethodAnalytic,
|
||||||
|
required final ProductAnalytic productAnalytic,
|
||||||
|
required final Option<AnalyticFailure> failureOptionAnalytic,
|
||||||
|
required final Outlet outlet,
|
||||||
|
required final Option<OutletFailure> failureOptionOutlet,
|
||||||
|
final bool isFetching,
|
||||||
|
final bool isFetchingOutlet,
|
||||||
|
}) = _$TransactionReportStateImpl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
CategoryAnalytic get categoryAnalytic;
|
||||||
|
@override
|
||||||
|
ProfitLossAnalytic get profitLossAnalytic;
|
||||||
|
@override
|
||||||
|
PaymentMethodAnalytic get paymentMethodAnalytic;
|
||||||
|
@override
|
||||||
|
ProductAnalytic get productAnalytic;
|
||||||
|
@override
|
||||||
|
Option<AnalyticFailure> get failureOptionAnalytic;
|
||||||
|
@override
|
||||||
|
Outlet get outlet;
|
||||||
|
@override
|
||||||
|
Option<OutletFailure> get failureOptionOutlet;
|
||||||
|
@override
|
||||||
|
bool get isFetching;
|
||||||
|
@override
|
||||||
|
bool get isFetchingOutlet;
|
||||||
|
|
||||||
|
/// Create a copy of TransactionReportState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$TransactionReportStateImplCopyWith<_$TransactionReportStateImpl>
|
||||||
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
part of 'transaction_report_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class TransactionReportEvent with _$TransactionReportEvent {
|
||||||
|
const factory TransactionReportEvent.fetchedOutlet() = _FetchedOutlet;
|
||||||
|
const factory TransactionReportEvent.fetchedTransaction(
|
||||||
|
DateTime dateFrom,
|
||||||
|
DateTime dateTo,
|
||||||
|
) = _FetchedTransaction;
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
part of 'transaction_report_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class TransactionReportState with _$TransactionReportState {
|
||||||
|
const factory TransactionReportState({
|
||||||
|
required CategoryAnalytic categoryAnalytic,
|
||||||
|
required ProfitLossAnalytic profitLossAnalytic,
|
||||||
|
required PaymentMethodAnalytic paymentMethodAnalytic,
|
||||||
|
required ProductAnalytic productAnalytic,
|
||||||
|
required Option<AnalyticFailure> failureOptionAnalytic,
|
||||||
|
required Outlet outlet,
|
||||||
|
required Option<OutletFailure> failureOptionOutlet,
|
||||||
|
@Default(false) bool isFetching,
|
||||||
|
@Default(false) bool isFetchingOutlet,
|
||||||
|
}) = _TransactionReportState;
|
||||||
|
|
||||||
|
factory TransactionReportState.initial() => TransactionReportState(
|
||||||
|
failureOptionAnalytic: none(),
|
||||||
|
outlet: Outlet.empty(),
|
||||||
|
failureOptionOutlet: none(),
|
||||||
|
categoryAnalytic: CategoryAnalytic.empty(),
|
||||||
|
profitLossAnalytic: ProfitLossAnalytic.empty(),
|
||||||
|
paymentMethodAnalytic: PaymentMethodAnalytic.empty(),
|
||||||
|
productAnalytic: ProductAnalytic.empty(),
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -43,6 +43,8 @@ import 'package:apskel_owner_flutter/application/product/product_loader/product_
|
|||||||
as _i458;
|
as _i458;
|
||||||
import 'package:apskel_owner_flutter/application/report/inventory_report/inventory_report_bloc.dart'
|
import 'package:apskel_owner_flutter/application/report/inventory_report/inventory_report_bloc.dart'
|
||||||
as _i346;
|
as _i346;
|
||||||
|
import 'package:apskel_owner_flutter/application/report/transaction_report/transaction_report_bloc.dart'
|
||||||
|
as _i605;
|
||||||
import 'package:apskel_owner_flutter/application/user/change_password_form/change_password_form_bloc.dart'
|
import 'package:apskel_owner_flutter/application/user/change_password_form/change_password_form_bloc.dart'
|
||||||
as _i1030;
|
as _i1030;
|
||||||
import 'package:apskel_owner_flutter/application/user/user_edit_form/user_edit_form_bloc.dart'
|
import 'package:apskel_owner_flutter/application/user/user_edit_form/user_edit_form_bloc.dart'
|
||||||
@ -265,6 +267,12 @@ extension GetItInjectableX on _i174.GetIt {
|
|||||||
gh.factory<_i1030.ChangePasswordFormBloc>(
|
gh.factory<_i1030.ChangePasswordFormBloc>(
|
||||||
() => _i1030.ChangePasswordFormBloc(gh<_i635.IUserRepository>()),
|
() => _i1030.ChangePasswordFormBloc(gh<_i635.IUserRepository>()),
|
||||||
);
|
);
|
||||||
|
gh.factory<_i605.TransactionReportBloc>(
|
||||||
|
() => _i605.TransactionReportBloc(
|
||||||
|
gh<_i477.IAnalyticRepository>(),
|
||||||
|
gh<_i197.IOutletRepository>(),
|
||||||
|
),
|
||||||
|
);
|
||||||
gh.factory<_i346.InventoryReportBloc>(
|
gh.factory<_i346.InventoryReportBloc>(
|
||||||
() => _i346.InventoryReportBloc(
|
() => _i346.InventoryReportBloc(
|
||||||
gh<_i477.IAnalyticRepository>(),
|
gh<_i477.IAnalyticRepository>(),
|
||||||
|
|||||||
956
lib/presentation/components/report/transaction_report.dart
Normal file
956
lib/presentation/components/report/transaction_report.dart
Normal file
@ -0,0 +1,956 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:pdf/pdf.dart';
|
||||||
|
import 'package:pdf/widgets.dart' as pw;
|
||||||
|
|
||||||
|
import '../../../common/extension/extension.dart';
|
||||||
|
import '../../../common/utils/pdf_service.dart';
|
||||||
|
import '../../../domain/analytic/analytic.dart';
|
||||||
|
import '../../../domain/outlet/outlet.dart';
|
||||||
|
|
||||||
|
class TransactionReport {
|
||||||
|
static final primaryColor = PdfColor.fromHex("36175e");
|
||||||
|
|
||||||
|
static Future<File> previewPdf({
|
||||||
|
required Outlet outlet,
|
||||||
|
required String searchDateFormatted,
|
||||||
|
required CategoryAnalytic categoryAnalyticData,
|
||||||
|
required ProfitLossAnalytic profitLossData,
|
||||||
|
required PaymentMethodAnalytic paymentMethodAnalyticData,
|
||||||
|
required ProductAnalytic productAnalyticData,
|
||||||
|
}) async {
|
||||||
|
final pdf = pw.Document();
|
||||||
|
final ByteData dataImage = await rootBundle.load('assets/images/logo.png');
|
||||||
|
final Uint8List bytes = dataImage.buffer.asUint8List();
|
||||||
|
|
||||||
|
final profitLossProductSummary = {
|
||||||
|
'totalRevenue': profitLossData.productData.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.revenue),
|
||||||
|
),
|
||||||
|
'totalCost': profitLossData.productData.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.cost),
|
||||||
|
),
|
||||||
|
'totalGrossProfit': profitLossData.productData.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.grossProfit),
|
||||||
|
),
|
||||||
|
'totalQuantity': profitLossData.productData.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.quantitySold),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
final categorySummary = {
|
||||||
|
'totalRevenue': categoryAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.totalRevenue),
|
||||||
|
),
|
||||||
|
'orderCount': categoryAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.orderCount),
|
||||||
|
),
|
||||||
|
'productCount': categoryAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.productCount),
|
||||||
|
),
|
||||||
|
'totalQuantity': categoryAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.totalQuantity),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
final productItemSummary = {
|
||||||
|
'totalRevenue': productAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.revenue),
|
||||||
|
),
|
||||||
|
'orderCount': productAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.orderCount),
|
||||||
|
),
|
||||||
|
'totalQuantitySold': productAnalyticData.data.fold<num>(
|
||||||
|
0,
|
||||||
|
(sum, item) => sum + (item.quantitySold),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Membuat objek Image dari gambar
|
||||||
|
final image = pw.MemoryImage(bytes);
|
||||||
|
pdf.addPage(
|
||||||
|
pw.MultiPage(
|
||||||
|
pageFormat: PdfPageFormat.a4,
|
||||||
|
margin: pw.EdgeInsets.zero,
|
||||||
|
build: (pw.Context context) {
|
||||||
|
return [
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(20),
|
||||||
|
child: pw.Row(
|
||||||
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Bagian kiri - Logo dan Info Perusahaan
|
||||||
|
pw.Row(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
// Icon/Logo placeholder (bisa diganti dengan gambar logo)
|
||||||
|
pw.Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
child: pw.Image(image),
|
||||||
|
),
|
||||||
|
pw.SizedBox(width: 15),
|
||||||
|
pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
pw.Text(
|
||||||
|
'Apskel',
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 4),
|
||||||
|
pw.Text(
|
||||||
|
outlet.name,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: PdfColors.grey700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 2),
|
||||||
|
pw.Text(
|
||||||
|
outlet.address,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: PdfColors.grey600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// Bagian kanan - Info Laporan
|
||||||
|
pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
pw.Text(
|
||||||
|
'Laporan Transaksi',
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
color: PdfColors.grey800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 8),
|
||||||
|
pw.Text(
|
||||||
|
searchDateFormatted,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: PdfColors.grey600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 4),
|
||||||
|
pw.Text(
|
||||||
|
'Laporan',
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: PdfColors.grey500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 3,
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Summary
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(20),
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSectionWidget('1. Ringkasan'),
|
||||||
|
pw.SizedBox(height: 30),
|
||||||
|
pw.Row(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
pw.Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSummaryItem(
|
||||||
|
'Total Penjualan (termasuk rasik)',
|
||||||
|
(profitLossData.summary.totalRevenue)
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
_buildSummaryItem(
|
||||||
|
'Total Terjual',
|
||||||
|
(profitLossData.summary.totalOrders).toString(),
|
||||||
|
),
|
||||||
|
_buildSummaryItem(
|
||||||
|
'HPP',
|
||||||
|
'${safeCurrency(profitLossData.summary.totalCost)} | ${safePercentage(profitLossData.summary.totalCost, profitLossData.summary.totalRevenue)}',
|
||||||
|
),
|
||||||
|
_buildSummaryItem(
|
||||||
|
'Laba Kotor',
|
||||||
|
'${safeCurrency(profitLossData.summary.grossProfit)} | ${safeRound(profitLossData.summary.grossProfitMargin)}%',
|
||||||
|
valueStyle: pw.TextStyle(
|
||||||
|
color: PdfColors.green800,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
labelStyle: pw.TextStyle(
|
||||||
|
color: PdfColors.green800,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(width: 20),
|
||||||
|
pw.Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSummaryItem(
|
||||||
|
'Biaya Lain lain',
|
||||||
|
'${safeCurrency(profitLossData.summary.totalTax)} | ${safePercentage(profitLossData.summary.totalTax, profitLossData.summary.totalRevenue)}',
|
||||||
|
),
|
||||||
|
_buildSummaryItem(
|
||||||
|
'Laba/Rugi',
|
||||||
|
'${safeCurrency(profitLossData.summary.netProfit)} | ${safeRound(profitLossData.summary.netProfitMargin)}%',
|
||||||
|
valueStyle: pw.TextStyle(
|
||||||
|
color: PdfColors.blue800,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
labelStyle: pw.TextStyle(
|
||||||
|
color: PdfColors.blue800,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 16),
|
||||||
|
pw.Text(
|
||||||
|
"Laba Rugi Perproduk",
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 20),
|
||||||
|
pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
topLeft: pw.Radius.circular(8),
|
||||||
|
topRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(1), // Qty
|
||||||
|
2: pw.FlexColumnWidth(2.5), // Pendapatan
|
||||||
|
3: pw.FlexColumnWidth(2), // HPP
|
||||||
|
4: pw.FlexColumnWidth(2), // Laba Kotor
|
||||||
|
5: pw.FlexColumnWidth(2), // Margin (%)
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildHeaderCell('Produk'),
|
||||||
|
_buildHeaderCell('Qty'),
|
||||||
|
_buildHeaderCell('Pendapatan'),
|
||||||
|
_buildHeaderCell('HPP'),
|
||||||
|
_buildHeaderCell('Laba Kotor'),
|
||||||
|
_buildHeaderCell('Margin (%)'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(color: PdfColors.white),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(1), // Qty
|
||||||
|
2: pw.FlexColumnWidth(2.5), // Pendapatan
|
||||||
|
3: pw.FlexColumnWidth(2), // HPP
|
||||||
|
4: pw.FlexColumnWidth(2), // Laba Kotor
|
||||||
|
5: pw.FlexColumnWidth(2), // Margin (%)
|
||||||
|
},
|
||||||
|
children: profitLossData.productData
|
||||||
|
.map(
|
||||||
|
(profitLoss) => _buildPerProductDataRow(
|
||||||
|
product: profitLoss.productName,
|
||||||
|
qty: profitLoss.quantitySold.toString(),
|
||||||
|
pendapatan: profitLoss.revenue
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
hpp: profitLoss.cost
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
labaKotor: profitLoss.grossProfit
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
margin:
|
||||||
|
'${safeRound(profitLoss.grossProfitMargin)}%',
|
||||||
|
isEven:
|
||||||
|
profitLossData.productData.indexOf(
|
||||||
|
profitLoss,
|
||||||
|
) %
|
||||||
|
2 ==
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
bottomLeft: pw.Radius.circular(8),
|
||||||
|
bottomRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(1), // Qty
|
||||||
|
2: pw.FlexColumnWidth(2.5), // Pendapatan
|
||||||
|
3: pw.FlexColumnWidth(2), // HPP
|
||||||
|
4: pw.FlexColumnWidth(2), // Laba Kotor
|
||||||
|
5: pw.FlexColumnWidth(2), // Margin (%)
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildTotalCell('TOTAL'),
|
||||||
|
_buildTotalCell(
|
||||||
|
profitLossProductSummary['totalQuantity']
|
||||||
|
.toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
profitLossProductSummary['totalRevenue']
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
profitLossProductSummary['totalCost']
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
profitLossProductSummary['totalGrossProfit']
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
_buildTotalCell(''),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Summary Payment Method
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(20),
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSectionWidget('2. Ringkasan Metode Pembayaran'),
|
||||||
|
pw.SizedBox(height: 30),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
topLeft: pw.Radius.circular(8),
|
||||||
|
topRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Nama
|
||||||
|
1: pw.FlexColumnWidth(1), // Tipe
|
||||||
|
2: pw.FlexColumnWidth(2.5), // Jumlah Order
|
||||||
|
3: pw.FlexColumnWidth(2), // Total Amount
|
||||||
|
4: pw.FlexColumnWidth(2), // Presentase
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildHeaderCell('Nama'),
|
||||||
|
_buildHeaderCell('Tipe'),
|
||||||
|
_buildHeaderCell('Jumlah Order'),
|
||||||
|
_buildHeaderCell('Total Amount'),
|
||||||
|
_buildHeaderCell('Presentase'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(color: PdfColors.white),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Nama
|
||||||
|
1: pw.FlexColumnWidth(1), // Tipe
|
||||||
|
2: pw.FlexColumnWidth(2.5), // Jumlah Order
|
||||||
|
3: pw.FlexColumnWidth(2), // Total Amount
|
||||||
|
4: pw.FlexColumnWidth(2), // Presentase
|
||||||
|
},
|
||||||
|
children: paymentMethodAnalyticData.data
|
||||||
|
.map(
|
||||||
|
(payment) => _buildPaymentMethodDataRow(
|
||||||
|
name: payment.paymentMethodName,
|
||||||
|
tipe: payment.paymentMethodType.toTitleCase,
|
||||||
|
jumlahOrder: payment.orderCount.toString(),
|
||||||
|
totalAmount: payment.totalAmount
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
presentase:
|
||||||
|
'${safeRound(payment.percentage)}%',
|
||||||
|
isEven:
|
||||||
|
paymentMethodAnalyticData.data.indexOf(
|
||||||
|
payment,
|
||||||
|
) %
|
||||||
|
2 ==
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
bottomLeft: pw.Radius.circular(8),
|
||||||
|
bottomRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(1), // Qty
|
||||||
|
2: pw.FlexColumnWidth(2.5), // Pendapatan
|
||||||
|
3: pw.FlexColumnWidth(2), // HPP
|
||||||
|
4: pw.FlexColumnWidth(2), // Laba Kotor
|
||||||
|
5: pw.FlexColumnWidth(2), // Margin (%)
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildTotalCell('TOTAL'),
|
||||||
|
_buildTotalCell(''),
|
||||||
|
_buildTotalCell(
|
||||||
|
(paymentMethodAnalyticData
|
||||||
|
.summary
|
||||||
|
.totalOrders)
|
||||||
|
.toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
(paymentMethodAnalyticData
|
||||||
|
.summary
|
||||||
|
.totalAmount)
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
_buildTotalCell(''),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Summary Category
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(20),
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSectionWidget('3. Ringkasan Kategori'),
|
||||||
|
pw.SizedBox(height: 30),
|
||||||
|
pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
topLeft: pw.Radius.circular(8),
|
||||||
|
topRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Nama
|
||||||
|
1: pw.FlexColumnWidth(2), // Total Product
|
||||||
|
2: pw.FlexColumnWidth(1), // qty
|
||||||
|
3: pw.FlexColumnWidth(2), // Jumlah Order
|
||||||
|
4: pw.FlexColumnWidth(2.5), // Presentase
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildHeaderCell('Nama'),
|
||||||
|
_buildHeaderCell('Total Produk'),
|
||||||
|
_buildHeaderCell('Qty'),
|
||||||
|
_buildHeaderCell('Jumlah Order'),
|
||||||
|
_buildHeaderCell('Pendapatan'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(color: PdfColors.white),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Nama
|
||||||
|
1: pw.FlexColumnWidth(2), // Total Product
|
||||||
|
2: pw.FlexColumnWidth(1), // qty
|
||||||
|
3: pw.FlexColumnWidth(2), // Jumlah Order
|
||||||
|
4: pw.FlexColumnWidth(2.5), // Presentase
|
||||||
|
},
|
||||||
|
children: categoryAnalyticData.data
|
||||||
|
.map(
|
||||||
|
(category) => _buildCategoryDataRow(
|
||||||
|
name: category.categoryName,
|
||||||
|
totalProduct: category.productCount
|
||||||
|
.toString(),
|
||||||
|
qty: category.totalQuantity.toString(),
|
||||||
|
jumlahOrder: category.orderCount.toString(),
|
||||||
|
pendapatan: category.totalRevenue
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
isEven:
|
||||||
|
categoryAnalyticData.data.indexOf(
|
||||||
|
category,
|
||||||
|
) %
|
||||||
|
2 ==
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
bottomLeft: pw.Radius.circular(8),
|
||||||
|
bottomRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Nama
|
||||||
|
1: pw.FlexColumnWidth(2), // Total Product
|
||||||
|
2: pw.FlexColumnWidth(1), // qty
|
||||||
|
3: pw.FlexColumnWidth(2), // Jumlah Order
|
||||||
|
4: pw.FlexColumnWidth(2.5), // Presentase
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildTotalCell('TOTAL'),
|
||||||
|
_buildTotalCell(
|
||||||
|
categorySummary['productCount'].toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
categorySummary['totalQuantity'].toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
categorySummary['orderCount'].toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
categorySummary['totalRevenue']
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Summary Item
|
||||||
|
pw.Container(
|
||||||
|
padding: pw.EdgeInsets.all(20),
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSectionWidget('4. Ringkasan Item'),
|
||||||
|
pw.SizedBox(height: 30),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
topLeft: pw.Radius.circular(8),
|
||||||
|
topRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(2), // Kategori
|
||||||
|
2: pw.FlexColumnWidth(1), // qty
|
||||||
|
3: pw.FlexColumnWidth(2), // Order
|
||||||
|
4: pw.FlexColumnWidth(2), // Pendapatan
|
||||||
|
5: pw.FlexColumnWidth(2), // Average
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildHeaderCell('Produk'),
|
||||||
|
_buildHeaderCell('Kategori'),
|
||||||
|
_buildHeaderCell('Qty'),
|
||||||
|
_buildHeaderCell('Order'),
|
||||||
|
_buildHeaderCell('Pendapatan'),
|
||||||
|
_buildHeaderCell('Rata Rata'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(color: PdfColors.white),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(2), // Kategori
|
||||||
|
2: pw.FlexColumnWidth(1), // qty
|
||||||
|
3: pw.FlexColumnWidth(2), // Order
|
||||||
|
4: pw.FlexColumnWidth(2), // Pendapatan
|
||||||
|
5: pw.FlexColumnWidth(2), // Average
|
||||||
|
},
|
||||||
|
children: productAnalyticData.data
|
||||||
|
.map(
|
||||||
|
(item) => _buildItemDataRow(
|
||||||
|
product: item.productName,
|
||||||
|
category: item.categoryName,
|
||||||
|
qty: item.quantitySold.toString(),
|
||||||
|
order: item.orderCount.toString(),
|
||||||
|
pendapatan: item.revenue
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
average: safeCurrency(
|
||||||
|
item.averagePrice.round(),
|
||||||
|
),
|
||||||
|
isEven:
|
||||||
|
productAnalyticData.data.indexOf(item) %
|
||||||
|
2 ==
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: primaryColor, // Purple color
|
||||||
|
borderRadius: pw.BorderRadius.only(
|
||||||
|
bottomLeft: pw.Radius.circular(8),
|
||||||
|
bottomRight: pw.Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: pw.Table(
|
||||||
|
columnWidths: const {
|
||||||
|
0: pw.FlexColumnWidth(2.5), // Produk
|
||||||
|
1: pw.FlexColumnWidth(2), // Kategori
|
||||||
|
2: pw.FlexColumnWidth(1), // qty
|
||||||
|
3: pw.FlexColumnWidth(2), // Order
|
||||||
|
4: pw.FlexColumnWidth(2), // Pendapatan
|
||||||
|
5: pw.FlexColumnWidth(2), // Average
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
pw.TableRow(
|
||||||
|
children: [
|
||||||
|
_buildTotalCell('TOTAL'),
|
||||||
|
_buildTotalCell(''),
|
||||||
|
_buildTotalCell(
|
||||||
|
productItemSummary['totalQuantitySold']
|
||||||
|
.toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
productItemSummary['orderCount'].toString(),
|
||||||
|
),
|
||||||
|
_buildTotalCell(
|
||||||
|
productItemSummary['totalRevenue']
|
||||||
|
.toString()
|
||||||
|
.currencyFormatRpV2,
|
||||||
|
),
|
||||||
|
_buildTotalCell(''),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return HelperPdfService.saveDocument(
|
||||||
|
name: 'Laporan Transaksi | $searchDateFormatted.pdf',
|
||||||
|
pdf: pdf,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String safePercentage(num numerator, num denominator) {
|
||||||
|
if (denominator == 0 ||
|
||||||
|
numerator.isInfinite ||
|
||||||
|
numerator.isNaN ||
|
||||||
|
denominator.isInfinite ||
|
||||||
|
denominator.isNaN) {
|
||||||
|
return '0%';
|
||||||
|
}
|
||||||
|
final result = (numerator / denominator) * 100;
|
||||||
|
if (result.isInfinite || result.isNaN) {
|
||||||
|
return '0%';
|
||||||
|
}
|
||||||
|
return '${result.round()}%';
|
||||||
|
}
|
||||||
|
|
||||||
|
static String safeRound(num value) {
|
||||||
|
if (value.isInfinite || value.isNaN) {
|
||||||
|
return '0';
|
||||||
|
}
|
||||||
|
return value.round().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static String safeCurrency(num value) {
|
||||||
|
if (value.isInfinite || value.isNaN) {
|
||||||
|
return '0'.currencyFormatRpV2;
|
||||||
|
}
|
||||||
|
return value.toString().currencyFormatRpV2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _buildSectionWidget(String title) {
|
||||||
|
return pw.Text(
|
||||||
|
title,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _buildSummaryItem(
|
||||||
|
String label,
|
||||||
|
String value, {
|
||||||
|
pw.TextStyle? valueStyle,
|
||||||
|
pw.TextStyle? labelStyle,
|
||||||
|
}) {
|
||||||
|
return pw.Container(
|
||||||
|
padding: pw.EdgeInsets.only(bottom: 8),
|
||||||
|
margin: pw.EdgeInsets.only(bottom: 16),
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
border: pw.Border(bottom: pw.BorderSide(color: PdfColors.grey300)),
|
||||||
|
),
|
||||||
|
child: pw.Row(
|
||||||
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
pw.Text(label, style: labelStyle),
|
||||||
|
pw.Text(
|
||||||
|
value,
|
||||||
|
style: valueStyle ?? pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _buildHeaderCell(String text) {
|
||||||
|
return pw.Container(
|
||||||
|
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||||
|
child: pw.Text(
|
||||||
|
text,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
color: PdfColors.white,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _buildDataCell(
|
||||||
|
String text, {
|
||||||
|
pw.Alignment alignment = pw.Alignment.center,
|
||||||
|
PdfColor? textColor,
|
||||||
|
}) {
|
||||||
|
return pw.Container(
|
||||||
|
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||||
|
alignment: alignment,
|
||||||
|
child: pw.Text(
|
||||||
|
text,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: textColor ?? PdfColors.black,
|
||||||
|
fontWeight: pw.FontWeight.normal,
|
||||||
|
),
|
||||||
|
textAlign: alignment == pw.Alignment.centerLeft
|
||||||
|
? pw.TextAlign.left
|
||||||
|
: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _buildTotalCell(String text) {
|
||||||
|
return pw.Container(
|
||||||
|
padding: pw.EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||||
|
child: pw.Text(
|
||||||
|
text,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
color: PdfColors.white,
|
||||||
|
fontWeight: pw.FontWeight.bold,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.TableRow _buildPerProductDataRow({
|
||||||
|
required String product,
|
||||||
|
required String qty,
|
||||||
|
required String pendapatan,
|
||||||
|
required String hpp,
|
||||||
|
required String labaKotor,
|
||||||
|
required String margin,
|
||||||
|
required bool isEven,
|
||||||
|
}) {
|
||||||
|
return pw.TableRow(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: isEven ? PdfColors.grey50 : PdfColors.white,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
_buildDataCell(product, alignment: pw.Alignment.centerLeft),
|
||||||
|
_buildDataCell(qty),
|
||||||
|
_buildDataCell(pendapatan),
|
||||||
|
_buildDataCell(hpp, textColor: PdfColors.red600),
|
||||||
|
_buildDataCell(labaKotor, textColor: PdfColors.green600),
|
||||||
|
_buildDataCell(margin),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.TableRow _buildPaymentMethodDataRow({
|
||||||
|
required String name,
|
||||||
|
required String tipe,
|
||||||
|
required String jumlahOrder,
|
||||||
|
required String totalAmount,
|
||||||
|
required String presentase,
|
||||||
|
required bool isEven,
|
||||||
|
}) {
|
||||||
|
return pw.TableRow(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: isEven ? PdfColors.grey50 : PdfColors.white,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
_buildDataCell(name, alignment: pw.Alignment.centerLeft),
|
||||||
|
_buildDataCell(tipe),
|
||||||
|
_buildDataCell(jumlahOrder),
|
||||||
|
_buildDataCell(totalAmount),
|
||||||
|
_buildDataCell(presentase),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.TableRow _buildCategoryDataRow({
|
||||||
|
required String name,
|
||||||
|
required String totalProduct,
|
||||||
|
required String qty,
|
||||||
|
required String jumlahOrder,
|
||||||
|
required String pendapatan,
|
||||||
|
required bool isEven,
|
||||||
|
}) {
|
||||||
|
return pw.TableRow(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: isEven ? PdfColors.grey50 : PdfColors.white,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
_buildDataCell(name, alignment: pw.Alignment.centerLeft),
|
||||||
|
_buildDataCell(totalProduct),
|
||||||
|
_buildDataCell(qty),
|
||||||
|
_buildDataCell(jumlahOrder),
|
||||||
|
_buildDataCell(pendapatan),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.TableRow _buildItemDataRow({
|
||||||
|
required String product,
|
||||||
|
required String category,
|
||||||
|
required String qty,
|
||||||
|
required String order,
|
||||||
|
required String pendapatan,
|
||||||
|
required String average,
|
||||||
|
required bool isEven,
|
||||||
|
}) {
|
||||||
|
return pw.TableRow(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: isEven ? PdfColors.grey50 : PdfColors.white,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
_buildDataCell(product, alignment: pw.Alignment.centerLeft),
|
||||||
|
_buildDataCell(category, alignment: pw.Alignment.centerLeft),
|
||||||
|
_buildDataCell(qty),
|
||||||
|
_buildDataCell(order),
|
||||||
|
_buildDataCell(pendapatan),
|
||||||
|
_buildDataCell(average),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
|
||||||
import '../../../application/report/inventory_report/inventory_report_bloc.dart';
|
import '../../../application/report/inventory_report/inventory_report_bloc.dart';
|
||||||
|
import '../../../application/report/transaction_report/transaction_report_bloc.dart';
|
||||||
import '../../../common/extension/extension.dart';
|
import '../../../common/extension/extension.dart';
|
||||||
import '../../../common/theme/theme.dart';
|
import '../../../common/theme/theme.dart';
|
||||||
import '../../../common/utils/pdf_service.dart';
|
import '../../../common/utils/pdf_service.dart';
|
||||||
@ -14,6 +15,7 @@ import '../../../injection.dart';
|
|||||||
import '../../components/appbar/appbar.dart';
|
import '../../components/appbar/appbar.dart';
|
||||||
import '../../components/field/date_range_picker_field.dart';
|
import '../../components/field/date_range_picker_field.dart';
|
||||||
import '../../components/report/inventory_report.dart';
|
import '../../components/report/inventory_report.dart';
|
||||||
|
import '../../components/report/transaction_report.dart';
|
||||||
import '../../components/toast/flushbar.dart';
|
import '../../components/toast/flushbar.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
@ -24,9 +26,19 @@ class DownloadReportPage extends StatefulWidget implements AutoRouteWrapper {
|
|||||||
State<DownloadReportPage> createState() => _DownloadReportPageState();
|
State<DownloadReportPage> createState() => _DownloadReportPageState();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
Widget wrappedRoute(BuildContext context) => MultiBlocProvider(
|
||||||
create: (context) =>
|
providers: [
|
||||||
getIt<InventoryReportBloc>()..add(InventoryReportEvent.fetchedOutlet()),
|
BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
getIt<InventoryReportBloc>()
|
||||||
|
..add(InventoryReportEvent.fetchedOutlet()),
|
||||||
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
getIt<TransactionReportBloc>()
|
||||||
|
..add(TransactionReportEvent.fetchedOutlet()),
|
||||||
|
),
|
||||||
|
],
|
||||||
child: this,
|
child: this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -88,17 +100,6 @@ class _DownloadReportPageState extends State<DownloadReportPage>
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _downloadReport(
|
|
||||||
String reportType,
|
|
||||||
DateTime? startDate,
|
|
||||||
DateTime? endDate,
|
|
||||||
) {
|
|
||||||
if (startDate == null || endDate == null) {
|
|
||||||
AppFlushbar.showError(context, 'Please select both start and end dates');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -127,30 +128,75 @@ class _DownloadReportPageState extends State<DownloadReportPage>
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Transaction Report Card
|
// Transaction Report Card
|
||||||
_ReportOptionCard(
|
BlocBuilder<
|
||||||
title: 'Transaction Report',
|
TransactionReportBloc,
|
||||||
subtitle:
|
TransactionReportState
|
||||||
'Export all transaction data with detailed analytics',
|
>(
|
||||||
icon: Icons.receipt_long_outlined,
|
builder: (context, state) {
|
||||||
gradient: const [
|
return _ReportOptionCard(
|
||||||
AppColor.primary,
|
title: 'Transaction Report',
|
||||||
AppColor.primaryLight,
|
subtitle:
|
||||||
],
|
'Export all transaction data with detailed analytics',
|
||||||
startDate: _transactionStartDate,
|
icon: Icons.receipt_long_outlined,
|
||||||
endDate: _transactionEndDate,
|
gradient: const [
|
||||||
isLoading: false,
|
AppColor.primary,
|
||||||
onDateRangeChanged: (start, end) {
|
AppColor.primaryLight,
|
||||||
setState(() {
|
],
|
||||||
_transactionStartDate = start;
|
startDate: _transactionStartDate,
|
||||||
_transactionEndDate = end;
|
endDate: _transactionEndDate,
|
||||||
});
|
isLoading: state.isFetching,
|
||||||
|
onDateRangeChanged: (start, end) {
|
||||||
|
setState(() {
|
||||||
|
_transactionStartDate = start;
|
||||||
|
_transactionEndDate = end;
|
||||||
|
});
|
||||||
|
if (start != null || end != null) {
|
||||||
|
context.read<TransactionReportBloc>().add(
|
||||||
|
TransactionReportEvent.fetchedTransaction(
|
||||||
|
start!,
|
||||||
|
end!,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDownload: () async {
|
||||||
|
try {
|
||||||
|
final status = await PermessionHelper()
|
||||||
|
.checkPermission();
|
||||||
|
if (status) {
|
||||||
|
final pdfFile =
|
||||||
|
await TransactionReport.previewPdf(
|
||||||
|
searchDateFormatted:
|
||||||
|
"${_transactionStartDate?.toServerDate} - ${_transactionEndDate?.toServerDate}",
|
||||||
|
outlet: state.outlet,
|
||||||
|
categoryAnalyticData:
|
||||||
|
state.categoryAnalytic,
|
||||||
|
profitLossData:
|
||||||
|
state.profitLossAnalytic,
|
||||||
|
paymentMethodAnalyticData:
|
||||||
|
state.paymentMethodAnalytic,
|
||||||
|
productAnalyticData:
|
||||||
|
state.productAnalytic,
|
||||||
|
);
|
||||||
|
log("pdfFile: $pdfFile");
|
||||||
|
await HelperPdfService.openFile(pdfFile);
|
||||||
|
} else {
|
||||||
|
AppFlushbar.showError(
|
||||||
|
context,
|
||||||
|
'Storage permission is required to save PDF',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log("Error generating PDF: $e");
|
||||||
|
AppFlushbar.showError(
|
||||||
|
context,
|
||||||
|
'Failed to generate PDF: $e',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delay: 200,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onDownload: () => _downloadReport(
|
|
||||||
'Transaction Report',
|
|
||||||
_transactionStartDate,
|
|
||||||
_transactionEndDate,
|
|
||||||
),
|
|
||||||
delay: 200,
|
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|||||||
@ -139,7 +139,7 @@ class DownloadReportRoute extends _i26.PageRouteInfo<void> {
|
|||||||
static _i26.PageInfo page = _i26.PageInfo(
|
static _i26.PageInfo page = _i26.PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const _i5.DownloadReportPage();
|
return _i26.WrappedRoute(child: const _i5.DownloadReportPage());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user