180 lines
4.6 KiB
Dart
180 lines
4.6 KiB
Dart
/// Local Data Source: Cart Storage
|
|
///
|
|
/// Handles local storage of cart items using Hive for offline access.
|
|
/// Supports offline-first functionality and cart persistence.
|
|
library;
|
|
|
|
import 'package:hive_ce/hive.dart';
|
|
|
|
import 'package:worker/core/constants/storage_constants.dart';
|
|
import 'package:worker/core/database/hive_service.dart';
|
|
import 'package:worker/core/errors/exceptions.dart';
|
|
import 'package:worker/features/cart/data/models/cart_item_model.dart';
|
|
|
|
/// Cart Local Data Source Interface
|
|
abstract class CartLocalDataSource {
|
|
/// Save cart items to local storage
|
|
///
|
|
/// [items] - List of cart items to save
|
|
Future<void> saveCartItems(List<CartItemModel> items);
|
|
|
|
/// Get cart items from local storage
|
|
///
|
|
/// Returns list of cart items
|
|
Future<List<CartItemModel>> getCartItems();
|
|
|
|
/// Add item to local cart
|
|
///
|
|
/// [item] - Cart item to add
|
|
Future<void> addCartItem(CartItemModel item);
|
|
|
|
/// Update item in local cart
|
|
///
|
|
/// [item] - Cart item to update
|
|
Future<void> updateCartItem(CartItemModel item);
|
|
|
|
/// Remove items from local cart
|
|
///
|
|
/// [itemIds] - Product IDs to remove
|
|
Future<void> removeCartItems(List<String> itemIds);
|
|
|
|
/// Clear all items from local cart
|
|
Future<void> clearCart();
|
|
|
|
/// Get cart item count
|
|
///
|
|
/// Returns total number of items
|
|
Future<int> getCartItemCount();
|
|
|
|
/// Get cart total
|
|
///
|
|
/// Returns total amount
|
|
Future<double> getCartTotal();
|
|
}
|
|
|
|
/// Cart Local Data Source Implementation
|
|
class CartLocalDataSourceImpl implements CartLocalDataSource {
|
|
CartLocalDataSourceImpl(this._hiveService);
|
|
|
|
final HiveService _hiveService;
|
|
|
|
/// Get cart box as Box<dynamic> (following best practices)
|
|
Box<dynamic> get _cartBox => _hiveService.getBox<dynamic>(HiveBoxNames.cartBox);
|
|
|
|
@override
|
|
Future<void> saveCartItems(List<CartItemModel> items) async {
|
|
try {
|
|
// Clear existing items
|
|
await _cartBox.clear();
|
|
|
|
// Save new items with productId as key
|
|
for (final item in items) {
|
|
await _cartBox.put(item.productId, item);
|
|
}
|
|
} catch (e) {
|
|
throw StorageException('Failed to save cart items: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<List<CartItemModel>> getCartItems() async {
|
|
try {
|
|
// Get all cart items from box using .whereType() for type safety
|
|
final items = _cartBox.values
|
|
.whereType<CartItemModel>()
|
|
.toList();
|
|
|
|
return items;
|
|
} catch (e) {
|
|
throw StorageException('Failed to get cart items: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> addCartItem(CartItemModel item) async {
|
|
try {
|
|
// Check if item already exists
|
|
final existingItem = _cartBox.get(item.productId);
|
|
|
|
if (existingItem != null && existingItem is CartItemModel) {
|
|
// Update quantity if item exists
|
|
final updatedItem = existingItem.copyWith(
|
|
quantity: existingItem.quantity + item.quantity,
|
|
subtotal: (existingItem.quantity + item.quantity) * existingItem.unitPrice,
|
|
);
|
|
await _cartBox.put(item.productId, updatedItem);
|
|
} else {
|
|
// Add new item
|
|
await _cartBox.put(item.productId, item);
|
|
}
|
|
} catch (e) {
|
|
throw StorageException('Failed to add cart item: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> updateCartItem(CartItemModel item) async {
|
|
try {
|
|
// Update or add item
|
|
await _cartBox.put(item.productId, item);
|
|
} catch (e) {
|
|
throw StorageException('Failed to update cart item: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> removeCartItems(List<String> itemIds) async {
|
|
try {
|
|
// Remove items by productId keys
|
|
for (final itemId in itemIds) {
|
|
await _cartBox.delete(itemId);
|
|
}
|
|
} catch (e) {
|
|
throw StorageException('Failed to remove cart items: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> clearCart() async {
|
|
try {
|
|
await _cartBox.clear();
|
|
} catch (e) {
|
|
throw StorageException('Failed to clear cart: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<int> getCartItemCount() async {
|
|
try {
|
|
final items = await getCartItems();
|
|
|
|
// Sum up all quantities
|
|
final totalQuantity = items.fold<double>(
|
|
0.0,
|
|
(sum, item) => sum + item.quantity,
|
|
);
|
|
|
|
return totalQuantity.toInt();
|
|
} catch (e) {
|
|
throw StorageException('Failed to get cart item count: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<double> getCartTotal() async {
|
|
try {
|
|
final items = await getCartItems();
|
|
|
|
// Sum up all subtotals
|
|
final total = items.fold<double>(
|
|
0.0,
|
|
(sum, item) => sum + item.subtotal,
|
|
);
|
|
|
|
return total;
|
|
} catch (e) {
|
|
throw StorageException('Failed to get cart total: $e');
|
|
}
|
|
}
|
|
}
|