update cart

This commit is contained in:
Phuoc Nguyen
2025-11-14 16:19:25 +07:00
parent 4738553d2e
commit aae3c9d080
30 changed files with 5954 additions and 758 deletions

View File

@@ -0,0 +1,179 @@
/// 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');
}
}
}