2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 05:26:47 +00:00

Stock test actions (#345)

* Use FAB for stock item test result

* Change long press to tap

* Add setting to control display of stock tests results

* Add question mark if no result recorded
This commit is contained in:
Oliver 2023-04-28 23:27:59 +10:00 committed by GitHub
parent 49226a5fce
commit 383571707e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 34 deletions

View File

@ -4,6 +4,7 @@
- Add support for Project Codes
- Improve purchase order support
- Fix action button colors
- Improvements for stock item test result display
- Added Norwegian translations
- Fix serial number field when creating stock item

View File

@ -11,6 +11,9 @@ import "package:inventree/inventree/model.dart";
/*
* Class representing a test result for a single stock item
*/
class InvenTreeStockItemTestResult extends InvenTreeModel {
InvenTreeStockItemTestResult() : super();

View File

@ -1208,6 +1208,9 @@
"description": ""
},
"testResultsDetail": "Display stock item test results",
"@testResultsDetail": {},
"testResultAdd": "Add Test Result",
"@testResultAdd": {},

View File

@ -24,6 +24,7 @@ const String INV_PART_SHOW_BOM = "partShowBom";
// Stock settings
const String INV_STOCK_SHOW_HISTORY = "stockShowHistory";
const String INV_STOCK_SHOW_TESTS = "stockShowTests";
const String INV_REPORT_ERRORS = "reportErrors";
const String INV_STRICT_HTTPS = "strictHttps";

View File

@ -18,6 +18,7 @@ class _InvenTreePartSettingsState extends State<InvenTreePartSettingsWidget> {
bool partShowParameters = true;
bool partShowBom = true;
bool stockShowHistory = false;
bool stockShowTests = false;
@override
void initState() {
@ -30,6 +31,7 @@ class _InvenTreePartSettingsState extends State<InvenTreePartSettingsWidget> {
partShowParameters = await InvenTreeSettingsManager().getValue(INV_PART_SHOW_PARAMETERS, true) as bool;
partShowBom = await InvenTreeSettingsManager().getValue(INV_PART_SHOW_BOM, true) as bool;
stockShowHistory = await InvenTreeSettingsManager().getValue(INV_STOCK_SHOW_HISTORY, false) as bool;
stockShowTests = await InvenTreeSettingsManager().getValue(INV_STOCK_SHOW_TESTS, true) as bool;
if (mounted) {
setState(() {
@ -86,6 +88,20 @@ class _InvenTreePartSettingsState extends State<InvenTreePartSettingsWidget> {
},
),
),
ListTile(
title: Text(L10().testResults),
subtitle: Text(L10().testResultsDetail),
leading: FaIcon(FontAwesomeIcons.vial),
trailing: Switch(
value: stockShowTests,
onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_STOCK_SHOW_TESTS, value);
setState(() {
stockShowTests = value;
});
},
),
)
]
)
)

View File

@ -47,6 +47,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
String getAppBarTitle() => L10().stockItem;
bool stockShowHistory = false;
bool stockShowTests = true;
@override
List<Widget> appBarActions(BuildContext context) {
@ -214,6 +215,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
await api.StockStatus.load();
stockShowHistory = await InvenTreeSettingsManager().getValue(INV_STOCK_SHOW_HISTORY, false) as bool;
stockShowTests = await InvenTreeSettingsManager().getValue(INV_STOCK_SHOW_TESTS, true) as bool;
final bool result = widget.item.pk > 0 && await widget.item.reload();
@ -226,7 +228,10 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
// Request part information
part = await InvenTreePart().get(widget.item.partId) as InvenTreePart?;
stockShowTests &= part?.isTrackable ?? false;
// Request test results (async)
if (stockShowTests) {
widget.item.getTestResults().then((value) {
if (mounted) {
@ -235,6 +240,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
});
}
});
}
// Request the number of attachments
InvenTreeStockItemAttachment().count(
@ -753,7 +759,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
);
}
if ((widget.item.testResultCount > 0) || (part?.isTrackable ?? false)) {
if (stockShowTests || (widget.item.testResultCount > 0)) {
tiles.add(
ListTile(
title: Text(L10().testResults),

View File

@ -1,15 +1,17 @@
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/api.dart";
import "package:inventree/app_colors.dart";
import "package:inventree/l10.dart";
import "package:inventree/inventree/part.dart";
import "package:inventree/inventree/stock.dart";
import "package:inventree/inventree/model.dart";
import "package:inventree/api.dart";
import "package:inventree/widget/progress.dart";
import "package:inventree/l10.dart";
import "package:flutter/material.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:font_awesome_flutter/font_awesome_flutter.dart";
class StockItemTestResultsWidget extends StatefulWidget {
@ -31,15 +33,25 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
String getAppBarTitle() => L10().testResults;
@override
List<Widget> appBarActions(BuildContext context) {
return [
IconButton(
icon: FaIcon(FontAwesomeIcons.circlePlus),
onPressed: () {
List<Widget> appBarActions(BuildContext context) => [];
@override
List<SpeedDialChild> actionButtons(BuildContext context) {
List<SpeedDialChild> actions = [];
if (InvenTreeStockItemTestResult().canCreate) {
actions.add(
SpeedDialChild(
child: FaIcon(FontAwesomeIcons.circlePlus),
label: L10().testResultAdd,
onTap: () {
addTestResult(context);
}
),
];
)
);
}
return actions;
}
@override
@ -153,6 +165,7 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
for (var item in results) {
bool _hasResult = false;
bool _required = false;
String _test = "";
bool _result = false;
@ -167,34 +180,37 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
_result = item.passFailStatus();
_test = item.testName;
_required = item.required;
_value = item.latestResult()?.value ?? "";
_value = item.latestResult()?.value ?? L10().noResults;
_valueRequired = item.requiresValue;
_attachmentRequired = item.requiresAttachment;
_notes = item.latestResult()?.notes ?? "";
_notes = item.latestResult()?.notes ?? item.description;
_hasResult = item.latestResult() != null;
} else if (item is InvenTreeStockItemTestResult) {
_result = item.result;
_test = item.testName;
_required = false;
_value = item.value;
_notes = item.notes;
_hasResult = true;
}
if (_result == true) {
_icon = FaIcon(FontAwesomeIcons.circleCheck,
color: COLOR_SUCCESS,
);
if (!_hasResult) {
_icon = FaIcon(FontAwesomeIcons.circleQuestion, color: Colors.blue);
} else if (_result == true) {
_icon = FaIcon(FontAwesomeIcons.circleCheck, color: COLOR_SUCCESS);
} else if (_result == false) {
_icon = FaIcon(FontAwesomeIcons.circleXmark,
color: COLOR_DANGER,
);
_icon = FaIcon(FontAwesomeIcons.circleXmark, color: COLOR_DANGER);
}
tiles.add(ListTile(
title: Text(_test, style: TextStyle(fontWeight: _required ? FontWeight.bold : FontWeight.normal)),
title: Text(_test, style: TextStyle(
fontWeight: _required ? FontWeight.bold : FontWeight.normal,
fontStyle: _hasResult ? FontStyle.normal : FontStyle.italic
)),
subtitle: Text(_notes),
trailing: Text(_value),
leading: _icon,
onLongPress: () {
onTap: () {
addTestResult(
context,
name: _test,