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:
parent
eb1be30df4
commit
1ec1a867d9
@ -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
|
||||
|
@ -188,7 +188,6 @@ class POAllocateBarcodeHandler extends BarcodeHandler {
|
||||
context,
|
||||
L10().lineItemAdd,
|
||||
fields: fields,
|
||||
onSuccess: (data) async {},
|
||||
);
|
||||
}
|
||||
|
||||
|
81
lib/barcode/sales_order.dart
Normal file
81
lib/barcode/sales_order.dart
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -118,7 +118,11 @@ class InvenTreeSOLineItem extends InvenTreeOrderLine {
|
||||
"order": {
|
||||
"hidden": true,
|
||||
},
|
||||
"part": {},
|
||||
"part": {
|
||||
"filters": {
|
||||
"salable": true,
|
||||
}
|
||||
},
|
||||
"quantity": {},
|
||||
"reference": {},
|
||||
"notes": {},
|
||||
|
@ -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": {},
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user