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:
parent
49226a5fce
commit
383571707e
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -1208,6 +1208,9 @@
|
||||
"description": ""
|
||||
},
|
||||
|
||||
"testResultsDetail": "Display stock item test results",
|
||||
"@testResultsDetail": {},
|
||||
|
||||
"testResultAdd": "Add Test Result",
|
||||
"@testResultAdd": {},
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user