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:
@@ -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
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -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": {},
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
|
||||||
parentPart = null;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} else if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
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,
|
||||||
|
|||||||
@@ -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),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user