first commit

This commit is contained in:
Aditya Siregar
2025-07-30 22:38:44 +07:00
commit 73320561b0
444 changed files with 64633 additions and 0 deletions
@@ -0,0 +1,48 @@
import 'dart:developer';
import 'package:bloc/bloc.dart';
import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'add_order_items_event.dart';
part 'add_order_items_state.dart';
part 'add_order_items_bloc.freezed.dart';
class AddOrderItemsBloc extends Bloc<AddOrderItemsEvent, AddOrderItemsState> {
final OrderRemoteDatasource orderRemoteDatasource;
AddOrderItemsBloc(
this.orderRemoteDatasource,
) : super(const _Initial()) {
on<_AddOrderItems>((event, emit) async {
emit(const _Loading());
try {
// Convert ProductQuantity list to the format expected by the API
final orderItems = event.items.map((item) => {
'id_product': item.product.productId,
'quantity': item.quantity,
'price': item.product.price!.toIntegerFromText,
'notes': item.notes,
}).toList();
log("Adding order items: ${orderItems.toString()}");
final result = await orderRemoteDatasource.addOrderItems(
event.orderId,
orderItems,
);
result.fold(
(error) => emit(_Error(error)),
(success) => emit(const _Success()),
);
} catch (e) {
log("Error in AddOrderItemsBloc: $e");
emit(_Error("Failed to add order items: $e"));
}
});
}
}
@@ -0,0 +1,836 @@
// 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 'add_order_items_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 _$AddOrderItemsEvent {
int get orderId => throw _privateConstructorUsedError;
List<ProductQuantity> get items => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(int orderId, List<ProductQuantity> items)
addOrderItems,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(int orderId, List<ProductQuantity> items)? addOrderItems,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(int orderId, List<ProductQuantity> items)? addOrderItems,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_AddOrderItems value) addOrderItems,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_AddOrderItems value)? addOrderItems,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_AddOrderItems value)? addOrderItems,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
/// Create a copy of AddOrderItemsEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$AddOrderItemsEventCopyWith<AddOrderItemsEvent> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AddOrderItemsEventCopyWith<$Res> {
factory $AddOrderItemsEventCopyWith(
AddOrderItemsEvent value, $Res Function(AddOrderItemsEvent) then) =
_$AddOrderItemsEventCopyWithImpl<$Res, AddOrderItemsEvent>;
@useResult
$Res call({int orderId, List<ProductQuantity> items});
}
/// @nodoc
class _$AddOrderItemsEventCopyWithImpl<$Res, $Val extends AddOrderItemsEvent>
implements $AddOrderItemsEventCopyWith<$Res> {
_$AddOrderItemsEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of AddOrderItemsEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? orderId = null,
Object? items = null,
}) {
return _then(_value.copyWith(
orderId: null == orderId
? _value.orderId
: orderId // ignore: cast_nullable_to_non_nullable
as int,
items: null == items
? _value.items
: items // ignore: cast_nullable_to_non_nullable
as List<ProductQuantity>,
) as $Val);
}
}
/// @nodoc
abstract class _$$AddOrderItemsImplCopyWith<$Res>
implements $AddOrderItemsEventCopyWith<$Res> {
factory _$$AddOrderItemsImplCopyWith(
_$AddOrderItemsImpl value, $Res Function(_$AddOrderItemsImpl) then) =
__$$AddOrderItemsImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({int orderId, List<ProductQuantity> items});
}
/// @nodoc
class __$$AddOrderItemsImplCopyWithImpl<$Res>
extends _$AddOrderItemsEventCopyWithImpl<$Res, _$AddOrderItemsImpl>
implements _$$AddOrderItemsImplCopyWith<$Res> {
__$$AddOrderItemsImplCopyWithImpl(
_$AddOrderItemsImpl _value, $Res Function(_$AddOrderItemsImpl) _then)
: super(_value, _then);
/// Create a copy of AddOrderItemsEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? orderId = null,
Object? items = null,
}) {
return _then(_$AddOrderItemsImpl(
null == orderId
? _value.orderId
: orderId // ignore: cast_nullable_to_non_nullable
as int,
null == items
? _value._items
: items // ignore: cast_nullable_to_non_nullable
as List<ProductQuantity>,
));
}
}
/// @nodoc
class _$AddOrderItemsImpl implements _AddOrderItems {
const _$AddOrderItemsImpl(this.orderId, final List<ProductQuantity> items)
: _items = items;
@override
final int orderId;
final List<ProductQuantity> _items;
@override
List<ProductQuantity> get items {
if (_items is EqualUnmodifiableListView) return _items;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_items);
}
@override
String toString() {
return 'AddOrderItemsEvent.addOrderItems(orderId: $orderId, items: $items)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$AddOrderItemsImpl &&
(identical(other.orderId, orderId) || other.orderId == orderId) &&
const DeepCollectionEquality().equals(other._items, _items));
}
@override
int get hashCode => Object.hash(
runtimeType, orderId, const DeepCollectionEquality().hash(_items));
/// Create a copy of AddOrderItemsEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$AddOrderItemsImplCopyWith<_$AddOrderItemsImpl> get copyWith =>
__$$AddOrderItemsImplCopyWithImpl<_$AddOrderItemsImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(int orderId, List<ProductQuantity> items)
addOrderItems,
}) {
return addOrderItems(orderId, items);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(int orderId, List<ProductQuantity> items)? addOrderItems,
}) {
return addOrderItems?.call(orderId, items);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(int orderId, List<ProductQuantity> items)? addOrderItems,
required TResult orElse(),
}) {
if (addOrderItems != null) {
return addOrderItems(orderId, items);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_AddOrderItems value) addOrderItems,
}) {
return addOrderItems(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_AddOrderItems value)? addOrderItems,
}) {
return addOrderItems?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_AddOrderItems value)? addOrderItems,
required TResult orElse(),
}) {
if (addOrderItems != null) {
return addOrderItems(this);
}
return orElse();
}
}
abstract class _AddOrderItems implements AddOrderItemsEvent {
const factory _AddOrderItems(
final int orderId, final List<ProductQuantity> items) =
_$AddOrderItemsImpl;
@override
int get orderId;
@override
List<ProductQuantity> get items;
/// Create a copy of AddOrderItemsEvent
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$AddOrderItemsImplCopyWith<_$AddOrderItemsImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$AddOrderItemsState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
required TResult Function(_Error value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
TResult? Function(_Error value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
TResult Function(_Error value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AddOrderItemsStateCopyWith<$Res> {
factory $AddOrderItemsStateCopyWith(
AddOrderItemsState value, $Res Function(AddOrderItemsState) then) =
_$AddOrderItemsStateCopyWithImpl<$Res, AddOrderItemsState>;
}
/// @nodoc
class _$AddOrderItemsStateCopyWithImpl<$Res, $Val extends AddOrderItemsState>
implements $AddOrderItemsStateCopyWith<$Res> {
_$AddOrderItemsStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$AddOrderItemsStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'AddOrderItemsState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
required TResult Function(String message) error,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
TResult? Function(String message)? error,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
required TResult Function(_Error value) error,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
TResult? Function(_Error value)? error,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements AddOrderItemsState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
factory _$$LoadingImplCopyWith(
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
__$$LoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
extends _$AddOrderItemsStateCopyWithImpl<$Res, _$LoadingImpl>
implements _$$LoadingImplCopyWith<$Res> {
__$$LoadingImplCopyWithImpl(
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
: super(_value, _then);
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$LoadingImpl implements _Loading {
const _$LoadingImpl();
@override
String toString() {
return 'AddOrderItemsState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$LoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
required TResult Function(String message) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
TResult? Function(String message)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
required TResult Function(_Error value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
TResult? Function(_Error value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class _Loading implements AddOrderItemsState {
const factory _Loading() = _$LoadingImpl;
}
/// @nodoc
abstract class _$$SuccessImplCopyWith<$Res> {
factory _$$SuccessImplCopyWith(
_$SuccessImpl value, $Res Function(_$SuccessImpl) then) =
__$$SuccessImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SuccessImplCopyWithImpl<$Res>
extends _$AddOrderItemsStateCopyWithImpl<$Res, _$SuccessImpl>
implements _$$SuccessImplCopyWith<$Res> {
__$$SuccessImplCopyWithImpl(
_$SuccessImpl _value, $Res Function(_$SuccessImpl) _then)
: super(_value, _then);
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SuccessImpl implements _Success {
const _$SuccessImpl();
@override
String toString() {
return 'AddOrderItemsState.success()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$SuccessImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
required TResult Function(String message) error,
}) {
return success();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
TResult? Function(String message)? error,
}) {
return success?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (success != null) {
return success();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
required TResult Function(_Error value) error,
}) {
return success(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
TResult? Function(_Error value)? error,
}) {
return success?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (success != null) {
return success(this);
}
return orElse();
}
}
abstract class _Success implements AddOrderItemsState {
const factory _Success() = _$SuccessImpl;
}
/// @nodoc
abstract class _$$ErrorImplCopyWith<$Res> {
factory _$$ErrorImplCopyWith(
_$ErrorImpl value, $Res Function(_$ErrorImpl) then) =
__$$ErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String message});
}
/// @nodoc
class __$$ErrorImplCopyWithImpl<$Res>
extends _$AddOrderItemsStateCopyWithImpl<$Res, _$ErrorImpl>
implements _$$ErrorImplCopyWith<$Res> {
__$$ErrorImplCopyWithImpl(
_$ErrorImpl _value, $Res Function(_$ErrorImpl) _then)
: super(_value, _then);
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? message = null,
}) {
return _then(_$ErrorImpl(
null == message
? _value.message
: message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$ErrorImpl implements _Error {
const _$ErrorImpl(this.message);
@override
final String message;
@override
String toString() {
return 'AddOrderItemsState.error(message: $message)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ErrorImpl &&
(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType, message);
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
__$$ErrorImplCopyWithImpl<_$ErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
required TResult Function(String message) error,
}) {
return error(message);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
TResult? Function(String message)? error,
}) {
return error?.call(message);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(message);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
required TResult Function(_Error value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
TResult? Function(_Error value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class _Error implements AddOrderItemsState {
const factory _Error(final String message) = _$ErrorImpl;
String get message;
/// Create a copy of AddOrderItemsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -0,0 +1,9 @@
part of 'add_order_items_bloc.dart';
@freezed
class AddOrderItemsEvent with _$AddOrderItemsEvent {
const factory AddOrderItemsEvent.addOrderItems(
int orderId,
List<ProductQuantity> items,
) = _AddOrderItems;
}
@@ -0,0 +1,9 @@
part of 'add_order_items_bloc.dart';
@freezed
class AddOrderItemsState with _$AddOrderItemsState {
const factory AddOrderItemsState.initial() = _Initial;
const factory AddOrderItemsState.loading() = _Loading;
const factory AddOrderItemsState.success() = _Success;
const factory AddOrderItemsState.error(String message) = _Error;
}
@@ -0,0 +1,269 @@
import 'dart:developer';
import 'package:bloc/bloc.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:enaklo_pos/data/models/response/discount_response_model.dart';
import 'package:enaklo_pos/presentation/home/models/order_item.dart';
import 'package:enaklo_pos/presentation/table/models/draft_order_item.dart';
import 'package:enaklo_pos/presentation/table/models/draft_order_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:intl/intl.dart';
import '../../../../data/models/response/product_response_model.dart';
import '../../../../data/datasources/settings_local_datasource.dart';
import '../../models/product_quantity.dart';
import '../../models/order_type.dart';
part 'checkout_event.dart';
part 'checkout_state.dart';
part 'checkout_bloc.freezed.dart';
class CheckoutBloc extends Bloc<CheckoutEvent, CheckoutState> {
final SettingsLocalDatasource settingsLocalDatasource;
CheckoutBloc({required this.settingsLocalDatasource}) : super(const CheckoutState.initial()) {
on<_AddItem>((event, emit) {
var currentState = state as _Loaded;
List<ProductQuantity> items = [...currentState.items];
var index =
items.indexWhere((element) => element.product.id == event.product.id);
emit(const _Loading());
if (index != -1) {
items[index] = ProductQuantity(
product: event.product, quantity: items[index].quantity + 1);
} else {
items.add(ProductQuantity(product: event.product, quantity: 1));
}
emit(_Loaded(
items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
currentState.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_RemoveItem>((event, emit) {
var currentState = state as _Loaded;
List<ProductQuantity> items = [...currentState.items];
var index =
items.indexWhere((element) => element.product.id == event.product.id);
emit(const _Loading());
if (index != -1) {
if (items[index].quantity > 1) {
items[index] = ProductQuantity(
product: event.product, quantity: items[index].quantity - 1);
} else {
items.removeAt(index);
}
}
emit(_Loaded(
items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
currentState.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_Started>((event, emit) async {
emit(const _Loading());
try {
// Load tax and service charge from settings
final tax = await settingsLocalDatasource.getTax();
final serviceCharge = await settingsLocalDatasource.getServiceCharge();
emit(_Loaded([], null, 0, 0, tax.value, serviceCharge, 0, 0, '', OrderType.dineIn));
} catch (e) {
// If loading fails, use default values
log('Failed to load settings: $e');
emit(const _Loaded([], null, 0, 0, 10, 5, 0, 0, '', OrderType.dineIn));
}
});
on<_AddDiscount>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
event.discount,
currentState.discount,
currentState.discountAmount,
currentState.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType,
));
});
on<_RemoveDiscount>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
null,
currentState.discount,
currentState.discountAmount,
currentState.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_AddTax>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
event.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_AddServiceCharge>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
currentState.tax,
event.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType,
));
});
on<_RemoveTax>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
0,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_RemoveServiceCharge>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
currentState.tax,
0,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_UpdateOrderType>((event, emit) {
var currentState = state as _Loaded;
emit(_Loaded(
currentState.items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
currentState.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
event.orderType));
});
on<_UpdateItemNotes>((event, emit) {
var currentState = state as _Loaded;
List<ProductQuantity> items = [...currentState.items];
var index = items.indexWhere((element) => element.product.id == event.product.id);
if (index != -1) {
items[index] = items[index].copyWith(notes: event.notes);
}
emit(_Loaded(
items,
currentState.discountModel,
currentState.discount,
currentState.discountAmount,
currentState.tax,
currentState.serviceCharge,
currentState.totalQuantity,
currentState.totalPrice,
currentState.draftName,
currentState.orderType));
});
on<_SaveDraftOrder>((event, emit) async {
var currentStates = state as _Loaded;
emit(const _Loading());
final draftOrder = DraftOrderModel(
orders: currentStates.items
.map((e) => DraftOrderItem(
product: e.product,
quantity: e.quantity,
))
.toList(),
totalQuantity: currentStates.totalQuantity,
totalPrice: currentStates.totalPrice,
discount: currentStates.discount,
discountAmount: event.discountAmount,
tax: currentStates.tax,
serviceCharge: currentStates.serviceCharge,
subTotal: currentStates.totalPrice,
tableNumber: event.tableNumber,
draftName: event.draftName,
transactionTime:
DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now()),
);
log("draftOrder12: ${draftOrder.toMapForLocal()}");
final orderDraftId =
await ProductLocalDatasource.instance.saveDraftOrder(draftOrder);
emit(_SavedDraftOrder(orderDraftId));
});
//load draft order
on<_LoadDraftOrder>((event, emit) async {
emit(const _Loading());
final draftOrder = event.data;
log("draftOrder: ${draftOrder.toMap()}");
emit(_Loaded(
draftOrder.orders
.map((e) =>
ProductQuantity(product: e.product, quantity: e.quantity))
.toList(),
null,
draftOrder.discount,
draftOrder.discountAmount,
draftOrder.tax,
draftOrder.serviceCharge,
draftOrder.totalQuantity,
draftOrder.totalPrice,
draftOrder.draftName,
OrderType.dineIn));
});
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,38 @@
part of 'checkout_bloc.dart';
@freezed
class CheckoutEvent with _$CheckoutEvent {
const factory CheckoutEvent.started() = _Started;
//add item
const factory CheckoutEvent.addItem(Product product) = _AddItem;
//remove item
const factory CheckoutEvent.removeItem(Product product) = _RemoveItem;
//add discount
const factory CheckoutEvent.addDiscount(Discount discount) = _AddDiscount;
//remove discount
const factory CheckoutEvent.removeDiscount() = _RemoveDiscount;
//add tax
const factory CheckoutEvent.addTax(int tax) = _AddTax;
//add service charge
const factory CheckoutEvent.addServiceCharge(int serviceCharge) =
_AddServiceCharge;
//remove tax
const factory CheckoutEvent.removeTax() = _RemoveTax;
//remove service charge
const factory CheckoutEvent.removeServiceCharge() = _RemoveServiceCharge;
//update order type
const factory CheckoutEvent.updateOrderType(OrderType orderType) = _UpdateOrderType;
//update item notes
const factory CheckoutEvent.updateItemNotes(Product product, String notes) = _UpdateItemNotes;
//save draft order
const factory CheckoutEvent.saveDraftOrder(
int tableNumber, String draftName, int discountAmount) = _SaveDraftOrder;
//load draft order
const factory CheckoutEvent.loadDraftOrder(DraftOrderModel data) =
_LoadDraftOrder;
}
@@ -0,0 +1,22 @@
part of 'checkout_bloc.dart';
@freezed
class CheckoutState with _$CheckoutState {
const factory CheckoutState.initial() = _Initial;
const factory CheckoutState.loading() = _Loading;
const factory CheckoutState.loaded(
List<ProductQuantity> items,
Discount? discountModel,
int discount,
int discountAmount,
int tax,
int serviceCharge,
int totalQuantity,
int totalPrice,
String draftName,
OrderType orderType) = _Loaded;
const factory CheckoutState.error(String message) = _Error;
//save draft order
const factory CheckoutState.savedDraftOrder(int orderId) = _SavedDraftOrder;
}
@@ -0,0 +1,20 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:enaklo_pos/data/models/response/table_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'get_table_status_event.dart';
part 'get_table_status_state.dart';
part 'get_table_status_bloc.freezed.dart';
class GetTableStatusBloc
extends Bloc<GetTableStatusEvent, GetTableStatusState> {
GetTableStatusBloc() : super(_Initial()) {
on<_GetTablesStatus>((event, emit) async {
emit(_Loading());
final tables =
await ProductLocalDatasource.instance.getTableByStatus(event.status);
emit(_Success(tables));
});
}
}
@@ -0,0 +1,767 @@
// 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 'get_table_status_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 _$GetTableStatusEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(String status) getTablesStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(String status)? getTablesStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(String status)? getTablesStatus,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_GetTablesStatus value) getTablesStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_GetTablesStatus value)? getTablesStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_GetTablesStatus value)? getTablesStatus,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $GetTableStatusEventCopyWith<$Res> {
factory $GetTableStatusEventCopyWith(
GetTableStatusEvent value, $Res Function(GetTableStatusEvent) then) =
_$GetTableStatusEventCopyWithImpl<$Res, GetTableStatusEvent>;
}
/// @nodoc
class _$GetTableStatusEventCopyWithImpl<$Res, $Val extends GetTableStatusEvent>
implements $GetTableStatusEventCopyWith<$Res> {
_$GetTableStatusEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of GetTableStatusEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$StartedImplCopyWith<$Res> {
factory _$$StartedImplCopyWith(
_$StartedImpl value, $Res Function(_$StartedImpl) then) =
__$$StartedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$StartedImplCopyWithImpl<$Res>
extends _$GetTableStatusEventCopyWithImpl<$Res, _$StartedImpl>
implements _$$StartedImplCopyWith<$Res> {
__$$StartedImplCopyWithImpl(
_$StartedImpl _value, $Res Function(_$StartedImpl) _then)
: super(_value, _then);
/// Create a copy of GetTableStatusEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$StartedImpl implements _Started {
const _$StartedImpl();
@override
String toString() {
return 'GetTableStatusEvent.started()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$StartedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(String status) getTablesStatus,
}) {
return started();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(String status)? getTablesStatus,
}) {
return started?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(String status)? getTablesStatus,
required TResult orElse(),
}) {
if (started != null) {
return started();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_GetTablesStatus value) getTablesStatus,
}) {
return started(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_GetTablesStatus value)? getTablesStatus,
}) {
return started?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_GetTablesStatus value)? getTablesStatus,
required TResult orElse(),
}) {
if (started != null) {
return started(this);
}
return orElse();
}
}
abstract class _Started implements GetTableStatusEvent {
const factory _Started() = _$StartedImpl;
}
/// @nodoc
abstract class _$$GetTablesStatusImplCopyWith<$Res> {
factory _$$GetTablesStatusImplCopyWith(_$GetTablesStatusImpl value,
$Res Function(_$GetTablesStatusImpl) then) =
__$$GetTablesStatusImplCopyWithImpl<$Res>;
@useResult
$Res call({String status});
}
/// @nodoc
class __$$GetTablesStatusImplCopyWithImpl<$Res>
extends _$GetTableStatusEventCopyWithImpl<$Res, _$GetTablesStatusImpl>
implements _$$GetTablesStatusImplCopyWith<$Res> {
__$$GetTablesStatusImplCopyWithImpl(
_$GetTablesStatusImpl _value, $Res Function(_$GetTablesStatusImpl) _then)
: super(_value, _then);
/// Create a copy of GetTableStatusEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? status = null,
}) {
return _then(_$GetTablesStatusImpl(
null == status
? _value.status
: status // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$GetTablesStatusImpl implements _GetTablesStatus {
const _$GetTablesStatusImpl(this.status);
@override
final String status;
@override
String toString() {
return 'GetTableStatusEvent.getTablesStatus(status: $status)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$GetTablesStatusImpl &&
(identical(other.status, status) || other.status == status));
}
@override
int get hashCode => Object.hash(runtimeType, status);
/// Create a copy of GetTableStatusEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$GetTablesStatusImplCopyWith<_$GetTablesStatusImpl> get copyWith =>
__$$GetTablesStatusImplCopyWithImpl<_$GetTablesStatusImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(String status) getTablesStatus,
}) {
return getTablesStatus(status);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(String status)? getTablesStatus,
}) {
return getTablesStatus?.call(status);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(String status)? getTablesStatus,
required TResult orElse(),
}) {
if (getTablesStatus != null) {
return getTablesStatus(status);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_GetTablesStatus value) getTablesStatus,
}) {
return getTablesStatus(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_GetTablesStatus value)? getTablesStatus,
}) {
return getTablesStatus?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_GetTablesStatus value)? getTablesStatus,
required TResult orElse(),
}) {
if (getTablesStatus != null) {
return getTablesStatus(this);
}
return orElse();
}
}
abstract class _GetTablesStatus implements GetTableStatusEvent {
const factory _GetTablesStatus(final String status) = _$GetTablesStatusImpl;
String get status;
/// Create a copy of GetTableStatusEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$GetTablesStatusImplCopyWith<_$GetTablesStatusImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$GetTableStatusState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<TableModel> tables) success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<TableModel> tables)? success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<TableModel> tables)? success,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $GetTableStatusStateCopyWith<$Res> {
factory $GetTableStatusStateCopyWith(
GetTableStatusState value, $Res Function(GetTableStatusState) then) =
_$GetTableStatusStateCopyWithImpl<$Res, GetTableStatusState>;
}
/// @nodoc
class _$GetTableStatusStateCopyWithImpl<$Res, $Val extends GetTableStatusState>
implements $GetTableStatusStateCopyWith<$Res> {
_$GetTableStatusStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of GetTableStatusState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$GetTableStatusStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of GetTableStatusState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'GetTableStatusState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<TableModel> tables) success,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<TableModel> tables)? success,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<TableModel> tables)? success,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements GetTableStatusState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
factory _$$LoadingImplCopyWith(
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
__$$LoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
extends _$GetTableStatusStateCopyWithImpl<$Res, _$LoadingImpl>
implements _$$LoadingImplCopyWith<$Res> {
__$$LoadingImplCopyWithImpl(
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
: super(_value, _then);
/// Create a copy of GetTableStatusState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$LoadingImpl implements _Loading {
const _$LoadingImpl();
@override
String toString() {
return 'GetTableStatusState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$LoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<TableModel> tables) success,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<TableModel> tables)? success,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<TableModel> tables)? success,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class _Loading implements GetTableStatusState {
const factory _Loading() = _$LoadingImpl;
}
/// @nodoc
abstract class _$$SuccessImplCopyWith<$Res> {
factory _$$SuccessImplCopyWith(
_$SuccessImpl value, $Res Function(_$SuccessImpl) then) =
__$$SuccessImplCopyWithImpl<$Res>;
@useResult
$Res call({List<TableModel> tables});
}
/// @nodoc
class __$$SuccessImplCopyWithImpl<$Res>
extends _$GetTableStatusStateCopyWithImpl<$Res, _$SuccessImpl>
implements _$$SuccessImplCopyWith<$Res> {
__$$SuccessImplCopyWithImpl(
_$SuccessImpl _value, $Res Function(_$SuccessImpl) _then)
: super(_value, _then);
/// Create a copy of GetTableStatusState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? tables = null,
}) {
return _then(_$SuccessImpl(
null == tables
? _value._tables
: tables // ignore: cast_nullable_to_non_nullable
as List<TableModel>,
));
}
}
/// @nodoc
class _$SuccessImpl implements _Success {
const _$SuccessImpl(final List<TableModel> tables) : _tables = tables;
final List<TableModel> _tables;
@override
List<TableModel> get tables {
if (_tables is EqualUnmodifiableListView) return _tables;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_tables);
}
@override
String toString() {
return 'GetTableStatusState.success(tables: $tables)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SuccessImpl &&
const DeepCollectionEquality().equals(other._tables, _tables));
}
@override
int get hashCode =>
Object.hash(runtimeType, const DeepCollectionEquality().hash(_tables));
/// Create a copy of GetTableStatusState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$SuccessImplCopyWith<_$SuccessImpl> get copyWith =>
__$$SuccessImplCopyWithImpl<_$SuccessImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<TableModel> tables) success,
}) {
return success(tables);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<TableModel> tables)? success,
}) {
return success?.call(tables);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<TableModel> tables)? success,
required TResult orElse(),
}) {
if (success != null) {
return success(tables);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) {
return success(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) {
return success?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) {
if (success != null) {
return success(this);
}
return orElse();
}
}
abstract class _Success implements GetTableStatusState {
const factory _Success(final List<TableModel> tables) = _$SuccessImpl;
List<TableModel> get tables;
/// Create a copy of GetTableStatusState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$SuccessImplCopyWith<_$SuccessImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -0,0 +1,9 @@
part of 'get_table_status_bloc.dart';
@freezed
class GetTableStatusEvent with _$GetTableStatusEvent {
const factory GetTableStatusEvent.started() = _Started;
const factory GetTableStatusEvent.getTablesStatus(String status) =
_GetTablesStatus;
}
@@ -0,0 +1,8 @@
part of 'get_table_status_bloc.dart';
@freezed
class GetTableStatusState with _$GetTableStatusState {
const factory GetTableStatusState.initial() = _Initial;
const factory GetTableStatusState.loading() = _Loading;
const factory GetTableStatusState.success(List<TableModel> tables) = _Success;
}
@@ -0,0 +1,26 @@
import 'dart:developer';
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import '../../../../data/models/response/product_response_model.dart';
part 'local_product_bloc.freezed.dart';
part 'local_product_event.dart';
part 'local_product_state.dart';
class LocalProductBloc extends Bloc<LocalProductEvent, LocalProductState> {
final ProductLocalDatasource productLocalDatasource;
LocalProductBloc(
this.productLocalDatasource,
) : super(const _Initial()) {
on<_GetLocalProduct>((event, emit) async {
emit(const _Loading());
final result = await productLocalDatasource.getProducts();
log("Result: ${result.length}");
emit(_Loaded(result));
});
}
}
@@ -0,0 +1,907 @@
// 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 'local_product_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 _$LocalProductEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function() getLocalProduct,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function()? getLocalProduct,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function()? getLocalProduct,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_GetLocalProduct value) getLocalProduct,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_GetLocalProduct value)? getLocalProduct,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_GetLocalProduct value)? getLocalProduct,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $LocalProductEventCopyWith<$Res> {
factory $LocalProductEventCopyWith(
LocalProductEvent value, $Res Function(LocalProductEvent) then) =
_$LocalProductEventCopyWithImpl<$Res, LocalProductEvent>;
}
/// @nodoc
class _$LocalProductEventCopyWithImpl<$Res, $Val extends LocalProductEvent>
implements $LocalProductEventCopyWith<$Res> {
_$LocalProductEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of LocalProductEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$StartedImplCopyWith<$Res> {
factory _$$StartedImplCopyWith(
_$StartedImpl value, $Res Function(_$StartedImpl) then) =
__$$StartedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$StartedImplCopyWithImpl<$Res>
extends _$LocalProductEventCopyWithImpl<$Res, _$StartedImpl>
implements _$$StartedImplCopyWith<$Res> {
__$$StartedImplCopyWithImpl(
_$StartedImpl _value, $Res Function(_$StartedImpl) _then)
: super(_value, _then);
/// Create a copy of LocalProductEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$StartedImpl implements _Started {
const _$StartedImpl();
@override
String toString() {
return 'LocalProductEvent.started()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$StartedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function() getLocalProduct,
}) {
return started();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function()? getLocalProduct,
}) {
return started?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function()? getLocalProduct,
required TResult orElse(),
}) {
if (started != null) {
return started();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_GetLocalProduct value) getLocalProduct,
}) {
return started(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_GetLocalProduct value)? getLocalProduct,
}) {
return started?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_GetLocalProduct value)? getLocalProduct,
required TResult orElse(),
}) {
if (started != null) {
return started(this);
}
return orElse();
}
}
abstract class _Started implements LocalProductEvent {
const factory _Started() = _$StartedImpl;
}
/// @nodoc
abstract class _$$GetLocalProductImplCopyWith<$Res> {
factory _$$GetLocalProductImplCopyWith(_$GetLocalProductImpl value,
$Res Function(_$GetLocalProductImpl) then) =
__$$GetLocalProductImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$GetLocalProductImplCopyWithImpl<$Res>
extends _$LocalProductEventCopyWithImpl<$Res, _$GetLocalProductImpl>
implements _$$GetLocalProductImplCopyWith<$Res> {
__$$GetLocalProductImplCopyWithImpl(
_$GetLocalProductImpl _value, $Res Function(_$GetLocalProductImpl) _then)
: super(_value, _then);
/// Create a copy of LocalProductEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$GetLocalProductImpl implements _GetLocalProduct {
const _$GetLocalProductImpl();
@override
String toString() {
return 'LocalProductEvent.getLocalProduct()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$GetLocalProductImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function() getLocalProduct,
}) {
return getLocalProduct();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function()? getLocalProduct,
}) {
return getLocalProduct?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function()? getLocalProduct,
required TResult orElse(),
}) {
if (getLocalProduct != null) {
return getLocalProduct();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_GetLocalProduct value) getLocalProduct,
}) {
return getLocalProduct(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_GetLocalProduct value)? getLocalProduct,
}) {
return getLocalProduct?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_GetLocalProduct value)? getLocalProduct,
required TResult orElse(),
}) {
if (getLocalProduct != null) {
return getLocalProduct(this);
}
return orElse();
}
}
abstract class _GetLocalProduct implements LocalProductEvent {
const factory _GetLocalProduct() = _$GetLocalProductImpl;
}
/// @nodoc
mixin _$LocalProductState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Product> products) loaded,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Product> products)? loaded,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Product> products)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $LocalProductStateCopyWith<$Res> {
factory $LocalProductStateCopyWith(
LocalProductState value, $Res Function(LocalProductState) then) =
_$LocalProductStateCopyWithImpl<$Res, LocalProductState>;
}
/// @nodoc
class _$LocalProductStateCopyWithImpl<$Res, $Val extends LocalProductState>
implements $LocalProductStateCopyWith<$Res> {
_$LocalProductStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$LocalProductStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'LocalProductState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Product> products) loaded,
required TResult Function(String message) error,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Product> products)? loaded,
TResult? Function(String message)? error,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Product> products)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements LocalProductState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
factory _$$LoadingImplCopyWith(
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
__$$LoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
extends _$LocalProductStateCopyWithImpl<$Res, _$LoadingImpl>
implements _$$LoadingImplCopyWith<$Res> {
__$$LoadingImplCopyWithImpl(
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
: super(_value, _then);
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$LoadingImpl implements _Loading {
const _$LoadingImpl();
@override
String toString() {
return 'LocalProductState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$LoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Product> products) loaded,
required TResult Function(String message) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Product> products)? loaded,
TResult? Function(String message)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Product> products)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class _Loading implements LocalProductState {
const factory _Loading() = _$LoadingImpl;
}
/// @nodoc
abstract class _$$LoadedImplCopyWith<$Res> {
factory _$$LoadedImplCopyWith(
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
__$$LoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({List<Product> products});
}
/// @nodoc
class __$$LoadedImplCopyWithImpl<$Res>
extends _$LocalProductStateCopyWithImpl<$Res, _$LoadedImpl>
implements _$$LoadedImplCopyWith<$Res> {
__$$LoadedImplCopyWithImpl(
_$LoadedImpl _value, $Res Function(_$LoadedImpl) _then)
: super(_value, _then);
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? products = null,
}) {
return _then(_$LoadedImpl(
null == products
? _value._products
: products // ignore: cast_nullable_to_non_nullable
as List<Product>,
));
}
}
/// @nodoc
class _$LoadedImpl implements _Loaded {
const _$LoadedImpl(final List<Product> products) : _products = products;
final List<Product> _products;
@override
List<Product> get products {
if (_products is EqualUnmodifiableListView) return _products;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_products);
}
@override
String toString() {
return 'LocalProductState.loaded(products: $products)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$LoadedImpl &&
const DeepCollectionEquality().equals(other._products, _products));
}
@override
int get hashCode =>
Object.hash(runtimeType, const DeepCollectionEquality().hash(_products));
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$LoadedImplCopyWith<_$LoadedImpl> get copyWith =>
__$$LoadedImplCopyWithImpl<_$LoadedImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Product> products) loaded,
required TResult Function(String message) error,
}) {
return loaded(products);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Product> products)? loaded,
TResult? Function(String message)? error,
}) {
return loaded?.call(products);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Product> products)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(products);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class _Loaded implements LocalProductState {
const factory _Loaded(final List<Product> products) = _$LoadedImpl;
List<Product> get products;
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$LoadedImplCopyWith<_$LoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$ErrorImplCopyWith<$Res> {
factory _$$ErrorImplCopyWith(
_$ErrorImpl value, $Res Function(_$ErrorImpl) then) =
__$$ErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String message});
}
/// @nodoc
class __$$ErrorImplCopyWithImpl<$Res>
extends _$LocalProductStateCopyWithImpl<$Res, _$ErrorImpl>
implements _$$ErrorImplCopyWith<$Res> {
__$$ErrorImplCopyWithImpl(
_$ErrorImpl _value, $Res Function(_$ErrorImpl) _then)
: super(_value, _then);
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? message = null,
}) {
return _then(_$ErrorImpl(
null == message
? _value.message
: message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$ErrorImpl implements _Error {
const _$ErrorImpl(this.message);
@override
final String message;
@override
String toString() {
return 'LocalProductState.error(message: $message)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ErrorImpl &&
(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType, message);
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
__$$ErrorImplCopyWithImpl<_$ErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Product> products) loaded,
required TResult Function(String message) error,
}) {
return error(message);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Product> products)? loaded,
TResult? Function(String message)? error,
}) {
return error?.call(message);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Product> products)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(message);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class _Error implements LocalProductState {
const factory _Error(final String message) = _$ErrorImpl;
String get message;
/// Create a copy of LocalProductState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -0,0 +1,7 @@
part of 'local_product_bloc.dart';
@freezed
class LocalProductEvent with _$LocalProductEvent {
const factory LocalProductEvent.started() = _Started;
const factory LocalProductEvent.getLocalProduct() = _GetLocalProduct;
}
@@ -0,0 +1,9 @@
part of 'local_product_bloc.dart';
@freezed
class LocalProductState with _$LocalProductState {
const factory LocalProductState.initial() = _Initial;
const factory LocalProductState.loading() = _Loading;
const factory LocalProductState.loaded(List<Product> products) = _Loaded;
const factory LocalProductState.error(String message) = _Error;
}
@@ -0,0 +1,18 @@
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'online_checker_event.dart';
part 'online_checker_state.dart';
part 'online_checker_bloc.freezed.dart';
class OnlineCheckerBloc extends Bloc<OnlineCheckerEvent, OnlineCheckerState> {
OnlineCheckerBloc() : super(_Initial()) {
on<_Check>((event, emit) {
if (event.isOnline) {
emit(const _Online());
} else {
emit(const _Offline());
}
});
}
}
@@ -0,0 +1,902 @@
// 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 'online_checker_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 _$OnlineCheckerEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(bool isOnline) check,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(bool isOnline)? check,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(bool isOnline)? check,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_Check value) check,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_Check value)? check,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_Check value)? check,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OnlineCheckerEventCopyWith<$Res> {
factory $OnlineCheckerEventCopyWith(
OnlineCheckerEvent value, $Res Function(OnlineCheckerEvent) then) =
_$OnlineCheckerEventCopyWithImpl<$Res, OnlineCheckerEvent>;
}
/// @nodoc
class _$OnlineCheckerEventCopyWithImpl<$Res, $Val extends OnlineCheckerEvent>
implements $OnlineCheckerEventCopyWith<$Res> {
_$OnlineCheckerEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of OnlineCheckerEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$StartedImplCopyWith<$Res> {
factory _$$StartedImplCopyWith(
_$StartedImpl value, $Res Function(_$StartedImpl) then) =
__$$StartedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$StartedImplCopyWithImpl<$Res>
extends _$OnlineCheckerEventCopyWithImpl<$Res, _$StartedImpl>
implements _$$StartedImplCopyWith<$Res> {
__$$StartedImplCopyWithImpl(
_$StartedImpl _value, $Res Function(_$StartedImpl) _then)
: super(_value, _then);
/// Create a copy of OnlineCheckerEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$StartedImpl implements _Started {
const _$StartedImpl();
@override
String toString() {
return 'OnlineCheckerEvent.started()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$StartedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(bool isOnline) check,
}) {
return started();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(bool isOnline)? check,
}) {
return started?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(bool isOnline)? check,
required TResult orElse(),
}) {
if (started != null) {
return started();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_Check value) check,
}) {
return started(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_Check value)? check,
}) {
return started?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_Check value)? check,
required TResult orElse(),
}) {
if (started != null) {
return started(this);
}
return orElse();
}
}
abstract class _Started implements OnlineCheckerEvent {
const factory _Started() = _$StartedImpl;
}
/// @nodoc
abstract class _$$CheckImplCopyWith<$Res> {
factory _$$CheckImplCopyWith(
_$CheckImpl value, $Res Function(_$CheckImpl) then) =
__$$CheckImplCopyWithImpl<$Res>;
@useResult
$Res call({bool isOnline});
}
/// @nodoc
class __$$CheckImplCopyWithImpl<$Res>
extends _$OnlineCheckerEventCopyWithImpl<$Res, _$CheckImpl>
implements _$$CheckImplCopyWith<$Res> {
__$$CheckImplCopyWithImpl(
_$CheckImpl _value, $Res Function(_$CheckImpl) _then)
: super(_value, _then);
/// Create a copy of OnlineCheckerEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? isOnline = null,
}) {
return _then(_$CheckImpl(
null == isOnline
? _value.isOnline
: isOnline // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
class _$CheckImpl implements _Check {
const _$CheckImpl(this.isOnline);
@override
final bool isOnline;
@override
String toString() {
return 'OnlineCheckerEvent.check(isOnline: $isOnline)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CheckImpl &&
(identical(other.isOnline, isOnline) ||
other.isOnline == isOnline));
}
@override
int get hashCode => Object.hash(runtimeType, isOnline);
/// Create a copy of OnlineCheckerEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CheckImplCopyWith<_$CheckImpl> get copyWith =>
__$$CheckImplCopyWithImpl<_$CheckImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(bool isOnline) check,
}) {
return check(isOnline);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(bool isOnline)? check,
}) {
return check?.call(isOnline);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(bool isOnline)? check,
required TResult orElse(),
}) {
if (check != null) {
return check(isOnline);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_Check value) check,
}) {
return check(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_Check value)? check,
}) {
return check?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_Check value)? check,
required TResult orElse(),
}) {
if (check != null) {
return check(this);
}
return orElse();
}
}
abstract class _Check implements OnlineCheckerEvent {
const factory _Check(final bool isOnline) = _$CheckImpl;
bool get isOnline;
/// Create a copy of OnlineCheckerEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CheckImplCopyWith<_$CheckImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$OnlineCheckerState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() online,
required TResult Function() offline,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? online,
TResult? Function()? offline,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? online,
TResult Function()? offline,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Online value) online,
required TResult Function(_Offline value) offline,
required TResult Function(_Error value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Online value)? online,
TResult? Function(_Offline value)? offline,
TResult? Function(_Error value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Online value)? online,
TResult Function(_Offline value)? offline,
TResult Function(_Error value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OnlineCheckerStateCopyWith<$Res> {
factory $OnlineCheckerStateCopyWith(
OnlineCheckerState value, $Res Function(OnlineCheckerState) then) =
_$OnlineCheckerStateCopyWithImpl<$Res, OnlineCheckerState>;
}
/// @nodoc
class _$OnlineCheckerStateCopyWithImpl<$Res, $Val extends OnlineCheckerState>
implements $OnlineCheckerStateCopyWith<$Res> {
_$OnlineCheckerStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$OnlineCheckerStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'OnlineCheckerState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() online,
required TResult Function() offline,
required TResult Function(String message) error,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? online,
TResult? Function()? offline,
TResult? Function(String message)? error,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? online,
TResult Function()? offline,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Online value) online,
required TResult Function(_Offline value) offline,
required TResult Function(_Error value) error,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Online value)? online,
TResult? Function(_Offline value)? offline,
TResult? Function(_Error value)? error,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Online value)? online,
TResult Function(_Offline value)? offline,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements OnlineCheckerState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$OnlineImplCopyWith<$Res> {
factory _$$OnlineImplCopyWith(
_$OnlineImpl value, $Res Function(_$OnlineImpl) then) =
__$$OnlineImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$OnlineImplCopyWithImpl<$Res>
extends _$OnlineCheckerStateCopyWithImpl<$Res, _$OnlineImpl>
implements _$$OnlineImplCopyWith<$Res> {
__$$OnlineImplCopyWithImpl(
_$OnlineImpl _value, $Res Function(_$OnlineImpl) _then)
: super(_value, _then);
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$OnlineImpl implements _Online {
const _$OnlineImpl();
@override
String toString() {
return 'OnlineCheckerState.online()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$OnlineImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() online,
required TResult Function() offline,
required TResult Function(String message) error,
}) {
return online();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? online,
TResult? Function()? offline,
TResult? Function(String message)? error,
}) {
return online?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? online,
TResult Function()? offline,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (online != null) {
return online();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Online value) online,
required TResult Function(_Offline value) offline,
required TResult Function(_Error value) error,
}) {
return online(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Online value)? online,
TResult? Function(_Offline value)? offline,
TResult? Function(_Error value)? error,
}) {
return online?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Online value)? online,
TResult Function(_Offline value)? offline,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (online != null) {
return online(this);
}
return orElse();
}
}
abstract class _Online implements OnlineCheckerState {
const factory _Online() = _$OnlineImpl;
}
/// @nodoc
abstract class _$$OfflineImplCopyWith<$Res> {
factory _$$OfflineImplCopyWith(
_$OfflineImpl value, $Res Function(_$OfflineImpl) then) =
__$$OfflineImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$OfflineImplCopyWithImpl<$Res>
extends _$OnlineCheckerStateCopyWithImpl<$Res, _$OfflineImpl>
implements _$$OfflineImplCopyWith<$Res> {
__$$OfflineImplCopyWithImpl(
_$OfflineImpl _value, $Res Function(_$OfflineImpl) _then)
: super(_value, _then);
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$OfflineImpl implements _Offline {
const _$OfflineImpl();
@override
String toString() {
return 'OnlineCheckerState.offline()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$OfflineImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() online,
required TResult Function() offline,
required TResult Function(String message) error,
}) {
return offline();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? online,
TResult? Function()? offline,
TResult? Function(String message)? error,
}) {
return offline?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? online,
TResult Function()? offline,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (offline != null) {
return offline();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Online value) online,
required TResult Function(_Offline value) offline,
required TResult Function(_Error value) error,
}) {
return offline(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Online value)? online,
TResult? Function(_Offline value)? offline,
TResult? Function(_Error value)? error,
}) {
return offline?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Online value)? online,
TResult Function(_Offline value)? offline,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (offline != null) {
return offline(this);
}
return orElse();
}
}
abstract class _Offline implements OnlineCheckerState {
const factory _Offline() = _$OfflineImpl;
}
/// @nodoc
abstract class _$$ErrorImplCopyWith<$Res> {
factory _$$ErrorImplCopyWith(
_$ErrorImpl value, $Res Function(_$ErrorImpl) then) =
__$$ErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String message});
}
/// @nodoc
class __$$ErrorImplCopyWithImpl<$Res>
extends _$OnlineCheckerStateCopyWithImpl<$Res, _$ErrorImpl>
implements _$$ErrorImplCopyWith<$Res> {
__$$ErrorImplCopyWithImpl(
_$ErrorImpl _value, $Res Function(_$ErrorImpl) _then)
: super(_value, _then);
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? message = null,
}) {
return _then(_$ErrorImpl(
null == message
? _value.message
: message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$ErrorImpl implements _Error {
const _$ErrorImpl(this.message);
@override
final String message;
@override
String toString() {
return 'OnlineCheckerState.error(message: $message)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ErrorImpl &&
(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType, message);
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
__$$ErrorImplCopyWithImpl<_$ErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() online,
required TResult Function() offline,
required TResult Function(String message) error,
}) {
return error(message);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? online,
TResult? Function()? offline,
TResult? Function(String message)? error,
}) {
return error?.call(message);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? online,
TResult Function()? offline,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(message);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Online value) online,
required TResult Function(_Offline value) offline,
required TResult Function(_Error value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Online value)? online,
TResult? Function(_Offline value)? offline,
TResult? Function(_Error value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Online value)? online,
TResult Function(_Offline value)? offline,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class _Error implements OnlineCheckerState {
const factory _Error(final String message) = _$ErrorImpl;
String get message;
/// Create a copy of OnlineCheckerState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -0,0 +1,7 @@
part of 'online_checker_bloc.dart';
@freezed
class OnlineCheckerEvent with _$OnlineCheckerEvent {
const factory OnlineCheckerEvent.started() = _Started;
const factory OnlineCheckerEvent.check(bool isOnline) = _Check;
}
@@ -0,0 +1,9 @@
part of 'online_checker_bloc.dart';
@freezed
class OnlineCheckerState with _$OnlineCheckerState {
const factory OnlineCheckerState.initial() = _Initial;
const factory OnlineCheckerState.online() = _Online;
const factory OnlineCheckerState.offline() = _Offline;
const factory OnlineCheckerState.error(String message) = _Error;
}
@@ -0,0 +1,97 @@
import 'dart:developer';
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import '../../models/order_model.dart';
import '../../models/product_quantity.dart';
import '../../models/order_type.dart';
part 'order_bloc.freezed.dart';
part 'order_event.dart';
part 'order_state.dart';
class OrderBloc extends Bloc<OrderEvent, OrderState> {
final OrderRemoteDatasource orderRemoteDatasource;
OrderBloc(
this.orderRemoteDatasource,
) : super(const _Initial()) {
log("🔧 OrderBloc: Constructor called");
log("🔧 OrderBloc: OrderRemoteDatasource instance: $orderRemoteDatasource");
on<_Order>((event, emit) async {
log("🎯 OrderBloc: Event handler triggered!");
emit(const _Loading());
log("🚀 OrderBloc: Starting order process");
log("📋 Order event received: ${event.toString()}");
log("Start 1");
final subTotal = event.items.fold<int>(
0,
(previousValue, element) =>
previousValue +
(element.product.price!.toIntegerFromText * element.quantity));
// final total = subTotal + event.tax + event.serviceCharge - event.discount;
final totalItem = event.items.fold<int>(
0, (previousValue, element) => previousValue + element.quantity);
final userData = await AuthLocalDataSource().getAuthData();
final dataInput = OrderModel(
subTotal: subTotal,
paymentAmount: event.paymentAmount,
tax: event.tax,
discount: event.discount,
discountAmount: event.discountAmount,
serviceCharge: event.serviceCharge,
total: event.totalPriceFinal,
paymentMethod: event.paymentMethod,
totalItem: totalItem,
idKasir: userData.user?.id ?? 1,
namaKasir: userData.user?.name ?? 'Kasir A',
transactionTime: DateTime.now().toIso8601String(),
customerName: event.customerName,
tableNumber: event.tableNumber,
status: event.status,
paymentStatus: event.paymentStatus,
isSync: 0,
orderItems: event.items,
orderType: event.orderType,
);
log("Start 2");
//check state online or offline
log("🔄 About to call API to save order...");
log("📤 Order data being sent to API: ${dataInput.toServerMap()}");
log("🌐 OrderRemoteDatasource instance: $orderRemoteDatasource");
bool value = false;
try {
value = await orderRemoteDatasource.saveOrder(dataInput);
log("📥 API response received: $value");
} catch (e) {
log("💥 Error calling API: $e");
value = false;
}
int id = 0;
if (value) {
id = await ProductLocalDatasource.instance
.saveOrder(dataInput.copyWith(isSync: 1));
} else {
id = await ProductLocalDatasource.instance
.saveOrder(dataInput.copyWith(isSync: 1));
}
emit(_Loaded(
dataInput,
id,
));
});
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
part of 'order_bloc.dart';
@freezed
class OrderEvent with _$OrderEvent {
const factory OrderEvent.started() = _Started;
const factory OrderEvent.order(
List<ProductQuantity> items,
int discount,
int discountAmount,
int tax,
int serviceCharge,
int paymentAmount,
String customerName,
int tableNumber,
String status,
String paymentStatus,
String paymentMethod,
int totalPriceFinal,
OrderType orderType,
) = _Order;
}
@@ -0,0 +1,9 @@
part of 'order_bloc.dart';
@freezed
class OrderState with _$OrderState {
const factory OrderState.initial() = _Initial;
const factory OrderState.loading() = _Loading;
const factory OrderState.loaded(OrderModel orderModel, int orderId) = _Loaded;
const factory OrderState.error(String message) = _Error;
}
@@ -0,0 +1,24 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:enaklo_pos/data/datasources/payment_methods_remote_datasource.dart';
import 'package:enaklo_pos/data/models/response/payment_methods_response_model.dart';
part 'payment_methods_event.dart';
part 'payment_methods_state.dart';
part 'payment_methods_bloc.freezed.dart';
class PaymentMethodsBloc extends Bloc<PaymentMethodsEvent, PaymentMethodsState> {
final PaymentMethodsRemoteDatasource datasource;
PaymentMethodsBloc(this.datasource) : super(const _Initial()) {
on<_FetchPaymentMethods>((event, emit) async {
emit(const _Loading());
final response = await datasource.getPaymentMethods();
response.fold(
(l) => emit(_Error(l)),
(r) => emit(_Loaded(r.data ?? [])),
);
});
}
}
@@ -0,0 +1,794 @@
// 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 'payment_methods_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 _$PaymentMethodsEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchPaymentMethods,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchPaymentMethods,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchPaymentMethods,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchPaymentMethods value) fetchPaymentMethods,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchPaymentMethods value)? fetchPaymentMethods,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchPaymentMethods value)? fetchPaymentMethods,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PaymentMethodsEventCopyWith<$Res> {
factory $PaymentMethodsEventCopyWith(
PaymentMethodsEvent value, $Res Function(PaymentMethodsEvent) then) =
_$PaymentMethodsEventCopyWithImpl<$Res, PaymentMethodsEvent>;
}
/// @nodoc
class _$PaymentMethodsEventCopyWithImpl<$Res, $Val extends PaymentMethodsEvent>
implements $PaymentMethodsEventCopyWith<$Res> {
_$PaymentMethodsEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of PaymentMethodsEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$FetchPaymentMethodsImplCopyWith<$Res> {
factory _$$FetchPaymentMethodsImplCopyWith(_$FetchPaymentMethodsImpl value,
$Res Function(_$FetchPaymentMethodsImpl) then) =
__$$FetchPaymentMethodsImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$FetchPaymentMethodsImplCopyWithImpl<$Res>
extends _$PaymentMethodsEventCopyWithImpl<$Res, _$FetchPaymentMethodsImpl>
implements _$$FetchPaymentMethodsImplCopyWith<$Res> {
__$$FetchPaymentMethodsImplCopyWithImpl(_$FetchPaymentMethodsImpl _value,
$Res Function(_$FetchPaymentMethodsImpl) _then)
: super(_value, _then);
/// Create a copy of PaymentMethodsEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$FetchPaymentMethodsImpl implements _FetchPaymentMethods {
const _$FetchPaymentMethodsImpl();
@override
String toString() {
return 'PaymentMethodsEvent.fetchPaymentMethods()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$FetchPaymentMethodsImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() fetchPaymentMethods,
}) {
return fetchPaymentMethods();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? fetchPaymentMethods,
}) {
return fetchPaymentMethods?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? fetchPaymentMethods,
required TResult orElse(),
}) {
if (fetchPaymentMethods != null) {
return fetchPaymentMethods();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_FetchPaymentMethods value) fetchPaymentMethods,
}) {
return fetchPaymentMethods(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_FetchPaymentMethods value)? fetchPaymentMethods,
}) {
return fetchPaymentMethods?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_FetchPaymentMethods value)? fetchPaymentMethods,
required TResult orElse(),
}) {
if (fetchPaymentMethods != null) {
return fetchPaymentMethods(this);
}
return orElse();
}
}
abstract class _FetchPaymentMethods implements PaymentMethodsEvent {
const factory _FetchPaymentMethods() = _$FetchPaymentMethodsImpl;
}
/// @nodoc
mixin _$PaymentMethodsState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<PaymentMethod> paymentMethods) loaded,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<PaymentMethod> paymentMethods)? loaded,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<PaymentMethod> paymentMethods)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PaymentMethodsStateCopyWith<$Res> {
factory $PaymentMethodsStateCopyWith(
PaymentMethodsState value, $Res Function(PaymentMethodsState) then) =
_$PaymentMethodsStateCopyWithImpl<$Res, PaymentMethodsState>;
}
/// @nodoc
class _$PaymentMethodsStateCopyWithImpl<$Res, $Val extends PaymentMethodsState>
implements $PaymentMethodsStateCopyWith<$Res> {
_$PaymentMethodsStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$PaymentMethodsStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'PaymentMethodsState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<PaymentMethod> paymentMethods) loaded,
required TResult Function(String message) error,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<PaymentMethod> paymentMethods)? loaded,
TResult? Function(String message)? error,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<PaymentMethod> paymentMethods)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements PaymentMethodsState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
factory _$$LoadingImplCopyWith(
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
__$$LoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
extends _$PaymentMethodsStateCopyWithImpl<$Res, _$LoadingImpl>
implements _$$LoadingImplCopyWith<$Res> {
__$$LoadingImplCopyWithImpl(
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
: super(_value, _then);
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$LoadingImpl implements _Loading {
const _$LoadingImpl();
@override
String toString() {
return 'PaymentMethodsState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$LoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<PaymentMethod> paymentMethods) loaded,
required TResult Function(String message) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<PaymentMethod> paymentMethods)? loaded,
TResult? Function(String message)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<PaymentMethod> paymentMethods)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class _Loading implements PaymentMethodsState {
const factory _Loading() = _$LoadingImpl;
}
/// @nodoc
abstract class _$$LoadedImplCopyWith<$Res> {
factory _$$LoadedImplCopyWith(
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
__$$LoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({List<PaymentMethod> paymentMethods});
}
/// @nodoc
class __$$LoadedImplCopyWithImpl<$Res>
extends _$PaymentMethodsStateCopyWithImpl<$Res, _$LoadedImpl>
implements _$$LoadedImplCopyWith<$Res> {
__$$LoadedImplCopyWithImpl(
_$LoadedImpl _value, $Res Function(_$LoadedImpl) _then)
: super(_value, _then);
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? paymentMethods = null,
}) {
return _then(_$LoadedImpl(
null == paymentMethods
? _value._paymentMethods
: paymentMethods // ignore: cast_nullable_to_non_nullable
as List<PaymentMethod>,
));
}
}
/// @nodoc
class _$LoadedImpl implements _Loaded {
const _$LoadedImpl(final List<PaymentMethod> paymentMethods)
: _paymentMethods = paymentMethods;
final List<PaymentMethod> _paymentMethods;
@override
List<PaymentMethod> get paymentMethods {
if (_paymentMethods is EqualUnmodifiableListView) return _paymentMethods;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_paymentMethods);
}
@override
String toString() {
return 'PaymentMethodsState.loaded(paymentMethods: $paymentMethods)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$LoadedImpl &&
const DeepCollectionEquality()
.equals(other._paymentMethods, _paymentMethods));
}
@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(_paymentMethods));
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$LoadedImplCopyWith<_$LoadedImpl> get copyWith =>
__$$LoadedImplCopyWithImpl<_$LoadedImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<PaymentMethod> paymentMethods) loaded,
required TResult Function(String message) error,
}) {
return loaded(paymentMethods);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<PaymentMethod> paymentMethods)? loaded,
TResult? Function(String message)? error,
}) {
return loaded?.call(paymentMethods);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<PaymentMethod> paymentMethods)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(paymentMethods);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class _Loaded implements PaymentMethodsState {
const factory _Loaded(final List<PaymentMethod> paymentMethods) =
_$LoadedImpl;
List<PaymentMethod> get paymentMethods;
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$LoadedImplCopyWith<_$LoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$ErrorImplCopyWith<$Res> {
factory _$$ErrorImplCopyWith(
_$ErrorImpl value, $Res Function(_$ErrorImpl) then) =
__$$ErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String message});
}
/// @nodoc
class __$$ErrorImplCopyWithImpl<$Res>
extends _$PaymentMethodsStateCopyWithImpl<$Res, _$ErrorImpl>
implements _$$ErrorImplCopyWith<$Res> {
__$$ErrorImplCopyWithImpl(
_$ErrorImpl _value, $Res Function(_$ErrorImpl) _then)
: super(_value, _then);
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? message = null,
}) {
return _then(_$ErrorImpl(
null == message
? _value.message
: message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$ErrorImpl implements _Error {
const _$ErrorImpl(this.message);
@override
final String message;
@override
String toString() {
return 'PaymentMethodsState.error(message: $message)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ErrorImpl &&
(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType, message);
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
__$$ErrorImplCopyWithImpl<_$ErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<PaymentMethod> paymentMethods) loaded,
required TResult Function(String message) error,
}) {
return error(message);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<PaymentMethod> paymentMethods)? loaded,
TResult? Function(String message)? error,
}) {
return error?.call(message);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<PaymentMethod> paymentMethods)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(message);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class _Error implements PaymentMethodsState {
const factory _Error(final String message) = _$ErrorImpl;
String get message;
/// Create a copy of PaymentMethodsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}
@@ -0,0 +1,6 @@
part of 'payment_methods_bloc.dart';
@freezed
class PaymentMethodsEvent with _$PaymentMethodsEvent {
const factory PaymentMethodsEvent.fetchPaymentMethods() = _FetchPaymentMethods;
}
@@ -0,0 +1,9 @@
part of 'payment_methods_bloc.dart';
@freezed
class PaymentMethodsState with _$PaymentMethodsState {
const factory PaymentMethodsState.initial() = _Initial;
const factory PaymentMethodsState.loading() = _Loading;
const factory PaymentMethodsState.loaded(List<PaymentMethod> paymentMethods) = _Loaded;
const factory PaymentMethodsState.error(String message) = _Error;
}
@@ -0,0 +1,38 @@
import 'dart:async';
import 'dart:developer';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/datasources/midtrans_remote_datasource.dart';
import 'package:enaklo_pos/data/models/response/qris_response_model.dart';
import 'package:enaklo_pos/data/models/response/qris_status_response_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'qris_event.dart';
part 'qris_state.dart';
part 'qris_bloc.freezed.dart';
class QrisBloc extends Bloc<QrisEvent, QrisState> {
final MidtransRemoteDatasource datasource;
QrisBloc(
this.datasource,
) : super(const _Initial()) {
on<_GenerateQRCode>((event, emit) async {
emit(const QrisState.loading());
final response =
await datasource.generateQRCode(event.orderId, event.grossAmount);
log("response: ${response}");
emit(_QrisResponse(response));
});
on<_CheckPaymentStatus>((event, emit) async {
// emit(const QrisState.loading());
final response = await datasource.checkPaymentStatus(event.orderId);
log(" OrderID: ${event.orderId} | response: ${response}");
// Future.delayed(const Duration(seconds: 5));
// emit(QrisState.statusCheck(response));
if (response.transactionStatus == 'settlement') {
emit(_Success('Pembayaran Berhasil'));
}
});
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,13 @@
part of 'qris_bloc.dart';
@freezed
class QrisEvent with _$QrisEvent {
const factory QrisEvent.started() = _Started;
//generateQRCode
const factory QrisEvent.generateQRCode(String orderId, int grossAmount) =
_GenerateQRCode;
//checkPaymentStatus
const factory QrisEvent.checkPaymentStatus(String orderId) =
_CheckPaymentStatus;
}
@@ -0,0 +1,13 @@
part of 'qris_bloc.dart';
@freezed
class QrisState with _$QrisState {
const factory QrisState.initial() = _Initial;
const factory QrisState.loading() = _Loading;
const factory QrisState.qrisResponse(QrisResponseModel qrisResponseModel) =
_QrisResponse;
const factory QrisState.success(String message) = _Success;
const factory QrisState.error(String message) = _Error;
const factory QrisState.statusCheck(
QrisStatusResponseModel qrisStatusResponseModel) = _StatusCheck;
}
@@ -0,0 +1,19 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:enaklo_pos/data/models/response/table_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'status_table_event.dart';
part 'status_table_state.dart';
part 'status_table_bloc.freezed.dart';
class StatusTableBloc extends Bloc<StatusTableEvent, StatusTableState> {
final ProductLocalDatasource datasource;
StatusTableBloc(this.datasource) : super(StatusTableState.initial()) {
on<_StatusTable>((event, emit) async {
emit(_Loading());
await datasource.updateStatusTable(event.table);
emit(_Success());
});
}
}
@@ -0,0 +1,725 @@
// 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 'status_table_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 _$StatusTableEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(TableModel table) statusTabel,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(TableModel table)? statusTabel,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(TableModel table)? statusTabel,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_StatusTable value) statusTabel,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_StatusTable value)? statusTabel,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_StatusTable value)? statusTabel,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $StatusTableEventCopyWith<$Res> {
factory $StatusTableEventCopyWith(
StatusTableEvent value, $Res Function(StatusTableEvent) then) =
_$StatusTableEventCopyWithImpl<$Res, StatusTableEvent>;
}
/// @nodoc
class _$StatusTableEventCopyWithImpl<$Res, $Val extends StatusTableEvent>
implements $StatusTableEventCopyWith<$Res> {
_$StatusTableEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of StatusTableEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$StartedImplCopyWith<$Res> {
factory _$$StartedImplCopyWith(
_$StartedImpl value, $Res Function(_$StartedImpl) then) =
__$$StartedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$StartedImplCopyWithImpl<$Res>
extends _$StatusTableEventCopyWithImpl<$Res, _$StartedImpl>
implements _$$StartedImplCopyWith<$Res> {
__$$StartedImplCopyWithImpl(
_$StartedImpl _value, $Res Function(_$StartedImpl) _then)
: super(_value, _then);
/// Create a copy of StatusTableEvent
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$StartedImpl implements _Started {
const _$StartedImpl();
@override
String toString() {
return 'StatusTableEvent.started()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$StartedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(TableModel table) statusTabel,
}) {
return started();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(TableModel table)? statusTabel,
}) {
return started?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(TableModel table)? statusTabel,
required TResult orElse(),
}) {
if (started != null) {
return started();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_StatusTable value) statusTabel,
}) {
return started(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_StatusTable value)? statusTabel,
}) {
return started?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_StatusTable value)? statusTabel,
required TResult orElse(),
}) {
if (started != null) {
return started(this);
}
return orElse();
}
}
abstract class _Started implements StatusTableEvent {
const factory _Started() = _$StartedImpl;
}
/// @nodoc
abstract class _$$StatusTableImplCopyWith<$Res> {
factory _$$StatusTableImplCopyWith(
_$StatusTableImpl value, $Res Function(_$StatusTableImpl) then) =
__$$StatusTableImplCopyWithImpl<$Res>;
@useResult
$Res call({TableModel table});
}
/// @nodoc
class __$$StatusTableImplCopyWithImpl<$Res>
extends _$StatusTableEventCopyWithImpl<$Res, _$StatusTableImpl>
implements _$$StatusTableImplCopyWith<$Res> {
__$$StatusTableImplCopyWithImpl(
_$StatusTableImpl _value, $Res Function(_$StatusTableImpl) _then)
: super(_value, _then);
/// Create a copy of StatusTableEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? table = null,
}) {
return _then(_$StatusTableImpl(
null == table
? _value.table
: table // ignore: cast_nullable_to_non_nullable
as TableModel,
));
}
}
/// @nodoc
class _$StatusTableImpl implements _StatusTable {
const _$StatusTableImpl(this.table);
@override
final TableModel table;
@override
String toString() {
return 'StatusTableEvent.statusTabel(table: $table)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$StatusTableImpl &&
(identical(other.table, table) || other.table == table));
}
@override
int get hashCode => Object.hash(runtimeType, table);
/// Create a copy of StatusTableEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$StatusTableImplCopyWith<_$StatusTableImpl> get copyWith =>
__$$StatusTableImplCopyWithImpl<_$StatusTableImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() started,
required TResult Function(TableModel table) statusTabel,
}) {
return statusTabel(table);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? started,
TResult? Function(TableModel table)? statusTabel,
}) {
return statusTabel?.call(table);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? started,
TResult Function(TableModel table)? statusTabel,
required TResult orElse(),
}) {
if (statusTabel != null) {
return statusTabel(table);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Started value) started,
required TResult Function(_StatusTable value) statusTabel,
}) {
return statusTabel(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Started value)? started,
TResult? Function(_StatusTable value)? statusTabel,
}) {
return statusTabel?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Started value)? started,
TResult Function(_StatusTable value)? statusTabel,
required TResult orElse(),
}) {
if (statusTabel != null) {
return statusTabel(this);
}
return orElse();
}
}
abstract class _StatusTable implements StatusTableEvent {
const factory _StatusTable(final TableModel table) = _$StatusTableImpl;
TableModel get table;
/// Create a copy of StatusTableEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$StatusTableImplCopyWith<_$StatusTableImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$StatusTableState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $StatusTableStateCopyWith<$Res> {
factory $StatusTableStateCopyWith(
StatusTableState value, $Res Function(StatusTableState) then) =
_$StatusTableStateCopyWithImpl<$Res, StatusTableState>;
}
/// @nodoc
class _$StatusTableStateCopyWithImpl<$Res, $Val extends StatusTableState>
implements $StatusTableStateCopyWith<$Res> {
_$StatusTableStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of StatusTableState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$StatusTableStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of StatusTableState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'StatusTableState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements StatusTableState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
factory _$$LoadingImplCopyWith(
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
__$$LoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
extends _$StatusTableStateCopyWithImpl<$Res, _$LoadingImpl>
implements _$$LoadingImplCopyWith<$Res> {
__$$LoadingImplCopyWithImpl(
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
: super(_value, _then);
/// Create a copy of StatusTableState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$LoadingImpl implements _Loading {
const _$LoadingImpl();
@override
String toString() {
return 'StatusTableState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$LoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class _Loading implements StatusTableState {
const factory _Loading() = _$LoadingImpl;
}
/// @nodoc
abstract class _$$SuccessImplCopyWith<$Res> {
factory _$$SuccessImplCopyWith(
_$SuccessImpl value, $Res Function(_$SuccessImpl) then) =
__$$SuccessImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SuccessImplCopyWithImpl<$Res>
extends _$StatusTableStateCopyWithImpl<$Res, _$SuccessImpl>
implements _$$SuccessImplCopyWith<$Res> {
__$$SuccessImplCopyWithImpl(
_$SuccessImpl _value, $Res Function(_$SuccessImpl) _then)
: super(_value, _then);
/// Create a copy of StatusTableState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SuccessImpl implements _Success {
const _$SuccessImpl();
@override
String toString() {
return 'StatusTableState.success()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$SuccessImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function() success,
}) {
return success();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function()? success,
}) {
return success?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function()? success,
required TResult orElse(),
}) {
if (success != null) {
return success();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Success value) success,
}) {
return success(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Success value)? success,
}) {
return success?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Success value)? success,
required TResult orElse(),
}) {
if (success != null) {
return success(this);
}
return orElse();
}
}
abstract class _Success implements StatusTableState {
const factory _Success() = _$SuccessImpl;
}
@@ -0,0 +1,9 @@
part of 'status_table_bloc.dart';
@freezed
class StatusTableEvent with _$StatusTableEvent {
const factory StatusTableEvent.started() = _Started;
const factory StatusTableEvent.statusTabel(
TableModel table,
) = _StatusTable;
}
@@ -0,0 +1,8 @@
part of 'status_table_bloc.dart';
@freezed
class StatusTableState with _$StatusTableState {
const factory StatusTableState.initial() = _Initial;
const factory StatusTableState.loading() = _Loading;
const factory StatusTableState.success() = _Success;
}
@@ -0,0 +1,98 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/presentation/home/bloc/checkout/checkout_bloc.dart';
import '../../../core/constants/colors.dart';
import '../../setting/bloc/discount/discount_bloc.dart';
class DiscountDialog extends StatefulWidget {
const DiscountDialog({super.key});
@override
State<DiscountDialog> createState() => _DiscountDialogState();
}
class _DiscountDialogState extends State<DiscountDialog> {
@override
void initState() {
context.read<DiscountBloc>().add(const DiscountEvent.getDiscounts());
super.initState();
}
int discountIdSelected = 0;
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Stack(
alignment: Alignment.center,
children: [
const Text(
'DISKON',
style: TextStyle(
color: AppColors.primary,
fontSize: 28,
fontWeight: FontWeight.w600,
),
),
Align(
alignment: Alignment.centerRight,
child: IconButton(
onPressed: () {
context.pop();
},
icon: const Icon(
Icons.cancel,
color: AppColors.primary,
size: 30.0,
),
),
),
],
),
content: BlocBuilder<DiscountBloc, DiscountState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => const SizedBox.shrink(),
loading: () => const Center(
child: CircularProgressIndicator(),
),
loaded: (discounts) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: discounts
.map(
(discount) => ListTile(
title: Text('Nama Diskon: ${discount.name}'),
subtitle: Text('Potongan harga (${discount.value}%)'),
contentPadding: EdgeInsets.zero,
textColor: AppColors.primary,
trailing: Checkbox(
value: discount.id == discountIdSelected,
onChanged: (value) {
setState(() {
discountIdSelected = discount.id!;
context.read<CheckoutBloc>().add(
CheckoutEvent.addDiscount(
discount,
),
);
});
},
),
onTap: () {
// context.pop();
},
),
)
.toList(),
);
},
);
},
),
);
}
}
@@ -0,0 +1,282 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
import 'package:intl/intl.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/presentation/home/bloc/qris/qris_bloc.dart';
import 'package:enaklo_pos/presentation/home/widgets/success_payment_dialog.dart';
import 'package:enaklo_pos/presentation/setting/bloc/sync_order/sync_order_bloc.dart';
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import 'package:widgets_to_image/widgets_to_image.dart';
import 'package:enaklo_pos/core/utils/printer_service.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
import '../bloc/order/order_bloc.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
class PaymentQrisDialog extends StatefulWidget {
final List<ProductQuantity> items;
final int discount;
final int discountAmount;
final int tax;
final int serviceCharge;
final int paymentAmount;
final String customerName;
final int tableNumber;
final String status;
final String paymentStatus;
final String paymentMethod;
final int price;
final int totalQty;
final int subTotal;
final bool? isTablePaymentPage;
const PaymentQrisDialog({
super.key,
required this.items,
required this.discount,
required this.discountAmount,
required this.tax,
required this.serviceCharge,
required this.paymentAmount,
required this.customerName,
required this.tableNumber,
required this.status,
required this.paymentStatus,
required this.paymentMethod,
required this.price,
required this.totalQty,
required this.subTotal,
this.isTablePaymentPage = false,
});
@override
State<PaymentQrisDialog> createState() => _PaymentQrisDialogState();
}
class _PaymentQrisDialogState extends State<PaymentQrisDialog> {
String orderId = '';
Timer? timer;
WidgetsToImageController controller = WidgetsToImageController();
@override
void initState() {
orderId = DateTime.now().millisecondsSinceEpoch.toString();
context.read<QrisBloc>().add(QrisEvent.generateQRCode(
orderId,
widget.price,
));
super.initState();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
scrollable: true,
contentPadding: const EdgeInsets.all(0),
backgroundColor: AppColors.primary,
content: SizedBox(
width: context.deviceWidth * 0.4,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Padding(
padding: EdgeInsets.all(12.0),
child: Text(
'Pembayaran QRIS',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontFamily: 'Quicksand',
fontWeight: FontWeight.w700,
height: 0,
),
),
),
const SpaceHeight(6.0),
Container(
width: context.deviceWidth,
padding: const EdgeInsets.all(14.0),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
color: AppColors.white,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
BlocListener<QrisBloc, QrisState>(
listener: (context, state) {
state.maybeWhen(orElse: () {
return;
}, qrisResponse: (data) {
const onSec = Duration(seconds: 5);
timer = Timer.periodic(onSec, (timer) {
context
.read<QrisBloc>()
.add(QrisEvent.checkPaymentStatus(
orderId.toString(),
));
});
}, success: (message) async {
context.read<OrderBloc>().add(OrderEvent.order(
widget.items,
widget.discount,
widget.discountAmount,
widget.tax,
widget.serviceCharge,
widget.paymentAmount,
widget.customerName,
widget.tableNumber,
'completed',
'paid',
'Qris',
widget.price,
OrderType.dineIn));
await showDialog(
context: context,
barrierDismissible: false,
builder: (context) => SuccessPaymentDialog(
isTablePaymentPage: widget.isTablePaymentPage,
data: widget.items,
totalQty: widget.totalQty,
totalPrice: widget.price,
totalTax: widget.tax,
totalDiscount: widget.discountAmount,
subTotal: widget.subTotal,
normalPrice: widget.price,
totalService: widget.serviceCharge,
draftName: widget.customerName,
),
);
});
},
child: BlocBuilder<QrisBloc, QrisState>(
builder: (context, state) {
log('state: $state');
return state.maybeWhen(
orElse: () {
return const SizedBox();
},
qrisResponse: (data) {
log("URL: ${data.actions!.first.url!}");
return WidgetsToImage(
controller: controller,
child: Container(
width: 340.0,
// height: 256.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
),
child: Column(
children: [
Center(
child: Image.network(
data.actions!.first.url!,
),
),
// const SpaceHeight(5.0),
Text(
NumberFormat.currency(
locale: 'id',
symbol: 'Rp ',
).format(widget.price),
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
],
),
),
);
},
loading: () {
return Container(
width: 256.0,
height: 256.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white,
),
child: const Center(
child: CircularProgressIndicator(
color: AppColors.white,
),
),
);
},
);
},
),
),
const SpaceHeight(12.0),
const Text(
'Scan QRIS to make payment',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
),
),
const SpaceHeight(12.0),
//button print qr
ElevatedButton(
onPressed: () async {
try {
final sizeReceipt = await AuthLocalDataSource().getSizeReceipt();
final bytes = await controller.capture();
final printValue = await PrintDataoutputs.instance
.printQRIS(widget.price, bytes!, int.parse(sizeReceipt));
// Get the receipt printer to print QRIS
final receiptPrinter = await ProductLocalDatasource.instance
.getPrinterByCode('receipt');
if (receiptPrinter != null) {
await PrinterService().printWithPrinter(
receiptPrinter,
printValue,
context
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('No receipt printer configured')),
);
}
} catch (e) {
log("Error printing QRIS: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing QRIS: $e')),
);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
child: const Text(
'Print QRIS',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
],
),
),
],
),
),
);
}
}
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/presentation/home/bloc/checkout/checkout_bloc.dart';
import '../../../core/constants/colors.dart';
class ServiceDialog extends StatelessWidget {
const ServiceDialog({super.key});
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Stack(
alignment: Alignment.center,
children: [
const Text(
'LAYANAN',
style: TextStyle(
color: AppColors.primary,
fontSize: 28,
fontWeight: FontWeight.w600,
),
),
Align(
alignment: Alignment.centerRight,
child: IconButton(
onPressed: () => context.pop(),
icon: const Icon(
Icons.cancel,
color: AppColors.primary,
size: 30.0,
),
),
),
],
),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
return state.maybeWhen(
initial: () => const SizedBox(),
loading: () => const Center(child: CircularProgressIndicator()),
loaded: (data, a, b, c, d, service, e, f, g, orderType) => ListTile(
title: Text('Presentase ($service%)'),
subtitle: const Text('Biaya layanan'),
contentPadding: EdgeInsets.zero,
textColor: AppColors.primary,
trailing: Checkbox(
value: service > 0,
onChanged: (value) {
context.read<CheckoutBloc>().add(
CheckoutEvent.addServiceCharge(service > 0 ? 0 : service),
);
},
),
onTap: () {
context.pop();
},
),
orElse: () => const SizedBox(),
);
},
),
],
),
);
}
}
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import '../../../core/constants/colors.dart';
import '../bloc/checkout/checkout_bloc.dart';
class TaxDialog extends StatelessWidget {
const TaxDialog({super.key});
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Stack(
alignment: Alignment.center,
children: [
const Text(
'PAJAK PB1',
style: TextStyle(
color: AppColors.primary,
fontSize: 28,
fontWeight: FontWeight.w600,
),
),
Align(
alignment: Alignment.centerRight,
child: IconButton(
onPressed: () => context.pop(),
icon: const Icon(
Icons.cancel,
color: AppColors.primary,
size: 30.0,
),
),
),
],
),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
return state.maybeWhen(
initial: () => const SizedBox(),
loading: () => const Center(child: CircularProgressIndicator()),
loaded: (data, a, b, c, tax, d, e, f, g, orderType) => ListTile(
title: const Text('PB1'),
subtitle: Text('tarif pajak ($tax%)'),
contentPadding: EdgeInsets.zero,
textColor: AppColors.primary,
trailing: Checkbox(
value: tax > 0,
onChanged: (value) {
context.read<CheckoutBloc>().add(
CheckoutEvent.addTax(tax > 0 ? 0 : tax),
);
},
),
onTap: () {
context.pop();
},
),
orElse: () => const SizedBox(),
);
},
),
],
),
);
}
}
@@ -0,0 +1,31 @@
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
import 'product_model.dart';
class OrderItem {
final Product product;
int quantity;
OrderItem({
required this.product,
required this.quantity,
});
factory OrderItem.fromMap(Map<String, dynamic> map) {
return OrderItem(
product: Product.fromMap(map['product']),
quantity: map['quantity']?.toInt() ?? 0,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is OrderItem &&
other.product == product &&
other.quantity == quantity;
}
@override
int get hashCode => product.hashCode ^ quantity.hashCode;
}
@@ -0,0 +1,211 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// sub_total INTEGER,
// tax INTEGER,
// discount INTEGER,
// service_charge INTEGER,
// total INTEGER,
// payment_method TEXT,
// total_item INTEGER,
// id_kasir INTEGER,
// nama_kasir TEXT,
// transaction_time TEXT,
// is_sync INTEGER DEFAULT 0
class OrderModel {
final int? id;
//payment_amount
final int paymentAmount;
final int subTotal;
final int tax;
final int discount;
final int discountAmount;
final int serviceCharge;
final int total;
final String paymentMethod;
final int totalItem;
final int idKasir;
final String namaKasir;
final String transactionTime;
final String customerName;
final int tableNumber;
final String status;
final String paymentStatus;
final int isSync;
final List<ProductQuantity> orderItems;
final OrderType orderType;
OrderModel({
this.id,
required this.paymentAmount,
required this.subTotal,
required this.tax,
required this.discount,
required this.discountAmount,
required this.serviceCharge,
required this.total,
required this.paymentMethod,
required this.totalItem,
required this.idKasir,
required this.namaKasir,
required this.transactionTime,
required this.customerName,
required this.tableNumber,
required this.status,
required this.paymentStatus,
required this.isSync,
required this.orderItems,
this.orderType = OrderType.dineIn,
});
// 'payment_amount' => 'required',
// 'sub_total' => 'required',
// 'tax' => 'required',
// 'discount' => 'required',
// 'service_charge' => 'required',
// 'total' => 'required',
// 'payment_method' => 'required',
// 'total_item' => 'required',
// 'id_kasir' => 'required',
// 'nama_kasir' => 'required',
// 'transaction_time' => 'required',
// 'order_items' => 'required'
Map<String, dynamic> toServerMap() {
return {
'payment_amount': paymentAmount,
'sub_total': subTotal,
'tax': tax,
'discount': discount,
'discount_amount': discountAmount,
'service_charge': serviceCharge,
'total': total,
'payment_method': paymentMethod,
'total_item': totalItem,
'id_kasir': idKasir,
'nama_kasir': namaKasir,
'customer_name': customerName,
'table_number': tableNumber,
'status': status,
'payment_status': paymentStatus,
'transaction_time': transactionTime,
'order_type': orderType.value,
'order_items': orderItems.map((e) => e.toServerMap(id)).toList(),
};
}
Map<String, dynamic> toMap({bool includeOrderType = true}) {
final map = {
// 'id': id,
'payment_amount': paymentAmount,
'sub_total': subTotal,
'tax': tax,
'discount': discount,
'discount_amount': discountAmount,
'service_charge': serviceCharge,
'total': total,
'payment_method': paymentMethod,
'total_item': totalItem,
'id_kasir': 1,
'nama_kasir': 'Kasir',
'transaction_time': transactionTime,
'customer_name': customerName,
'table_number': tableNumber,
'status': status,
'payment_status': paymentStatus,
'is_sync': isSync,
};
if (includeOrderType) {
map['order_type'] = orderType.value;
}
return map;
}
factory OrderModel.fromMap(Map<String, dynamic> map) {
print("Discount AMount${map['discount_amount']}");
return OrderModel(
id: map['id']?.toInt(),
paymentAmount: map['payment_amount']?.toInt() ?? 0,
subTotal: map['sub_total']?.toInt() ?? 0,
tax: map['tax']?.toInt() ?? 0,
discount: map['discount']?.toInt() ?? 0,
discountAmount: map['discount_amount']?.toInt() ?? 0,
serviceCharge: map['service_charge']?.toInt() ?? 0,
total: map['total']?.toInt() ?? 0,
paymentMethod: map['payment_method'] ?? '',
totalItem: map['total_item']?.toInt() ?? 0,
idKasir: map['id_kasir']?.toInt() ?? 0,
namaKasir: map['nama_kasir'] ?? '',
transactionTime: map['transaction_time'] ?? '',
isSync: map['is_sync']?.toInt() ?? 0,
customerName: map['customer_name'] ?? '',
tableNumber: map['table_number']?.toInt() ?? 0,
status: map['status'] ?? '',
paymentStatus: map['payment_status'] ?? '',
orderType: OrderType.fromString(map['order_type'] ?? 'DINE IN'),
orderItems: [],
);
}
String toJson() => json.encode(toServerMap());
factory OrderModel.fromJson(String source) =>
OrderModel.fromMap(json.decode(source));
OrderModel copyWith({
int? id,
int? paymentAmount,
int? subTotal,
int? tax,
int? discount,
int? discountAmount,
int? serviceCharge,
int? total,
String? paymentMethod,
int? totalItem,
int? idKasir,
String? namaKasir,
String? transactionTime,
String? customerName,
int? tableNumber,
String? status,
String? paymentStatus,
int? isSync,
List<ProductQuantity>? orderItems,
OrderType? orderType,
}) {
return OrderModel(
id: id ?? this.id,
paymentAmount: paymentAmount ?? this.paymentAmount,
subTotal: subTotal ?? this.subTotal,
tax: tax ?? this.tax,
discount: discount ?? this.discount,
discountAmount: discountAmount ?? this.discountAmount,
serviceCharge: serviceCharge ?? this.serviceCharge,
total: total ?? this.total,
paymentMethod: paymentMethod ?? this.paymentMethod,
totalItem: totalItem ?? this.totalItem,
idKasir: idKasir ?? this.idKasir,
namaKasir: namaKasir ?? this.namaKasir,
transactionTime: transactionTime ?? this.transactionTime,
customerName: customerName ?? this.customerName,
tableNumber: tableNumber ?? this.tableNumber,
status: status ?? this.status,
paymentStatus: paymentStatus ?? this.paymentStatus,
isSync: isSync ?? this.isSync,
orderItems: orderItems ?? this.orderItems,
orderType: orderType ?? this.orderType,
);
}
@override
String toString() {
return 'OrderModel(id: $id, paymentAmount: $paymentAmount, subTotal: $subTotal, tax: $tax, discount: $discount, discountAmount: $discountAmount, serviceCharge: $serviceCharge, total: $total, paymentMethod: $paymentMethod, totalItem: $totalItem, idKasir: $idKasir, namaKasir: $namaKasir, transactionTime: $transactionTime, customerName: $customerName, tableNumber: $tableNumber, status: $status, paymentStatus: $paymentStatus, isSync: $isSync, orderItems: $orderItems, orderType: $orderType)';
}
}
@@ -0,0 +1,16 @@
enum OrderType {
dineIn('DINE IN'),
takeAway('TAKE AWAY'),
grab('GRAB'),
delivery('DELIVERY');
final String value;
const OrderType(this.value);
static OrderType fromString(String value) {
return OrderType.values.firstWhere(
(type) => type.value == value,
orElse: () => OrderType.dineIn,
);
}
}
@@ -0,0 +1,13 @@
enum ProductCategory {
none('None'),
drink('Minuman'),
food('Makanan'),
snack('Snack');
final String value;
const ProductCategory(this.value);
bool get isFood => this == ProductCategory.food;
bool get isDrink => this == ProductCategory.drink;
bool get isSnack => this == ProductCategory.snack;
}
@@ -0,0 +1,43 @@
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'product_category.dart';
class ProductModel {
final String image;
final String name;
final ProductCategory category;
final int price;
final int stock;
ProductModel({
required this.image,
required this.name,
required this.category,
required this.price,
required this.stock,
});
String get priceFormat => price.currencyFormatRp;
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is ProductModel &&
other.image == image &&
other.name == name &&
other.category == category &&
other.price == price &&
other.stock == stock;
}
@override
int get hashCode {
return image.hashCode ^
name.hashCode ^
category.hashCode ^
price.hashCode ^
stock.hashCode;
}
}
@@ -0,0 +1,94 @@
import 'dart:convert';
import 'dart:developer';
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
class ProductQuantity {
final Product product;
int quantity;
String notes;
ProductQuantity({
required this.product,
required this.quantity,
this.notes = '',
});
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is ProductQuantity &&
other.product == product &&
other.quantity == quantity &&
other.notes == notes;
}
@override
int get hashCode => product.hashCode ^ quantity.hashCode ^ notes.hashCode;
Map<String, dynamic> toMap() {
return {
'product': product.toMap(),
'quantity': quantity,
'notes': notes,
};
}
Map<String, dynamic> toLocalMap(int orderId) {
log("OrderProductId: ${product.id}");
return {
'id_order': orderId,
'id_product': product.productId,
'quantity': quantity,
'price': product.price,
'notes': notes,
};
}
Map<String, dynamic> toServerMap(int? orderId) {
log("toServerMap: ${product.productId}");
return {
'id_order': orderId ?? 0,
'id_product': product.productId,
'quantity': quantity,
'price': product.price,
'notes': notes,
};
}
factory ProductQuantity.fromMap(Map<String, dynamic> map) {
return ProductQuantity(
product: Product.fromMap(map['product']),
quantity: map['quantity']?.toInt() ?? 0,
notes: map['notes'] ?? '',
);
}
factory ProductQuantity.fromLocalMap(Map<String, dynamic> map) {
log("ProductQuantity: $map");
return ProductQuantity(
product: Product.fromOrderMap(map),
quantity: map['quantity']?.toInt() ?? 0,
notes: map['notes'] ?? '',
);
}
String toJson() => json.encode(toMap());
factory ProductQuantity.fromJson(String source) =>
ProductQuantity.fromMap(json.decode(source));
ProductQuantity copyWith({
Product? product,
int? quantity,
String? notes,
}) {
return ProductQuantity(
product: product ?? this.product,
quantity: quantity ?? this.quantity,
notes: notes ?? this.notes,
);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,226 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:async';
import 'dart:developer';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/models/response/table_model.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:enaklo_pos/core/components/spaces.dart';
import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/presentation/auth/login_page.dart';
import 'package:enaklo_pos/presentation/report/pages/report_page.dart';
import 'package:enaklo_pos/presentation/sales/pages/sales_page.dart';
import 'package:enaklo_pos/presentation/setting/bloc/sync_order/sync_order_bloc.dart';
import 'package:enaklo_pos/presentation/setting/pages/printer_configuration_page.dart';
import 'package:enaklo_pos/presentation/setting/pages/settings_page.dart';
import 'package:enaklo_pos/presentation/table/pages/new_table_management_page.dart';
import 'package:enaklo_pos/presentation/table/pages/table_page.dart';
import '../../../core/assets/assets.gen.dart';
import '../../auth/bloc/logout/logout_bloc.dart';
import '../bloc/online_checker/online_checker_bloc.dart';
import '../widgets/nav_item.dart';
import 'home_page.dart';
class DashboardPage extends StatefulWidget {
final int? index;
final TableModel? table;
const DashboardPage({
Key? key,
this.index = 0,
this.table,
}) : super(key: key);
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
int _selectedIndex = 0;
List<Widget> _pages = [];
void _onItemTapped(int index) {
_selectedIndex = index;
setState(() {});
}
@override
void initState() {
super.initState();
_selectedIndex = widget.index!;
_pages = [
HomePage(
isTable: false,
table: widget.table,
),
// const TablePage(),
TableManagementScreen(),
const ReportPage(),
const PrinterConfigurationPage(),
// SalesPage(),
const SettingsPage(),
];
StreamSubscription<List<ConnectivityResult>> subscription = Connectivity()
.onConnectivityChanged
.listen((List<ConnectivityResult> connectivityResult) {
// Received changes in available connectivity types!
if (connectivityResult.contains(ConnectivityResult.mobile)) {
// Mobile network available.
context
.read<OnlineCheckerBloc>()
.add(const OnlineCheckerEvent.check(true));
} else if (connectivityResult.contains(ConnectivityResult.wifi)) {
// Wi-fi is available.
context
.read<OnlineCheckerBloc>()
.add(const OnlineCheckerEvent.check(true));
// Note for Android:
// When both mobile and Wi-Fi are turned on system will return Wi-Fi only as active network type
} else {
// Neither mobile network nor Wi-fi available.
context
.read<OnlineCheckerBloc>()
.add(const OnlineCheckerEvent.check(false));
}
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Row(
children: [
Expanded(
flex: 1,
child: SizedBox(
height: (context.deviceHeight - 40.0).clamp(0.0, double.infinity),
child: ColoredBox(
color: AppColors.primary,
child: ListView(
children: [
NavItem(
iconPath: Assets.icons.homeResto.path,
isActive: _selectedIndex == 0,
onTap: () => _onItemTapped(0),
),
NavItem(
iconPath: Assets.icons.kelolaProduk.path,
isActive: _selectedIndex == 1,
onTap: () => _onItemTapped(1),
),
NavItem(
iconPath: Assets.icons.dashboard.path,
isActive: _selectedIndex == 2,
onTap: () => _onItemTapped(2),
),
NavItem(
iconPath: Assets.icons.print.path,
isActive: _selectedIndex == 3,
onTap: () => _onItemTapped(3),
),
NavItem(
iconPath: Assets.icons.setting.path,
isActive: _selectedIndex == 4,
onTap: () => _onItemTapped(4),
),
//container flag online/offline
BlocBuilder<OnlineCheckerBloc, OnlineCheckerState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => Container(
width: 40,
margin:
const EdgeInsets.symmetric(horizontal: 16),
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: AppColors.red,
borderRadius: BorderRadius.circular(8.0),
),
child: const Icon(
Icons.signal_wifi_off,
color: AppColors.white,
),
),
online: () {
log("🌐 Dashboard: Internet connection detected, triggering sync");
context.read<SyncOrderBloc>().add(
const SyncOrderEvent.syncOrder(),
);
return Container(
width: 40,
margin:
const EdgeInsets.symmetric(horizontal: 16),
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: AppColors.green,
borderRadius: BorderRadius.circular(8.0),
),
child: const Icon(
Icons.wifi,
color: AppColors.white,
),
);
},
);
},
),
BlocListener<LogoutBloc, LogoutState>(
listener: (context, state) {
state.maybeMap(
orElse: () {},
error: (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(e.message),
backgroundColor: AppColors.red,
),
);
},
success: (value) {
AuthLocalDataSource().removeAuthData();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Logout success'),
backgroundColor: AppColors.primary,
),
);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return const LoginPage();
}));
},
);
},
child: NavItem(
iconPath: Assets.icons.logout.path,
isActive: false,
onTap: () {
context
.read<LogoutBloc>()
.add(const LogoutEvent.logout());
},
),
),
],
),
),
),
),
Expanded(
flex: 10,
child: _pages[_selectedIndex],
),
],
),
),
);
}
}
+690
View File
@@ -0,0 +1,690 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/data/models/response/table_model.dart';
import 'package:enaklo_pos/presentation/home/bloc/local_product/local_product_bloc.dart';
import 'package:enaklo_pos/presentation/home/dialog/discount_dialog.dart';
import 'package:enaklo_pos/presentation/home/dialog/tax_dialog.dart';
import 'package:enaklo_pos/presentation/home/pages/confirm_payment_page.dart';
import 'package:enaklo_pos/presentation/home/pages/dashboard_page.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:enaklo_pos/presentation/setting/bloc/sync_product/sync_product_bloc.dart';
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
import '../../../core/assets/assets.gen.dart';
import '../../../core/components/buttons.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
import '../bloc/checkout/checkout_bloc.dart';
import '../dialog/service_dialog.dart';
import '../widgets/column_button.dart';
import '../widgets/custom_tab_bar.dart';
import '../widgets/home_title.dart';
import '../widgets/order_menu.dart';
import '../widgets/product_card.dart';
class HomePage extends StatefulWidget {
final bool isTable;
final TableModel? table;
const HomePage({
Key? key,
required this.isTable,
this.table,
}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final searchController = TextEditingController();
String searchQuery = '';
@override
void initState() {
// First sync products from API, then load local products
_syncAndLoadProducts();
super.initState();
}
void _syncAndLoadProducts() {
// Trigger sync from API first
context.read<SyncProductBloc>().add(const SyncProductEvent.syncProduct());
// Also load local products initially in case sync fails or takes time
context
.read<LocalProductBloc>()
.add(const LocalProductEvent.getLocalProduct());
// Initialize checkout with tax and service charge settings
context.read<CheckoutBloc>().add(const CheckoutEvent.started());
}
void onCategoryTap(int index) {
searchController.clear();
setState(() {
searchQuery = '';
});
}
List<Product> _filterProducts(List<Product> products) {
if (searchQuery.isEmpty) {
return products;
}
return products.where((product) {
final productName = product.name?.toLowerCase() ?? '';
final queryLower = searchQuery.toLowerCase();
return productName.contains(queryLower);
}).toList();
}
List<Product> _filterProductsByCategory(List<Product> products, int categoryId) {
final filteredBySearch = _filterProducts(products);
return filteredBySearch.where((element) => element.category?.id == categoryId).toList();
}
@override
Widget build(BuildContext context) {
return Hero(
tag: 'confirmation_screen',
child: Scaffold(
body: BlocListener<SyncProductBloc, SyncProductState>(
listener: (context, state) {
state.maybeWhen(
orElse: () {},
error: (message) {
// If sync fails, still try to load local products
context
.read<LocalProductBloc>()
.add(const LocalProductEvent.getLocalProduct());
},
loaded: (productResponseModel) async {
// Store context reference before async operations
final localProductBloc = context.read<LocalProductBloc>();
// Save synced products to local database
await ProductLocalDatasource.instance.deleteAllProducts();
await ProductLocalDatasource.instance.insertProducts(
productResponseModel.data!,
);
// Then load local products to display
localProductBloc.add(const LocalProductEvent.getLocalProduct());
},
);
},
child: Row(
children: [
Expanded(
flex: 3,
child: Align(
alignment: AlignmentDirectional.topStart,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
HomeTitle(
controller: searchController,
onChanged: (value) {
setState(() {
searchQuery = value;
});
},
),
const SizedBox(height: 24),
BlocBuilder<LocalProductBloc, LocalProductState>(
builder: (context, state) {
return CustomTabBar(
tabTitles: const [
'Semua',
'Makanan',
'Minuman',
'Paket'
],
initialTabIndex: 0,
tabViews: [
// All Products Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
final filteredProducts = _filterProducts(products);
if (filteredProducts.isEmpty) {
return const Center(
child: Text('No Items Found'),
);
}
return GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) =>
ProductCard(
data: filteredProducts[index],
onCartButton: () {},
),
);
}),
),
// Makanan Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
final filteredProducts = _filterProductsByCategory(products, 1);
return filteredProducts.isEmpty
? const _IsEmpty()
: GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) =>
ProductCard(
data: filteredProducts[index],
onCartButton: () {},
),
);
}),
),
// Minuman Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
final filteredProducts = _filterProductsByCategory(products, 2);
return filteredProducts.isEmpty
? const _IsEmpty()
: GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) {
return ProductCard(
data: filteredProducts[index],
onCartButton: () {},
);
},
);
}),
),
// Snack Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
final filteredProducts = _filterProductsByCategory(products, 3);
return filteredProducts.isEmpty
? const _IsEmpty()
: GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) {
return ProductCard(
data: filteredProducts[index],
onCartButton: () {},
);
},
);
}),
),
],
);
},
),
],
),
),
),
),
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.topCenter,
child: Stack(
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
if (widget.table == null) {
context.push(DashboardPage(
index: 1,
));
}
},
child: Text(
'Meja: ${widget.table == null ? 'Belum Pilih Meja' : '${widget.table!.id}'}',
style: TextStyle(
color: AppColors.primary,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
),
const SpaceHeight(8.0),
Button.filled(
width: 180.0,
height: 40,
onPressed: () {},
label: 'Pesanan#',
),
// Row(
// children: [
// Button.filled(
// width: 120.0,
// height: 40,
// onPressed: () {},
// label: 'Dine In',
// ),
// const SpaceWidth(8.0),
// Button.outlined(
// width: 100.0,
// height: 40,
// onPressed: () {},
// label: 'To Go',
// ),
// ],
// ),
const SpaceHeight(16.0),
const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Item',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
SizedBox(
width: 130,
),
SizedBox(
width: 50.0,
child: Text(
'Qty',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
SizedBox(
child: Text(
'Price',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
],
),
const SpaceHeight(8),
const Divider(),
const SpaceHeight(8),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => const Center(
child: Text('No Items'),
),
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName, orderType) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
return ListView.separated(
shrinkWrap: true,
physics:
const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) =>
OrderMenu(data: products[index]),
separatorBuilder: (context, index) =>
const SpaceHeight(1.0),
itemCount: products.length,
);
},
);
},
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ColumnButton(
label: 'Diskon',
svgGenImage: Assets.icons.diskon,
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const DiscountDialog(),
),
),
ColumnButton(
label: 'Pajak PB1',
svgGenImage: Assets.icons.pajak,
onPressed: () => showDialog(
context: context,
builder: (context) => const TaxDialog(),
),
),
ColumnButton(
label: 'Layanan',
svgGenImage: Assets.icons.layanan,
onPressed: () => showDialog(
context: context,
builder: (context) => const ServiceDialog(),
),
),
],
),
const SpaceHeight(8.0),
const Divider(),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Pajak PB1',
style: TextStyle(color: AppColors.grey),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final tax = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName, orderType) {
if (products.isEmpty) {
return 0;
}
return tax;
});
return Text(
'$tax %',
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
);
},
),
],
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Layanan',
style: TextStyle(color: AppColors.grey),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final serviceCharge = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName, orderType) {
return serviceCharge;
});
return Text(
'$serviceCharge %',
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
);
},
),
],
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Diskon',
style: TextStyle(color: AppColors.grey),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final discount = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName, orderType) {
if (discountModel == null) {
return 0;
}
return discountModel.value!
.replaceAll('.00', '')
.toIntegerFromText;
});
return Text(
'$discount %',
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
);
},
),
],
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Sub total',
style: TextStyle(
color: AppColors.grey,
fontWeight: FontWeight.bold,
fontSize: 16),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final price = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName, orderType) {
if (products.isEmpty) {
return 0;
}
return products
.map((e) =>
e.product.price!
.toIntegerFromText *
e.quantity)
.reduce((value, element) =>
value + element);
});
return Text(
price.currencyFormatRp,
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.bold,
fontSize: 16),
);
},
),
],
),
const SpaceHeight(100.0),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: ColoredBox(
color: AppColors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0, vertical: 16.0),
child: Button.filled(
onPressed: () {
context.push(ConfirmPaymentPage(
isTable: widget.isTable,
table: widget.table,
));
},
label: 'Lanjutkan Pembayaran',
),
),
),
),
],
),
),
),
],
),
),
),
);
}
}
class _IsEmpty extends StatelessWidget {
const _IsEmpty();
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpaceHeight(40),
Assets.icons.noProduct.svg(),
const SizedBox(height: 40.0),
const Text(
'Belum Ada Produk',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16),
),
],
);
}
}
@@ -0,0 +1,688 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_posresto_app/core/extensions/build_context_ext.dart';
import 'package:flutter_posresto_app/core/extensions/int_ext.dart';
import 'package:flutter_posresto_app/core/extensions/string_ext.dart';
import 'package:flutter_posresto_app/data/models/response/table_model.dart';
import 'package:flutter_posresto_app/presentation/home/bloc/local_product/local_product_bloc.dart';
import 'package:flutter_posresto_app/presentation/home/dialog/discount_dialog.dart';
import 'package:flutter_posresto_app/presentation/home/dialog/tax_dialog.dart';
import 'package:flutter_posresto_app/presentation/home/pages/confirm_payment_page.dart';
import 'package:flutter_posresto_app/presentation/home/pages/dashboard_page.dart';
import 'package:flutter_posresto_app/data/datasources/product_local_datasource.dart';
import 'package:flutter_posresto_app/presentation/setting/bloc/sync_product/sync_product_bloc.dart';
import 'package:flutter_posresto_app/data/models/response/product_response_model.dart';
import '../../../core/assets/assets.gen.dart';
import '../../../core/components/buttons.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
import '../bloc/checkout/checkout_bloc.dart';
import '../dialog/service_dialog.dart';
import '../widgets/column_button.dart';
import '../widgets/custom_tab_bar.dart';
import '../widgets/home_title.dart';
import '../widgets/order_menu.dart';
import '../widgets/product_card.dart';
class HomePage extends StatefulWidget {
final bool isTable;
final TableModel? table;
const HomePage({
Key? key,
required this.isTable,
this.table,
}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final searchController = TextEditingController();
String searchQuery = '';
@override
void initState() {
// First sync products from API, then load local products
_syncAndLoadProducts();
super.initState();
}
void _syncAndLoadProducts() {
// Trigger sync from API first
context.read<SyncProductBloc>().add(const SyncProductEvent.syncProduct());
// Also load local products initially in case sync fails or takes time
context
.read<LocalProductBloc>()
.add(const LocalProductEvent.getLocalProduct());
// Initialize checkout with tax and service charge settings
context.read<CheckoutBloc>().add(const CheckoutEvent.started());
}
void onCategoryTap(int index) {
searchController.clear();
setState(() {
searchQuery = '';
});
}
List<Product> _filterProducts(List<Product> products) {
if (searchQuery.isEmpty) {
return products;
}
return products.where((product) {
final productName = product.name?.toLowerCase() ?? '';
final queryLower = searchQuery.toLowerCase();
return productName.contains(queryLower);
}).toList();
}
List<Product> _filterProductsByCategory(List<Product> products, int categoryId) {
final filteredBySearch = _filterProducts(products);
return filteredBySearch.where((element) => element.category?.id == categoryId).toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocListener<SyncProductBloc, SyncProductState>(
listener: (context, state) {
state.maybeWhen(
orElse: () {},
error: (message) {
// If sync fails, still try to load local products
context
.read<LocalProductBloc>()
.add(const LocalProductEvent.getLocalProduct());
},
loaded: (productResponseModel) async {
// Store context reference before async operations
final localProductBloc = context.read<LocalProductBloc>();
// Save synced products to local database
await ProductLocalDatasource.instance.deleteAllProducts();
await ProductLocalDatasource.instance.insertProducts(
productResponseModel.data!,
);
// Then load local products to display
localProductBloc.add(const LocalProductEvent.getLocalProduct());
},
);
},
child: Row(
children: [
Expanded(
flex: 3,
child: Align(
alignment: AlignmentDirectional.topStart,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
HomeTitle(
controller: searchController,
onChanged: (value) {
setState(() {
searchQuery = value;
});
},
),
const SizedBox(height: 24),
BlocBuilder<LocalProductBloc, LocalProductState>(
builder: (context, state) {
return CustomTabBar(
tabTitles: const [
'Semua',
'Makanan',
'Minuman',
'Snack'
],
initialTabIndex: 0,
tabViews: [
// All Products Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
final filteredProducts = _filterProducts(products);
if (filteredProducts.isEmpty) {
return const Center(
child: Text('No Items Found'),
);
}
return GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) =>
ProductCard(
data: filteredProducts[index],
onCartButton: () {},
),
);
}),
),
// Makanan Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
final filteredProducts = _filterProductsByCategory(products, 1);
return filteredProducts.isEmpty
? const _IsEmpty()
: GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) =>
ProductCard(
data: filteredProducts[index],
onCartButton: () {},
),
);
}),
),
// Minuman Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
final filteredProducts = _filterProductsByCategory(products, 2);
return filteredProducts.isEmpty
? const _IsEmpty()
: GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) {
return ProductCard(
data: filteredProducts[index],
onCartButton: () {},
);
},
);
}),
),
// Snack Tab
SizedBox(
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loading: () {
return const Center(
child: CircularProgressIndicator(),
);
}, loaded: (products) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
final filteredProducts = _filterProductsByCategory(products, 3);
return filteredProducts.isEmpty
? const _IsEmpty()
: GridView.builder(
shrinkWrap: true,
itemCount: filteredProducts.length,
physics:
const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.85,
crossAxisCount: 3,
crossAxisSpacing: 30.0,
mainAxisSpacing: 30.0,
),
itemBuilder: (context, index) {
return ProductCard(
data: filteredProducts[index],
onCartButton: () {},
);
},
);
}),
),
],
);
},
),
],
),
),
),
),
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.topCenter,
child: Stack(
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
if (widget.table == null) {
context.push(DashboardPage(
index: 1,
));
}
},
child: Text(
'Meja: ${widget.table == null ? 'Belum Pilih Meja' : '${widget.table!.id}'}',
style: TextStyle(
color: AppColors.primary,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
),
const SpaceHeight(8.0),
Button.filled(
width: 180.0,
height: 40,
onPressed: () {},
label: 'Pesanan#',
),
// Row(
// children: [
// Button.filled(
// width: 120.0,
// height: 40,
// onPressed: () {},
// label: 'Dine In',
// ),
// const SpaceWidth(8.0),
// Button.outlined(
// width: 100.0,
// height: 40,
// onPressed: () {},
// label: 'To Go',
// ),
// ],
// ),
const SpaceHeight(16.0),
const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Item',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
SizedBox(
width: 130,
),
SizedBox(
width: 50.0,
child: Text(
'Qty',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
SizedBox(
child: Text(
'Price',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
],
),
const SpaceHeight(8),
const Divider(),
const SpaceHeight(8),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => const Center(
child: Text('No Items'),
),
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName) {
if (products.isEmpty) {
return const Center(
child: Text('No Items'),
);
}
return ListView.separated(
shrinkWrap: true,
physics:
const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) =>
OrderMenu(data: products[index]),
separatorBuilder: (context, index) =>
const SpaceHeight(1.0),
itemCount: products.length,
);
},
);
},
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ColumnButton(
label: 'Diskon',
svgGenImage: Assets.icons.diskon,
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const DiscountDialog(),
),
),
ColumnButton(
label: 'Pajak PB1',
svgGenImage: Assets.icons.pajak,
onPressed: () => showDialog(
context: context,
builder: (context) => const TaxDialog(),
),
),
ColumnButton(
label: 'Layanan',
svgGenImage: Assets.icons.layanan,
onPressed: () => showDialog(
context: context,
builder: (context) => const ServiceDialog(),
),
),
],
),
const SpaceHeight(8.0),
const Divider(),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Pajak PB1',
style: TextStyle(color: AppColors.grey),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final tax = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName) {
if (products.isEmpty) {
return 0;
}
return tax;
});
return Text(
'$tax %',
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
);
},
),
],
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Layanan',
style: TextStyle(color: AppColors.grey),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final serviceCharge = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName) {
return serviceCharge;
});
return Text(
'$serviceCharge %',
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
);
},
),
],
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Diskon',
style: TextStyle(color: AppColors.grey),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final discount = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName) {
if (discountModel == null) {
return 0;
}
return discountModel.value!
.replaceAll('.00', '')
.toIntegerFromText;
});
return Text(
'$discount %',
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
);
},
),
],
),
const SpaceHeight(8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Sub total',
style: TextStyle(
color: AppColors.grey,
fontWeight: FontWeight.bold,
fontSize: 16),
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final price = state.maybeWhen(
orElse: () => 0,
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName) {
if (products.isEmpty) {
return 0;
}
return products
.map((e) =>
e.product.price!
.toIntegerFromText *
e.quantity)
.reduce((value, element) =>
value + element);
});
return Text(
price.currencyFormatRp,
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.bold,
fontSize: 16),
);
},
),
],
),
const SpaceHeight(100.0),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: ColoredBox(
color: AppColors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0, vertical: 16.0),
child: Button.filled(
onPressed: () {
context.push(ConfirmPaymentPage(
isTable: widget.isTable,
table: widget.table,
));
},
label: 'Lanjutkan Pembayaran',
),
),
),
),
],
),
),
),
],
),
),
),
);
}
}
class _IsEmpty extends StatelessWidget {
const _IsEmpty();
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpaceHeight(40),
Assets.icons.noProduct.svg(),
const SizedBox(height: 40.0),
const Text(
'Belum Ada Produk',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16),
),
],
);
}
}
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../core/constants/colors.dart';
import '../../../data/datasources/auth_local_datasource.dart';
import '../../auth/bloc/logout/logout_bloc.dart';
import '../../auth/login_page.dart';
class LogoutPage extends StatefulWidget {
const LogoutPage({super.key});
@override
State<LogoutPage> createState() => _LogoutPageState();
}
class _LogoutPageState extends State<LogoutPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Dashboard'),
),
body: Center(
child: Column(
children: [
const Text('Welcome to Dashboard'),
const SizedBox(
height: 100,
),
BlocListener<LogoutBloc, LogoutState>(
listener: (context, state) {
state.maybeMap(
orElse: () {},
error: (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(e.message),
backgroundColor: AppColors.red,
),
);
},
success: (value) {
AuthLocalDataSource().removeAuthData();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Logout success'),
backgroundColor: AppColors.primary,
),
);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return const LoginPage();
}));
},
);
},
child: ElevatedButton(
onPressed: () {
context.read<LogoutBloc>().add(const LogoutEvent.logout());
},
child: const Text('Logout'),
),
),
],
),
),
);
}
}
@@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import '../../../core/assets/assets.gen.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
class ColumnButton extends StatelessWidget {
final String label;
final SvgGenImage svgGenImage;
final VoidCallback onPressed;
const ColumnButton({
super.key,
required this.label,
required this.svgGenImage,
required this.onPressed,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: Column(
children: [
Container(
padding: const EdgeInsets.all(8.0),
height: 40.0,
width: 40.0,
decoration: BoxDecoration(
color: AppColors.white,
border: Border.all(color: AppColors.primary),
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
),
child: svgGenImage.svg(),
),
const SpaceHeight(8.0),
Text(
label,
style: const TextStyle(
color: AppColors.primary,
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
],
),
);
}
}
@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import '../../../core/constants/colors.dart';
class CustomTabBar extends StatefulWidget {
final List<String> tabTitles;
final int initialTabIndex;
final List<Widget> tabViews;
const CustomTabBar({
super.key,
required this.tabTitles,
required this.initialTabIndex,
required this.tabViews,
});
@override
State<CustomTabBar> createState() => _CustomTabBarState();
}
class _CustomTabBarState extends State<CustomTabBar> {
late int _selectedIndex;
@override
void initState() {
super.initState();
_selectedIndex = widget.initialTabIndex;
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: List.generate(
widget.tabTitles.length,
(index) => GestureDetector(
onTap: () {
setState(() {
_selectedIndex = index;
});
},
child: Container(
padding: const EdgeInsets.symmetric(vertical: 14),
margin: const EdgeInsets.only(right: 32),
decoration: BoxDecoration(
border: _selectedIndex == index
? const Border(
bottom: BorderSide(
width: 3.0,
color: AppColors.primary,
),
)
: null,
),
child: Text(
widget.tabTitles[index],
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 18.0),
child: widget.tabViews[_selectedIndex],
),
],
);
}
}
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:enaklo_pos/core/extensions/date_time_ext.dart';
import '../../../core/components/search_input.dart';
import '../../../core/constants/colors.dart';
class HomeTitle extends StatelessWidget {
final TextEditingController controller;
final Function(String value)? onChanged;
const HomeTitle({
super.key,
required this.controller,
this.onChanged,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Enaklo POS',
style: TextStyle(
color: AppColors.primary,
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 4.0),
Text(
DateTime.now().toFormattedDate(),
style: const TextStyle(
color: AppColors.subtitle,
fontSize: 16,
),
),
],
),
SizedBox(
width: 300.0,
child: SearchInput(
controller: controller,
onChanged: onChanged,
hintText: 'Search..',
),
),
],
);
}
}
@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/presentation/home/bloc/checkout/checkout_bloc.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
import '../../../core/components/buttons.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
class ItemNotesDialog extends StatefulWidget {
final ProductQuantity item;
const ItemNotesDialog({
super.key,
required this.item,
});
@override
State<ItemNotesDialog> createState() => _ItemNotesDialogState();
}
class _ItemNotesDialogState extends State<ItemNotesDialog> {
late TextEditingController notesController;
@override
void initState() {
super.initState();
notesController = TextEditingController(text: widget.item.notes);
}
@override
void dispose() {
notesController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Add Notes'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.item.product.name ?? 'Product',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SpaceHeight(16.0),
TextField(
controller: notesController,
maxLines: 3,
decoration: const InputDecoration(
hintText: 'Enter notes for this item...',
border: OutlineInputBorder(),
),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
Button.filled(
onPressed: () {
context.read<CheckoutBloc>().add(
CheckoutEvent.updateItemNotes(
widget.item.product,
notesController.text,
),
);
Navigator.of(context).pop();
},
label: 'Save',
),
],
);
}
}
@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../../core/constants/colors.dart';
class NavItem extends StatelessWidget {
final String iconPath;
final bool isActive;
final VoidCallback onTap;
final Color color;
const NavItem({
super.key,
required this.iconPath,
required this.isActive,
required this.onTap,
this.color = AppColors.white,
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(12.0)),
child: ColoredBox(
color: isActive
? AppColors.disabled.withOpacity(0.25)
: Colors.transparent,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 25.0,
height: 25.0,
child: SvgPicture.asset(
iconPath,
colorFilter: ColorFilter.mode(
color,
BlendMode.srcIn,
),
),
),
],
),
),
),
),
),
);
}
}
@@ -0,0 +1,160 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/constants/variables.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/presentation/home/bloc/checkout/checkout_bloc.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:enaklo_pos/presentation/home/widgets/item_notes_dialog.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
class OrderMenu extends StatelessWidget {
final ProductQuantity data;
const OrderMenu({super.key, required this.data});
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
Flexible(
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(50.0)),
child:
// Icon(
// Icons.fastfood,
// size: 50,
// color: AppColors.primary,
// ),
CachedNetworkImage(
imageUrl: data.product.image!.contains('http')
? data.product.image!
: '${Variables.baseUrl}/${data.product.image}',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
title: Row(
children: [
Expanded(
child: Text(data.product.name ?? "-",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
)),
),
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (context) => ItemNotesDialog(item: data),
);
},
child: const Icon(
Icons.edit_note,
size: 20,
color: AppColors.primary,
),
),
],
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(data.product.price!.toIntegerFromText.currencyFormatRp),
if (data.notes.isNotEmpty) ...[
const SpaceHeight(4.0),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 4.0,
),
decoration: BoxDecoration(
color: AppColors.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(4.0),
),
child: Text(
'Notes: ${data.notes}',
style: const TextStyle(
fontSize: 12,
color: AppColors.primary,
fontStyle: FontStyle.italic,
),
),
),
],
],
),
),
),
Row(
children: [
GestureDetector(
onTap: () {
context
.read<CheckoutBloc>()
.add(CheckoutEvent.removeItem(data.product));
},
child: Container(
width: 30,
height: 30,
color: AppColors.white,
child: const Icon(
Icons.remove_circle,
color: AppColors.primary,
),
),
),
SizedBox(
width: 30.0,
child: Center(
child: Text(
data.quantity.toString(),
)),
),
GestureDetector(
onTap: () {
context
.read<CheckoutBloc>()
.add(CheckoutEvent.addItem(data.product));
},
child: Container(
width: 30,
height: 30,
color: AppColors.white,
child: const Icon(
Icons.add_circle,
color: AppColors.primary,
),
),
),
],
),
const SpaceWidth(8),
SizedBox(
width: 80.0,
child: Text(
(data.product.price!.toIntegerFromText * data.quantity)
.currencyFormatRp,
textAlign: TextAlign.right,
style: const TextStyle(
color: AppColors.primary,
fontWeight: FontWeight.bold,
),
),
),
],
),
],
);
}
}
@@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/presentation/home/bloc/checkout/checkout_bloc.dart';
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
class OrderTypeSelector extends StatelessWidget {
const OrderTypeSelector({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => const SizedBox.shrink(),
loaded: (items, discountModel, discount, discountAmount, tax, serviceCharge, totalQuantity, totalPrice, draftName, orderType) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Order Type',
style: TextStyle(
color: AppColors.primary,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SpaceHeight(12.0),
Wrap(
spacing: 12.0,
runSpacing: 8.0,
children: OrderType.values.map((type) {
final isSelected = orderType == type;
return GestureDetector(
onTap: () {
context.read<CheckoutBloc>().add(
CheckoutEvent.updateOrderType(type),
);
},
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 8.0,
),
decoration: BoxDecoration(
color: isSelected ? AppColors.primary : AppColors.white,
border: Border.all(
color: isSelected ? AppColors.primary : AppColors.grey,
width: 1.0,
),
borderRadius: BorderRadius.circular(8.0),
),
child: Text(
type.value,
style: TextStyle(
color: isSelected ? AppColors.white : AppColors.black,
fontSize: 14,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
),
),
),
);
}).toList(),
),
],
);
},
);
},
);
}
}
@@ -0,0 +1,189 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/constants/variables.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/data/models/response/product_response_model.dart';
import 'package:enaklo_pos/presentation/home/bloc/checkout/checkout_bloc.dart';
import '../../../core/assets/assets.gen.dart';
import '../../../core/components/spaces.dart';
import '../../../core/constants/colors.dart';
class ProductCard extends StatelessWidget {
final Product data;
final VoidCallback onCartButton;
const ProductCard({
super.key,
required this.data,
required this.onCartButton,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
context.read<CheckoutBloc>().add(CheckoutEvent.addItem(data));
},
child: Container(
padding: const EdgeInsets.all(16.0),
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: const BorderSide(width: 1, color: AppColors.card),
borderRadius: BorderRadius.circular(16),
),
),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SpaceHeight(8),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColors.disabled.withOpacity(0.4),
),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(40.0)),
child:
// Icon(
// Icons.fastfood,
// size: 40,
// color: AppColors.primary,
// ),
CachedNetworkImage(
imageUrl: data.image!.contains('http')
? data.image!
: '${Variables.baseUrl}/${data.image}',
width: 60,
height: 60,
fit: BoxFit.cover,
),
),
),
const Spacer(),
Text(
"${data.name}",
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
data.category?.name ?? '-',
style: const TextStyle(
color: AppColors.grey,
fontSize: 12,
),
),
),
Flexible(
child: Text(
data.price!.toIntegerFromText.currencyFormatRp,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 13,
),
),
),
],
),
const Spacer(),
],
),
BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => const SizedBox(),
loaded: (products,
discountModel,
discount,
discountAmount,
tax,
serviceCharge,
totalQuantity,
totalPrice,
draftName,
orderType) {
return products.any((element) => element.product == data)
? products
.firstWhere(
(element) => element.product == data)
.quantity >
0
? Align(
alignment: Alignment.topRight,
child: Container(
width: 40,
height: 40,
padding: const EdgeInsets.all(6),
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(9.0)),
color: AppColors.primary,
),
child: Center(
child: Text(
products
.firstWhere((element) =>
element.product == data)
.quantity
.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
),
)
: Align(
alignment: Alignment.topRight,
child: Container(
width: 36,
height: 36,
padding: const EdgeInsets.all(6),
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(9.0)),
color: AppColors.primary,
),
child: Assets.icons.shoppingBasket.svg(),
),
)
: Align(
alignment: Alignment.topRight,
child: Container(
width: 36,
height: 36,
padding: const EdgeInsets.all(6),
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(9.0)),
color: AppColors.primary,
),
child: Assets.icons.shoppingBasket.svg(),
),
);
},
);
},
),
],
),
),
);
}
}
@@ -0,0 +1,205 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:intl/intl.dart';
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
import 'package:enaklo_pos/data/models/response/table_model.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import '../../../core/assets/assets.gen.dart';
import '../../../core/components/buttons.dart';
import '../../../core/components/spaces.dart';
import '../../table/blocs/get_table/get_table_bloc.dart';
import '../bloc/checkout/checkout_bloc.dart';
import '../bloc/order/order_bloc.dart';
import '../models/order_type.dart';
import 'package:enaklo_pos/core/utils/printer_service.dart';
class SaveOrderDialog extends StatefulWidget {
const SaveOrderDialog({
super.key,
required this.data,
required this.totalQty,
required this.totalPrice,
required this.totalTax,
required this.totalDiscount,
required this.subTotal,
required this.normalPrice,
required this.table,
required this.draftName,
});
final List<ProductQuantity> data;
final int totalQty;
final int totalPrice;
final int totalTax;
final int totalDiscount;
final int subTotal;
final int normalPrice;
final TableModel table;
final String draftName;
@override
State<SaveOrderDialog> createState() => _SaveOrderDialogState();
}
class _SaveOrderDialogState extends State<SaveOrderDialog> {
// List<ProductQuantity> data = [];
// int totalQty = 0;
// int totalPrice = 0;
@override
Widget build(BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(child: Assets.icons.success.svg()),
const SpaceHeight(16.0),
const Center(
child: Text(
'Order Berhasil Disimpan',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
),
),
),
const SpaceHeight(20.0),
Row(
children: [
Flexible(
child: Button.outlined(
onPressed: () {
context
.read<CheckoutBloc>()
.add(const CheckoutEvent.started());
context
.read<GetTableBloc>()
.add(const GetTableEvent.getTables());
context.popToRoot();
},
label: 'Kembali',
),
),
const SpaceWidth(8.0),
Flexible(
child: BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, state) {
final orderType = state.maybeWhen(
orElse: () => OrderType.dineIn,
loaded: (items, discountModel, discount, discountAmount, tax, serviceCharge, totalQuantity, totalPrice, draftName, orderType) => orderType,
);
return Button.filled(
onPressed: () async {
final checkerPrinter = await ProductLocalDatasource
.instance
.getPrinterByCode('checker');
final kitchenPrinter = await ProductLocalDatasource
.instance
.getPrinterByCode('kitchen');
final barPrinter = await ProductLocalDatasource.instance
.getPrinterByCode('bar');
log("Checker printer: ${checkerPrinter?.toMap()}");
log("Kitchen printer: ${kitchenPrinter?.toMap()}");
log("Bar printer: ${barPrinter?.toMap()}");
// Checker printer
if (checkerPrinter != null) {
try {
final printValue = await PrintDataoutputs.instance
.printChecker(
widget.data,
widget.table.tableName,
widget.draftName,
'kasir',
checkerPrinter.paper.toIntegerFromText,
orderType.value);
await PrinterService().printWithPrinter(
checkerPrinter,
printValue,
context
);
} catch (e) {
log("Error printing checker: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing checker: $e')),
);
}
}
// Kitchen printer
if (kitchenPrinter != null) {
try {
final printValue = await PrintDataoutputs.instance.printKitchen(
widget.data,
widget.table.tableName,
widget.draftName,
'kasir',
kitchenPrinter.paper.toIntegerFromText,
orderType.value,
);
await PrinterService().printWithPrinter(
kitchenPrinter,
printValue,
context
);
} catch (e) {
log("Error printing kitchen order: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing kitchen order: $e')),
);
}
}
// Bar printer
if (barPrinter != null) {
try {
final printValue = await PrintDataoutputs.instance.printBar(
widget.data,
widget.table.tableName,
widget.draftName,
'kasir',
barPrinter.paper.toIntegerFromText,
orderType.value,
);
await PrinterService().printWithPrinter(
barPrinter,
printValue,
context
);
} catch (e) {
log("Error printing bar order: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing bar order: $e')),
);
}
}
},
label: 'Print Checker',
);
},
),
),
],
),
],
),
),
);
}
}
@@ -0,0 +1,331 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
import 'package:intl/intl.dart';
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/core/extensions/string_ext.dart';
import 'package:enaklo_pos/data/dataoutputs/laman_print.dart';
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/datasources/product_local_datasource.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:enaklo_pos/presentation/home/models/order_type.dart';
import 'package:enaklo_pos/core/utils/printer_service.dart';
import 'package:enaklo_pos/data/datasources/settings_local_datasource.dart';
import '../../../core/assets/assets.gen.dart';
import '../../../core/components/buttons.dart';
import '../../../core/components/spaces.dart';
import '../../table/blocs/get_table/get_table_bloc.dart';
import '../bloc/checkout/checkout_bloc.dart';
import '../bloc/order/order_bloc.dart';
class SuccessPaymentDialog extends StatefulWidget {
const SuccessPaymentDialog({
Key? key,
required this.data,
required this.totalQty,
required this.totalPrice,
required this.totalTax,
required this.totalDiscount,
required this.subTotal,
required this.normalPrice,
required this.totalService,
required this.draftName,
this.isTablePaymentPage = false,
}) : super(key: key);
final List<ProductQuantity> data;
final int totalQty;
final int totalPrice;
final int totalTax;
final int totalDiscount;
final int subTotal;
final int normalPrice;
final int totalService;
final String draftName;
final bool? isTablePaymentPage;
@override
State<SuccessPaymentDialog> createState() => _SuccessPaymentDialogState();
}
class _SuccessPaymentDialogState extends State<SuccessPaymentDialog> {
// List<ProductQuantity> data = [];
// int totalQty = 0;
// int totalPrice = 0;
@override
Widget build(BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(child: Assets.icons.success.svg()),
const SpaceHeight(16.0),
const Center(
child: Text(
'Pembayaran telah sukses dilakukan',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
),
),
),
const SpaceHeight(20.0),
const Text('METODE BAYAR'),
const SpaceHeight(5.0),
BlocBuilder<OrderBloc, OrderState>(
builder: (context, state) {
final paymentMethod = state.maybeWhen(
orElse: () => 'Cash',
loaded: (model, orderId) => model.paymentMethod,
);
return Text(
paymentMethod,
style: const TextStyle(
fontWeight: FontWeight.w700,
),
);
},
),
const SpaceHeight(10.0),
const Divider(),
const SpaceHeight(8.0),
const Text('TOTAL TAGIHAN'),
const SpaceHeight(5.0),
BlocBuilder<OrderBloc, OrderState>(
builder: (context, state) {
final total = state.maybeWhen(
orElse: () => 0,
loaded: (model, orderId) => model.total,
);
return Text(
widget.totalPrice.currencyFormatRp,
style: const TextStyle(
fontWeight: FontWeight.w700,
),
);
},
),
const SpaceHeight(10.0),
const Divider(),
const SpaceHeight(8.0),
const Text('NOMINAL BAYAR'),
const SpaceHeight(5.0),
BlocBuilder<OrderBloc, OrderState>(
builder: (context, state) {
final paymentAmount = state.maybeWhen(
orElse: () => 0,
loaded: (model, orderId) => model.paymentAmount,
);
return Text(
paymentAmount.ceil().currencyFormatRp,
style: const TextStyle(
fontWeight: FontWeight.w700,
),
);
},
),
const Divider(),
const SpaceHeight(8.0),
const Text('KEMBALIAN'),
const SpaceHeight(5.0),
BlocBuilder<OrderBloc, OrderState>(
builder: (context, state) {
final paymentAmount = state.maybeWhen(
orElse: () => 0,
loaded: (model, orderId) => model.paymentAmount,
);
final total = state.maybeWhen(
orElse: () => 0,
loaded: (model, orderId) => model.total,
);
final diff = paymentAmount - total;
log("DIFF: $diff paymentAmount: $paymentAmount total: $total");
return Text(
diff.ceil().currencyFormatRp,
style: const TextStyle(
fontWeight: FontWeight.w700,
),
);
},
),
const SpaceHeight(10.0),
const Divider(),
const SpaceHeight(8.0),
const Text('WAKTU PEMBAYARAN'),
const SpaceHeight(5.0),
Text(
DateFormat('dd MMMM yyyy, HH:mm').format(DateTime.now()),
style: const TextStyle(
fontWeight: FontWeight.w700,
),
),
const SpaceHeight(20.0),
Row(
children: [
Flexible(
child: Button.outlined(
onPressed: () {
// For table payment page, just close the dialog
// The cleanup and navigation is handled by the payment page
if (widget.isTablePaymentPage == true) {
Navigator.of(context).pop(); // Close dialog only
} else {
// For regular payment flow, reset and go to root
context
.read<CheckoutBloc>()
.add(const CheckoutEvent.started());
context
.read<GetTableBloc>()
.add(const GetTableEvent.getTables());
context.popToRoot();
}
},
label: 'Kembali',
),
),
const SpaceWidth(8.0),
Flexible(
child: BlocBuilder<OrderBloc, OrderState>(
builder: (context, state) {
final paymentAmount = state.maybeWhen(
orElse: () => 0,
loaded: (model, orderId) => model.paymentAmount,
);
final kembalian = paymentAmount - widget.totalPrice;
return BlocBuilder<CheckoutBloc, CheckoutState>(
builder: (context, checkoutState) {
final orderType = checkoutState.maybeWhen(
orElse: () => OrderType.dineIn,
loaded: (items, discountModel, discount, discountAmount, tax, serviceCharge, totalQuantity, totalPrice, draftName, orderType) => orderType,
);
return Button.filled(
onPressed: () async {
final receiptPrinter = await ProductLocalDatasource
.instance
.getPrinterByCode('receipt');
final kitchenPrinter = await ProductLocalDatasource
.instance
.getPrinterByCode('kitchen');
final barPrinter = await ProductLocalDatasource.instance
.getPrinterByCode('bar');
// Receipt Printer
if (receiptPrinter != null) {
try {
final settingsLocalDatasource = SettingsLocalDatasource();
final taxModel = await settingsLocalDatasource.getTax();
final serviceChargeValue = await settingsLocalDatasource.getServiceCharge();
// Get the actual payment method from OrderBloc
final paymentMethod = state.maybeWhen(
orElse: () => 'Cash',
loaded: (model, orderId) => model.paymentMethod,
);
final printValue =
await PrintDataoutputs.instance.printOrderV3(
widget.data,
widget.totalQty,
widget.totalPrice,
paymentMethod,
paymentAmount,
kembalian,
widget.subTotal,
widget.totalDiscount,
widget.totalTax,
widget.totalService,
'kasir',
widget.draftName,
receiptPrinter.paper.toIntegerFromText,
taxPercentage: taxModel.value,
serviceChargePercentage: serviceChargeValue,
);
await PrinterService().printWithPrinter(
receiptPrinter,
printValue,
context
);
} catch (e) {
log("Error printing receipt: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing receipt: $e')),
);
}
}
// Kitchen Printer
if (kitchenPrinter != null && widget.isTablePaymentPage == false) {
try {
final printValue = await PrintDataoutputs.instance.printKitchen(
widget.data,
'',
widget.draftName,
'kasir',
kitchenPrinter.paper.toIntegerFromText,
orderType.value,
);
await PrinterService().printWithPrinter(
kitchenPrinter,
printValue,
context
);
} catch (e) {
log("Error printing kitchen order: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing kitchen order: $e')),
);
}
}
// Bar printer
if (barPrinter != null && widget.isTablePaymentPage == false) {
try {
final printValue = await PrintDataoutputs.instance.printBar(
widget.data,
'',
widget.draftName,
'kasir',
barPrinter.paper.toIntegerFromText,
orderType.value,
);
await PrinterService().printWithPrinter(
barPrinter,
printValue,
context
);
} catch (e) {
log("Error printing bar order: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error printing bar order: $e')),
);
}
}
},
label: 'Print',
);
},
);
},
),
),
],
),
],
),
),
);
}
}