2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-07-01 11:20:41 +00:00

Format Code and Add Format Checks to CI (#643)

* Remove unused lib/generated/i18n.dart

* Use `fvm dart format .`

* Add contributing guidelines

* Enforce dart format

* Add `dart format off` directive to generated files
This commit is contained in:
Ben Hagen
2025-06-24 01:55:01 +02:00
committed by GitHub
parent e9db6532e4
commit 4444884afa
100 changed files with 5332 additions and 5592 deletions

View File

@ -10,7 +10,6 @@ import "package:inventree/widget/company/manufacturer_part_detail.dart";
import "package:inventree/widget/order/sales_order_detail.dart";
import "package:one_context/one_context.dart";
import "package:inventree/api.dart";
import "package:inventree/l10.dart";
@ -35,10 +34,8 @@ import "package:inventree/widget/stock/stock_detail.dart";
import "package:inventree/widget/company/company_detail.dart";
import "package:inventree/widget/company/supplier_part_detail.dart";
// Signal a barcode scan success to the user
Future<void> barcodeSuccess(String msg) async {
barcodeSuccessTone();
showSnackIcon(msg, success: true);
}
@ -47,24 +44,23 @@ Future<void> barcodeSuccess(String msg) async {
Future<void> barcodeFailure(String msg, dynamic extra) async {
barcodeFailureTone();
showSnackIcon(
msg,
success: false,
msg,
success: false,
onAction: () {
if (hasContext()) {
OneContext().showDialog(
builder: (BuildContext context) =>
SimpleDialog(
title: Text(L10().barcodeError),
children: <Widget>[
ListTile(
title: Text(L10().responseData),
subtitle: Text(extra.toString())
)
]
)
);
}
}
if (hasContext()) {
OneContext().showDialog(
builder: (BuildContext context) => SimpleDialog(
title: Text(L10().barcodeError),
children: <Widget>[
ListTile(
title: Text(L10().responseData),
subtitle: Text(extra.toString()),
),
],
),
);
}
},
);
}
@ -75,15 +71,22 @@ Future<void> barcodeFailure(String msg, dynamic extra) async {
* - Returns a Future which resolves when the scanner is dismissed
* - The provided BarcodeHandler instance is used to handle the scanned barcode
*/
Future<Object?> scanBarcode(BuildContext context, {BarcodeHandler? handler}) async {
Future<Object?> scanBarcode(
BuildContext context, {
BarcodeHandler? handler,
}) async {
// Default to generic scan handler
handler ??= BarcodeScanHandler();
InvenTreeBarcodeController controller = CameraBarcodeController(handler);
// Select barcode controller based on user preference
final int barcodeControllerType = await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_TYPE, BARCODE_CONTROLLER_CAMERA) as int;
final int barcodeControllerType =
await InvenTreeSettingsManager().getValue(
INV_BARCODE_SCAN_TYPE,
BARCODE_CONTROLLER_CAMERA,
)
as int;
switch (barcodeControllerType) {
case BARCODE_CONTROLLER_WEDGE:
@ -95,14 +98,10 @@ Future<Object?> scanBarcode(BuildContext context, {BarcodeHandler? handler}) asy
}
return Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, _, _) => controller,
opaque: false,
)
PageRouteBuilder(pageBuilder: (context, _, _) => controller, opaque: false),
);
}
/*
* Class for general barcode scanning.
* Scan *any* barcode without context, and then redirect app to correct view.
@ -116,19 +115,17 @@ Future<Object?> scanBarcode(BuildContext context, {BarcodeHandler? handler}) asy
* - PurchaseOrder
*/
class BarcodeScanHandler extends BarcodeHandler {
@override
String getOverlayText(BuildContext context) => L10().barcodeScanGeneral;
@override
Future<void> onBarcodeUnknown(Map<String, dynamic> data) async {
barcodeFailureTone();
showSnackIcon(
L10().barcodeNoMatch,
icon: TablerIcons.exclamation_circle,
success: false,
L10().barcodeNoMatch,
icon: TablerIcons.exclamation_circle,
success: false,
);
}
@ -136,12 +133,13 @@ class BarcodeScanHandler extends BarcodeHandler {
* Response when a "Part" instance is scanned
*/
Future<void> handlePart(int pk) async {
var part = await InvenTreePart().get(pk);
if (part is InvenTreePart) {
OneContext().pop();
OneContext().push(MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
OneContext().push(
MaterialPageRoute(builder: (context) => PartDetailWidget(part)),
);
}
}
@ -149,13 +147,13 @@ class BarcodeScanHandler extends BarcodeHandler {
* Response when a "StockItem" instance is scanned
*/
Future<void> handleStockItem(int pk) async {
var item = await InvenTreeStockItem().get(pk);
if (item is InvenTreeStockItem) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => StockDetailWidget(item)));
OneContext().push(
MaterialPageRoute(builder: (context) => StockDetailWidget(item)),
);
}
}
@ -163,13 +161,13 @@ class BarcodeScanHandler extends BarcodeHandler {
* Response when a "StockLocation" instance is scanned
*/
Future<void> handleStockLocation(int pk) async {
var loc = await InvenTreeStockLocation().get(pk);
if (loc is InvenTreeStockLocation) {
OneContext().pop();
OneContext().navigator.push(MaterialPageRoute(
builder: (context) => LocationDisplayWidget(loc)));
OneContext().navigator.push(
MaterialPageRoute(builder: (context) => LocationDisplayWidget(loc)),
);
}
}
@ -177,13 +175,15 @@ class BarcodeScanHandler extends BarcodeHandler {
* Response when a "SupplierPart" instance is scanned
*/
Future<void> handleSupplierPart(int pk) async {
var supplierPart = await InvenTreeSupplierPart().get(pk);
if (supplierPart is InvenTreeSupplierPart) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => SupplierPartDetailWidget(supplierPart)));
OneContext().push(
MaterialPageRoute(
builder: (context) => SupplierPartDetailWidget(supplierPart),
),
);
}
}
@ -195,8 +195,11 @@ class BarcodeScanHandler extends BarcodeHandler {
if (manufacturerPart is InvenTreeManufacturerPart) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => ManufacturerPartDetailWidget(manufacturerPart)));
OneContext().push(
MaterialPageRoute(
builder: (context) => ManufacturerPartDetailWidget(manufacturerPart),
),
);
}
}
@ -205,8 +208,9 @@ class BarcodeScanHandler extends BarcodeHandler {
if (company is InvenTreeCompany) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => CompanyDetailWidget(company)));
OneContext().push(
MaterialPageRoute(builder: (context) => CompanyDetailWidget(company)),
);
}
}
@ -218,8 +222,11 @@ class BarcodeScanHandler extends BarcodeHandler {
if (order is InvenTreePurchaseOrder) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => PurchaseOrderDetailWidget(order)));
OneContext().push(
MaterialPageRoute(
builder: (context) => PurchaseOrderDetailWidget(order),
),
);
}
}
@ -229,8 +236,9 @@ class BarcodeScanHandler extends BarcodeHandler {
if (order is InvenTreeSalesOrder) {
OneContext().pop();
OneContext().push(MaterialPageRoute(
builder: (context) => SalesOrderDetailWidget(order)));
OneContext().push(
MaterialPageRoute(builder: (context) => SalesOrderDetailWidget(order)),
);
}
}
@ -250,7 +258,6 @@ class BarcodeScanHandler extends BarcodeHandler {
InvenTreeManufacturerPart.MODEL_TYPE,
];
if (InvenTreeAPI().supportsOrderBarcodes) {
validModels.add(InvenTreePurchaseOrder.MODEL_TYPE);
validModels.add(InvenTreeSalesOrder.MODEL_TYPE);
@ -274,7 +281,6 @@ class BarcodeScanHandler extends BarcodeHandler {
// A valid result has been found
if (pk > 0 && model.isNotEmpty) {
barcodeSuccessTone();
switch (model) {
@ -312,35 +318,31 @@ class BarcodeScanHandler extends BarcodeHandler {
barcodeFailureTone();
showSnackIcon(
L10().barcodeUnknown,
success: false,
onAction: () {
if (hasContext()) {
OneContext().showDialog(
builder: (BuildContext context) =>
SimpleDialog(
title: Text(L10().unknownResponse),
children: <Widget>[
ListTile(
title: Text(L10().responseData),
subtitle: Text(data.toString()),
)
],
)
);
}
L10().barcodeUnknown,
success: false,
onAction: () {
if (hasContext()) {
OneContext().showDialog(
builder: (BuildContext context) => SimpleDialog(
title: Text(L10().unknownResponse),
children: <Widget>[
ListTile(
title: Text(L10().responseData),
subtitle: Text(data.toString()),
),
],
),
);
}
},
);
}
}
/*
* Barcode handler for finding a "unique" barcode (one that does not match an item in the database)
*/
class UniqueBarcodeHandler extends BarcodeHandler {
UniqueBarcodeHandler(this.callback, {this.overlayText = ""});
// Callback function when a "unique" barcode hash is found
@ -360,11 +362,7 @@ class UniqueBarcodeHandler extends BarcodeHandler {
@override
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
if (!data.containsKey("hash") && !data.containsKey("barcode_hash")) {
showServerError(
"barcode/",
L10().missingData,
L10().barcodeMissingHash,
);
showServerError("barcode/", L10().missingData, L10().barcodeMissingHash);
} else {
String barcode;
@ -373,12 +371,8 @@ class UniqueBarcodeHandler extends BarcodeHandler {
if (barcode.isEmpty) {
barcodeFailureTone();
showSnackIcon(
L10().barcodeError,
success: false,
);
showSnackIcon(L10().barcodeError, success: false);
} else {
barcodeSuccessTone();
// Close the barcode scanner
@ -395,41 +389,43 @@ class UniqueBarcodeHandler extends BarcodeHandler {
Future<void> onBarcodeUnknown(Map<String, dynamic> data) async {
await onBarcodeMatched(data);
}
}
SpeedDialChild customBarcodeAction(BuildContext context, RefreshableState state, String barcode, String model, int pk) {
SpeedDialChild customBarcodeAction(
BuildContext context,
RefreshableState state,
String barcode,
String model,
int pk,
) {
if (barcode.isEmpty) {
return SpeedDialChild(
label: L10().barcodeAssign,
child: Icon(Icons.barcode_reader),
onTap: () {
var handler = UniqueBarcodeHandler((String barcode) {
InvenTreeAPI().linkBarcode({
model: pk.toString(),
"barcode": barcode,
}).then((bool result) {
showSnackIcon(
result ? L10().barcodeAssigned : L10().barcodeNotAssigned,
success: result
);
InvenTreeAPI()
.linkBarcode({model: pk.toString(), "barcode": barcode})
.then((bool result) {
showSnackIcon(
result ? L10().barcodeAssigned : L10().barcodeNotAssigned,
success: result,
);
state.refresh(context);
});
state.refresh(context);
});
});
scanBarcode(context, handler: handler);
}
},
);
} else {
return SpeedDialChild(
child: Icon(Icons.barcode_reader),
label: L10().barcodeUnassign,
onTap: () {
InvenTreeAPI().unlinkBarcode({
model: pk.toString()
}).then((bool result) {
InvenTreeAPI().unlinkBarcode({model: pk.toString()}).then((
bool result,
) {
showSnackIcon(
result ? L10().requestSuccessful : L10().requestFailed,
success: result,
@ -437,7 +433,7 @@ SpeedDialChild customBarcodeAction(BuildContext context, RefreshableState state,
state.refresh(context);
});
}
},
);
}
}

View File

@ -273,8 +273,9 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
}
Widget bottomCenterOverlay() {
String info_text =
scanning_paused ? L10().barcodeScanPaused : L10().barcodeScanPause;
String info_text = scanning_paused
? L10().barcodeScanPaused
: L10().barcodeScanPause;
String text = scanned_code.isNotEmpty ? scanned_code : info_text;

View File

@ -11,7 +11,6 @@ import "package:inventree/widget/progress.dart";
* which is used to process the scanned barcode.
*/
class InvenTreeBarcodeController extends StatefulWidget {
const InvenTreeBarcodeController(this.handler, {Key? key}) : super(key: key);
final BarcodeHandler handler;
@ -20,16 +19,17 @@ class InvenTreeBarcodeController extends StatefulWidget {
State<StatefulWidget> createState() => InvenTreeBarcodeControllerState();
}
/*
* Base state widget for the barcode controller.
* This defines the basic interface for the barcode controller.
*/
class InvenTreeBarcodeControllerState extends State<InvenTreeBarcodeController> {
class InvenTreeBarcodeControllerState
extends State<InvenTreeBarcodeController> {
InvenTreeBarcodeControllerState() : super();
final GlobalKey barcodeControllerKey = GlobalKey(debugLabel: "barcodeController");
final GlobalKey barcodeControllerKey = GlobalKey(
debugLabel: "barcodeController",
);
// Internal state flag to test if we are currently processing a barcode
bool processingBarcode = false;
@ -40,7 +40,6 @@ class InvenTreeBarcodeControllerState extends State<InvenTreeBarcodeController>
* Barcode data should be passed as a string
*/
Future<void> handleBarcodeData(String? data) async {
// Check that the data is valid, and this view is still mounted
if (!mounted || data == null || data.isEmpty) {
return;
@ -66,7 +65,9 @@ class InvenTreeBarcodeControllerState extends State<InvenTreeBarcodeController>
return;
}
int delay = await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_DELAY, 500) as int;
int delay =
await InvenTreeSettingsManager().getValue(INV_BARCODE_SCAN_DELAY, 500)
as int;
Future.delayed(Duration(milliseconds: delay), () {
hideLoadingOverlay();
@ -99,5 +100,4 @@ class InvenTreeBarcodeControllerState extends State<InvenTreeBarcodeController>
Widget build(BuildContext context) {
return Container();
}
}
}

View File

@ -1,4 +1,3 @@
import "package:flutter/material.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
@ -13,7 +12,6 @@ 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.
*
@ -21,7 +19,6 @@ import "package:inventree/widget/snacks.dart";
* based on the response returned from the InvenTree server
*/
class BarcodeHandler {
BarcodeHandler();
// Return the text to display on the barcode overlay
@ -57,23 +54,23 @@ class BarcodeHandler {
*
* 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 {
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
success: false,
);
return;
@ -84,10 +81,7 @@ class BarcodeHandler {
try {
response = await InvenTreeAPI().post(
url,
body: {
"barcode": barcode,
...extra_data,
},
body: {"barcode": barcode, ...extra_data},
expectedStatusCode: null, // Do not show an error on "unexpected code"
);
} catch (error, stackTrace) {
@ -113,17 +107,17 @@ class BarcodeHandler {
// 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}",
}
"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);

View File

@ -20,7 +20,6 @@ import "package:inventree/widget/snacks.dart";
* - If location or quantity information wasn't provided, show a form to fill it in
*/
class POReceiveBarcodeHandler extends BarcodeHandler {
POReceiveBarcodeHandler({this.purchaseOrder, this.location, this.lineItem});
InvenTreePurchaseOrder? purchaseOrder;
@ -31,11 +30,15 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
String getOverlayText(BuildContext context) => L10().barcodeReceivePart;
@override
Future<void> processBarcode(String barcode,
{String url = "barcode/po-receive/",
Map<String, dynamic> extra_data = const {}}) async {
final bool confirm = await InvenTreeSettingsManager().getBool(INV_PO_CONFIRM_SCAN, true);
Future<void> processBarcode(
String barcode, {
String url = "barcode/po-receive/",
Map<String, dynamic> extra_data = const {},
}) async {
final bool confirm = await InvenTreeSettingsManager().getBool(
INV_PO_CONFIRM_SCAN,
true,
);
final po_extra_data = {
"purchase_order": purchaseOrder?.pk,
@ -50,7 +53,6 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
@override
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
if (data.containsKey("lineitem") || data.containsKey("success")) {
barcodeSuccess(L10().receivedItem);
return;
@ -66,7 +68,8 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
}
final lineItemData = data["lineitem"] as Map<String, dynamic>;
if (!lineItemData.containsKey("pk") || !lineItemData.containsKey("purchase_order")) {
if (!lineItemData.containsKey("pk") ||
!lineItemData.containsKey("purchase_order")) {
barcodeFailureTone();
showSnackIcon(L10().missingData, success: false);
}
@ -79,7 +82,8 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
return;
}
InvenTreePOLineItem? lineItem = await InvenTreePOLineItem().get(lineItemId) as InvenTreePOLineItem?;
InvenTreePOLineItem? lineItem =
await InvenTreePOLineItem().get(lineItemId) as InvenTreePOLineItem?;
if (lineItem == null) {
barcodeFailureTone();
@ -89,7 +93,9 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
// Next, extract the "optional" fields
// Extract information from the returned server response
double? quantity = double.tryParse((lineItemData["quantity"] ?? "0").toString());
double? quantity = double.tryParse(
(lineItemData["quantity"] ?? "0").toString(),
);
int? destination = lineItemData["location"] as int?;
String? barcode = data["barcode_data"] as String?;
@ -105,7 +111,7 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
barcode: barcode,
onSuccess: () {
showSnackIcon(L10().receivedItem, success: true);
}
},
);
}
@ -113,18 +119,16 @@ class POReceiveBarcodeHandler extends BarcodeHandler {
Future<void> onBarcodeUnknown(Map<String, dynamic> data) async {
barcodeFailureTone();
showSnackIcon(
data["error"] as String? ?? L10().barcodeError,
success: false
data["error"] as String? ?? L10().barcodeError,
success: false,
);
}
}
/*
* Barcode handler to add a line item to a purchase order
*/
class POAllocateBarcodeHandler extends BarcodeHandler {
POAllocateBarcodeHandler({this.purchaseOrder});
InvenTreePurchaseOrder? purchaseOrder;
@ -133,21 +137,14 @@ class POAllocateBarcodeHandler extends BarcodeHandler {
String getOverlayText(BuildContext context) => L10().scanSupplierPart;
@override
Future<void> processBarcode(String barcode, {
Future<void> processBarcode(
String barcode, {
String url = "barcode/po-allocate/",
Map<String, dynamic> extra_data = const {}}
) {
Map<String, dynamic> extra_data = const {},
}) {
final po_extra_data = {"purchase_order": purchaseOrder?.pk, ...extra_data};
final po_extra_data = {
"purchase_order": purchaseOrder?.pk,
...extra_data,
};
return super.processBarcode(
barcode,
url: url,
extra_data: po_extra_data,
);
return super.processBarcode(barcode, url: url, extra_data: po_extra_data);
}
@override
@ -189,10 +186,9 @@ class POAllocateBarcodeHandler extends BarcodeHandler {
@override
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async {
print("onBarcodeUnhandled:");
print(data.toString());
super.onBarcodeUnhandled(data);
}
}
}

View File

@ -14,13 +14,11 @@ import "package:inventree/barcode/tones.dart";
import "package:inventree/widget/snacks.dart";
/*
* Barcode handler class for scanning a new part into a SalesOrder
*/
class SOAddItemBarcodeHandler extends BarcodeHandler {
SOAddItemBarcodeHandler({this.salesOrder});
InvenTreeSalesOrder? salesOrder;
@ -30,7 +28,6 @@ class SOAddItemBarcodeHandler extends BarcodeHandler {
@override
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
// Extract the part ID from the returned data
int part_id = -1;
@ -46,7 +43,6 @@ class SOAddItemBarcodeHandler extends BarcodeHandler {
var part = await InvenTreePart().get(part_id);
if (part is InvenTreePart) {
if (part.isSalable) {
// Dispose of the barcode scanner
if (OneContext.hasContext) {
@ -68,23 +64,18 @@ class SOAddItemBarcodeHandler extends BarcodeHandler {
L10().lineItemAdd,
fields: fields,
);
} else {
barcodeFailureTone();
showSnackIcon(L10().partNotSalable, success: false);
}
} else {
// Failed to fetch part
return onBarcodeUnknown(data);
}
}
}
class SOAllocateStockHandler extends BarcodeHandler {
SOAllocateStockHandler({this.salesOrder, this.lineItem, this.shipment});
InvenTreeSalesOrder? salesOrder;
@ -95,16 +86,16 @@ class SOAllocateStockHandler extends BarcodeHandler {
String getOverlayText(BuildContext context) => L10().allocateStock;
@override
Future<void> processBarcode(String barcode,
{
Future<void> processBarcode(
String barcode, {
String url = "barcode/so-allocate/",
Map<String, dynamic> extra_data = const {}}) {
Map<String, dynamic> extra_data = const {},
}) {
final so_extra_data = {
"sales_order": salesOrder?.pk,
"shipment": shipment?.pk,
"line": lineItem?.pk,
...extra_data
...extra_data,
};
return super.processBarcode(barcode, url: url, extra_data: so_extra_data);
@ -121,8 +112,8 @@ class SOAllocateStockHandler extends BarcodeHandler {
@override
Future<void> onBarcodeUnhandled(Map<String, dynamic> data) async {
if (!data.containsKey("action_required") || !data.containsKey("line_item")) {
if (!data.containsKey("action_required") ||
!data.containsKey("line_item")) {
return super.onBarcodeUnhandled(data);
}
@ -132,10 +123,7 @@ class SOAllocateStockHandler extends BarcodeHandler {
// Update fields with data gathered from the API response
fields["line_item"]?["value"] = data["line_item"];
Map<String, dynamic> stock_filters = {
"in_stock": true,
"available": true,
};
Map<String, dynamic> stock_filters = {"in_stock": true, "available": true};
if (data.containsKey("part")) {
stock_filters["part"] = data["part"];
@ -147,9 +135,7 @@ class SOAllocateStockHandler extends BarcodeHandler {
fields["quantity"]?["value"] = data["quantity"];
fields["shipment"]?["value"] = data["shipment"];
fields["shipment"]?["filters"] = {
"order": salesOrder!.pk.toString()
};
fields["shipment"]?["filters"] = {"order": salesOrder!.pk.toString()};
final context = OneContext().context!;
@ -157,20 +143,21 @@ class SOAllocateStockHandler extends BarcodeHandler {
context,
L10().allocateStock,
salesOrder!.allocate_url,
fields,
method: "POST",
icon: TablerIcons.transition_right,
onSuccess: (data) async {
fields,
method: "POST",
icon: TablerIcons.transition_right,
onSuccess: (data) async {
showSnackIcon(L10().allocated, success: true);
});
},
);
}
@override
Future<void> onBarcodeUnknown(Map<String, dynamic> data) async {
barcodeFailureTone();
showSnackIcon(
data["error"] as String? ?? L10().barcodeError,
success: false
data["error"] as String? ?? L10().barcodeError,
success: false,
);
}
}
}

View File

@ -16,7 +16,6 @@ import "package:inventree/inventree/stock.dart";
import "package:inventree/widget/dialogs.dart";
import "package:inventree/widget/snacks.dart";
/*
* Generic class for scanning a StockLocation.
*
@ -24,20 +23,17 @@ import "package:inventree/widget/snacks.dart";
* - Runs a "callback" function if a valid StockLocation is found
*/
class BarcodeScanStockLocationHandler extends BarcodeHandler {
@override
String getOverlayText(BuildContext context) => L10().barcodeScanLocation;
@override
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
// We expect that the barcode points to a 'stocklocation'
if (data.containsKey("stocklocation")) {
int _loc = (data["stocklocation"]?["pk"] ?? -1) as int;
// A valid stock location!
if (_loc > 0) {
debug("Scanned stock location ${_loc}");
final bool result = await onLocationScanned(_loc);
@ -52,10 +48,7 @@ class BarcodeScanStockLocationHandler extends BarcodeHandler {
// If we get to this point, something went wrong during the scan process
barcodeFailureTone();
showSnackIcon(
L10().invalidStockLocation,
success: false,
);
showSnackIcon(L10().invalidStockLocation, success: false);
}
// Callback function which runs when a valid StockLocation is scanned
@ -64,10 +57,8 @@ class BarcodeScanStockLocationHandler extends BarcodeHandler {
// Re-implement this for particular subclass
return false;
}
}
/*
* Generic class for scanning a StockItem
*
@ -75,7 +66,6 @@ class BarcodeScanStockLocationHandler extends BarcodeHandler {
* - Runs a "callback" function if a valid StockItem is found
*/
class BarcodeScanStockItemHandler extends BarcodeHandler {
@override
String getOverlayText(BuildContext context) => L10().barcodeScanItem;
@ -87,7 +77,6 @@ class BarcodeScanStockItemHandler extends BarcodeHandler {
// A valid stock location!
if (_item > 0) {
barcodeSuccessTone();
bool result = await onItemScanned(_item);
@ -102,10 +91,7 @@ class BarcodeScanStockItemHandler extends BarcodeHandler {
// If we get to this point, something went wrong during the scan process
barcodeFailureTone();
showSnackIcon(
L10().invalidStockItem,
success: false,
);
showSnackIcon(L10().invalidStockItem, success: false);
}
// Callback function which runs when a valid StockItem is scanned
@ -115,7 +101,6 @@ class BarcodeScanStockItemHandler extends BarcodeHandler {
}
}
/*
* Barcode handler for scanning a provided StockItem into a scanned StockLocation.
*
@ -124,20 +109,20 @@ class BarcodeScanStockItemHandler extends BarcodeHandler {
* - The StockItem is transferred into the scanned location
*/
class StockItemScanIntoLocationHandler extends BarcodeScanStockLocationHandler {
StockItemScanIntoLocationHandler(this.item);
final InvenTreeStockItem item;
@override
Future<bool> onLocationScanned(int locationId) async {
final bool confirm = await InvenTreeSettingsManager().getBool(INV_STOCK_CONFIRM_SCAN, false);
final bool confirm = await InvenTreeSettingsManager().getBool(
INV_STOCK_CONFIRM_SCAN,
false,
);
bool result = false;
if (confirm) {
Map<String, dynamic> fields = item.transferFields();
// Override location with scanned value
@ -152,7 +137,7 @@ class StockItemScanIntoLocationHandler extends BarcodeScanStockLocationHandler {
icon: TablerIcons.transfer,
onSuccess: (data) async {
showSnackIcon(L10().stockItemUpdated, success: true);
}
},
);
return true;
@ -171,7 +156,6 @@ class StockItemScanIntoLocationHandler extends BarcodeScanStockLocationHandler {
}
}
/*
* Barcode handler for scanning stock item(s) into the specified StockLocation.
*
@ -180,7 +164,6 @@ class StockItemScanIntoLocationHandler extends BarcodeScanStockLocationHandler {
* - The scanned StockItem is transferred into the provided StockLocation
*/
class StockLocationScanInItemsHandler extends BarcodeScanStockItemHandler {
StockLocationScanInItemsHandler(this.location);
final InvenTreeStockLocation location;
@ -190,14 +173,16 @@ class StockLocationScanInItemsHandler extends BarcodeScanStockItemHandler {
@override
Future<bool> onItemScanned(int itemId) async {
final InvenTreeStockItem? item = await InvenTreeStockItem().get(itemId) as InvenTreeStockItem?;
final bool confirm = await InvenTreeSettingsManager().getBool(INV_STOCK_CONFIRM_SCAN, false);
final InvenTreeStockItem? item =
await InvenTreeStockItem().get(itemId) as InvenTreeStockItem?;
final bool confirm = await InvenTreeSettingsManager().getBool(
INV_STOCK_CONFIRM_SCAN,
false,
);
bool result = false;
if (item != null) {
// Item is already *in* the specified location
if (item.locationId == location.pk) {
barcodeFailureTone();
@ -211,25 +196,26 @@ class StockLocationScanInItemsHandler extends BarcodeScanStockItemHandler {
fields["location"]?["value"] = location.pk;
launchApiForm(
OneContext().context!,
L10().transferStock,
InvenTreeStockItem.transferStockUrl(),
fields,
method: "POST",
icon: TablerIcons.transfer,
onSuccess: (data) async {
showSnackIcon(L10().stockItemUpdated, success: true);
}
OneContext().context!,
L10().transferStock,
InvenTreeStockItem.transferStockUrl(),
fields,
method: "POST",
icon: TablerIcons.transfer,
onSuccess: (data) async {
showSnackIcon(L10().stockItemUpdated, success: true);
},
);
return true;
} else {
result = await item.transferStock(location.pk);
showSnackIcon(
result ? L10().barcodeScanIntoLocationSuccess : L10().barcodeScanIntoLocationFailure,
success: result
result
? L10().barcodeScanIntoLocationSuccess
: L10().barcodeScanIntoLocationFailure,
success: result,
);
}
}
@ -240,7 +226,6 @@ class StockLocationScanInItemsHandler extends BarcodeScanStockItemHandler {
}
}
/*
* Barcode handler class for scanning a StockLocation into another StockLocation
*
@ -249,18 +234,14 @@ class StockLocationScanInItemsHandler extends BarcodeScanStockItemHandler {
* - The scanned StockLocation is set as the "parent" of the provided StockLocation
*/
class ScanParentLocationHandler extends BarcodeScanStockLocationHandler {
ScanParentLocationHandler(this.location);
final InvenTreeStockLocation location;
@override
Future<bool> onLocationScanned(int locationId) async {
final response = await location.update(
values: {
"parent": locationId.toString(),
},
values: {"parent": locationId.toString()},
expectedStatusCode: null,
);
@ -269,22 +250,19 @@ class ScanParentLocationHandler extends BarcodeScanStockLocationHandler {
case 201:
barcodeSuccess(L10().barcodeScanIntoLocationSuccess);
return true;
case 400: // Invalid parent location chosen
case 400: // Invalid parent location chosen
barcodeFailureTone();
showSnackIcon(L10().invalidStockLocation, success: false);
return false;
default:
barcodeFailureTone();
showSnackIcon(
L10().barcodeScanIntoLocationFailure,
success: false,
actionText: L10().details,
onAction: () {
showErrorDialog(
L10().barcodeError,
response: response,
);
}
L10().barcodeScanIntoLocationFailure,
success: false,
actionText: L10().details,
onAction: () {
showErrorDialog(L10().barcodeError, response: response);
},
);
return false;
}

View File

@ -5,19 +5,21 @@ import "package:inventree/preferences.dart";
* Play an audible 'success' alert to the user.
*/
Future<void> barcodeSuccessTone() async {
final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
final bool en =
await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true)
as bool;
if (en) {
playAudioFile("sounds/barcode_scan.mp3");
}
}
Future <void> barcodeFailureTone() async {
final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
Future<void> barcodeFailureTone() async {
final bool en =
await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true)
as bool;
if (en) {
playAudioFile("sounds/barcode_error.mp3");
}
}
}

View File

@ -1,4 +1,3 @@
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
@ -15,17 +14,14 @@ import "package:inventree/helpers.dart";
* intercepting barcode data which is entered as rapid keyboard presses
*/
class WedgeBarcodeController extends InvenTreeBarcodeController {
const WedgeBarcodeController(BarcodeHandler handler, {Key? key}) : super(handler, key: key);
const WedgeBarcodeController(BarcodeHandler handler, {Key? key})
: super(handler, key: key);
@override
State<StatefulWidget> createState() => _WedgeBarcodeControllerState();
}
class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
_WedgeBarcodeControllerState() : super();
bool canScan = true;
@ -40,7 +36,6 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Future<void> pauseScan() async {
if (mounted) {
setState(() {
canScan = false;
@ -50,7 +45,6 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Future<void> resumeScan() async {
if (mounted) {
setState(() {
canScan = true;
@ -60,7 +54,6 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
// Callback for a single key press / scan
void handleKeyEvent(KeyEvent event) {
if (!scanning) {
return;
}
@ -78,7 +71,8 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
DateTime now = DateTime.now();
// Throw away old characters
if (_lastScanTime == null || _lastScanTime!.isBefore(now.subtract(Duration(milliseconds: 250)))) {
if (_lastScanTime == null ||
_lastScanTime!.isBefore(now.subtract(Duration(milliseconds: 250)))) {
_scannedCharacters.clear();
}
@ -99,7 +93,6 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: COLOR_APP_BAR,
@ -118,7 +111,7 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
focusNode: _focusNode,
child: SizedBox(
child: CircularProgressIndicator(
color: scanning ? COLOR_ACTION : COLOR_PROGRESS
color: scanning ? COLOR_ACTION : COLOR_PROGRESS,
),
width: 64,
height: 64,
@ -140,14 +133,14 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
widget.handler.getOverlayText(context),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white)
color: Colors.white,
),
),
padding: EdgeInsets.all(20),
)
),
],
)
)
),
),
);
}
}
}