2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-12-03 18:59:50 +00:00

Default location (#715)

* Fix async loading of parent part

- Don't block render while fetching data

* Display default location on part detail page

* Use pathstring instead of name

* Update release notes

* Display in stock detail too

* dart format
This commit is contained in:
Oliver
2025-11-13 23:37:05 +11:00
committed by GitHub
parent 0eedf25d11
commit ed7d73b9c0
5 changed files with 87 additions and 12 deletions

View File

@@ -1,3 +1,8 @@
### 0.21.0 - November 2025
---
- Display default stock location in part detail page
### 0.20.2 - November 2025 ### 0.20.2 - November 2025
--- ---

View File

@@ -719,7 +719,6 @@
"languageSelect": "Select Language", "languageSelect": "Select Language",
"@languageSelect": {}, "@languageSelect": {},
"lastStocktake": "Last Stocktake", "lastStocktake": "Last Stocktake",
"@lastStocktake": {}, "@lastStocktake": {},
@@ -753,6 +752,9 @@
"locationCreateDetail": "Create new stock location", "locationCreateDetail": "Create new stock location",
"@locationCreateDetail": {}, "@locationCreateDetail": {},
"locationDefault": "Default Location",
"@locationDefault": {},
"locationNotSet": "No location specified", "locationNotSet": "No location specified",
"@locationNotSet": {}, "@locationNotSet": {},

View File

@@ -47,6 +47,8 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
InvenTreePart? parentPart; InvenTreePart? parentPart;
InvenTreeStockLocation? defaultLocation;
int parameterCount = 0; int parameterCount = 0;
bool allowLabelPrinting = false; bool allowLabelPrinting = false;
@@ -177,16 +179,35 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
// If the part points to a parent "template" part, request that too // If the part points to a parent "template" part, request that too
int? templatePartId = part.variantOf; int? templatePartId = part.variantOf;
if (templatePartId == null) { if (templatePartId != null) {
parentPart = null; InvenTreePart().get(templatePartId).then((value) {
} else { if (mounted) {
final result = await InvenTreePart().get(templatePartId); setState(() {
parentPart = value as InvenTreePart?;
if (result != null && result is InvenTreePart) { });
parentPart = result; }
} else { });
} else if (mounted) {
setState(() {
parentPart = null; parentPart = null;
} });
}
// Is there a default location specified for this part?
int? defaultLocationId = part.defaultLocation;
if (defaultLocationId != null) {
InvenTreeStockLocation().get(defaultLocationId).then((value) {
if (mounted) {
setState(() {
defaultLocation = value as InvenTreeStockLocation?;
});
}
});
} else if (mounted) {
setState(() {
defaultLocation = null;
});
} }
// Request part test templates // Request part test templates
@@ -414,6 +435,20 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
), ),
); );
if (defaultLocation != null) {
tiles.add(
ListTile(
title: Text(L10().locationDefault),
subtitle: Text(defaultLocation!.pathstring),
leading: Icon(TablerIcons.map_pin),
trailing: LinkIcon(),
onTap: () {
defaultLocation?.goToDetailPage(context);
},
),
);
}
if (showPricing && partPricing != null) { if (showPricing && partPricing != null) {
String pricing = formatPriceRange( String pricing = formatPriceRange(
partPricing?.overallMin, partPricing?.overallMin,

View File

@@ -49,6 +49,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
// Linked data fields // Linked data fields
InvenTreePart? part; InvenTreePart? part;
InvenTreeStockLocation? defaultLocation;
InvenTreeSalesOrder? salesOrder; InvenTreeSalesOrder? salesOrder;
InvenTreeCompany? customer; InvenTreeCompany? customer;
@@ -234,6 +235,23 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
stockShowTests &= part?.isTrackable ?? false; stockShowTests &= part?.isTrackable ?? false;
// Request default location
int? defaultLocationId = part?.defaultLocation;
if (defaultLocationId != null) {
InvenTreeStockLocation().get(defaultLocationId).then((value) {
if (mounted) {
setState(() {
defaultLocation = value as InvenTreeStockLocation?;
});
}
});
} else if (mounted) {
setState(() {
defaultLocation = null;
});
}
// Request test results (async) // Request test results (async)
if (stockShowTests) { if (stockShowTests) {
widget.item.getTestResults().then((value) { widget.item.getTestResults().then((value) {
@@ -569,6 +587,21 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
); );
} }
if (defaultLocation != null &&
defaultLocation?.pk != widget.item.locationId) {
tiles.add(
ListTile(
title: Text(L10().locationDefault),
subtitle: Text(defaultLocation!.pathstring),
leading: Icon(TablerIcons.map_pin),
trailing: LinkIcon(),
onTap: () {
defaultLocation?.goToDetailPage(context);
},
),
);
}
// Quantity information // Quantity information
if (widget.item.isSerialized()) { if (widget.item.isSerialized()) {
tiles.add( tiles.add(
@@ -744,7 +777,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
tiles.add( tiles.add(
ListTile( ListTile(
title: Text(L10().lastStocktake), title: Text(L10().lastStocktake),
subtitle: Text(widget.item.stocktakeDateString), trailing: LargeText(widget.item.stocktakeDateString),
leading: Icon(TablerIcons.calendar), leading: Icon(TablerIcons.calendar),
), ),
); );

View File

@@ -1,7 +1,7 @@
name: inventree name: inventree
description: InvenTree stock management description: InvenTree stock management
version: 0.20.2+105 version: 0.21.0+106
environment: environment:
sdk: ^3.8.1 sdk: ^3.8.1