Legacy prune (#850)

* Update minimum supported API version

* Remove legacy search support

* Remove supportsContactModel

* More updates

* Final updates

* Remove broken ref
This commit is contained in:
Oliver
2026-07-06 22:11:29 +10:00
committed by GitHub
parent 349a8e0ef5
commit cb6b5a437d
14 changed files with 95 additions and 279 deletions
+7 -45
View File
@@ -192,12 +192,10 @@ class InvenTreeAPI {
} }
} }
// Minimum required API version for server. // Minimum required API version for server
// Deliberately kept low/permissive: individual features are gated by their // 2024-03-02 (release 0.14.0)
// own apiVersion checks below (up to 496 at last count), so this floor // Ref: https://github.com/inventree/InvenTree/releases/tag/0.14.0
// only needs to reject servers old enough to predate those checks static const _minApiVersion = 180;
// entirely, not enforce feature parity. Last reviewed 2026-07-06.
static const _minApiVersion = 100;
bool _strictHttps = false; bool _strictHttps = false;
@@ -294,45 +292,9 @@ class InvenTreeAPI {
String get serverVersion => (serverInfo["version"] ?? "") as String; String get serverVersion => (serverInfo["version"] ?? "") as String;
int get apiVersion => (serverInfo["apiVersion"] ?? 1) as int; int get apiVersion => (serverInfo["apiVersion"] ?? 1) as int;
// Consolidated search request API v102 or newer /* API Version Checks
bool get supportsConsolidatedSearch => apiVersion >= 102; * These functions are used to determine if the server supports a particular feature
*/
// ReturnOrder supports API v104 or newer
bool get supportsReturnOrders => apiVersion >= 104;
// "Contact" model exposed to API
bool get supportsContactModel => apiVersion >= 104;
// Status label endpoints API v105 or newer
bool get supportsStatusLabelEndpoints => apiVersion >= 105;
// Regex search API v106 or newer
bool get supportsRegexSearch => apiVersion >= 106;
// Order barcodes API v107 or newer
bool get supportsOrderBarcodes => apiVersion >= 107;
// Project codes require v109 or newer
bool get supportsProjectCodes => apiVersion >= 109;
// Does the server support extra fields on stock adjustment actions?
bool get supportsStockAdjustExtraFields => apiVersion >= 133;
// Does the server support receiving items against a PO using barcodes?
bool get supportsBarcodePOReceiveEndpoint => apiVersion >= 139;
// Does the server support adding line items to a PO using barcodes?
bool get supportsBarcodePOAddLineEndpoint => apiVersion >= 153;
// Does the server support allocating stock to sales order using barcodes?
bool get supportsBarcodeSOAllocateEndpoint => apiVersion >= 160;
// Does the server support the "modern" test results API
// Ref: https://github.com/inventree/InvenTree/pull/6430/
bool get supportsModernTestResults => apiVersion >= 169;
// Does the server support "null" top-level filtering for PartCategory and StockLocation endpoints?
bool get supportsNullTopLevelFiltering => apiVersion < 174;
// Does the server support "active" status on Company and SupplierPart API endpoints? // Does the server support "active" status on Company and SupplierPart API endpoints?
bool get supportsCompanyActiveStatus => apiVersion >= 189; bool get supportsCompanyActiveStatus => apiVersion >= 189;
+3 -6
View File
@@ -272,14 +272,11 @@ class BarcodeScanHandler extends BarcodeHandler {
InvenTreePart.MODEL_TYPE, InvenTreePart.MODEL_TYPE,
InvenTreeStockLocation.MODEL_TYPE, InvenTreeStockLocation.MODEL_TYPE,
InvenTreeCompany.MODEL_TYPE, InvenTreeCompany.MODEL_TYPE,
InvenTreeBuildOrder.MODEL_TYPE,
InvenTreePurchaseOrder.MODEL_TYPE,
InvenTreeSalesOrder.MODEL_TYPE,
]; ];
if (InvenTreeAPI().supportsOrderBarcodes) {
validModels.add(InvenTreeBuildOrder.MODEL_TYPE);
validModels.add(InvenTreePurchaseOrder.MODEL_TYPE);
validModels.add(InvenTreeSalesOrder.MODEL_TYPE);
}
for (var key in validModels) { for (var key in validModels) {
if (data.containsKey(key)) { if (data.containsKey(key)) {
try { try {
-4
View File
@@ -63,10 +63,6 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
}, },
}; };
if (!InvenTreeAPI().supportsProjectCodes) {
fields.remove("project_code");
}
if (!InvenTreeAPI().supportsPurchaseOrderDestination) { if (!InvenTreeAPI().supportsPurchaseOrderDestination) {
fields.remove("destination"); fields.remove("destination");
} }
-8
View File
@@ -62,14 +62,6 @@ class InvenTreeSalesOrder extends InvenTreeOrder {
}, },
}; };
if (!InvenTreeAPI().supportsProjectCodes) {
fields.remove("project_code");
}
if (!InvenTreeAPI().supportsContactModel) {
fields.remove("contact");
}
if (!InvenTreeAPI().supportsStartDate) { if (!InvenTreeAPI().supportsStartDate) {
fields.remove("start_date"); fields.remove("start_date");
} }
-5
View File
@@ -46,11 +46,6 @@ class InvenTreeStatusCode {
return; return;
} }
// The server must support this feature!
if (!InvenTreeAPI().supportsStatusLabelEndpoints) {
return;
}
debug("Loading status codes from ${URL}"); debug("Loading status codes from ${URL}");
APIResponse response = await InvenTreeAPI().get(URL); APIResponse response = await InvenTreeAPI().get(URL);
-13
View File
@@ -34,7 +34,6 @@ class InvenTreeStockItemTestResult extends InvenTreeModel {
Map<String, Map<String, dynamic>> formFields() { Map<String, Map<String, dynamic>> formFields() {
Map<String, Map<String, dynamic>> fields = { Map<String, Map<String, dynamic>> fields = {
"stock_item": {"hidden": true}, "stock_item": {"hidden": true},
"test": {},
"template": { "template": {
"filters": {"enabled": "true"}, "filters": {"enabled": "true"},
}, },
@@ -44,12 +43,6 @@ class InvenTreeStockItemTestResult extends InvenTreeModel {
"attachment": {}, "attachment": {},
}; };
if (InvenTreeAPI().supportsModernTestResults) {
fields.remove("test");
} else {
fields.remove("template");
}
return fields; return fields;
} }
@@ -168,12 +161,6 @@ class InvenTreeStockItem extends InvenTreeModel {
fields["quantity"]?["hidden"] = true; fields["quantity"]?["hidden"] = true;
} }
// Old API does not support these fields
if (!api.supportsStockAdjustExtraFields) {
fields.remove("packaging");
fields.remove("status");
}
return fields; return fields;
} }
+3 -10
View File
@@ -241,7 +241,7 @@ class _PurchaseOrderDetailState
List<SpeedDialChild> barcodeButtons(BuildContext context) { List<SpeedDialChild> barcodeButtons(BuildContext context) {
List<SpeedDialChild> actions = []; List<SpeedDialChild> actions = [];
if (api.supportsBarcodePOReceiveEndpoint && widget.order.isPlaced) { if (widget.order.isPlaced) {
actions.add( actions.add(
SpeedDialChild( SpeedDialChild(
child: Icon(Icons.barcode_reader), child: Icon(Icons.barcode_reader),
@@ -258,7 +258,7 @@ class _PurchaseOrderDetailState
); );
} }
if (widget.order.isPending && api.supportsBarcodePOAddLineEndpoint) { if (widget.order.isPending) {
actions.add( actions.add(
SpeedDialChild( SpeedDialChild(
child: Icon(TablerIcons.circle_plus, color: COLOR_SUCCESS), child: Icon(TablerIcons.circle_plus, color: COLOR_SUCCESS),
@@ -288,9 +288,7 @@ class _PurchaseOrderDetailState
INV_PO_SHOW_CAMERA, INV_PO_SHOW_CAMERA,
true, true,
); );
supportProjectCodes = supportProjectCodes = await api.getGlobalBooleanSetting(
api.supportsProjectCodes &&
await api.getGlobalBooleanSetting(
"PROJECT_CODES_ENABLED", "PROJECT_CODES_ENABLED",
backup: true, backup: true,
); );
@@ -367,11 +365,6 @@ class _PurchaseOrderDetailState
// Cannot edit supplier field from here // Cannot edit supplier field from here
fields.remove("supplier"); fields.remove("supplier");
// Contact model not supported by server
if (!api.supportsContactModel) {
fields.remove("contact");
}
// ProjectCode model not supported by server // ProjectCode model not supported by server
if (!supportProjectCodes) { if (!supportProjectCodes) {
fields.remove("project_code"); fields.remove("project_code");
@@ -79,7 +79,6 @@ class _PurchaseOrderListWidgetState
List<SpeedDialChild> barcodeButtons(BuildContext context) { List<SpeedDialChild> barcodeButtons(BuildContext context) {
List<SpeedDialChild> actions = []; List<SpeedDialChild> actions = [];
if (api.supportsBarcodePOReceiveEndpoint) {
actions.add( actions.add(
SpeedDialChild( SpeedDialChild(
child: Icon(Icons.barcode_reader), child: Icon(Icons.barcode_reader),
@@ -89,7 +88,6 @@ class _PurchaseOrderListWidgetState
}, },
), ),
); );
}
return actions; return actions;
} }
+1 -10
View File
@@ -239,7 +239,6 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
), ),
); );
if (api.supportsBarcodeSOAllocateEndpoint) {
actions.add( actions.add(
SpeedDialChild( SpeedDialChild(
child: Icon(TablerIcons.transition_right), child: Icon(TablerIcons.transition_right),
@@ -253,7 +252,6 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
), ),
); );
} }
}
return actions; return actions;
} }
@@ -263,9 +261,7 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
await widget.order.reload(); await widget.order.reload();
await api.SalesOrderStatus.load(); await api.SalesOrderStatus.load();
supportsProjectCodes = supportsProjectCodes = await api.getGlobalBooleanSetting(
api.supportsProjectCodes &&
await api.getGlobalBooleanSetting(
"PROJECT_CODES_ENABLED", "PROJECT_CODES_ENABLED",
backup: true, backup: true,
); );
@@ -312,11 +308,6 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
fields.remove("customer"); fields.remove("customer");
// Contact model not supported by server
if (!api.supportsContactModel) {
fields.remove("contact");
}
// ProjectCode model not supported by server // ProjectCode model not supported by server
if (!supportsProjectCodes) { if (!supportsProjectCodes) {
fields.remove("project_code"); fields.remove("project_code");
-2
View File
@@ -128,7 +128,6 @@ class _SOLineDetailWidgetState extends RefreshableState<SoLineDetailWidget> {
List<SpeedDialChild> actions = []; List<SpeedDialChild> actions = [];
if (order != null && order!.isOpen && InvenTreeSOLineItem().canCreate) { if (order != null && order!.isOpen && InvenTreeSOLineItem().canCreate) {
if (api.supportsBarcodeSOAllocateEndpoint) {
actions.add( actions.add(
SpeedDialChild( SpeedDialChild(
child: Icon(TablerIcons.transition_right), child: Icon(TablerIcons.transition_right),
@@ -145,7 +144,6 @@ class _SOLineDetailWidgetState extends RefreshableState<SoLineDetailWidget> {
), ),
); );
} }
}
return actions; return actions;
} }
+1 -1
View File
@@ -192,7 +192,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
if (parent != null) { if (parent != null) {
filters["parent"] = parent.toString(); filters["parent"] = parent.toString();
} else if (api.supportsNullTopLevelFiltering) { } else {
filters["parent"] = "null"; filters["parent"] = "null";
} }
-87
View File
@@ -255,8 +255,6 @@ class _SearchDisplayState extends RefreshableState<SearchWidget> {
return; return;
} }
// Consolidated search allows us to perform *all* searches in a single query
if (api.supportsConsolidatedSearch) {
Map<String, dynamic> body = { Map<String, dynamic> body = {
"limit": 1, "limit": 1,
"search": term, "search": term,
@@ -289,91 +287,6 @@ class _SearchDisplayState extends RefreshableState<SearchWidget> {
_search_query = CancelableOperation.fromFuture(_perform_search(body)); _search_query = CancelableOperation.fromFuture(_perform_search(body));
} }
} }
} else {
legacySearch(term);
}
}
/*
* Perform "legacy" search (without consolidated search API endpoint
*/
Future<void> legacySearch(String term) async {
// Search parts
if (InvenTreePart().canView) {
nPendingSearches++;
InvenTreePart().count(searchQuery: term).then((int n) {
if (term == searchController.text) {
if (mounted) {
decrementPendingSearches();
setState(() {
nPartResults = n;
});
}
}
});
}
// Search part categories
if (InvenTreePartCategory().canView) {
nPendingSearches++;
InvenTreePartCategory().count(searchQuery: term).then((int n) {
if (term == searchController.text) {
if (mounted) {
decrementPendingSearches();
setState(() {
nCategoryResults = n;
});
}
}
});
}
// Search stock items
if (InvenTreeStockItem().canView) {
nPendingSearches++;
InvenTreeStockItem().count(searchQuery: term).then((int n) {
if (term == searchController.text) {
if (mounted) {
decrementPendingSearches();
setState(() {
nStockResults = n;
});
}
}
});
}
// Search stock locations
if (InvenTreeStockLocation().canView) {
nPendingSearches++;
InvenTreeStockLocation().count(searchQuery: term).then((int n) {
if (term == searchController.text) {
if (mounted) {
decrementPendingSearches();
setState(() {
nLocationResults = n;
});
}
}
});
}
// Search purchase orders
if (InvenTreePurchaseOrder().canView) {
nPendingSearches++;
InvenTreePurchaseOrder()
.count(searchQuery: term, filters: {"outstanding": "true"})
.then((int n) {
if (term == searchController.text) {
if (mounted) {
decrementPendingSearches();
setState(() {
nPurchaseOrderResults = n;
});
}
}
});
}
} }
@override @override
+1 -3
View File
@@ -101,7 +101,6 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
); );
} }
if (api.supportsBarcodePOReceiveEndpoint) {
actions.add( actions.add(
SpeedDialChild( SpeedDialChild(
child: Icon(Icons.barcode_reader), child: Icon(Icons.barcode_reader),
@@ -114,7 +113,6 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
}, },
), ),
); );
}
// Scan this location into another one // Scan this location into another one
if (InvenTreeStockLocation().canEdit) { if (InvenTreeStockLocation().canEdit) {
@@ -362,7 +360,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
if (parent != null) { if (parent != null) {
filters["parent"] = parent.toString(); filters["parent"] = parent.toString();
} else if (api.supportsNullTopLevelFiltering) { } else {
filters["parent"] = "null"; filters["parent"] = "null";
} }
-4
View File
@@ -112,10 +112,6 @@ class _PaginatedStockItemListState
}, },
}; };
if (!InvenTreeAPI().supportsStatusLabelEndpoints) {
filters.remove("status");
}
return filters; return filters;
} }