feat: enhance receipt import functionality with category selection and PDF opening support

This commit is contained in:
Nils-Johan Gynther
2026-05-01 22:46:58 +02:00
parent 5c263a14df
commit 4cbd658fa0
7 changed files with 440 additions and 68 deletions
@@ -13,6 +13,20 @@ import '../../features/admin/domain/admin_category_node.dart';
class CategoryThenProductPicker {
CategoryThenProductPicker._();
static List<String>? _findPath(
List<AdminCategoryNode> nodes,
int id,
List<String> parents,
) {
for (final node in nodes) {
final path = [...parents, node.name];
if (node.id == id) return path;
final found = _findPath(node.children, id, path);
if (found != null) return found;
}
return null;
}
/// Samlar alla ID:n för [node] och alla dess ättlingar rekursivt.
static Set<int> _collectIds(AdminCategoryNode node) {
final ids = <int>{node.id};
@@ -74,7 +88,7 @@ class CategoryThenProductPicker {
}
// Samla alla kategori-IDs i den valda grenen (inkl. ättlingar)
final categoryIds = _collectIds(selectedCategory!);
final categoryIds = _collectIds(selectedCategory);
// Filtrera produkter på dessa kategorier
final filtered = products
@@ -93,12 +107,39 @@ class CategoryThenProductPicker {
context,
products: useList,
value: currentProductId,
label: 'Produkt i "${selectedCategory!.name}"',
label: 'Produkt i "${selectedCategory.name}"',
categoryFilter: null, // redan förfiltrerat
initialQuery: initialQuery,
onCreate: onCreateBound,
);
}
static Future<({int id, String name, String path})?> showCategorySheet(
BuildContext context, {
required List<AdminCategoryNode> categoryTree,
int? preselectedCategoryId,
}) async {
if (!context.mounted) return null;
final selectedCategory = await showModalBottomSheet<AdminCategoryNode>(
context: context,
isScrollControlled: true,
useSafeArea: true,
builder: (ctx) => _CategoryPickerSheet(
tree: categoryTree,
preselectedId: preselectedCategoryId,
onSelected: (node) => Navigator.pop(ctx, node),
),
);
if (selectedCategory == null) return null;
final path = _findPath(categoryTree, selectedCategory.id, const [])
?.join(' > ') ??
selectedCategory.name;
return (
id: selectedCategory.id,
name: selectedCategory.name,
path: path,
);
}
}
// ── Kategoriträdets bottenark ────────────────────────────────────────────────
@@ -293,7 +334,7 @@ class _CategoryTileState extends State<_CategoryTile> {
dense: true,
selected: isPreselected,
selectedColor: theme.colorScheme.primary,
selectedTileColor: theme.colorScheme.primaryContainer.withOpacity(0.3),
selectedTileColor: theme.colorScheme.primaryContainer.withValues(alpha: 0.3),
leading: Icon(
Icons.label_outline,
size: 16,