mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 13:36:50 +00:00
Snack bars for barcode actions
This commit is contained in:
parent
0773b2e70d
commit
b7e9c06dfa
137
lib/barcode.dart
137
lib/barcode.dart
@ -45,28 +45,19 @@ class BarcodeHandler {
|
|||||||
Future<void> onBarcodeUnknown(Map<String, dynamic> data) {
|
Future<void> onBarcodeUnknown(Map<String, dynamic> data) {
|
||||||
// Called when the server does not know about a barcode
|
// Called when the server does not know about a barcode
|
||||||
// Override this function
|
// Override this function
|
||||||
showErrorDialog(
|
showSnackIcon(
|
||||||
"Invalid Barcode",
|
I18N.of(OneContext().context).barcodeNoMatch,
|
||||||
"Barcode does not match any known item",
|
success: false,
|
||||||
error: "Barcode Error",
|
icon: FontAwesomeIcons.qrcode
|
||||||
icon: FontAwesomeIcons.barcode,
|
|
||||||
onDismissed: () {
|
|
||||||
_controller.resumeCamera();
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) {
|
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) {
|
||||||
// Called when the server returns an unhandled response
|
// Called when the server returns an unhandled response
|
||||||
showErrorDialog(
|
showServerError(I18N.of(OneContext().context).responseUnknown, data.toString());
|
||||||
"Response Data",
|
|
||||||
data.toString(),
|
|
||||||
error: "Unknown Response",
|
|
||||||
onDismissed: () {
|
|
||||||
_controller.resumeCamera();
|
_controller.resumeCamera();
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> processBarcode(BuildContext context, QRViewController _controller, String barcode, {String url = "barcode/"}) {
|
Future<void> processBarcode(BuildContext context, QRViewController _controller, String barcode, {String url = "barcode/"}) {
|
||||||
this._context = context;
|
this._context = context;
|
||||||
@ -93,23 +84,22 @@ class BarcodeHandler {
|
|||||||
final Map<String, dynamic> data = json.decode(response.body);
|
final Map<String, dynamic> data = json.decode(response.body);
|
||||||
|
|
||||||
if (data.containsKey('error')) {
|
if (data.containsKey('error')) {
|
||||||
|
_controller.resumeCamera();
|
||||||
onBarcodeUnknown(data);
|
onBarcodeUnknown(data);
|
||||||
} else if (data.containsKey('success')) {
|
} else if (data.containsKey('success')) {
|
||||||
|
_controller.resumeCamera();
|
||||||
onBarcodeMatched(data);
|
onBarcodeMatched(data);
|
||||||
} else {
|
} else {
|
||||||
|
_controller.resumeCamera();
|
||||||
onBarcodeUnhandled(data);
|
onBarcodeUnhandled(data);
|
||||||
}
|
}
|
||||||
}).timeout(
|
}).timeout(
|
||||||
Duration(seconds: 5)
|
Duration(seconds: 5)
|
||||||
).catchError((error) {
|
).catchError((error) {
|
||||||
|
|
||||||
showErrorDialog(
|
showServerError(I18N.of(OneContext().context).error, error.toString());
|
||||||
I18N.of(OneContext().context).error,
|
|
||||||
error.toString(),
|
|
||||||
onDismissed: () {
|
|
||||||
_controller.resumeCamera();
|
_controller.resumeCamera();
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -129,30 +119,10 @@ class BarcodeScanHandler extends BarcodeHandler {
|
|||||||
Future<void> onBarcodeUnknown(Map<String, dynamic> data) {
|
Future<void> onBarcodeUnknown(Map<String, dynamic> data) {
|
||||||
|
|
||||||
showSnackIcon(
|
showSnackIcon(
|
||||||
"No barcode",
|
I18N.of(OneContext().context).barcodeNoMatch,
|
||||||
icon: FontAwesomeIcons.exclamationCircle,
|
icon: FontAwesomeIcons.exclamationCircle,
|
||||||
actionText: "Details",
|
success: false,
|
||||||
onAction: () {
|
|
||||||
print("Action!");
|
|
||||||
},
|
|
||||||
success: true,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
_controller.resumeCamera();
|
|
||||||
|
|
||||||
/*
|
|
||||||
showErrorDialog(
|
|
||||||
_context,
|
|
||||||
data['error'] ?? '',
|
|
||||||
data['plugin'] ?? 'No barcode plugin information',
|
|
||||||
error: "Barcode Error",
|
|
||||||
icon: FontAwesomeIcons.barcode,
|
|
||||||
onDismissed: () {
|
|
||||||
_controller.resumeCamera();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -175,7 +145,10 @@ class BarcodeScanHandler extends BarcodeHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// TODO - Show an error here!
|
showSnackIcon(
|
||||||
|
I18N.of(OneContext().context).invalidStockLocation,
|
||||||
|
success: false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (data.containsKey('stockitem')) {
|
} else if (data.containsKey('stockitem')) {
|
||||||
@ -188,7 +161,10 @@ class BarcodeScanHandler extends BarcodeHandler {
|
|||||||
Navigator.push(_context, MaterialPageRoute(builder: (context) => StockDetailWidget(item)));
|
Navigator.push(_context, MaterialPageRoute(builder: (context) => StockDetailWidget(item)));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// TODO - Show an error here!
|
showSnackIcon(
|
||||||
|
I18N.of(OneContext().context).invalidStockItem,
|
||||||
|
success: false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (data.containsKey('part')) {
|
} else if (data.containsKey('part')) {
|
||||||
|
|
||||||
@ -200,9 +176,16 @@ class BarcodeScanHandler extends BarcodeHandler {
|
|||||||
Navigator.push(_context, MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
|
Navigator.push(_context, MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// TODO - Show an error here!
|
showSnackIcon(
|
||||||
|
I18N.of(OneContext().context).invalidPart,
|
||||||
|
success: false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
showSnackIcon(
|
||||||
|
I18N.of(OneContext().context).barcodeUnknown,
|
||||||
|
success: false,
|
||||||
|
onAction: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: _context,
|
context: _context,
|
||||||
child: SimpleDialog(
|
child: SimpleDialog(
|
||||||
@ -216,6 +199,8 @@ class BarcodeScanHandler extends BarcodeHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,12 +220,10 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
|||||||
@override
|
@override
|
||||||
Future<void> onBarcodeMatched(Map<String, dynamic> data) {
|
Future<void> onBarcodeMatched(Map<String, dynamic> data) {
|
||||||
// If the barcode is known, we can't asisgn it to the stock item!
|
// If the barcode is known, we can't asisgn it to the stock item!
|
||||||
showErrorDialog(
|
showSnackIcon(
|
||||||
"Barcode in Use",
|
I18N.of(OneContext().context).barcodeInUse,
|
||||||
"Barcode is already known",
|
icon: FontAwesomeIcons.qrcode,
|
||||||
onDismissed: () {
|
success: false
|
||||||
_controller.resumeCamera();
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,14 +232,9 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
|||||||
// If the barcode is unknown, we *can* assign it to the stock item!
|
// If the barcode is unknown, we *can* assign it to the stock item!
|
||||||
|
|
||||||
if (!data.containsKey("hash")) {
|
if (!data.containsKey("hash")) {
|
||||||
showErrorDialog(
|
showServerError("Missing data", "Barcode hash data missing from response");
|
||||||
"Missing Data",
|
|
||||||
"Missing hash data from server",
|
|
||||||
onDismissed: () {
|
|
||||||
_controller.resumeCamera();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Send the 'hash' code as the UID for the stock item
|
// Send the 'hash' code as the UID for the stock item
|
||||||
item.update(
|
item.update(
|
||||||
_context,
|
_context,
|
||||||
@ -265,22 +243,22 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
|||||||
}
|
}
|
||||||
).then((result) {
|
).then((result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
showInfoDialog(
|
|
||||||
_context,
|
// Close the barcode scanner
|
||||||
"Barcode Set",
|
|
||||||
"Barcode assigned to stock item",
|
|
||||||
onDismissed: () {
|
|
||||||
_controller.dispose();
|
_controller.dispose();
|
||||||
Navigator.of(_context).pop();
|
Navigator.of(_context).pop();
|
||||||
}
|
|
||||||
|
showSnackIcon(
|
||||||
|
I18N.of(OneContext().context).barcodeAssigned,
|
||||||
|
success: true,
|
||||||
|
icon: FontAwesomeIcons.qrcode
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
showErrorDialog(
|
|
||||||
"Server Error",
|
showSnackIcon(
|
||||||
"Could not assign barcode",
|
I18N.of(OneContext().context).barcodeNotAssigned,
|
||||||
onDismissed: () {
|
success: false,
|
||||||
_controller.resumeCamera();
|
icon: FontAwesomeIcons.qrcode
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -393,14 +371,23 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler {
|
|||||||
// Transfer stock to specified location
|
// Transfer stock to specified location
|
||||||
item.transferStock(location).then((response) {
|
item.transferStock(location).then((response) {
|
||||||
print("Response: ${response.statusCode}");
|
print("Response: ${response.statusCode}");
|
||||||
|
|
||||||
|
// Close the scanner
|
||||||
_controller.dispose();
|
_controller.dispose();
|
||||||
Navigator.of(_context).pop();
|
Navigator.of(_context).pop();
|
||||||
|
|
||||||
|
showSnackIcon(
|
||||||
|
I18N.of(OneContext().context).barcodeScanIntoLocationSuccess,
|
||||||
|
success: true,
|
||||||
|
);
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Display a snack bar with the error
|
showSnackIcon(
|
||||||
OneContext().showSnackBar(builder: (context) => SnackBar(
|
I18N.of(OneContext().context).invalidStockLocation,
|
||||||
content: Text("This was not a stock item!")
|
success: false,
|
||||||
));
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
lib/l10n
2
lib/l10n
@ -1 +1 @@
|
|||||||
Subproject commit f1e991199f3656bfc774f3793ad7ea1609857027
|
Subproject commit 0e412995061a5b01530d0929f80e06c29ff639f8
|
@ -24,8 +24,18 @@ void showSnackIcon(String text, {IconData icon, Function onAction, bool success,
|
|||||||
if (success == true) {
|
if (success == true) {
|
||||||
backgroundColor = Colors.lightGreen;
|
backgroundColor = Colors.lightGreen;
|
||||||
|
|
||||||
|
// Select an icon if we do not have an action
|
||||||
|
if (icon == null && onAction == null) {
|
||||||
|
icon = FontAwesomeIcons.checkCircle;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (success == false) {
|
} else if (success == false) {
|
||||||
backgroundColor = Colors.deepOrange;
|
backgroundColor = Colors.deepOrange;
|
||||||
|
|
||||||
|
if (icon == null && onAction == null) {
|
||||||
|
icon = FontAwesomeIcons.exclamationCircle;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SnackBarAction action;
|
SnackBarAction action;
|
||||||
|
@ -245,6 +245,26 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _unassignBarcode(BuildContext context) async {
|
||||||
|
|
||||||
|
final bool result = await item.update(context, values: {'uid': ''});
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
showSnackIcon(
|
||||||
|
I18N.of(context).stockItemUpdateSuccess,
|
||||||
|
success: true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
showSnackIcon(
|
||||||
|
I18N.of(context).stockItemUpdateFailure,
|
||||||
|
success: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void _transferStock(BuildContext context, InvenTreeStockLocation location) async {
|
void _transferStock(BuildContext context, InvenTreeStockLocation location) async {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
@ -568,7 +588,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
if (item.uid.isEmpty) {
|
if (item.uid.isEmpty) {
|
||||||
tiles.add(
|
tiles.add(
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(I18N.of(context).assignBarcode),
|
title: Text(I18N.of(context).barcodeAssign),
|
||||||
leading: FaIcon(FontAwesomeIcons.barcode),
|
leading: FaIcon(FontAwesomeIcons.barcode),
|
||||||
trailing: FaIcon(FontAwesomeIcons.qrcode),
|
trailing: FaIcon(FontAwesomeIcons.qrcode),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -581,6 +601,16 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
tiles.add(
|
||||||
|
ListTile(
|
||||||
|
title: Text(I18N.of(context).barcodeUnassign),
|
||||||
|
leading: FaIcon(FontAwesomeIcons.barcode),
|
||||||
|
onTap: () {
|
||||||
|
_unassignBarcode(context);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tiles;
|
return tiles;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user