2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-27 21:16:48 +00:00

Add part to sales order via barcode scan (#461)

* Add part to sales order via barcode scan

* Update release notes

* Remove unused imports
This commit is contained in:
Oliver 2023-11-22 00:14:55 +11:00 committed by GitHub
parent eb1be30df4
commit 1ec1a867d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 110 additions and 3 deletions

View File

@ -7,6 +7,8 @@
- Fixes bug when removing entire quantity of a stock item
- Add line items to purchase orders directly from the app
- Add line items to purchase order using barcode scanner
- Add line items to sales orders directly from the app
- Add line items to sales order using barcode scanner
### 0.13.0 - October 2023

View File

@ -188,7 +188,6 @@ class POAllocateBarcodeHandler extends BarcodeHandler {
context,
L10().lineItemAdd,
fields: fields,
onSuccess: (data) async {},
);
}

View File

@ -0,0 +1,81 @@
import "package:flutter/material.dart";
import "package:inventree/inventree/part.dart";
import "package:inventree/inventree/sales_order.dart";
import "package:one_context/one_context.dart";
import "package:inventree/l10.dart";
import "package:inventree/barcode/handler.dart";
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;
@override
String getOverlayText(BuildContext context) => L10().barcodeScanPart;
@override
Future<void> onBarcodeMatched(Map<String, dynamic> data) async {
// Extract the part ID from the returned data
int part_id = -1;
if (data.containsKey("part")) {
part_id = (data["part"] ?? {} as Map<String, dynamic>)["pk"] as int;
}
if (part_id <= 0) {
return onBarcodeUnknown(data);
}
// Request the part from the server
var part = await InvenTreePart().get(part_id);
if (part is InvenTreePart) {
if (part.isSalable) {
// Dispose of the barcode scanner
if (OneContext.hasContext) {
OneContext().pop();
}
final context = OneContext().context!;
var fields = InvenTreeSOLineItem().formFields();
fields["order"]?["value"] = salesOrder!.pk;
fields["order"]?["hidden"] = true;
fields["part"]?["value"] = part.pk;
fields["part"]?["hidden"] = false;
InvenTreeSOLineItem().createForm(
context,
L10().lineItemAdd,
fields: fields,
);
} else {
barcodeFailureTone();
showSnackIcon(L10().partNotSalable, success: false);
}
} else {
// Failed to fetch part
return onBarcodeUnknown(data);
}
}
}

View File

@ -118,7 +118,11 @@ class InvenTreeSOLineItem extends InvenTreeOrderLine {
"order": {
"hidden": true,
},
"part": {},
"part": {
"filters": {
"salable": true,
}
},
"quantity": {},
"reference": {},
"notes": {},

View File

@ -112,6 +112,9 @@
"barcodeNotAssigned": "Barcode not assigned",
"@barcodeNotAssigned": {},
"barcodeScanPart": "Scan part barcode",
"@barcodeScanPart": {},
"barcodeReceivePart": "Scan barcode to receive part",
"@barcodeReceivePart": {},
@ -766,6 +769,9 @@
"description": "Part (multiple)"
},
"partNotSalable": "Part not marked as salable",
"@partNotSalable": {},
"partsNone": "No Parts",
"@partsNone": {},

View File

@ -2,6 +2,8 @@
import "package:flutter/material.dart";
import "package:flutter_speed_dial/flutter_speed_dial.dart";
import "package:font_awesome_flutter/font_awesome_flutter.dart";
import "package:inventree/barcode/barcode.dart";
import "package:inventree/barcode/sales_order.dart";
import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/sales_order.dart";
import "package:inventree/widget/order/so_line_list.dart";
@ -101,7 +103,20 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
List<SpeedDialChild> barcodeButtons(BuildContext context) {
List<SpeedDialChild> actions = [];
// TODO
if (widget.order.isOpen && InvenTreeSOLineItem().canCreate) {
actions.add(
SpeedDialChild(
child: Icon(Icons.barcode_reader),
label: L10().lineItemAdd,
onTap: () async {
scanBarcode(
context,
handler: SOAddItemBarcodeHandler(salesOrder: widget.order),
);
}
)
);
}
return actions;
}