mirror of
https://github.com/inventree/inventree-app.git
synced 2026-09-09 03:10:14 +00:00
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:
+7
-45
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,10 +112,6 @@ class _PaginatedStockItemListState
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!InvenTreeAPI().supportsStatusLabelEndpoints) {
|
|
||||||
filters.remove("status");
|
|
||||||
}
|
|
||||||
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user