feat: scan book to add to sell
This commit is contained in:
parent
3a013c829f
commit
07c7c98edb
11 changed files with 238 additions and 31 deletions
|
|
@ -1,18 +1,34 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:mobile_scanner/mobile_scanner.dart';
|
||||
import 'package:seshat/data/repositories/bal_repository.dart';
|
||||
import 'package:seshat/data/repositories/book_instance_repository.dart';
|
||||
import 'package:seshat/data/repositories/book_repository.dart';
|
||||
import 'package:seshat/data/repositories/owner_repository.dart';
|
||||
import 'package:seshat/domain/models/bal.dart';
|
||||
import 'package:seshat/domain/models/book.dart';
|
||||
import 'package:seshat/domain/models/book_instance.dart';
|
||||
import 'package:seshat/domain/models/book_stack.dart';
|
||||
import 'package:seshat/domain/models/owner.dart';
|
||||
import 'package:seshat/utils/command.dart';
|
||||
import 'package:seshat/utils/result.dart';
|
||||
|
||||
class SellViewModel extends ChangeNotifier {
|
||||
SellViewModel({required BalRepository balRepository})
|
||||
: _balRepository = balRepository {
|
||||
SellViewModel({
|
||||
required BalRepository balRepository,
|
||||
required BookInstanceRepository bookInstanceRepository,
|
||||
required BookRepository bookRepository,
|
||||
required OwnerRepository ownerRepository,
|
||||
}) : _balRepository = balRepository,
|
||||
_bookInstanceRepository = bookInstanceRepository,
|
||||
_bookRepository = bookRepository,
|
||||
_ownerRepository = ownerRepository {
|
||||
load = Command0(_load)..execute();
|
||||
}
|
||||
|
||||
final BalRepository _balRepository;
|
||||
final BookInstanceRepository _bookInstanceRepository;
|
||||
final BookRepository _bookRepository;
|
||||
final OwnerRepository _ownerRepository;
|
||||
|
||||
bool _showScan = false;
|
||||
bool get showScan => _showScan;
|
||||
|
|
@ -27,28 +43,26 @@ class SellViewModel extends ChangeNotifier {
|
|||
* ===============================
|
||||
*/
|
||||
|
||||
final List<BookInstance> _scannedBooks = [];
|
||||
List<BookInstance> get scannedBooks => _scannedBooks;
|
||||
void scanBook(BarcodeCapture barcode) {
|
||||
final addedBook = BookInstance(
|
||||
balId: 5,
|
||||
bookId: 5,
|
||||
id: _scannedBooks.length,
|
||||
ownerId: 5,
|
||||
price: 5,
|
||||
available: true,
|
||||
);
|
||||
_scannedBooks.add(addedBook);
|
||||
final List<BookStack> _soldBooks = [];
|
||||
List<BookStack> get soldBooks => _soldBooks;
|
||||
|
||||
final List<BookStack> _scannedBooks = [];
|
||||
List<BookStack> get scannedBooks => _scannedBooks;
|
||||
|
||||
bool isScanLoaded = false;
|
||||
|
||||
void sellBook(BookStack addedBook) {
|
||||
_soldBooks.add(addedBook);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void sendSell() {
|
||||
_scannedBooks.clear();
|
||||
_soldBooks.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void deleteBook(int id) {
|
||||
_scannedBooks.removeWhere((book) => book.id == id);
|
||||
_soldBooks.removeWhere((book) => book.instance.id == id);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
|
@ -61,6 +75,11 @@ class SellViewModel extends ChangeNotifier {
|
|||
switch (result) {
|
||||
case Ok():
|
||||
for (BookInstance instance in result.value) {
|
||||
if (_soldBooks
|
||||
.where((book) => book.instance.id == instance.id)
|
||||
.isNotEmpty) {
|
||||
continue;
|
||||
}
|
||||
Book book;
|
||||
final result2 = await _bookRepository.getBookById(instance.bookId);
|
||||
switch (result2) {
|
||||
|
|
@ -79,9 +98,7 @@ class SellViewModel extends ChangeNotifier {
|
|||
case Error():
|
||||
continue;
|
||||
}
|
||||
_scannedBooks.add(
|
||||
BookStack(instance: instance, book: book, owner: owner),
|
||||
);
|
||||
_scannedBooks.add(BookStack(book, instance, owner));
|
||||
}
|
||||
break;
|
||||
case Error():
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:flutter_svg/svg.dart';
|
|||
import 'package:mobile_scanner/mobile_scanner.dart';
|
||||
import 'package:seshat/ui/sell_page/view_model/sell_view_model.dart';
|
||||
import 'package:seshat/ui/sell_page/widgets/manual_scan_popup.dart';
|
||||
import 'package:seshat/ui/sell_page/widgets/sell_choice_popup.dart';
|
||||
|
||||
class ScanScreen extends StatefulWidget {
|
||||
const ScanScreen({super.key, required this.viewModel});
|
||||
|
|
@ -30,12 +31,23 @@ class _ScanScreenState extends State<ScanScreen> {
|
|||
final theme = Theme.of(context);
|
||||
return Stack(
|
||||
children: [
|
||||
ColoredBox(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
),
|
||||
),
|
||||
MobileScanner(
|
||||
controller: controller,
|
||||
onDetect: (barcodes) async {
|
||||
widget.viewModel.showScan = false;
|
||||
widget.viewModel.scanBook(barcodes);
|
||||
controller.dispose();
|
||||
controller.stop();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
SellChoicePopup(viewModel: widget.viewModel),
|
||||
);
|
||||
await widget.viewModel.scanBook(barcodes);
|
||||
},
|
||||
),
|
||||
SafeArea(
|
||||
|
|
|
|||
64
lib/ui/sell_page/widgets/sell_choice_popup.dart
Normal file
64
lib/ui/sell_page/widgets/sell_choice_popup.dart
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:seshat/domain/models/book_stack.dart';
|
||||
import 'package:seshat/ui/sell_page/view_model/sell_view_model.dart';
|
||||
|
||||
class SellChoicePopup extends StatelessWidget {
|
||||
const SellChoicePopup({super.key, required this.viewModel});
|
||||
|
||||
final SellViewModel viewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListenableBuilder(
|
||||
listenable: viewModel,
|
||||
builder: (context, child) {
|
||||
return AlertDialog(
|
||||
title: Text("Choix du bon livre"),
|
||||
content: switch (viewModel.isScanLoaded) {
|
||||
false => SizedBox(
|
||||
height: 300,
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
true => SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
(viewModel.scannedBooks.isEmpty)
|
||||
? Text(
|
||||
"Ce livre n'a jamais été rentré, ou vous l'avez déjà mis dans cette vente.",
|
||||
)
|
||||
: SizedBox(),
|
||||
for (BookStack book in viewModel.scannedBooks)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: Card(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
viewModel.sellBook(book);
|
||||
Navigator.of(context).pop();
|
||||
viewModel.showScan = false;
|
||||
},
|
||||
child: ListTile(
|
||||
leading: Text(
|
||||
"${book.instance.price.toString()}€",
|
||||
style: TextStyle(fontSize: 30),
|
||||
),
|
||||
title: Text(
|
||||
"${book.book.title} · ${book.book.author}",
|
||||
),
|
||||
subtitle: Text(
|
||||
"${book.owner.firstName} ${book.owner.lastName} (${book.shortId()})",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:seshat/domain/models/book_instance.dart';
|
||||
import 'package:seshat/domain/models/book_stack.dart';
|
||||
import 'package:seshat/routing/routes.dart';
|
||||
import 'package:seshat/ui/core/ui/navigation_bar.dart';
|
||||
import 'package:seshat/ui/sell_page/view_model/sell_view_model.dart';
|
||||
|
|
@ -75,8 +75,7 @@ class _SellPageState extends State<SellPage> {
|
|||
(widget.viewModel.scannedBooks.isEmpty)
|
||||
? Center(child: Text("Aucun"))
|
||||
: SizedBox(),
|
||||
for (BookInstance bookInstance
|
||||
in widget.viewModel.scannedBooks)
|
||||
for (BookStack book in widget.viewModel.soldBooks)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
|
|
@ -84,19 +83,19 @@ class _SellPageState extends State<SellPage> {
|
|||
child: Card(
|
||||
child: ListTile(
|
||||
leading: Text(
|
||||
"${bookInstance.price.toString()}€",
|
||||
"${book.instance.price.toString()}€",
|
||||
style: TextStyle(fontSize: 30),
|
||||
),
|
||||
title: Text(
|
||||
"Les chiens et la charrue · Patrick K. Dewdney ${bookInstance.id}",
|
||||
"${book.book.title} · ${book.book.author}",
|
||||
),
|
||||
subtitle: Text(
|
||||
"Union Étudiante Auvergne",
|
||||
"${book.owner.firstName} ${book.owner.lastName} (${book.shortId()})",
|
||||
),
|
||||
trailing: IconButton(
|
||||
onPressed: () {
|
||||
widget.viewModel.deleteBook(
|
||||
bookInstance.id,
|
||||
book.instance.id,
|
||||
);
|
||||
},
|
||||
icon: Icon(Icons.delete),
|
||||
|
|
|
|||
Reference in a new issue