/// Data Source: Quotes Local Data Source /// /// Handles local storage operations for quotes using Hive. library; import 'package:hive_ce/hive.dart'; import 'package:worker/core/constants/storage_constants.dart'; import 'package:worker/core/database/models/enums.dart'; import 'package:worker/features/quotes/data/models/quote_model.dart'; /// Quotes Local Data Source /// /// Provides methods to interact with locally stored quote data. class QuotesLocalDataSource { Box? _quotesBox; /// Get Hive box for quotes Future> get quotesBox async { _quotesBox ??= await Hive.openBox(HiveBoxNames.quotes); return _quotesBox!; } /// Get all quotes Future> getAllQuotes() async { final box = await quotesBox; return box.values.toList(); } /// Get quote by ID Future getQuoteById(String quoteId) async { final box = await quotesBox; return box.values.firstWhere( (quote) => quote.quoteId == quoteId, orElse: () => throw Exception('Quote not found'), ); } /// Save quote Future saveQuote(QuoteModel quote) async { final box = await quotesBox; await box.put(quote.quoteId, quote); } /// Save multiple quotes Future saveQuotes(List quotes) async { final box = await quotesBox; final Map quotesMap = { for (var quote in quotes) quote.quoteId: quote, }; await box.putAll(quotesMap); } /// Delete quote Future deleteQuote(String quoteId) async { final box = await quotesBox; await box.delete(quoteId); } /// Clear all quotes Future clearQuotes() async { final box = await quotesBox; await box.clear(); } /// Get quotes by status Future> getQuotesByStatus(QuoteStatus status) async { final quotes = await getAllQuotes(); return quotes.where((quote) => quote.status == status).toList(); } /// Search quotes Future> searchQuotes(String query) async { final quotes = await getAllQuotes(); final lowerQuery = query.toLowerCase(); return quotes.where((quote) { final matchesNumber = quote.quoteNumber.toLowerCase().contains( lowerQuery, ); final matchesProject = quote.projectName?.toLowerCase().contains(lowerQuery) ?? false; return matchesNumber || matchesProject; }).toList(); } /// Seed mock data for development Future seedMockQuotes() async { final mockQuotes = [ QuoteModel( quoteId: 'quote_001', quoteNumber: 'YC001234', userId: 'user_001', status: QuoteStatus.viewed, totalAmount: 45000000, discountAmount: 2250000, finalAmount: 42750000, projectName: 'Villa Thủ Đức - Giai đoạn 2', notes: 'Khách hàng yêu cầu giảm giá 5%', validUntil: DateTime.now().add(const Duration(days: 30)), createdAt: DateTime(2023, 8, 5), ), QuoteModel( quoteId: 'quote_002', quoteNumber: 'YC001233', userId: 'user_001', status: QuoteStatus.accepted, totalAmount: 125500000, discountAmount: 0, finalAmount: 125500000, projectName: 'Chung cư Landmark Center', notes: 'Tổng giá trị: 125.500.000 VND', validUntil: DateTime.now().add(const Duration(days: 45)), createdAt: DateTime(2023, 8, 3), ), QuoteModel( quoteId: 'quote_003', quoteNumber: 'YC001232', userId: 'user_001', status: QuoteStatus.converted, totalAmount: 32500000, discountAmount: 500000, finalAmount: 32000000, projectName: 'Nhà phố Bình Thạnh', notes: 'Mã đơn hàng: #DH005432', convertedOrderId: 'order_005432', validUntil: DateTime.now().subtract(const Duration(days: 5)), createdAt: DateTime(2023, 8, 1), ), QuoteModel( quoteId: 'quote_004', quoteNumber: 'YC001231', userId: 'user_001', status: QuoteStatus.sent, totalAmount: 78000000, discountAmount: 3000000, finalAmount: 75000000, projectName: 'Văn phòng Quận 7', notes: 'Chờ khách hàng phản hồi', validUntil: DateTime.now().add(const Duration(days: 20)), createdAt: DateTime(2023, 7, 31), ), QuoteModel( quoteId: 'quote_005', quoteNumber: 'YC001230', userId: 'user_001', status: QuoteStatus.draft, totalAmount: 185000000, discountAmount: 5000000, finalAmount: 180000000, projectName: 'Resort Vũng Tàu', notes: 'Yêu cầu báo giá cho khu vực pool và spa', validUntil: DateTime.now().add(const Duration(days: 60)), createdAt: DateTime(2023, 7, 29), ), QuoteModel( quoteId: 'quote_006', quoteNumber: 'YC001229', userId: 'user_001', status: QuoteStatus.cancelled, totalAmount: 56000000, discountAmount: 1000000, finalAmount: 55000000, projectName: 'Showroom Quận 1', notes: 'Khách hàng hủy dự án', validUntil: DateTime.now().subtract(const Duration(days: 10)), createdAt: DateTime(2023, 7, 25), ), ]; await saveQuotes(mockQuotes); } }