fix(receipt-import): surface create-product errors and harden response parsing
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../../core/api/api_exception.dart';
|
||||
import '../../../core/api/api_paths.dart';
|
||||
import '../../../core/api/api_providers.dart';
|
||||
import '../../../core/ui/category_then_product_picker.dart';
|
||||
@@ -370,7 +371,16 @@ class _EditDialogState extends State<_EditDialog> {
|
||||
_newProductNameCtrl.text.trim(),
|
||||
_newCategoryId!,
|
||||
);
|
||||
if (newProduct == null || !mounted) return;
|
||||
if (newProduct == null || !mounted) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Kunde inte skapa produkten. Försök igen.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!_localProducts.any((p) => p.id == newProduct.id)) {
|
||||
_localProducts = [..._localProducts, newProduct];
|
||||
}
|
||||
@@ -379,6 +389,28 @@ class _EditDialogState extends State<_EditDialog> {
|
||||
_productCategoryId = _newCategoryId;
|
||||
_productCategoryPath = _newCategoryPath;
|
||||
_productCategorySource = _newCategorySource ?? CategorySelectionSource.manual;
|
||||
} on ApiException catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
e.message.trim().isEmpty
|
||||
? 'Kunde inte skapa produkten. Försök igen.'
|
||||
: e.message,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
} catch (_) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Kunde inte skapa produkten. Försök igen.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
if (mounted) setState(() => _isCreatingProduct = false);
|
||||
}
|
||||
@@ -997,27 +1029,44 @@ class _ReceiptImportTabState extends ConsumerState<ReceiptImportTab> {
|
||||
categoryTree: _categoryTree,
|
||||
initialEntryMode: initialEntryMode,
|
||||
onCreate: (name, categoryId) async {
|
||||
try {
|
||||
final token = await ref.read(authStateProvider.future);
|
||||
final api = ref.read(apiClientProvider);
|
||||
final data = await api.postJson(
|
||||
ProductApiPaths.createPrivate,
|
||||
body: {
|
||||
'name': name.trim(),
|
||||
'categoryId': categoryId,
|
||||
},
|
||||
token: token,
|
||||
) as Map<String, dynamic>;
|
||||
final newProduct = (
|
||||
id: data['id'] as int,
|
||||
name: (data['canonicalName'] ?? data['name']) as String,
|
||||
categoryId: categoryId,
|
||||
);
|
||||
if (mounted) setState(() => _products = [..._products, newProduct]);
|
||||
return newProduct;
|
||||
} catch (_) {
|
||||
return null;
|
||||
final token = await ref.read(authStateProvider.future);
|
||||
final api = ref.read(apiClientProvider);
|
||||
final raw = await api.postJson(
|
||||
ProductApiPaths.createPrivate,
|
||||
body: {
|
||||
'name': name.trim(),
|
||||
'categoryId': categoryId,
|
||||
},
|
||||
token: token,
|
||||
);
|
||||
|
||||
if (raw is! Map<String, dynamic>) {
|
||||
throw Exception('Ogiltigt API-svar vid produktskapande.');
|
||||
}
|
||||
|
||||
final idRaw = raw['id'];
|
||||
if (idRaw is! num) {
|
||||
throw Exception('API-svar saknar giltigt produkt-id.');
|
||||
}
|
||||
|
||||
final displayNameRaw = raw['canonicalName'] ?? raw['name'];
|
||||
final displayName = displayNameRaw?.toString().trim();
|
||||
if (displayName == null || displayName.isEmpty) {
|
||||
throw Exception('API-svar saknar produktnamn.');
|
||||
}
|
||||
|
||||
final returnedCategoryId = raw['categoryId'] is num
|
||||
? (raw['categoryId'] as num).toInt()
|
||||
: categoryId;
|
||||
|
||||
final newProduct = (
|
||||
id: idRaw.toInt(),
|
||||
name: displayName,
|
||||
categoryId: returnedCategoryId,
|
||||
);
|
||||
|
||||
if (mounted) setState(() => _products = [..._products, newProduct]);
|
||||
return newProduct;
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user