mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +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
|
- 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 orders directly from the app
|
||||||
- Add line items to purchase order using barcode scanner
|
- 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
|
### 0.13.0 - October 2023
|
||||||
|
@ -188,7 +188,6 @@ class POAllocateBarcodeHandler extends BarcodeHandler {
|
|||||||
context,
|
context,
|
||||||
L10().lineItemAdd,
|
L10().lineItemAdd,
|
||||||
fields: fields,
|
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": {
|
"order": {
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
},
|
},
|
||||||
"part": {},
|
"part": {
|
||||||
|
"filters": {
|
||||||
|
"salable": true,
|
||||||
|
}
|
||||||
|
},
|
||||||
"quantity": {},
|
"quantity": {},
|
||||||
"reference": {},
|
"reference": {},
|
||||||
"notes": {},
|
"notes": {},
|
||||||
|
@ -112,6 +112,9 @@
|
|||||||
"barcodeNotAssigned": "Barcode not assigned",
|
"barcodeNotAssigned": "Barcode not assigned",
|
||||||
"@barcodeNotAssigned": {},
|
"@barcodeNotAssigned": {},
|
||||||
|
|
||||||
|
"barcodeScanPart": "Scan part barcode",
|
||||||
|
"@barcodeScanPart": {},
|
||||||
|
|
||||||
"barcodeReceivePart": "Scan barcode to receive part",
|
"barcodeReceivePart": "Scan barcode to receive part",
|
||||||
"@barcodeReceivePart": {},
|
"@barcodeReceivePart": {},
|
||||||
|
|
||||||
@ -766,6 +769,9 @@
|
|||||||
"description": "Part (multiple)"
|
"description": "Part (multiple)"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"partNotSalable": "Part not marked as salable",
|
||||||
|
"@partNotSalable": {},
|
||||||
|
|
||||||
"partsNone": "No Parts",
|
"partsNone": "No Parts",
|
||||||
"@partsNone": {},
|
"@partsNone": {},
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_speed_dial/flutter_speed_dial.dart";
|
import "package:flutter_speed_dial/flutter_speed_dial.dart";
|
||||||
import "package:font_awesome_flutter/font_awesome_flutter.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/company.dart";
|
||||||
import "package:inventree/inventree/sales_order.dart";
|
import "package:inventree/inventree/sales_order.dart";
|
||||||
import "package:inventree/widget/order/so_line_list.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> barcodeButtons(BuildContext context) {
|
||||||
List<SpeedDialChild> actions = [];
|
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;
|
return actions;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user