mirror of
https://github.com/inventree/inventree-app.git
synced 2025-05-04 00:08:53 +00:00
Refactor stock adjustment actions
- Handle timeout - Handle error
This commit is contained in:
parent
c8c056f96d
commit
3757010599
@ -1,4 +1,5 @@
|
||||
import 'package:InvenTree/inventree/part.dart';
|
||||
import 'package:InvenTree/widget/dialogs.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'model.dart';
|
||||
@ -391,51 +392,81 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
return item;
|
||||
}
|
||||
|
||||
Future<http.Response> countStock(double quan, {String notes}) async {
|
||||
/*
|
||||
* Perform stocktake action:
|
||||
*
|
||||
* - Add
|
||||
* - Remove
|
||||
* - Count
|
||||
*/
|
||||
Future<bool> adjustStock(BuildContext context, String endpoint, double q, {String notes}) async {
|
||||
|
||||
// Cannot 'count' a serialized StockItem
|
||||
// Serialized stock cannot be adjusted
|
||||
if (isSerialized()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot handle negative stock
|
||||
if (q < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var response = await api.post(
|
||||
endpoint,
|
||||
body: {
|
||||
"item": {
|
||||
"pk": "${pk}",
|
||||
"quantity": "${q}",
|
||||
},
|
||||
"notes": notes ?? '',
|
||||
}).timeout(Duration(seconds: 10)).catchError((error) {
|
||||
if (error is TimeoutException) {
|
||||
showTimeoutError(context);
|
||||
} else if (error is SocketException) {
|
||||
showServerError(
|
||||
context,
|
||||
I18N.of(context).connectionRefused,
|
||||
error.toString()
|
||||
);
|
||||
} else {
|
||||
// Re-throw the error, let sentry handle it!
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Null response if error
|
||||
return null;
|
||||
}
|
||||
|
||||
// Cannot count negative stock
|
||||
if (quan < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return api.post("/stock/count/", body: {
|
||||
"item": {
|
||||
"pk": "${pk}",
|
||||
"quantity": "${quan}",
|
||||
},
|
||||
"notes": notes ?? '',
|
||||
});
|
||||
|
||||
if (response == null) return false;
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
showStatusCodeError(context, response.statusCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<http.Response> addStock(double quan, {String notes}) async {
|
||||
|
||||
if (isSerialized() || quan <= 0) return null;
|
||||
|
||||
return api.post("/stock/add/", body: {
|
||||
"item": {
|
||||
"pk": "${pk}",
|
||||
"quantity": "${quan}",
|
||||
},
|
||||
"notes": notes ?? '',
|
||||
});
|
||||
// Stock adjustment succeeded!
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<http.Response> removeStock(double quan, {String notes}) async {
|
||||
Future<bool> countStock(BuildContext context, double q, {String notes}) async {
|
||||
|
||||
if (isSerialized() || quan <= 0) return null;
|
||||
final bool result = await adjustStock(context, "/stock/count", q, notes: notes);
|
||||
|
||||
return api.post("/stock/remove/", body: {
|
||||
"item": {
|
||||
"pk": "${pk}",
|
||||
"quantity": "${quan}",
|
||||
},
|
||||
"notes": notes ?? '',
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<bool> addStock(BuildContext context, double q, {String notes}) async {
|
||||
|
||||
final bool result = await adjustStock(context, "/stock/add/", q, notes: notes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<bool> removeStock(BuildContext context, double q, {String notes}) async {
|
||||
|
||||
final bool result = await adjustStock(context, "/stock/remove/", q, notes: notes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<http.Response> transferStock(int location, {double quantity, String notes}) async {
|
||||
|
2
lib/l10n
2
lib/l10n
@ -1 +1 @@
|
||||
Subproject commit 249e4964a08b79e53df7e1ea18b051de0d307905
|
||||
Subproject commit ed3bd59b15b2c69b9a21649a0e0507efd811c1a1
|
@ -70,13 +70,11 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
double quantity = double.parse(_quantityController.text);
|
||||
_quantityController.clear();
|
||||
|
||||
// Await response to prevent the button from being pressed multiple times
|
||||
var response = await item.addStock(quantity, notes: _notesController.text);
|
||||
final bool result = await item.addStock(context, quantity, notes: _notesController.text);
|
||||
_notesController.clear();
|
||||
|
||||
_stockUpdateMessage(response);
|
||||
_stockUpdateMessage(result);
|
||||
|
||||
// TODO - Handle error cases
|
||||
refresh();
|
||||
}
|
||||
|
||||
@ -111,20 +109,27 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
void _stockUpdateMessage(bool result) {
|
||||
|
||||
showSnackIcon(
|
||||
refreshableKey,
|
||||
result ? "Stock item updated" : "Stock item updated failed",
|
||||
success: result
|
||||
);
|
||||
}
|
||||
|
||||
void _removeStock() async {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
double quantity = double.parse(_quantityController.text);
|
||||
_quantityController.clear();
|
||||
|
||||
var response = await item.removeStock(quantity, notes: _notesController.text);
|
||||
_notesController.clear();
|
||||
final bool result = await item.removeStock(context, quantity, notes: _notesController.text);
|
||||
|
||||
// TODO - Handle error cases
|
||||
_stockUpdateMessage(result);
|
||||
|
||||
refresh();
|
||||
|
||||
// TODO - Display a snackbar here indicating the action was successful (or otherwise)
|
||||
}
|
||||
|
||||
void _removeStockDialog() {
|
||||
@ -166,19 +171,16 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
double quantity = double.parse(_quantityController.text);
|
||||
_quantityController.clear();
|
||||
|
||||
var response = await item.countStock(quantity, notes: _notesController.text);
|
||||
_notesController.clear();
|
||||
final bool result = await item.countStock(context, quantity, notes: _notesController.text);
|
||||
|
||||
// TODO - Handle error cases, timeout, etc
|
||||
_stockUpdateMessage(result);
|
||||
|
||||
refresh();
|
||||
|
||||
// TODO - Display a snackbar here indicating the action was successful (or otherwise)
|
||||
}
|
||||
|
||||
void _countStockDialog() async {
|
||||
|
||||
_quantityController.text = item.quantity.toString();
|
||||
_quantityController.text = item.quantityString;
|
||||
_notesController.clear();
|
||||
|
||||
showFormDialog(context, I18N.of(context).countStock,
|
||||
@ -194,7 +196,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
fields: <Widget> [
|
||||
QuantityField(
|
||||
label: I18N.of(context).countStock,
|
||||
hint: "${item.quantity}",
|
||||
hint: "${item.quantityString}",
|
||||
controller: _quantityController,
|
||||
),
|
||||
TextFormField(
|
||||
@ -233,7 +235,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
|
||||
InvenTreeStockLocation selectedLocation;
|
||||
|
||||
_quantityController.text = "${item.quantity}";
|
||||
_quantityController.text = "${item.quantityString}";
|
||||
|
||||
showFormDialog(context, I18N.of(context).transferStock,
|
||||
key: _moveStockKey,
|
||||
@ -385,7 +387,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
ListTile(
|
||||
title: Text(I18N.of(context).quantity),
|
||||
leading: FaIcon(FontAwesomeIcons.cubes),
|
||||
trailing: Text("${item.quantity}"),
|
||||
trailing: Text("${item.quantityString}"),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user