mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-10-31 21:35:42 +00:00 
			
		
		
		
	Purchase order updates (#456)
* Support supplierpart in related field * Manual add line item to purchase order * Update release notes
This commit is contained in:
		| @@ -5,6 +5,7 @@ | |||||||
| - Adds option to pause and resume barcode scanning with camera | - Adds option to pause and resume barcode scanning with camera | ||||||
| - Adds option for "single shot" barcode scanning with camera | - Adds option for "single shot" barcode scanning with camera | ||||||
| - 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 | ||||||
|  |  | ||||||
|  |  | ||||||
| ### 0.13.0 - October 2023 | ### 0.13.0 - October 2023 | ||||||
|   | |||||||
| @@ -524,11 +524,10 @@ class APIFormField { | |||||||
|       ), |       ), | ||||||
|       selectedItem: initial_data, |       selectedItem: initial_data, | ||||||
|       asyncItems: (String filter) async { |       asyncItems: (String filter) async { | ||||||
|         Map<String, String> _filters = {}; |         Map<String, String> _filters = { | ||||||
|  |           ..._relatedFieldFilters(), | ||||||
|         filters.forEach((key, value) { |           ...filters, | ||||||
|           _filters[key] = value; |         }; | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         _filters["search"] = filter; |         _filters["search"] = filter; | ||||||
|         _filters["offset"] = "0"; |         _filters["offset"] = "0"; | ||||||
| @@ -586,6 +585,17 @@ class APIFormField { | |||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // Construct a set of custom filters for the dropdown search | ||||||
|  |   Map<String, String> _relatedFieldFilters() { | ||||||
|  |  | ||||||
|  |     switch (model) { | ||||||
|  |       case "supplierpart": | ||||||
|  |         return InvenTreeSupplierPart().defaultListFilters(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return {}; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Render a "related field" based on the "model" type |   // Render a "related field" based on the "model" type | ||||||
|   Widget _renderRelatedField(String fieldName, dynamic item, bool selected, bool extended) { |   Widget _renderRelatedField(String fieldName, dynamic item, bool selected, bool extended) { | ||||||
|  |  | ||||||
| @@ -611,7 +621,6 @@ class APIFormField { | |||||||
|  |  | ||||||
|     switch (model) { |     switch (model) { | ||||||
|       case "part": |       case "part": | ||||||
|  |  | ||||||
|         var part = InvenTreePart.fromJson(data); |         var part = InvenTreePart.fromJson(data); | ||||||
|  |  | ||||||
|         return ListTile( |         return ListTile( | ||||||
| @@ -626,6 +635,15 @@ class APIFormField { | |||||||
|           leading: extended ? InvenTreeAPI().getThumbnail(part.thumbnail) : null, |           leading: extended ? InvenTreeAPI().getThumbnail(part.thumbnail) : null, | ||||||
|         ); |         ); | ||||||
|  |  | ||||||
|  |       case "supplierpart": | ||||||
|  |         var part = InvenTreeSupplierPart.fromJson(data); | ||||||
|  |  | ||||||
|  |         return ListTile( | ||||||
|  |           title: Text(part.SKU), | ||||||
|  |           subtitle: Text(part.partName), | ||||||
|  |           leading: extended ? InvenTreeAPI().getThumbnail(part.partImage) : null, | ||||||
|  |           trailing: extended && part.supplierImage.isNotEmpty ? InvenTreeAPI().getThumbnail(part.supplierImage) : null, | ||||||
|  |         ); | ||||||
|       case "partcategory": |       case "partcategory": | ||||||
|  |  | ||||||
|         var cat = InvenTreePartCategory.fromJson(data); |         var cat = InvenTreePartCategory.fromJson(data); | ||||||
|   | |||||||
| @@ -74,6 +74,17 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg | |||||||
|  |  | ||||||
|     if (widget.order.canCreate) { |     if (widget.order.canCreate) { | ||||||
|       if (widget.order.isPending) { |       if (widget.order.isPending) { | ||||||
|  |  | ||||||
|  |         actions.add( | ||||||
|  |           SpeedDialChild( | ||||||
|  |             child: FaIcon(FontAwesomeIcons.circlePlus, color: Colors.green), | ||||||
|  |             label: L10().lineItemAdd, | ||||||
|  |             onTap: () async { | ||||||
|  |               _addLineItem(context); | ||||||
|  |             } | ||||||
|  |           ) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         actions.add( |         actions.add( | ||||||
|           SpeedDialChild( |           SpeedDialChild( | ||||||
|             child: FaIcon(FontAwesomeIcons.paperPlane, color: Colors.blue), |             child: FaIcon(FontAwesomeIcons.paperPlane, color: Colors.blue), | ||||||
| @@ -101,6 +112,30 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg | |||||||
|     return actions; |     return actions; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /// Add a new line item to this order | ||||||
|  |   Future<void> _addLineItem(BuildContext context) async { | ||||||
|  |  | ||||||
|  |     var fields = InvenTreePOLineItem().formFields(); | ||||||
|  |  | ||||||
|  |     // Update part field definition | ||||||
|  |     fields["part"]?["hidden"] = false; | ||||||
|  |     fields["part"]?["filters"] = { | ||||||
|  |       "supplier": widget.order.supplierId | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     fields["order"]?["value"] = widget.order.pk; | ||||||
|  |  | ||||||
|  |     InvenTreePOLineItem().createForm( | ||||||
|  |       context, | ||||||
|  |       L10().lineItemAdd, | ||||||
|  |       fields: fields, | ||||||
|  |       onSuccess: (data) async { | ||||||
|  |         refresh(context); | ||||||
|  |         showSnackIcon(L10().lineItemUpdated, success: true); | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /// Issue this order |   /// Issue this order | ||||||
|   Future<void> _issueOrder(BuildContext context) async { |   Future<void> _issueOrder(BuildContext context) async { | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user