mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
Allow user to manually remove (delete) a StockItem
This commit is contained in:
parent
6c3b83c05b
commit
ea724fcf5f
32
lib/api.dart
32
lib/api.dart
@ -918,7 +918,7 @@ class InvenTreeAPI {
|
||||
/*
|
||||
* Complete an API request, and return an APIResponse object
|
||||
*/
|
||||
Future<APIResponse> completeRequest(HttpClientRequest request, {String? data, int? statusCode}) async {
|
||||
Future<APIResponse> completeRequest(HttpClientRequest request, {String? data, int? statusCode, bool ignoreResponse = false}) async {
|
||||
|
||||
if (data != null && data.isNotEmpty) {
|
||||
|
||||
@ -954,8 +954,13 @@ class InvenTreeAPI {
|
||||
}
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
if (ignoreResponse) {
|
||||
response.data = {};
|
||||
} else {
|
||||
response.data = await responseToJson(_response) ?? {};
|
||||
}
|
||||
|
||||
if (statusCode != null) {
|
||||
|
||||
@ -1042,6 +1047,31 @@ class InvenTreeAPI {
|
||||
return completeRequest(request);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a HTTP DELETE request
|
||||
*/
|
||||
Future<APIResponse> delete(String url) async {
|
||||
|
||||
HttpClientRequest? request = await apiRequest(
|
||||
url,
|
||||
"DELETE",
|
||||
);
|
||||
|
||||
if (request == null) {
|
||||
// Return an "invalid" APIResponse object
|
||||
return APIResponse(
|
||||
url: url,
|
||||
method: "DELETE",
|
||||
error: "HttpClientRequest is null",
|
||||
);
|
||||
}
|
||||
|
||||
return completeRequest(
|
||||
request,
|
||||
ignoreResponse: true,
|
||||
);
|
||||
}
|
||||
|
||||
// Return a list of request headers
|
||||
Map<String, String> defaultHeaders() {
|
||||
Map<String, String> headers = {};
|
||||
|
@ -222,6 +222,38 @@ class InvenTreeModel {
|
||||
return {};
|
||||
}
|
||||
|
||||
/// Delete the instance on the remote server
|
||||
/// Returns true if the operation was successful, else false
|
||||
Future<bool> delete() async {
|
||||
var response = await api.delete(url);
|
||||
|
||||
if (!response.isValid() || response.data == null || (response.data is! Map)) {
|
||||
|
||||
if (response.statusCode > 0) {
|
||||
await sentryReportMessage(
|
||||
"InvenTreeModel.delete() returned invalid response",
|
||||
context: {
|
||||
"url": url,
|
||||
"statusCode": response.statusCode.toString(),
|
||||
"data": response.data?.toString() ?? "null",
|
||||
"error": response.error,
|
||||
"errorDetail": response.errorDetail,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
showServerError(
|
||||
L10().serverError,
|
||||
L10().errorDelete,
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Status code should be 204 for "record deleted"
|
||||
return response.statusCode == 204;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reload this object, by requesting data from the server
|
||||
*/
|
||||
@ -242,7 +274,7 @@ class InvenTreeModel {
|
||||
"valid": response.isValid().toString(),
|
||||
"error": response.error,
|
||||
"errorDetail": response.errorDetail,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -466,8 +498,6 @@ class InvenTreeModel {
|
||||
// Provide a listing of objects at the endpoint
|
||||
// TODO - Static function which returns a list of objects (of this class)
|
||||
|
||||
// TODO - Define a "delete" function
|
||||
|
||||
// TODO - Define a "save" / "update" function
|
||||
|
||||
// Override this function for each sub-class
|
||||
|
@ -8,7 +8,7 @@ import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
|
||||
Future<void> confirmationDialog(String title, String text, {String? acceptText, String? rejectText, Function? onAccept, Function? onReject}) async {
|
||||
Future<void> confirmationDialog(String title, String text, {IconData icon = FontAwesomeIcons.questionCircle, String? acceptText, String? rejectText, Function? onAccept, Function? onReject}) async {
|
||||
|
||||
String _accept = acceptText ?? L10().ok;
|
||||
String _reject = rejectText ?? L10().cancel;
|
||||
@ -18,7 +18,7 @@ Future<void> confirmationDialog(String title, String text, {String? acceptText,
|
||||
return AlertDialog(
|
||||
title: ListTile(
|
||||
title: Text(title),
|
||||
leading: FaIcon(FontAwesomeIcons.questionCircle),
|
||||
leading: FaIcon(icon),
|
||||
),
|
||||
content: Text(text),
|
||||
actions: [
|
||||
|
@ -157,6 +157,27 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
/// Delete the stock item from the database
|
||||
Future<void> _deleteItem(BuildContext context) async {
|
||||
|
||||
confirmationDialog(
|
||||
L10().stockItemDelete,
|
||||
L10().stockItemDeleteConfirm,
|
||||
icon: FontAwesomeIcons.trashAlt,
|
||||
onAccept: () async {
|
||||
final bool result = await item.delete();
|
||||
|
||||
if (result) {
|
||||
Navigator.of(context).pop();
|
||||
showSnackIcon(L10().stockItemDeleteSuccess, success: true);
|
||||
} else {
|
||||
showSnackIcon(L10().stockItemDeleteFailure, success: false);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/// Opens a popup dialog allowing user to select a label for printing
|
||||
Future <void> _printLabel(BuildContext context) async {
|
||||
|
||||
@ -1003,6 +1024,19 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
// If the user has permission to delete this stock item
|
||||
if (InvenTreeAPI().checkPermission("stock", "delete")) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text("Delete Stock Item"),
|
||||
leading: FaIcon(FontAwesomeIcons.trashAlt, color: COLOR_DANGER),
|
||||
onTap: () {
|
||||
_deleteItem(context);
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user