Implement admin inventory management features including CRUD operations, merging, filtering, sorting, previewing, and security enhancements. Update documentation and add comprehensive test coverage for security and validation.
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
This commit is contained in:
@@ -6,6 +6,7 @@ import '../../../core/api/guarded_api_call.dart';
|
||||
import '../../auth/data/auth_providers.dart';
|
||||
import '../domain/admin_ai_categorize_result.dart';
|
||||
import '../domain/admin_category_node.dart';
|
||||
import '../domain/admin_inventory_item.dart';
|
||||
import '../domain/admin_product.dart';
|
||||
import '../domain/ai_model_info.dart';
|
||||
import '../domain/pending_product.dart';
|
||||
@@ -311,4 +312,103 @@ class AdminRepository {
|
||||
|
||||
Future<void> removeReceiptAlias(int id) =>
|
||||
_deleteVoid(ReceiptAliasApiPaths.remove(id));
|
||||
|
||||
// ── Admin inventory (global tabellhantering) ─────────────────────────────
|
||||
|
||||
Future<List<AdminInventoryItem>> listAdminInventory({
|
||||
int? userId,
|
||||
String? sort,
|
||||
}) {
|
||||
final path = AdminInventoryApiPaths.withFilters(userId: userId, sort: sort);
|
||||
return _getList(path, AdminInventoryItem.fromJson);
|
||||
}
|
||||
|
||||
Future<AdminInventoryItem> createAdminInventory({
|
||||
int? userId,
|
||||
required int productId,
|
||||
required double quantity,
|
||||
required String unit,
|
||||
String? location,
|
||||
String? brand,
|
||||
String? receiptName,
|
||||
String? suitableFor,
|
||||
String? comment,
|
||||
}) {
|
||||
return _post<AdminInventoryItem>(
|
||||
AdminInventoryApiPaths.list,
|
||||
body: {
|
||||
if (userId != null) 'userId': userId,
|
||||
'productId': productId,
|
||||
'quantity': quantity,
|
||||
'unit': unit,
|
||||
if (location != null && location.trim().isNotEmpty)
|
||||
'location': location.trim(),
|
||||
if (brand != null && brand.trim().isNotEmpty) 'brand': brand.trim(),
|
||||
if (receiptName != null && receiptName.trim().isNotEmpty)
|
||||
'receiptName': receiptName.trim(),
|
||||
if (suitableFor != null && suitableFor.trim().isNotEmpty)
|
||||
'suitableFor': suitableFor.trim(),
|
||||
if (comment != null && comment.trim().isNotEmpty)
|
||||
'comment': comment.trim(),
|
||||
},
|
||||
parse: (d) =>
|
||||
AdminInventoryItem.fromJson(Map<String, dynamic>.from(d as Map)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<AdminInventoryItem> updateAdminInventory(
|
||||
int inventoryId, {
|
||||
int? productId,
|
||||
double? quantity,
|
||||
String? unit,
|
||||
String? location,
|
||||
String? brand,
|
||||
String? receiptName,
|
||||
String? suitableFor,
|
||||
String? comment,
|
||||
}) {
|
||||
final body = <String, dynamic>{
|
||||
if (productId != null) 'productId': productId,
|
||||
if (quantity != null) 'quantity': quantity,
|
||||
if (unit != null) 'unit': unit,
|
||||
if (location != null) 'location': location,
|
||||
if (brand != null) 'brand': brand,
|
||||
if (receiptName != null) 'receiptName': receiptName,
|
||||
if (suitableFor != null) 'suitableFor': suitableFor,
|
||||
if (comment != null) 'comment': comment,
|
||||
};
|
||||
|
||||
return _patch(
|
||||
AdminInventoryApiPaths.update(inventoryId),
|
||||
body: body,
|
||||
parse: AdminInventoryItem.fromJson,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> removeAdminInventory(int inventoryId) =>
|
||||
_deleteVoid(AdminInventoryApiPaths.remove(inventoryId));
|
||||
|
||||
Future<void> mergeAdminInventory({
|
||||
required int sourceInventoryId,
|
||||
required int targetInventoryId,
|
||||
}) =>
|
||||
_postVoid(AdminInventoryApiPaths.merge, {
|
||||
'sourceInventoryId': sourceInventoryId,
|
||||
'targetInventoryId': targetInventoryId,
|
||||
});
|
||||
|
||||
Future<Map<String, dynamic>> previewAdminInventoryMerge({
|
||||
required int sourceInventoryId,
|
||||
required int targetInventoryId,
|
||||
}) async {
|
||||
final token = await _token();
|
||||
final data = await guardedApiCall(
|
||||
_ref,
|
||||
() => _apiClient.getJson(
|
||||
AdminInventoryApiPaths.mergePreview(sourceInventoryId, targetInventoryId),
|
||||
token: token,
|
||||
),
|
||||
);
|
||||
return Map<String, dynamic>.from(data as Map);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user