2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-06-17 04:35:26 +00:00

Many many changes for null-safety support

This commit is contained in:
Oliver
2021-07-09 23:56:38 +10:00
parent 2988716bf3
commit d3eec6a79e
30 changed files with 563 additions and 456 deletions

View File

@ -33,7 +33,7 @@ class InvenTreePageResponse {
int get count => _count;
int get length => results?.length ?? 0;
int get length => results.length;
List<InvenTreeModel> results = [];
}
@ -91,16 +91,16 @@ class InvenTreeModel {
}
int get pk => jsondata['pk'] ?? -1;
int get pk => (jsondata['pk'] ?? -1) as int;
// Some common accessors
String get name => jsondata['name'] ?? '';
String get description => jsondata['description'] ?? '';
String get notes => jsondata['notes'] as String ?? '';
String get notes => jsondata['notes'] ?? '';
int get parentId => jsondata['parent'] as int ?? -1;
int get parentId => (jsondata['parent'] ?? -1) as int;
// Legacy API provided external link as "URL", while newer API uses "link"
String get link => jsondata['link'] ?? jsondata['URL'] ?? '';
@ -127,7 +127,7 @@ class InvenTreeModel {
}
}
String get keywords => jsondata['keywords'] as String ?? '';
String get keywords => jsondata['keywords'] ?? '';
// Create a new object from JSON data (not a constructor!)
InvenTreeModel createFromJson(Map<String, dynamic> json) {
@ -142,7 +142,7 @@ class InvenTreeModel {
// Search this Model type in the database
Future<List<InvenTreeModel>> search(BuildContext context, String searchTerm, {Map<String, String> filters}) async {
Future<List<InvenTreeModel>> search(BuildContext context, String searchTerm, {Map<String, String>? filters}) async {
if (filters == null) {
filters = {};
@ -150,7 +150,7 @@ class InvenTreeModel {
filters["search"] = searchTerm;
final results = list(context, filters: filters);
final results = list(filters: filters);
return results;
@ -164,7 +164,7 @@ class InvenTreeModel {
/*
* Reload this object, by requesting data from the server
*/
Future<bool> reload(BuildContext context) async {
Future<bool> reload() async {
var response = await api.get(url, params: defaultGetFilters());
@ -178,7 +178,7 @@ class InvenTreeModel {
}
// POST data to update the model
Future<bool> update(BuildContext context, {Map<String, String> values}) async {
Future<bool> update({Map<String, String>? values}) async {
var addr = path.join(URL, pk.toString());
@ -198,15 +198,15 @@ class InvenTreeModel {
}
// Return the detail view for the associated pk
Future<InvenTreeModel> get(BuildContext context, int pk, {Map<String, String> filters}) async {
Future<InvenTreeModel?> get(int pk, {Map<String, String>? filters}) async {
// TODO - Add "timeout"
// TODO - Add error catching
var addr = path.join(URL, pk.toString());
var url = path.join(URL, pk.toString());
if (!addr.endsWith("/")) {
addr += "/";
if (!url.endsWith("/")) {
url += "/";
}
var params = defaultGetFilters();
@ -214,13 +214,13 @@ class InvenTreeModel {
if (filters != null) {
// Override any default values
for (String key in filters.keys) {
params[key] = filters[key];
params[key] = filters[key] ?? '';
}
}
print("GET: $addr ${params.toString()}");
print("GET: $url ${params.toString()}");
var response = await api.get(addr, params: params);
var response = await api.get(url, params: params);
if (response == null) {
return null;
@ -229,7 +229,7 @@ class InvenTreeModel {
return createFromJson(response);
}
Future<InvenTreeModel> create(BuildContext context, Map<String, dynamic> data) async {
Future<InvenTreeModel?> create(Map<String, dynamic> data) async {
print("CREATE: ${URL} ${data.toString()}");
@ -241,8 +241,6 @@ class InvenTreeModel {
data.remove('id');
}
InvenTreeModel _model;
var response = await api.post(URL, body: data);
if (response == null) {
@ -252,12 +250,12 @@ class InvenTreeModel {
return createFromJson(response);
}
Future<InvenTreePageResponse> listPaginated(int limit, int offset, {Map<String, String> filters}) async {
Future<InvenTreePageResponse?> listPaginated(int limit, int offset, {Map<String, String>? filters = null}) async {
var params = defaultListFilters();
if (filters != null) {
for (String key in filters.keys) {
params[key] = filters[key];
params[key] = filters[key] ?? '';
}
}
@ -285,14 +283,12 @@ class InvenTreeModel {
return page;
} else {
// Inavlid response
print("Invalid!");
return null;
}
}
// Return list of objects from the database, with optional filters
Future<List<InvenTreeModel>> list(BuildContext context, {Map<String, String> filters}) async {
Future<List<InvenTreeModel>> list({Map<String, String>? filters}) async {
if (filters == null) {
filters = {};
@ -302,7 +298,7 @@ class InvenTreeModel {
if (filters != null) {
for (String key in filters.keys) {
params[key] = filters[key];
params[key] = filters[key] ?? '';
}
}
@ -311,7 +307,7 @@ class InvenTreeModel {
var response = await api.get(URL, params: params);
// A list of "InvenTreeModel" items
List<InvenTreeModel> results = new List<InvenTreeModel>();
List<InvenTreeModel> results = new List<InvenTreeModel>.empty();
if (response == null) {
return results;

View File

@ -100,10 +100,11 @@ class InvenTreePartTestTemplate extends InvenTreeModel {
}
bool passFailStatus() {
var result = latestResult();
if (result == null) {
return null;
return false;
}
return result.result;
@ -113,7 +114,7 @@ class InvenTreePartTestTemplate extends InvenTreeModel {
List<InvenTreeStockItemTestResult> results = [];
// Return the most recent test result recorded against this template
InvenTreeStockItemTestResult latestResult() {
InvenTreeStockItemTestResult? latestResult() {
if (results.isEmpty) {
return null;
}
@ -143,12 +144,12 @@ class InvenTreePart extends InvenTreeModel {
@override
Map<String, String> defaultGetFilters() {
return {
"category_detail": "1", // Include category detail information
"category_detail": "true", // Include category detail information
};
}
// Cached list of stock items
List<InvenTreeStockItem> stockItems = List<InvenTreeStockItem>();
List<InvenTreeStockItem> stockItems = List<InvenTreeStockItem>.empty();
int get stockItemCount => stockItems.length;
@ -156,7 +157,6 @@ class InvenTreePart extends InvenTreeModel {
Future<void> getStockItems(BuildContext context, {bool showDialog=false}) async {
await InvenTreeStockItem().list(
context,
filters: {
"part": "${pk}",
"in_stock": "true",
@ -172,18 +172,17 @@ class InvenTreePart extends InvenTreeModel {
});
}
int get supplier_count => jsondata['suppliers'] as int ?? 0;
int get supplier_count => (jsondata['suppliers'] ?? 0) as int;
// Cached list of test templates
List<InvenTreePartTestTemplate> testingTemplates = List<InvenTreePartTestTemplate>();
List<InvenTreePartTestTemplate> testingTemplates = List<InvenTreePartTestTemplate>.empty();
int get testTemplateCount => testingTemplates.length;
// Request test templates from the serve
Future<void> getTestTemplates(BuildContext context, {bool showDialog=false}) async {
Future<void> getTestTemplates({bool showDialog=false}) async {
InvenTreePartTestTemplate().list(
context,
filters: {
"part": "${pk}",
},
@ -200,10 +199,10 @@ class InvenTreePart extends InvenTreeModel {
}
// Get the number of stock on order for this Part
double get onOrder => double.tryParse(jsondata['ordering'].toString() ?? '0');
double get onOrder => double.tryParse(jsondata['ordering']) ?? 0;
// Get the stock count for this Part
double get inStock => double.tryParse(jsondata['in_stock'].toString() ?? '0');
double get inStock => double.tryParse(jsondata['in_stock']) ?? 0;
String get inStockString {
@ -215,51 +214,55 @@ class InvenTreePart extends InvenTreeModel {
}
// Get the number of units being build for this Part
double get building => double.tryParse(jsondata['building'].toString() ?? '0');
double get building => double.tryParse(jsondata['building']) ?? 0;
// Get the number of BOM items in this Part (if it is an assembly)
int get bomItemCount => jsondata['bom_items'] as int ?? 0;
int get bomItemCount => (jsondata['bom_items'] ?? 0) as int;
// Get the number of BOMs this Part is used in (if it is a component)
int get usedInCount => jsondata['used_in'] as int ?? 0;
int get usedInCount => (jsondata['used_in'] ?? 0) as int;
bool get isAssembly => jsondata['assembly'] ?? false;
bool get isAssembly => (jsondata['assembly'] ?? false) as bool;
bool get isComponent => jsondata['component'] ?? false;
bool get isComponent => (jsondata['component'] ?? false) as bool;
bool get isPurchaseable => jsondata['purchaseable'] ?? false;
bool get isPurchaseable => (jsondata['purchaseable'] ?? false) as bool;
bool get isSalable => jsondata['salable'] ?? false;
bool get isSalable => (jsondata['salable'] ?? false) as bool;
bool get isActive => jsondata['active'] ?? false;
bool get isActive => (jsondata['active'] ?? false) as bool;
bool get isVirtual => jsondata['virtual'] ?? false;
bool get isVirtual => (jsondata['virtual'] ?? false) as bool;
bool get isTrackable => jsondata['trackable'] ?? false;
bool get isTrackable => (jsondata['trackable'] ?? false) as bool;
// Get the IPN (internal part number) for the Part instance
String get IPN => jsondata['IPN'] as String ?? '';
String get IPN => jsondata['IPN'] ?? '';
// Get the revision string for the Part instance
String get revision => jsondata['revision'] as String ?? '';
String get revision => jsondata['revision'] ?? '';
// Get the category ID for the Part instance (or 'null' if does not exist)
int get categoryId => jsondata['category'] as int ?? null;
int get categoryId => (jsondata['category'] ?? -1) as int;
// Get the category name for the Part instance
String get categoryName {
if (categoryId == null) return '';
// Inavlid category ID
if (categoryId <= 0) return '';
if (!jsondata.containsKey('category_detail')) return '';
return jsondata['category_detail']['name'] as String ?? '';
return jsondata['category_detail']?['name'] ?? '';
}
// Get the category description for the Part instance
String get categoryDescription {
if (categoryId == null) return '';
// Invalid category ID
if (categoryId <= 0) return '';
if (!jsondata.containsKey('category_detail')) return '';
return jsondata['category_detail']['description'] as String ?? '';
return jsondata['category_detail']?['description'] ?? '';
}
// Get the image URL for the Part instance
String get _image => jsondata['image'] ?? '';
@ -274,7 +277,7 @@ class InvenTreePart extends InvenTreeModel {
if (fn.isNotEmpty) return fn;
List<String> elements = List<String>();
List<String> elements = List<String>.empty();
if (IPN.isNotEmpty) elements.add(IPN);
@ -324,7 +327,7 @@ class InvenTreePart extends InvenTreeModel {
}
// Return the "starred" status of this part
bool get starred => jsondata['starred'] as bool ?? false;
bool get starred => (jsondata['starred'] ?? false) as bool;
InvenTreePart() : super();

View File

@ -138,14 +138,13 @@ class InvenTreeStockItem extends InvenTreeModel {
// TODO
}
List<InvenTreePartTestTemplate> testTemplates = List<InvenTreePartTestTemplate>();
List<InvenTreePartTestTemplate> testTemplates = List<InvenTreePartTestTemplate>.empty();
int get testTemplateCount => testTemplates.length;
// Get all the test templates associated with this StockItem
Future<void> getTestTemplates(BuildContext context, {bool showDialog=false}) async {
Future<void> getTestTemplates({bool showDialog=false}) async {
await InvenTreePartTestTemplate().list(
context,
filters: {
"part": "${partId}",
},
@ -160,14 +159,13 @@ class InvenTreeStockItem extends InvenTreeModel {
});
}
List<InvenTreeStockItemTestResult> testResults = List<InvenTreeStockItemTestResult>();
List<InvenTreeStockItemTestResult> testResults = List<InvenTreeStockItemTestResult>.empty();
int get testResultCount => testResults.length;
Future<void> getTestResults(BuildContext context) async {
Future<void> getTestResults() async {
await InvenTreeStockItemTestResult().list(
context,
filters: {
"stock_item": "${pk}",
"user_detail": "true",
@ -183,7 +181,7 @@ class InvenTreeStockItem extends InvenTreeModel {
});
}
Future<bool> uploadTestResult(BuildContext context, String testName, bool result, {String value, String notes, File attachment}) async {
Future<bool> uploadTestResult(BuildContext context, String testName, bool result, {String? value, String? notes, File? attachment}) async {
Map<String, String> data = {
"stock_item": pk.toString(),
@ -204,7 +202,7 @@ class InvenTreeStockItem extends InvenTreeModel {
* TODO: Is there a nice way to refactor this one?
*/
if (attachment == null) {
var _result = await InvenTreeStockItemTestResult().create(context, data);
var _result = await InvenTreeStockItemTestResult().create(data);
return (_result != null) && (_result is InvenTreeStockItemTestResult);
} else {
@ -224,12 +222,12 @@ class InvenTreeStockItem extends InvenTreeModel {
int get partId => jsondata['part'] ?? -1;
int get trackingItemCount => jsondata['tracking_items'] as int ?? 0;
int get trackingItemCount => (jsondata['tracking_items'] ?? 0) as int;
// Date of last update
String get updated => jsondata["updated"] ?? "";
DateTime get stocktakeDate {
DateTime? get stocktakeDate {
if (jsondata.containsKey("stocktake_date")) {
if (jsondata["stocktake_date"] == null) {
return null;
@ -292,15 +290,18 @@ class InvenTreeStockItem extends InvenTreeModel {
*/
String get partThumbnail {
String thumb;
String thumb = "";
if (jsondata.containsKey('part_detail')) {
thumb = jsondata['part_detail']['thumbnail'] as String ?? '';
thumb = jsondata['part_detail']?['thumbnail'] ?? '';
// Use 'image' as a backup
if (thumb.isEmpty) {
thumb = jsondata['part_detail']?['image'] ?? '';
}
// Try a different approach
if (thumb.isEmpty) {
jsondata['part__thumbnail'] as String ?? '';
thumb = jsondata['part__thumbnail'] ?? '';
}
// Still no thumbnail? Use the 'no image' image
@ -309,7 +310,7 @@ class InvenTreeStockItem extends InvenTreeModel {
return thumb;
}
int get supplierPartId => jsondata['supplier_part'] as int ?? -1;
int get supplierPartId => (jsondata['supplier_part'] ?? -1) as int;
String get supplierImage {
String thumb = '';
@ -341,9 +342,9 @@ class InvenTreeStockItem extends InvenTreeModel {
return sku;
}
String get serialNumber => jsondata['serial'] as String ?? null;
String get serialNumber => jsondata['serial'] ?? "";
double get quantity => double.tryParse(jsondata['quantity'].toString() ?? '0');
double get quantity => double.tryParse(jsondata['quantity']) ?? 0;
String get quantityString {
@ -354,9 +355,9 @@ class InvenTreeStockItem extends InvenTreeModel {
}
}
int get locationId => jsondata['location'] as int ?? -1;
int get locationId => (jsondata['location'] ?? -1) as int;
bool isSerialized() => serialNumber != null && quantity.toInt() == 1;
bool isSerialized() => serialNumber.isNotEmpty && quantity.toInt() == 1;
String serialOrQuantityDisplay() {
if (isSerialized()) {
@ -397,7 +398,7 @@ class InvenTreeStockItem extends InvenTreeModel {
String get displayQuantity {
// Display either quantity or serial number!
if (serialNumber != null) {
if (serialNumber.isNotEmpty) {
return "SN: $serialNumber";
} else {
return quantity.toString().trim();
@ -420,7 +421,7 @@ class InvenTreeStockItem extends InvenTreeModel {
* - Remove
* - Count
*/
Future<bool> adjustStock(BuildContext context, String endpoint, double q, {String notes}) async {
Future<bool> adjustStock(BuildContext context, String endpoint, double q, {String? notes}) async {
// Serialized stock cannot be adjusted
if (isSerialized()) {
@ -456,30 +457,29 @@ class InvenTreeStockItem extends InvenTreeModel {
return true;
}
Future<bool> countStock(BuildContext context, double q, {String notes}) async {
Future<bool> countStock(BuildContext context, double q, {String? notes}) async {
final bool result = await adjustStock(context, "/stock/count", q, notes: notes);
return result;
}
Future<bool> addStock(BuildContext context, double q, {String notes}) async {
Future<bool> addStock(BuildContext context, double q, {String? notes}) async {
final bool result = await adjustStock(context, "/stock/add/", q, notes: notes);
return result;
}
Future<bool> removeStock(BuildContext context, double q, {String notes}) async {
Future<bool> removeStock(BuildContext context, double q, {String? notes}) async {
final bool result = await adjustStock(context, "/stock/remove/", q, notes: notes);
return result;
}
Future<bool> transferStock(int location, {double quantity, String notes}) async {
if (quantity == null) {} else
if ((quantity < 0) || (quantity > this.quantity)) {
Future<bool> transferStock(int location, {double? quantity, String? notes}) async {
if ((quantity == null) || (quantity < 0) || (quantity > this.quantity)) {
quantity = this.quantity;
}