Files
retail/.archive/product_local_datasource_hive.dart
Phuoc Nguyen b94c158004 runable
2025-10-10 16:38:07 +07:00

183 lines
5.0 KiB
Dart

import 'package:hive_ce/hive.dart';
import 'package:retail/core/database/hive_database.dart';
import 'package:retail/features/products/data/models/product_model.dart';
import 'package:retail/features/products/data/datasources/product_local_datasource.dart';
import 'package:retail/features/products/domain/entities/product.dart';
/// Hive implementation of ProductLocalDataSource
class ProductLocalDataSourceHive implements ProductLocalDataSource {
final HiveDatabase _database;
ProductLocalDataSourceHive(this._database);
Box<ProductModel> get _box => _database.productsBox;
/// Convert ProductModel to Product entity
Product _toEntity(ProductModel model) {
return Product(
id: model.id,
name: model.name,
description: model.description,
price: model.price,
imageUrl: model.imageUrl,
categoryId: model.categoryId,
stockQuantity: model.stockQuantity,
isAvailable: model.isAvailable,
createdAt: model.createdAt,
updatedAt: model.updatedAt,
);
}
/// Convert Product entity to ProductModel
ProductModel _toModel(Product entity) {
return ProductModel(
id: entity.id,
name: entity.name,
description: entity.description,
price: entity.price,
imageUrl: entity.imageUrl,
categoryId: entity.categoryId,
stockQuantity: entity.stockQuantity,
isAvailable: entity.isAvailable,
createdAt: entity.createdAt,
updatedAt: entity.updatedAt,
);
}
@override
Future<List<Product>> getAllProducts() async {
try {
return _box.values.map(_toEntity).toList();
} catch (e) {
throw Exception('Failed to get products: $e');
}
}
@override
Future<Product?> getProductById(String id) async {
try {
final model = _box.get(id);
return model != null ? _toEntity(model) : null;
} catch (e) {
throw Exception('Failed to get product by ID: $e');
}
}
@override
Future<List<Product>> getProductsByCategory(String categoryId) async {
try {
return _box.values
.where((product) => product.categoryId == categoryId)
.map(_toEntity)
.toList();
} catch (e) {
throw Exception('Failed to get products by category: $e');
}
}
@override
Future<void> saveProducts(List<Product> products) async {
try {
final models = products.map(_toModel).toList();
final Map<String, ProductModel> productsMap = {
for (var model in models) model.id: model
};
await _box.putAll(productsMap);
} catch (e) {
throw Exception('Failed to save products: $e');
}
}
@override
Future<void> deleteAllProducts() async {
try {
await _box.clear();
} catch (e) {
throw Exception('Failed to delete all products: $e');
}
}
/// Additional Hive-specific methods
/// Save a single product
Future<void> saveProduct(Product product) async {
try {
final model = _toModel(product);
await _box.put(model.id, model);
} catch (e) {
throw Exception('Failed to save product: $e');
}
}
/// Update an existing product
Future<void> updateProduct(Product product) async {
try {
if (!_box.containsKey(product.id)) {
throw Exception('Product not found: ${product.id}');
}
final model = _toModel(product);
await _box.put(model.id, model);
} catch (e) {
throw Exception('Failed to update product: $e');
}
}
/// Delete a specific product
Future<void> deleteProduct(String id) async {
try {
await _box.delete(id);
} catch (e) {
throw Exception('Failed to delete product: $e');
}
}
/// Check if product exists
Future<bool> productExists(String id) async {
try {
return _box.containsKey(id);
} catch (e) {
throw Exception('Failed to check product existence: $e');
}
}
/// Get available products only
Future<List<Product>> getAvailableProducts() async {
try {
return _box.values
.where((product) => product.isAvailable && product.stockQuantity > 0)
.map(_toEntity)
.toList();
} catch (e) {
throw Exception('Failed to get available products: $e');
}
}
/// Get products with low stock
Future<List<Product>> getLowStockProducts(int threshold) async {
try {
return _box.values
.where((product) =>
product.stockQuantity <= threshold && product.stockQuantity > 0)
.map(_toEntity)
.toList();
} catch (e) {
throw Exception('Failed to get low stock products: $e');
}
}
/// Search products by name or description
Future<List<Product>> searchProducts(String query) async {
try {
final lowercaseQuery = query.toLowerCase();
return _box.values
.where((product) =>
product.name.toLowerCase().contains(lowercaseQuery) ||
product.description.toLowerCase().contains(lowercaseQuery))
.map(_toEntity)
.toList();
} catch (e) {
throw Exception('Failed to search products: $e');
}
}
}