From 03c6de8255aed5eb5d01aa7d01b244b1565176c6 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 10 May 2022 00:15:20 +1000 Subject: [PATCH] Stock location can now be identified via the app --- assets/release_notes.md | 1 + lib/l10n/app_en.arb | 15 +++++ lib/widget/location_display.dart | 97 +++++++++++++++++++++++++++++--- lib/widget/stock_detail.dart | 4 +- 4 files changed, 107 insertions(+), 10 deletions(-) diff --git a/assets/release_notes.md b/assets/release_notes.md index c7dfde30..38487ba7 100644 --- a/assets/release_notes.md +++ b/assets/release_notes.md @@ -7,6 +7,7 @@ - Refactor home screen display - Display unread notifications on home screen - Fixes duplicated display of units when showing stock quantity +- Adds ability to locate / identify stock items or locations (requires server plugin) - Improve rendering of home screen when server is not connected - Adds ability to load global and user settings from the server diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 56371b44..7640b154 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -416,6 +416,9 @@ "keywords": "Keywords", "@keywords": {}, + "labelTemplate": "Label Template", + "@labelTemplate": {}, + "lastStocktake": "Last Stocktake", "@lastStocktake": {}, @@ -428,6 +431,12 @@ "lineItems": "Line Items", "@lineItems": {}, + "locateItem": "Locate stock item", + "@locateItem": {}, + + "locateLocation": "Locate stock location", + "@locateLocation": {}, + "locationCreate": "New Location", "@locationCreate": {}, @@ -575,6 +584,12 @@ "printLabel": "Print Label", "@printLabel": {}, + "plugin": "Plugin", + "@plugin": {}, + + "pluginPrinter": "Printer", + "@pluginPrinter": {}, + "printLabelFailure": "Label printing failed", "@printLabelFailure": {}, diff --git a/lib/widget/location_display.dart b/lib/widget/location_display.dart index cdf1856e..17ca0103 100644 --- a/lib/widget/location_display.dart +++ b/lib/widget/location_display.dart @@ -3,6 +3,7 @@ import "package:flutter/material.dart"; import "package:font_awesome_flutter/font_awesome_flutter.dart"; import "package:inventree/api.dart"; +import 'package:inventree/api_form.dart'; import "package:inventree/app_colors.dart"; import "package:inventree/barcode.dart"; import "package:inventree/inventree/stock.dart"; @@ -61,19 +62,99 @@ class _LocationDisplayState extends RefreshableState { ); */ - if ((location != null) && (InvenTreeAPI().checkPermission("stock_location", "change"))) { - actions.add( - IconButton( - icon: FaIcon(FontAwesomeIcons.edit), - tooltip: L10().edit, - onPressed: () { _editLocationDialog(context); }, - ) - ); + if (location != null) { + + // Add "locate" button + if (InvenTreeAPI().supportsMixin("locate")) { + actions.add( + IconButton( + icon: FaIcon(FontAwesomeIcons.searchLocation), + tooltip: L10().locateLocation, + onPressed: () async { + _locateStockLocation(context); + }, + ) + ); + } + + // Add "edit" button + if (InvenTreeAPI().checkPermission("stock_location", "change")) { + actions.add( + IconButton( + icon: FaIcon(FontAwesomeIcons.edit), + tooltip: L10().edit, + onPressed: () { _editLocationDialog(context); }, + ) + ); + } } return actions; } + Future _locateStockLocation(BuildContext context) async { + + final _loc = location; + + if (_loc != null) { + + final plugins = InvenTreeAPI().getPlugins(mixin: "locate"); + + if (plugins.isEmpty) { + // TODO: Error message here + return; + } + + String plugin_name = ""; + + if (plugins.length == 1) { + plugin_name = plugins.first.key; + } else { + // User selects which plugin to use + List> plugin_options = []; + + for (var plugin in plugins) { + plugin_options.add({ + "display_name": plugin.humanName, + "value": plugin.key, + }); + } + + Map fields = { + "plugin": { + "label": L10().plugin, + "type": "choice", + "value": plugins.first.key, + "choices": plugin_options, + "required": true, + } + }; + + await launchApiForm( + context, + L10().locateLocation, + "", + fields, + icon: FontAwesomeIcons.searchLocation, + onSuccess: (Map data) async { + plugin_name = (data["plugin"] ?? "") as String; + } + ); + } + + print("plugin: ${plugin_name}"); + + InvenTreeAPI().post( + "/api/locate/", + body: { + "plugin": plugin_name, + "location": "${_loc.pk}", + }, + expectedStatusCode: 200, + ); + } + } + void _editLocationDialog(BuildContext context) { final _loc = location; diff --git a/lib/widget/stock_detail.dart b/lib/widget/stock_detail.dart index 3b400b26..3e2f4709 100644 --- a/lib/widget/stock_detail.dart +++ b/lib/widget/stock_detail.dart @@ -217,14 +217,14 @@ class _StockItemDisplayState extends RefreshableState { Map fields = { "label": { - "label": "Label Template", + "label": L10().labelTemplate, "type": "choice", "value": initial_label, "choices": label_options, "required": true, }, "plugin": { - "label": "Printer", + "label": L10().pluginPrinter, "type": "choice", "value": initial_plugin, "choices": plugin_options,