2025-08-02 11:06:41 +07:00

294 lines
9.3 KiB
Dart

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/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<_DeleteItem>((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());
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));
});
}
}