mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 21:16:48 +00:00
* Handle error on unexpected barcode response * Add ManufacturerPart detail view * Support barcode scanning for manufacturer part * Refactoring for null checks * Ignore selected errors in sentry * Fix API implementation for ManufacturerPart * Update release notes * More error handling * Decode quantity betterer * Refactoring * Add option to confirm checkin details * Improve response handlign * Cleanup * Remove unused imports * Fix async function * Fix for assigning custom barcode * Handle barcode scan result for company * Fix * Adjust scan priority * Refactoring MODEL_TYPE - Use instead of duplicated const strings * @override fix
137 lines
3.7 KiB
Dart
137 lines
3.7 KiB
Dart
|
|
import "package:flutter/material.dart";
|
|
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
|
|
|
|
import "package:inventree/api.dart";
|
|
import "package:inventree/helpers.dart";
|
|
import "package:inventree/l10.dart";
|
|
|
|
import "package:inventree/barcode/tones.dart";
|
|
|
|
import "package:inventree/inventree/sentry.dart";
|
|
|
|
import "package:inventree/widget/dialogs.dart";
|
|
import "package:inventree/widget/snacks.dart";
|
|
|
|
|
|
/* Generic class which "handles" a barcode, by communicating with the InvenTree server,
|
|
* and handling match / unknown / error cases.
|
|
*
|
|
* Override functionality of this class to perform custom actions,
|
|
* based on the response returned from the InvenTree server
|
|
*/
|
|
class BarcodeHandler {
|
|
|
|
BarcodeHandler();
|
|
|
|
// Return the text to display on the barcode overlay
|
|
// Note: Will be overridden by child classes
|
|
String getOverlayText(BuildContext context) => "Barcode Overlay";
|
|
|
|
// Called when the server "matches" a barcode
|
|
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
|
|
// Override this function
|
|
}
|
|
|
|
// Called when the server does not know about a barcode
|
|
Future<void> onBarcodeUnknown(Map<String, dynamic> data) async {
|
|
// Override this function
|
|
|
|
barcodeFailureTone();
|
|
|
|
showSnackIcon(
|
|
(data["error"] ?? L10().barcodeNoMatch) as String,
|
|
success: false,
|
|
icon: Icons.qr_code,
|
|
);
|
|
}
|
|
|
|
// Called when the server returns an unhandled response
|
|
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async {
|
|
barcodeFailureTone();
|
|
showServerError("barcode/", L10().responseUnknown, data.toString());
|
|
}
|
|
|
|
/*
|
|
* Base function to capture and process barcode data.
|
|
*
|
|
* Returns true only if the barcode scanner should remain open
|
|
*/
|
|
Future<void> processBarcode(String barcode,
|
|
{String url = "barcode/",
|
|
Map<String, dynamic> extra_data = const {}}) async {
|
|
|
|
debug("Scanned barcode data: '${barcode}'");
|
|
|
|
barcode = barcode.trim();
|
|
|
|
// Empty barcode is invalid
|
|
if (barcode.isEmpty) {
|
|
|
|
barcodeFailureTone();
|
|
|
|
showSnackIcon(
|
|
L10().barcodeError,
|
|
icon: TablerIcons.exclamation_circle,
|
|
success: false
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
APIResponse? response;
|
|
|
|
try {
|
|
response = await InvenTreeAPI().post(
|
|
url,
|
|
body: {
|
|
"barcode": barcode,
|
|
...extra_data,
|
|
},
|
|
expectedStatusCode: null, // Do not show an error on "unexpected code"
|
|
);
|
|
} catch (error, stackTrace) {
|
|
sentryReportError("Barcode.processBarcode", error, stackTrace);
|
|
response = null;
|
|
}
|
|
|
|
if (response == null) {
|
|
barcodeFailureTone();
|
|
showSnackIcon(L10().barcodeError, success: false);
|
|
return;
|
|
}
|
|
|
|
debug("Barcode scan response" + response.data.toString());
|
|
|
|
Map<String, dynamic> data = response.asMap();
|
|
|
|
// Handle strange response from the server
|
|
if (!response.isValid() || !response.isMap()) {
|
|
await onBarcodeUnknown({});
|
|
|
|
showSnackIcon(L10().serverError, success: false);
|
|
|
|
// We want to know about this one!
|
|
await sentryReportMessage(
|
|
"BarcodeHandler.processBarcode returned unexpected value",
|
|
context: {
|
|
"data": response.data?.toString() ?? "null",
|
|
"barcode": barcode,
|
|
"url": url,
|
|
"statusCode": response.statusCode.toString(),
|
|
"valid": response.isValid().toString(),
|
|
"error": response.error,
|
|
"errorDetail": response.errorDetail,
|
|
"className": "${this}",
|
|
}
|
|
);
|
|
} else if (data.containsKey("success")) {
|
|
await onBarcodeMatched(data);
|
|
} else if ((response.statusCode >= 400) || data.containsKey("error")) {
|
|
await onBarcodeUnknown(data);
|
|
} else {
|
|
await onBarcodeUnhandled(data);
|
|
}
|
|
}
|
|
}
|