multiple receipts in a trip
This commit is contained in:
@@ -9,6 +9,7 @@ import 'models/line_item.dart';
|
||||
import 'models/shop.dart';
|
||||
import 'product_detail_screen.dart';
|
||||
import 'services/product_repository.dart';
|
||||
import 'services/receipt_capture.dart';
|
||||
import 'utils/dates.dart';
|
||||
import 'utils/money.dart';
|
||||
import 'widgets/confirm_dialog.dart';
|
||||
@@ -37,6 +38,7 @@ class _ShopDetailScreenState extends State<ShopDetailScreen> {
|
||||
bool _editing = false;
|
||||
List<String> _tagSuggestions = [];
|
||||
int _loadToken = 0;
|
||||
bool _addingReceipt = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -150,6 +152,42 @@ class _ShopDetailScreenState extends State<ShopDetailScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _addFromReceipt() async {
|
||||
final shop = _shop;
|
||||
if (shop == null || _addingReceipt) return;
|
||||
setState(() => _addingReceipt = true);
|
||||
try {
|
||||
final captured = await captureAndParseReceipt(context);
|
||||
if (captured == null || !mounted) return;
|
||||
|
||||
var added = 0;
|
||||
for (final item in captured.items) {
|
||||
await widget.repository.addShopItem(shopId: shop.id, item: item);
|
||||
added++;
|
||||
}
|
||||
if (!mounted) return;
|
||||
await _load();
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
added == 1
|
||||
? 'Added 1 item from receipt.'
|
||||
: 'Added $added items from receipt.',
|
||||
),
|
||||
),
|
||||
);
|
||||
} catch (_) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Could not add items from this receipt.')),
|
||||
);
|
||||
_load();
|
||||
} finally {
|
||||
if (mounted) setState(() => _addingReceipt = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _editItem(ShopItem item) async {
|
||||
final result = await showItemEditSheet(
|
||||
context,
|
||||
@@ -299,11 +337,41 @@ class _ShopDetailScreenState extends State<ShopDetailScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||
floatingActionButton: _editing
|
||||
? FloatingActionButton.extended(
|
||||
onPressed: _addItem,
|
||||
icon: const Icon(Icons.add),
|
||||
label: const Text('Add product'),
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: FilledButton.tonalIcon(
|
||||
onPressed: _addingReceipt ? null : _addFromReceipt,
|
||||
icon: _addingReceipt
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.receipt_long_outlined),
|
||||
label: const Text('Add receipt'),
|
||||
style: FilledButton.styleFrom(
|
||||
minimumSize: const Size.fromHeight(52),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: FilledButton.icon(
|
||||
onPressed: _addingReceipt ? null : _addItem,
|
||||
icon: const Icon(Icons.add),
|
||||
label: const Text('Add product'),
|
||||
style: FilledButton.styleFrom(
|
||||
minimumSize: const Size.fromHeight(52),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
body: Builder(
|
||||
|
||||
Reference in New Issue
Block a user