add quotes

This commit is contained in:
Phuoc Nguyen
2025-10-27 15:30:31 +07:00
parent 7ce4239772
commit 3020c4e626
8 changed files with 1177 additions and 4 deletions

View File

@@ -0,0 +1,170 @@
/// 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<QuoteModel>? _quotesBox;
/// Get Hive box for quotes
Future<Box<QuoteModel>> get quotesBox async {
_quotesBox ??= await Hive.openBox<QuoteModel>(HiveBoxNames.quotes);
return _quotesBox!;
}
/// Get all quotes
Future<List<QuoteModel>> getAllQuotes() async {
final box = await quotesBox;
return box.values.toList();
}
/// Get quote by ID
Future<QuoteModel?> 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<void> saveQuote(QuoteModel quote) async {
final box = await quotesBox;
await box.put(quote.quoteId, quote);
}
/// Save multiple quotes
Future<void> saveQuotes(List<QuoteModel> quotes) async {
final box = await quotesBox;
final Map<String, QuoteModel> quotesMap = {
for (var quote in quotes) quote.quoteId: quote,
};
await box.putAll(quotesMap);
}
/// Delete quote
Future<void> deleteQuote(String quoteId) async {
final box = await quotesBox;
await box.delete(quoteId);
}
/// Clear all quotes
Future<void> clearQuotes() async {
final box = await quotesBox;
await box.clear();
}
/// Get quotes by status
Future<List<QuoteModel>> getQuotesByStatus(QuoteStatus status) async {
final quotes = await getAllQuotes();
return quotes.where((quote) => quote.status == status).toList();
}
/// Search quotes
Future<List<QuoteModel>> 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<void> 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);
}
}