mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-31 13:25:40 +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:
		| @@ -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; | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user