mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
Fixes for type casting
This commit is contained in:
parent
9d95cae612
commit
c1152ee286
@ -1,8 +1,23 @@
|
|||||||
include: package:lint/analysis_options.yaml
|
include: package:lint/analysis_options.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
exclude: [build/**]
|
||||||
|
language:
|
||||||
|
strict-raw-types: true
|
||||||
|
strong-mode:
|
||||||
|
implicit-casts: false
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
rules:
|
rules:
|
||||||
# ------ Disable individual rules ----- #
|
# ------ Disable individual rules ----- #
|
||||||
# --- #
|
# --- #
|
||||||
# Turn off what you don't like. #
|
# Turn off what you don't like. #
|
||||||
# ------------------------------------- #
|
# ------------------------------------- #
|
||||||
|
|
||||||
|
# Make constructors the first thing in every class
|
||||||
|
sort_constructors_first: true
|
||||||
|
|
||||||
|
prefer_single_quotes: true
|
||||||
|
|
||||||
|
# Blindly follow the Flutter code style, which prefers types everywhere
|
||||||
|
always_specify_types: true
|
||||||
|
51
lib/api.dart
51
lib/api.dart
@ -51,6 +51,31 @@ class APIResponse {
|
|||||||
bool clientError() => (statusCode >= 400) && (statusCode < 500);
|
bool clientError() => (statusCode >= 400) && (statusCode < 500);
|
||||||
|
|
||||||
bool serverError() => (statusCode >= 500);
|
bool serverError() => (statusCode >= 500);
|
||||||
|
|
||||||
|
bool isMap() {
|
||||||
|
return data != null && data is Map<String, dynamic>;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> asMap() {
|
||||||
|
if (isMap()) {
|
||||||
|
return data as Map<String, dynamic>;
|
||||||
|
} else {
|
||||||
|
// Empty map
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isList() {
|
||||||
|
return data != null && data is List<dynamic>;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<dynamic> asList() {
|
||||||
|
if (isList()) {
|
||||||
|
return data as List<dynamic>;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -268,8 +293,10 @@ class InvenTreeAPI {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var data = response.asMap();
|
||||||
|
|
||||||
// We expect certain response from the server
|
// We expect certain response from the server
|
||||||
if (response.data == null || !response.data.containsKey("server") || !response.data.containsKey("version") || !response.data.containsKey("instance")) {
|
if (!data.containsKey("server") || !data.containsKey("version") || !data.containsKey("instance")) {
|
||||||
|
|
||||||
showServerError(
|
showServerError(
|
||||||
L10().missingData,
|
L10().missingData,
|
||||||
@ -280,11 +307,11 @@ class InvenTreeAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Record server information
|
// Record server information
|
||||||
_version = response.data["version"];
|
_version = (data["version"] ?? '') as String;
|
||||||
instance = response.data['instance'] ?? '';
|
instance = (data['instance'] ?? '') as String;
|
||||||
|
|
||||||
// Default API version is 1 if not provided
|
// Default API version is 1 if not provided
|
||||||
_apiVersion = (response.data['apiVersion'] ?? 1) as int;
|
_apiVersion = (data['apiVersion'] ?? 1) as int;
|
||||||
|
|
||||||
if (_apiVersion < _minApiVersion) {
|
if (_apiVersion < _minApiVersion) {
|
||||||
|
|
||||||
@ -333,7 +360,9 @@ class InvenTreeAPI {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.data == null || !response.data.containsKey("token")) {
|
data = response.asMap();
|
||||||
|
|
||||||
|
if (!data.containsKey("token")) {
|
||||||
showServerError(
|
showServerError(
|
||||||
L10().tokenMissing,
|
L10().tokenMissing,
|
||||||
L10().tokenMissingFromResponse,
|
L10().tokenMissingFromResponse,
|
||||||
@ -343,7 +372,7 @@ class InvenTreeAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return the received token
|
// Return the received token
|
||||||
_token = response.data["token"];
|
_token = (data["token"] ?? "") as String;
|
||||||
print("Received token - $_token");
|
print("Received token - $_token");
|
||||||
|
|
||||||
// Request user role information
|
// Request user role information
|
||||||
@ -415,9 +444,11 @@ class InvenTreeAPI {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.data.containsKey('roles')) {
|
var data = response.asMap();
|
||||||
|
|
||||||
|
if (data.containsKey('roles')) {
|
||||||
// Save a local copy of the user roles
|
// Save a local copy of the user roles
|
||||||
roles = response.data['roles'];
|
roles = response.data['roles'] as Map<String, dynamic>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,7 +469,7 @@ class InvenTreeAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> perms = List.from(roles[role]);
|
List<String> perms = List.from(roles[role] as List<dynamic>);
|
||||||
return perms.contains(permission);
|
return perms.contains(permission);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
sentryReportError(error, stackTrace);
|
sentryReportError(error, stackTrace);
|
||||||
@ -551,7 +582,7 @@ class InvenTreeAPI {
|
|||||||
showServerError(L10().connectionRefused, error.toString());
|
showServerError(L10().connectionRefused, error.toString());
|
||||||
} on TimeoutException {
|
} on TimeoutException {
|
||||||
showTimeoutError();
|
showTimeoutError();
|
||||||
} catch (error, stackTrace) {
|
} catch (error) {
|
||||||
print("Error downloading image:");
|
print("Error downloading image:");
|
||||||
print(error.toString());
|
print(error.toString());
|
||||||
showServerError(L10().downloadError, error.toString());
|
showServerError(L10().downloadError, error.toString());
|
||||||
|
@ -36,15 +36,15 @@ class APIFormField {
|
|||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
// JSON data which defines the field
|
// JSON data which defines the field
|
||||||
final dynamic data;
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
dynamic initial_data;
|
dynamic initial_data;
|
||||||
|
|
||||||
// Get the "api_url" associated with a related field
|
// Get the "api_url" associated with a related field
|
||||||
String get api_url => data["api_url"] ?? "";
|
String get api_url => (data["api_url"] ?? '') as String;
|
||||||
|
|
||||||
// Get the "model" associated with a related field
|
// Get the "model" associated with a related field
|
||||||
String get model => data["model"] ?? "";
|
String get model => (data["model"] ?? '') as String;
|
||||||
|
|
||||||
// Is this field hidden?
|
// Is this field hidden?
|
||||||
bool get hidden => (data['hidden'] ?? false) as bool;
|
bool get hidden => (data['hidden'] ?? false) as bool;
|
||||||
@ -71,7 +71,7 @@ class APIFormField {
|
|||||||
|
|
||||||
if (f is Map) {
|
if (f is Map) {
|
||||||
f.forEach((key, value) {
|
f.forEach((key, value) {
|
||||||
_filters[key] = value.toString();
|
_filters[key as String] = value.toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ class APIFormField {
|
|||||||
|
|
||||||
if (f is Map) {
|
if (f is Map) {
|
||||||
f.forEach((key, value) {
|
f.forEach((key, value) {
|
||||||
_filters[key] = value.toString();
|
_filters[key as String] = value.toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ class APIFormField {
|
|||||||
|
|
||||||
// Return the error message associated with this field
|
// Return the error message associated with this field
|
||||||
List<String> errorMessages() {
|
List<String> errorMessages() {
|
||||||
List<dynamic> errors = data['errors'] ?? [];
|
List<dynamic> errors = (data['errors'] ?? []) as List<dynamic>;
|
||||||
|
|
||||||
List<String> messages = [];
|
List<String> messages = [];
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ class APIFormField {
|
|||||||
|
|
||||||
String get placeholderText => (data['placeholder'] ?? '').toString();
|
String get placeholderText => (data['placeholder'] ?? '').toString();
|
||||||
|
|
||||||
List<dynamic> get choices => data["choices"] ?? [];
|
List<dynamic> get choices => (data["choices"] ?? []) as List<dynamic>;
|
||||||
|
|
||||||
Future<void> loadInitialData() async {
|
Future<void> loadInitialData() async {
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ class APIFormField {
|
|||||||
labelText: label,
|
labelText: label,
|
||||||
labelStyle: _labelStyle(),
|
labelStyle: _labelStyle(),
|
||||||
),
|
),
|
||||||
initialValue: DateTime.tryParse(value ?? ""),
|
initialValue: DateTime.tryParse((value ?? '') as String),
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
validator: (e) {
|
validator: (e) {
|
||||||
// TODO
|
// TODO
|
||||||
@ -267,7 +267,7 @@ class APIFormField {
|
|||||||
autoFocusSearchBox: true,
|
autoFocusSearchBox: true,
|
||||||
showClearButton: !required,
|
showClearButton: !required,
|
||||||
itemAsString: (dynamic item) {
|
itemAsString: (dynamic item) {
|
||||||
return item['display_name'];
|
return (item['display_name'] ?? '') as String;
|
||||||
},
|
},
|
||||||
onSaved: (item) {
|
onSaved: (item) {
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
@ -349,13 +349,16 @@ class APIFormField {
|
|||||||
onChanged: null,
|
onChanged: null,
|
||||||
showClearButton: !required,
|
showClearButton: !required,
|
||||||
itemAsString: (dynamic item) {
|
itemAsString: (dynamic item) {
|
||||||
|
|
||||||
|
Map<String, dynamic> data = item as Map<String, dynamic>;
|
||||||
|
|
||||||
switch (model) {
|
switch (model) {
|
||||||
case "part":
|
case "part":
|
||||||
return InvenTreePart.fromJson(item).fullname;
|
return InvenTreePart.fromJson(data).fullname;
|
||||||
case "partcategory":
|
case "partcategory":
|
||||||
return InvenTreePartCategory.fromJson(item).pathstring;
|
return InvenTreePartCategory.fromJson(data).pathstring;
|
||||||
case "stocklocation":
|
case "stocklocation":
|
||||||
return InvenTreeStockLocation.fromJson(item).pathstring;
|
return InvenTreeStockLocation.fromJson(data).pathstring;
|
||||||
default:
|
default:
|
||||||
return "itemAsString not implemented for '${model}'";
|
return "itemAsString not implemented for '${model}'";
|
||||||
}
|
}
|
||||||
@ -391,19 +394,13 @@ class APIFormField {
|
|||||||
Widget _renderRelatedField(dynamic item, bool selected, bool extended) {
|
Widget _renderRelatedField(dynamic item, bool selected, bool extended) {
|
||||||
// Render a "related field" based on the "model" type
|
// Render a "related field" based on the "model" type
|
||||||
|
|
||||||
if (item == null) {
|
// Convert to JSON
|
||||||
return Text(
|
Map<String, dynamic> data = item as Map<String, dynamic>;
|
||||||
helpText,
|
|
||||||
style: TextStyle(
|
|
||||||
fontStyle: FontStyle.italic
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (model) {
|
switch (model) {
|
||||||
case "part":
|
case "part":
|
||||||
|
|
||||||
var part = InvenTreePart.fromJson(item);
|
var part = InvenTreePart.fromJson(data);
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
@ -419,7 +416,7 @@ class APIFormField {
|
|||||||
|
|
||||||
case "partcategory":
|
case "partcategory":
|
||||||
|
|
||||||
var cat = InvenTreePartCategory.fromJson(item);
|
var cat = InvenTreePartCategory.fromJson(data);
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
@ -433,7 +430,7 @@ class APIFormField {
|
|||||||
);
|
);
|
||||||
case "stocklocation":
|
case "stocklocation":
|
||||||
|
|
||||||
var loc = InvenTreeStockLocation.fromJson(item);
|
var loc = InvenTreeStockLocation.fromJson(data);
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
@ -446,7 +443,7 @@ class APIFormField {
|
|||||||
) : null,
|
) : null,
|
||||||
);
|
);
|
||||||
case "owner":
|
case "owner":
|
||||||
String name = item["name"] ?? "";
|
String name = (item["name"] ?? '') as String;
|
||||||
bool isGroup = (item["label"] ?? "") == "group";
|
bool isGroup = (item["label"] ?? "") == "group";
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(name),
|
title: Text(name),
|
||||||
@ -481,7 +478,7 @@ class APIFormField {
|
|||||||
readOnly: readOnly,
|
readOnly: readOnly,
|
||||||
maxLines: multiline ? null : 1,
|
maxLines: multiline ? null : 1,
|
||||||
expands: false,
|
expands: false,
|
||||||
initialValue: value ?? '',
|
initialValue: (value ?? '') as String,
|
||||||
onSaved: (val) {
|
onSaved: (val) {
|
||||||
data["value"] = val;
|
data["value"] = val;
|
||||||
},
|
},
|
||||||
@ -501,7 +498,7 @@ class APIFormField {
|
|||||||
labelStyle: _labelStyle(),
|
labelStyle: _labelStyle(),
|
||||||
helperText: helpText,
|
helperText: helpText,
|
||||||
helperStyle: _helperStyle(),
|
helperStyle: _helperStyle(),
|
||||||
initial: value,
|
initial: value as bool,
|
||||||
onSaved: (val) {
|
onSaved: (val) {
|
||||||
data['value'] = val;
|
data['value'] = val;
|
||||||
},
|
},
|
||||||
@ -537,13 +534,17 @@ Map<String, dynamic> extractFields(APIResponse response) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.data.containsKey("actions")) {
|
var data = response.asMap();
|
||||||
|
|
||||||
|
if (!data.containsKey("actions")) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
var actions = response.data["actions"];
|
var actions = response.data["actions"] as Map<String, dynamic>;
|
||||||
|
|
||||||
return actions["POST"] ?? actions["PUT"] ?? actions["PATCH"] ?? {};
|
dynamic result = actions["POST"] ?? actions["PUT"] ?? actions["PATCH"] ?? {};
|
||||||
|
|
||||||
|
return result as Map<String, dynamic>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -599,8 +600,8 @@ Future<void> launchApiForm(BuildContext context, String title, String url, Map<S
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var remoteField = availableFields[fieldName] ?? {};
|
Map<String, dynamic> remoteField = (availableFields[fieldName] ?? {}) as Map<String, dynamic>;
|
||||||
var localField = fields[fieldName] ?? {};
|
Map<String, dynamic> localField = (fields[fieldName] ?? {}) as Map<String, dynamic>;
|
||||||
|
|
||||||
// Override defined field parameters, if provided
|
// Override defined field parameters, if provided
|
||||||
for (String key in localField.keys) {
|
for (String key in localField.keys) {
|
||||||
|
@ -22,6 +22,17 @@ class InvenTreeSettingsManager {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load a boolean setting
|
||||||
|
Future<bool> getBool(String key, bool backup) async {
|
||||||
|
final dynamic value = await getValue(key, backup);
|
||||||
|
|
||||||
|
if (value is bool) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return backup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> setValue(String key, dynamic value) async {
|
Future<void> setValue(String key, dynamic value) async {
|
||||||
|
|
||||||
await store.record(key).put(await _db, value);
|
await store.record(key).put(await _db, value);
|
||||||
|
@ -101,8 +101,10 @@ class BarcodeHandler {
|
|||||||
|
|
||||||
_controller?.resumeCamera();
|
_controller?.resumeCamera();
|
||||||
|
|
||||||
|
Map<String, dynamic> data = response.asMap();
|
||||||
|
|
||||||
// Handle strange response from the server
|
// Handle strange response from the server
|
||||||
if (!response.isValid() || response.data == null || !(response.data is Map)) {
|
if (!response.isValid() || !response.isMap()) {
|
||||||
onBarcodeUnknown(context, {});
|
onBarcodeUnknown(context, {});
|
||||||
|
|
||||||
// We want to know about this one!
|
// We want to know about this one!
|
||||||
@ -118,12 +120,12 @@ class BarcodeHandler {
|
|||||||
"errorDetail": response.errorDetail,
|
"errorDetail": response.errorDetail,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else if (response.data.containsKey('error')) {
|
} else if (data.containsKey('error')) {
|
||||||
onBarcodeUnknown(context, response.data);
|
onBarcodeUnknown(context, data);
|
||||||
} else if (response.data.containsKey('success')) {
|
} else if (data.containsKey('success')) {
|
||||||
onBarcodeMatched(context, response.data);
|
onBarcodeMatched(context, data);
|
||||||
} else {
|
} else {
|
||||||
onBarcodeUnhandled(context, response.data);
|
onBarcodeUnhandled(context, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,15 +296,15 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
|||||||
L10().barcodeMissingHash,
|
L10().barcodeMissingHash,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
String hash = (data['hash'] ?? '') as String;
|
||||||
|
|
||||||
// Send the 'hash' code as the UID for the stock item
|
if (hash.isNotEmpty) {
|
||||||
item.update(
|
item.update(
|
||||||
values: {
|
values: {
|
||||||
"uid": data['hash'],
|
"uid": hash,
|
||||||
}
|
}
|
||||||
).then((result) {
|
).then((result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|
||||||
failureTone();
|
failureTone();
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@ -313,7 +315,6 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
|||||||
icon: FontAwesomeIcons.qrcode
|
icon: FontAwesomeIcons.qrcode
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
successTone();
|
successTone();
|
||||||
|
|
||||||
showSnackIcon(
|
showSnackIcon(
|
||||||
@ -325,6 +326,7 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StockItemScanIntoLocationHandler extends BarcodeHandler {
|
class StockItemScanIntoLocationHandler extends BarcodeHandler {
|
||||||
|
@ -27,21 +27,21 @@ class InvenTreeCompany extends InvenTreeModel {
|
|||||||
|
|
||||||
InvenTreeCompany() : super();
|
InvenTreeCompany() : super();
|
||||||
|
|
||||||
String get image => jsondata['image'] ?? jsondata['thumbnail'] ?? InvenTreeAPI.staticImage;
|
String get image => (jsondata['image'] ?? jsondata['thumbnail'] ?? InvenTreeAPI.staticImage) as String;
|
||||||
|
|
||||||
String get thumbnail => jsondata['thumbnail'] ?? jsondata['image'] ?? InvenTreeAPI.staticThumb;
|
String get thumbnail => (jsondata['thumbnail'] ?? jsondata['image'] ?? InvenTreeAPI.staticThumb) as String;
|
||||||
|
|
||||||
String get website => jsondata['website'] ?? '';
|
String get website => (jsondata['website'] ?? '') as String;
|
||||||
|
|
||||||
String get phone => jsondata['phone'] ?? '';
|
String get phone => (jsondata['phone'] ?? '') as String;
|
||||||
|
|
||||||
String get email => jsondata['email'] ?? '';
|
String get email => (jsondata['email'] ?? '') as String;
|
||||||
|
|
||||||
bool get isSupplier => jsondata['is_supplier'] ?? false;
|
bool get isSupplier => (jsondata['is_supplier'] ?? false) as bool;
|
||||||
|
|
||||||
bool get isManufacturer => jsondata['is_manufacturer'] ?? false;
|
bool get isManufacturer => (jsondata['is_manufacturer'] ?? false) as bool;
|
||||||
|
|
||||||
bool get isCustomer => jsondata['is_customer'] ?? false;
|
bool get isCustomer => (jsondata['is_customer'] ?? false) as bool;
|
||||||
|
|
||||||
InvenTreeCompany.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
InvenTreeCompany.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||||
|
|
||||||
@ -85,27 +85,27 @@ class InvenTreeSupplierPart extends InvenTreeModel {
|
|||||||
|
|
||||||
int get manufacturerId => (jsondata['manufacturer'] ?? -1) as int;
|
int get manufacturerId => (jsondata['manufacturer'] ?? -1) as int;
|
||||||
|
|
||||||
String get manufacturerName => jsondata['manufacturer_detail']['name'];
|
String get manufacturerName => (jsondata['manufacturer_detail']['name'] ?? '') as String;
|
||||||
|
|
||||||
String get manufacturerImage => jsondata['manufacturer_detail']['image'] ?? jsondata['manufacturer_detail']['thumbnail'];
|
String get manufacturerImage => (jsondata['manufacturer_detail']['image'] ?? jsondata['manufacturer_detail']['thumbnail'] ?? InvenTreeAPI.staticThumb) as String;
|
||||||
|
|
||||||
int get manufacturerPartId => (jsondata['manufacturer_part'] ?? -1) as int;
|
int get manufacturerPartId => (jsondata['manufacturer_part'] ?? -1) as int;
|
||||||
|
|
||||||
int get supplierId => (jsondata['supplier'] ?? -1) as int;
|
int get supplierId => (jsondata['supplier'] ?? -1) as int;
|
||||||
|
|
||||||
String get supplierName => jsondata['supplier_detail']['name'];
|
String get supplierName => (jsondata['supplier_detail']['name'] ?? '') as String;
|
||||||
|
|
||||||
String get supplierImage => jsondata['supplier_detail']['image'] ?? jsondata['supplier_detail']['thumbnail'];
|
String get supplierImage => (jsondata['supplier_detail']['image'] ?? jsondata['supplier_detail']['thumbnail'] ?? InvenTreeAPI.staticThumb) as String;
|
||||||
|
|
||||||
String get SKU => (jsondata['SKU'] ?? '') as String;
|
String get SKU => (jsondata['SKU'] ?? '') as String;
|
||||||
|
|
||||||
String get MPN => jsondata['MPN'] ?? '';
|
String get MPN => (jsondata['MPN'] ?? '') as String;
|
||||||
|
|
||||||
int get partId => jsondata['part'] ?? -1;
|
int get partId => (jsondata['part'] ?? -1) as int;
|
||||||
|
|
||||||
String get partImage => jsondata["part_detail"]["thumbnail"] ?? InvenTreeAPI.staticThumb;
|
String get partImage => (jsondata["part_detail"]["thumbnail"] ?? InvenTreeAPI.staticThumb) as String;
|
||||||
|
|
||||||
String get partName => jsondata["part_detail"]["full_name"] ?? "";
|
String get partName => (jsondata["part_detail"]["full_name"] ?? '') as String;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||||
|
@ -132,16 +132,16 @@ class InvenTreeModel {
|
|||||||
int get pk => (jsondata['pk'] ?? -1) as int;
|
int get pk => (jsondata['pk'] ?? -1) as int;
|
||||||
|
|
||||||
// Some common accessors
|
// Some common accessors
|
||||||
String get name => jsondata['name'] ?? '';
|
String get name => (jsondata['name'] ?? '') as String;
|
||||||
|
|
||||||
String get description => jsondata['description'] ?? '';
|
String get description => (jsondata['description'] ?? '') as String;
|
||||||
|
|
||||||
String get notes => jsondata['notes'] ?? '';
|
String get notes => (jsondata['notes'] ?? '') as String;
|
||||||
|
|
||||||
int get parentId => (jsondata['parent'] ?? -1) as int;
|
int get parentId => (jsondata['parent'] ?? -1) as int;
|
||||||
|
|
||||||
// Legacy API provided external link as "URL", while newer API uses "link"
|
// Legacy API provided external link as "URL", while newer API uses "link"
|
||||||
String get link => jsondata['link'] ?? jsondata['URL'] ?? '';
|
String get link => (jsondata['link'] ?? jsondata['URL'] ?? '') as String;
|
||||||
|
|
||||||
void goToInvenTreePage() async {
|
void goToInvenTreePage() async {
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ class InvenTreeModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get keywords => jsondata['keywords'] ?? '';
|
String get keywords => (jsondata['keywords'] ?? '') as String;
|
||||||
|
|
||||||
// Create a new object from JSON data (not a constructor!)
|
// Create a new object from JSON data (not a constructor!)
|
||||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||||
@ -224,7 +224,7 @@ class InvenTreeModel {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsondata = response.data;
|
jsondata = response.asMap();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -297,13 +297,11 @@ class InvenTreeModel {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return createFromJson(response.data);
|
return createFromJson(response.asMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<InvenTreeModel?> create(Map<String, dynamic> data) async {
|
Future<InvenTreeModel?> create(Map<String, dynamic> data) async {
|
||||||
|
|
||||||
print("CREATE: ${URL} ${data.toString()}");
|
|
||||||
|
|
||||||
if (data.containsKey('pk')) {
|
if (data.containsKey('pk')) {
|
||||||
data.remove('pk');
|
data.remove('pk');
|
||||||
}
|
}
|
||||||
@ -340,7 +338,7 @@ class InvenTreeModel {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return createFromJson(response.data);
|
return createFromJson(response.asMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<InvenTreePageResponse?> listPaginated(int limit, int offset, {Map<String, String> filters = const {}}) async {
|
Future<InvenTreePageResponse?> listPaginated(int limit, int offset, {Map<String, String> filters = const {}}) async {
|
||||||
@ -362,13 +360,15 @@ class InvenTreeModel {
|
|||||||
// Construct the response
|
// Construct the response
|
||||||
InvenTreePageResponse page = new InvenTreePageResponse();
|
InvenTreePageResponse page = new InvenTreePageResponse();
|
||||||
|
|
||||||
if (response.data.containsKey("count") && response.data.containsKey("results")) {
|
var data = response.asMap();
|
||||||
page.count = response.data["count"] as int;
|
|
||||||
|
if (data.containsKey("count") && data.containsKey("results")) {
|
||||||
|
page.count = (data["count"] ?? 0) as int;
|
||||||
|
|
||||||
page.results = [];
|
page.results = [];
|
||||||
|
|
||||||
for (var result in response.data["results"]) {
|
for (var result in response.data["results"]) {
|
||||||
page.addResult(createFromJson(result));
|
page.addResult(createFromJson(result as Map<String, dynamic>));
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
@ -396,20 +396,22 @@ class InvenTreeModel {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic data;
|
List<dynamic> data = [];
|
||||||
|
|
||||||
if (response.data is List) {
|
if (response.isList()) {
|
||||||
data = response.data;
|
data = response.asList();
|
||||||
} else if (response.data.containsKey('results')) {
|
} else if (response.isMap()) {
|
||||||
data = response.data['results'];
|
var mData = response.asMap();
|
||||||
} else {
|
|
||||||
data = [];
|
if (mData.containsKey('results')) {
|
||||||
|
data = (response.data['results'] ?? []) as List<dynamic>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var d in data) {
|
for (var d in data) {
|
||||||
|
|
||||||
// Create a new object (of the current class type
|
// Create a new object (of the current class type
|
||||||
InvenTreeModel obj = createFromJson(d);
|
InvenTreeModel obj = createFromJson(d as Map<String, dynamic>);
|
||||||
|
|
||||||
results.add(obj);
|
results.add(obj);
|
||||||
}
|
}
|
||||||
@ -460,7 +462,7 @@ class InvenTreeAttachment extends InvenTreeModel {
|
|||||||
|
|
||||||
InvenTreeAttachment() : super();
|
InvenTreeAttachment() : super();
|
||||||
|
|
||||||
String get attachment => jsondata["attachment"] ?? '';
|
String get attachment => (jsondata["attachment"] ?? '') as String;
|
||||||
|
|
||||||
// Return the filename of the attachment
|
// Return the filename of the attachment
|
||||||
String get filename {
|
String get filename {
|
||||||
@ -498,11 +500,11 @@ class InvenTreeAttachment extends InvenTreeModel {
|
|||||||
return FontAwesomeIcons.fileAlt;
|
return FontAwesomeIcons.fileAlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get comment => jsondata["comment"] ?? '';
|
String get comment => (jsondata["comment"] ?? '') as String;
|
||||||
|
|
||||||
DateTime? get uploadDate {
|
DateTime? get uploadDate {
|
||||||
if (jsondata.containsKey("upload_date")) {
|
if (jsondata.containsKey("upload_date")) {
|
||||||
return DateTime.tryParse(jsondata["upload_date"] ?? '');
|
return DateTime.tryParse((jsondata["upload_date"] ?? '') as String);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class InvenTreePartCategory extends InvenTreeModel {
|
|||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get pathstring => jsondata['pathstring'] ?? '';
|
String get pathstring => (jsondata['pathstring'] ?? '') as String;
|
||||||
|
|
||||||
String get parentpathstring {
|
String get parentpathstring {
|
||||||
// TODO - Drive the refactor tractor through this
|
// TODO - Drive the refactor tractor through this
|
||||||
@ -52,7 +52,7 @@ class InvenTreePartCategory extends InvenTreeModel {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get partcount => jsondata['parts'] ?? 0;
|
int get partcount => (jsondata['parts'] ?? 0) as int;
|
||||||
|
|
||||||
InvenTreePartCategory() : super();
|
InvenTreePartCategory() : super();
|
||||||
|
|
||||||
@ -74,17 +74,17 @@ class InvenTreePartTestTemplate extends InvenTreeModel {
|
|||||||
@override
|
@override
|
||||||
String get URL => "part/test-template/";
|
String get URL => "part/test-template/";
|
||||||
|
|
||||||
String get key => jsondata['key'] ?? '';
|
String get key => (jsondata['key'] ?? '') as String;
|
||||||
|
|
||||||
String get testName => jsondata['test_name'] ?? '';
|
String get testName => (jsondata['test_name'] ?? '') as String;
|
||||||
|
|
||||||
String get description => jsondata['description'] ?? '';
|
String get description => (jsondata['description'] ?? '') as String;
|
||||||
|
|
||||||
bool get required => jsondata['required'] ?? false;
|
bool get required => (jsondata['required'] ?? false) as bool;
|
||||||
|
|
||||||
bool get requiresValue => jsondata['requires_value'] ?? false;
|
bool get requiresValue => (jsondata['requires_value'] ?? false) as bool;
|
||||||
|
|
||||||
bool get requiresAttachment => jsondata['requires_attachment'] ?? false;
|
bool get requiresAttachment => (jsondata['requires_attachment'] ?? false) as bool;
|
||||||
|
|
||||||
InvenTreePartTestTemplate() : super();
|
InvenTreePartTestTemplate() : super();
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ class InvenTreePart extends InvenTreeModel {
|
|||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get units => jsondata["units"] ?? "";
|
String get units => (jsondata["units"] as String) ?? "";
|
||||||
|
|
||||||
// Get the number of units being build for this Part
|
// 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'].toString()) ?? 0;
|
||||||
@ -297,10 +297,10 @@ class InvenTreePart extends InvenTreeModel {
|
|||||||
bool get isTrackable => (jsondata['trackable'] ?? false) as bool;
|
bool get isTrackable => (jsondata['trackable'] ?? false) as bool;
|
||||||
|
|
||||||
// Get the IPN (internal part number) for the Part instance
|
// Get the IPN (internal part number) for the Part instance
|
||||||
String get IPN => jsondata['IPN'] ?? '';
|
String get IPN => (jsondata['IPN'] ?? '') as String;
|
||||||
|
|
||||||
// Get the revision string for the Part instance
|
// Get the revision string for the Part instance
|
||||||
String get revision => jsondata['revision'] ?? '';
|
String get revision => (jsondata['revision'] ?? '') as String;
|
||||||
|
|
||||||
// Get the category ID for the Part instance (or 'null' if does not exist)
|
// Get the category ID for the Part instance (or 'null' if does not exist)
|
||||||
int get categoryId => (jsondata['category'] ?? -1) as int;
|
int get categoryId => (jsondata['category'] ?? -1) as int;
|
||||||
@ -312,7 +312,7 @@ class InvenTreePart extends InvenTreeModel {
|
|||||||
|
|
||||||
if (!jsondata.containsKey('category_detail')) return '';
|
if (!jsondata.containsKey('category_detail')) return '';
|
||||||
|
|
||||||
return jsondata['category_detail']?['name'] ?? '';
|
return (jsondata['category_detail']?['name'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the category description for the Part instance
|
// Get the category description for the Part instance
|
||||||
@ -322,18 +322,18 @@ class InvenTreePart extends InvenTreeModel {
|
|||||||
|
|
||||||
if (!jsondata.containsKey('category_detail')) return '';
|
if (!jsondata.containsKey('category_detail')) return '';
|
||||||
|
|
||||||
return jsondata['category_detail']?['description'] ?? '';
|
return (jsondata['category_detail']?['description'] ?? '') as String;
|
||||||
}
|
}
|
||||||
// Get the image URL for the Part instance
|
// Get the image URL for the Part instance
|
||||||
String get _image => jsondata['image'] ?? '';
|
String get _image => (jsondata['image'] ?? '') as String;
|
||||||
|
|
||||||
// Get the thumbnail URL for the Part instance
|
// Get the thumbnail URL for the Part instance
|
||||||
String get _thumbnail => jsondata['thumbnail'] ?? '';
|
String get _thumbnail => (jsondata['thumbnail'] ?? '') as String;
|
||||||
|
|
||||||
// Return the fully-qualified name for the Part instance
|
// Return the fully-qualified name for the Part instance
|
||||||
String get fullname {
|
String get fullname {
|
||||||
|
|
||||||
String fn = jsondata['full_name'] ?? '';
|
String fn = (jsondata['full_name'] ?? '') as String;
|
||||||
|
|
||||||
if (fn.isNotEmpty) return fn;
|
if (fn.isNotEmpty) return fn;
|
||||||
|
|
||||||
|
@ -44,23 +44,23 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
String get issueDate => jsondata['issue_date'] ?? "";
|
String get issueDate => (jsondata['issue_date'] ?? '') as String;
|
||||||
|
|
||||||
String get completeDate => jsondata['complete_date'] ?? "";
|
String get completeDate => (jsondata['complete_date'] ?? '') as String;
|
||||||
|
|
||||||
String get creationDate => jsondata['creation_date'] ?? "";
|
String get creationDate => (jsondata['creation_date'] ?? '') as String;
|
||||||
|
|
||||||
String get targetDate => jsondata['target_date'] ?? "";
|
String get targetDate => (jsondata['target_date'] ?? '') as String;
|
||||||
|
|
||||||
int get lineItemCount => jsondata['line_items'] ?? 0;
|
int get lineItemCount => (jsondata['line_items'] ?? 0) as int;
|
||||||
|
|
||||||
bool get overdue => jsondata['overdue'] ?? false;
|
bool get overdue => (jsondata['overdue'] ?? false) as bool;
|
||||||
|
|
||||||
String get reference => jsondata['reference'] ?? "";
|
String get reference => (jsondata['reference'] ?? '') as String;
|
||||||
|
|
||||||
int get responsible => jsondata['responsible'] ?? -1;
|
int get responsibleId => (jsondata['responsible'] ?? -1) as int;
|
||||||
|
|
||||||
int get supplierId => jsondata['supplier'] ?? -1;
|
int get supplierId => (jsondata['supplier'] ?? -1) as int;
|
||||||
|
|
||||||
InvenTreeCompany? get supplier {
|
InvenTreeCompany? get supplier {
|
||||||
|
|
||||||
@ -69,15 +69,15 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
|||||||
if (supplier_detail == null) {
|
if (supplier_detail == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return InvenTreeCompany.fromJson(supplier_detail);
|
return InvenTreeCompany.fromJson(supplier_detail as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get supplierReference => jsondata['supplier_reference'] ?? "";
|
String get supplierReference => (jsondata['supplier_reference'] ?? '') as String;
|
||||||
|
|
||||||
int get status => jsondata['status'] ?? -1;
|
int get status => (jsondata['status'] ?? -1) as int;
|
||||||
|
|
||||||
String get statusText => jsondata['status_text'] ?? "";
|
String get statusText => (jsondata['status_text'] ?? '') as String;
|
||||||
|
|
||||||
bool get isOpen => this.status == PO_STATUS_PENDING || this.status == PO_STATUS_PLACED;
|
bool get isOpen => this.status == PO_STATUS_PENDING || this.status == PO_STATUS_PLACED;
|
||||||
|
|
||||||
@ -146,25 +146,25 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
|||||||
|
|
||||||
bool get isComplete => received >= quantity;
|
bool get isComplete => received >= quantity;
|
||||||
|
|
||||||
double get quantity => jsondata['quantity'] ?? 0;
|
double get quantity => (jsondata['quantity'] ?? 0) as double;
|
||||||
|
|
||||||
double get received => jsondata['received'] ?? 0;
|
double get received => (jsondata['received'] ?? 0) as double;
|
||||||
|
|
||||||
double get outstanding => quantity - received;
|
double get outstanding => quantity - received;
|
||||||
|
|
||||||
String get reference => jsondata['reference'] ?? "";
|
String get reference => (jsondata['reference'] ?? '') as String;
|
||||||
|
|
||||||
int get orderId => jsondata['order'] ?? -1;
|
int get orderId => (jsondata['order'] ?? -1) as int;
|
||||||
|
|
||||||
int get supplirtPartId => jsondata['part'] ?? -1;
|
int get supplierPartId => (jsondata['part'] ?? -1) as int;
|
||||||
|
|
||||||
InvenTreePart? get part {
|
InvenTreePart? get part {
|
||||||
dynamic part_detail = jsondata["part_detail"] ?? null;
|
dynamic part_detail = jsondata["part_detail"];
|
||||||
|
|
||||||
if (part_detail == null) {
|
if (part_detail == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return InvenTreePart.fromJson(part_detail);
|
return InvenTreePart.fromJson(part_detail as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,19 +175,19 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
|||||||
if (detail == null) {
|
if (detail == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return InvenTreeSupplierPart.fromJson(detail);
|
return InvenTreeSupplierPart.fromJson(detail as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double get purchasePrice => double.parse(jsondata['purchase_price']);
|
double get purchasePrice => double.parse((jsondata['purchase_price'] ?? '') as String);
|
||||||
|
|
||||||
String get purchasePriceCurrency => jsondata['purchase_price_currency'] ?? "";
|
String get purchasePriceCurrency => (jsondata['purchase_price_currency'] ?? '') as String;
|
||||||
|
|
||||||
String get purchasePriceString => jsondata['purchase_price_string'] ?? "";
|
String get purchasePriceString => (jsondata['purchase_price_string'] ?? '') as String;
|
||||||
|
|
||||||
int get destination => jsondata['destination'] ?? -1;
|
int get destination => (jsondata['destination'] ?? -1) as int;
|
||||||
|
|
||||||
Map<String, dynamic> get destinationDetail => jsondata['destination_detail'];
|
Map<String, dynamic> get destinationDetail => (jsondata['destination_detail'] ?? {}) as Map<String, dynamic>;
|
||||||
|
|
||||||
InvenTreePOLineItem() : super();
|
InvenTreePOLineItem() : super();
|
||||||
|
|
||||||
|
@ -31,19 +31,19 @@ class InvenTreeStockItemTestResult extends InvenTreeModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
String get key => jsondata['key'] ?? '';
|
String get key => (jsondata['key'] ?? '') as String;
|
||||||
|
|
||||||
String get testName => jsondata['test'] ?? '';
|
String get testName => (jsondata['test'] ?? '') as String;
|
||||||
|
|
||||||
bool get result => jsondata['result'] ?? false;
|
bool get result => (jsondata['result'] ?? false) as bool;
|
||||||
|
|
||||||
String get value => jsondata['value'] ?? '';
|
String get value => (jsondata['value'] ?? '') as String;
|
||||||
|
|
||||||
String get notes => jsondata['notes'] ?? '';
|
String get notes => (jsondata['notes'] ?? '') as String;
|
||||||
|
|
||||||
String get attachment => jsondata['attachment'] ?? '';
|
String get attachment => (jsondata['attachment'] ?? '') as String;
|
||||||
|
|
||||||
String get date => jsondata['date'] ?? '';
|
String get date => (jsondata['date'] ?? '') as String;
|
||||||
|
|
||||||
InvenTreeStockItemTestResult() : super();
|
InvenTreeStockItemTestResult() : super();
|
||||||
|
|
||||||
@ -204,17 +204,17 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
String get uid => jsondata['uid'] ?? '';
|
String get uid => (jsondata['uid'] ?? '') as String;
|
||||||
|
|
||||||
int get status => jsondata['status'] ?? -1;
|
int get status => (jsondata['status'] ?? -1) as int;
|
||||||
|
|
||||||
String get packaging => jsondata["packaging"] ?? "";
|
String get packaging => (jsondata["packaging"] ?? '') as String;
|
||||||
|
|
||||||
String get batch => jsondata["batch"] ?? "";
|
String get batch => (jsondata["batch"] ?? '') as String;
|
||||||
|
|
||||||
int get partId => jsondata['part'] ?? -1;
|
int get partId => (jsondata['part'] ?? -1) as int;
|
||||||
|
|
||||||
String get purchasePrice => jsondata['purchase_price'] ?? "";
|
String get purchasePrice => (jsondata['purchase_price'] ?? '') as String;
|
||||||
|
|
||||||
bool get hasPurchasePrice {
|
bool get hasPurchasePrice {
|
||||||
|
|
||||||
@ -223,14 +223,14 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
return pp.isNotEmpty && pp.trim() != "-";
|
return pp.isNotEmpty && pp.trim() != "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
int get purchaseOrderId => jsondata['purchase_order'] ?? -1;
|
int get purchaseOrderId => (jsondata['purchase_order'] ?? -1) as int;
|
||||||
|
|
||||||
int get trackingItemCount => (jsondata['tracking_items'] ?? 0) as int;
|
int get trackingItemCount => (jsondata['tracking_items'] ?? 0) as int;
|
||||||
|
|
||||||
// Date of last update
|
// Date of last update
|
||||||
DateTime? get updatedDate {
|
DateTime? get updatedDate {
|
||||||
if (jsondata.containsKey("updated")) {
|
if (jsondata.containsKey("updated")) {
|
||||||
return DateTime.tryParse(jsondata["updated"] ?? '');
|
return DateTime.tryParse((jsondata["updated"] ?? '') as String);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
|
|
||||||
DateTime? get stocktakeDate {
|
DateTime? get stocktakeDate {
|
||||||
if (jsondata.containsKey("stocktake_date")) {
|
if (jsondata.containsKey("stocktake_date")) {
|
||||||
return DateTime.tryParse(jsondata["stocktake_date"] ?? '');
|
return DateTime.tryParse((jsondata["stocktake_date"] ?? '') as String);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -274,12 +274,12 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
|
|
||||||
// Use the detailed part information as priority
|
// Use the detailed part information as priority
|
||||||
if (jsondata.containsKey('part_detail')) {
|
if (jsondata.containsKey('part_detail')) {
|
||||||
nm = jsondata['part_detail']['full_name'] ?? '';
|
nm = (jsondata['part_detail']['full_name'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup if first value fails
|
// Backup if first value fails
|
||||||
if (nm.isEmpty) {
|
if (nm.isEmpty) {
|
||||||
nm = jsondata['part__name'] ?? '';
|
nm = (jsondata['part__name'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nm;
|
return nm;
|
||||||
@ -290,11 +290,11 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
|
|
||||||
// Use the detailed part description as priority
|
// Use the detailed part description as priority
|
||||||
if (jsondata.containsKey('part_detail')) {
|
if (jsondata.containsKey('part_detail')) {
|
||||||
desc = jsondata['part_detail']['description'] ?? '';
|
desc = (jsondata['part_detail']['description'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.isEmpty) {
|
if (desc.isEmpty) {
|
||||||
desc = jsondata['part__description'] ?? '';
|
desc = (jsondata['part__description'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
@ -304,11 +304,11 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
String img = '';
|
String img = '';
|
||||||
|
|
||||||
if (jsondata.containsKey('part_detail')) {
|
if (jsondata.containsKey('part_detail')) {
|
||||||
img = jsondata['part_detail']['thumbnail'] ?? '';
|
img = (jsondata['part_detail']['thumbnail'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img.isEmpty) {
|
if (img.isEmpty) {
|
||||||
img = jsondata['part__thumbnail'] ?? '';
|
img = (jsondata['part__thumbnail'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
@ -321,16 +321,16 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
|
|
||||||
String thumb = "";
|
String thumb = "";
|
||||||
|
|
||||||
thumb = jsondata['part_detail']?['thumbnail'] ?? '';
|
thumb = (jsondata['part_detail']?['thumbnail'] ?? '') as String;
|
||||||
|
|
||||||
// Use 'image' as a backup
|
// Use 'image' as a backup
|
||||||
if (thumb.isEmpty) {
|
if (thumb.isEmpty) {
|
||||||
thumb = jsondata['part_detail']?['image'] ?? '';
|
thumb = (jsondata['part_detail']?['image'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try a different approach
|
// Try a different approach
|
||||||
if (thumb.isEmpty) {
|
if (thumb.isEmpty) {
|
||||||
thumb = jsondata['part__thumbnail'] ?? '';
|
thumb = (jsondata['part__thumbnail'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still no thumbnail? Use the 'no image' image
|
// Still no thumbnail? Use the 'no image' image
|
||||||
@ -345,7 +345,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
String thumb = '';
|
String thumb = '';
|
||||||
|
|
||||||
if (jsondata.containsKey("supplier_detail")) {
|
if (jsondata.containsKey("supplier_detail")) {
|
||||||
thumb = jsondata['supplier_detail']['supplier_logo'] ?? '';
|
thumb = (jsondata['supplier_detail']['supplier_logo'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return thumb;
|
return thumb;
|
||||||
@ -355,27 +355,27 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
String sname = '';
|
String sname = '';
|
||||||
|
|
||||||
if (jsondata.containsKey("supplier_detail")) {
|
if (jsondata.containsKey("supplier_detail")) {
|
||||||
sname = jsondata["supplier_detail"]["supplier_name"] ?? '';
|
sname = (jsondata["supplier_detail"]["supplier_name"] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sname;
|
return sname;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get units {
|
String get units {
|
||||||
return jsondata['part_detail']?['units'] ?? '';
|
return (jsondata['part_detail']?['units'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get supplierSKU {
|
String get supplierSKU {
|
||||||
String sku = '';
|
String sku = '';
|
||||||
|
|
||||||
if (jsondata.containsKey("supplier_detail")) {
|
if (jsondata.containsKey("supplier_detail")) {
|
||||||
sku = jsondata["supplier_detail"]["SKU"] ?? '';
|
sku = (jsondata["supplier_detail"]["SKU"] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sku;
|
return sku;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get serialNumber => jsondata['serial'] ?? "";
|
String get serialNumber => (jsondata['serial'] ?? '') as String;
|
||||||
|
|
||||||
double get quantity => double.tryParse(jsondata['quantity'].toString()) ?? 0;
|
double get quantity => double.tryParse(jsondata['quantity'].toString()) ?? 0;
|
||||||
|
|
||||||
@ -417,11 +417,11 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
|
|
||||||
if (locationId == -1 || !jsondata.containsKey('location_detail')) return 'Unknown Location';
|
if (locationId == -1 || !jsondata.containsKey('location_detail')) return 'Unknown Location';
|
||||||
|
|
||||||
loc = jsondata['location_detail']['name'] ?? '';
|
loc = (jsondata['location_detail']['name'] ?? '') as String;
|
||||||
|
|
||||||
// Old-style name
|
// Old-style name
|
||||||
if (loc.isEmpty) {
|
if (loc.isEmpty) {
|
||||||
loc = jsondata['location__name'] ?? '';
|
loc = (jsondata['location__name'] ?? '') as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
return loc;
|
return loc;
|
||||||
@ -431,7 +431,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
|
|
||||||
if (locationId == -1 || !jsondata.containsKey('location_detail')) return L10().locationNotSet;
|
if (locationId == -1 || !jsondata.containsKey('location_detail')) return L10().locationNotSet;
|
||||||
|
|
||||||
String _loc = jsondata['location_detail']['pathstring'] ?? '';
|
String _loc = (jsondata['location_detail']['pathstring'] ?? '') as String;
|
||||||
|
|
||||||
if (_loc.isNotEmpty) {
|
if (_loc.isNotEmpty) {
|
||||||
return _loc;
|
return _loc;
|
||||||
@ -540,7 +540,7 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
|||||||
@override
|
@override
|
||||||
String get URL => "stock/location/";
|
String get URL => "stock/location/";
|
||||||
|
|
||||||
String get pathstring => jsondata['pathstring'] ?? '';
|
String get pathstring => (jsondata['pathstring'] ?? '') as String;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> formFields() {
|
Map<String, dynamic> formFields() {
|
||||||
@ -568,7 +568,7 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get itemcount => jsondata['items'] ?? 0;
|
int get itemcount => (jsondata['items'] ?? 0) as int;
|
||||||
|
|
||||||
InvenTreeStockLocation() : super();
|
InvenTreeStockLocation() : super();
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class InvenTreePreferencesDB {
|
|||||||
return _dbOpenCompleter.future;
|
return _dbOpenCompleter.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _openDatabase() async {
|
Future<void> _openDatabase() async {
|
||||||
// Get a platform-specific directory where persistent app data can be stored
|
// Get a platform-specific directory where persistent app data can be stored
|
||||||
final appDocumentDir = await getApplicationDocumentsDirectory();
|
final appDocumentDir = await getApplicationDocumentsDirectory();
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
|||||||
void setBarcodeSounds(bool en) async {
|
void setBarcodeSounds(bool en) async {
|
||||||
|
|
||||||
await InvenTreeSettingsManager().setValue("barcodeSounds", en);
|
await InvenTreeSettingsManager().setValue("barcodeSounds", en);
|
||||||
barcodeSounds = await InvenTreeSettingsManager().getValue("barcodeSounds", true);
|
barcodeSounds = await InvenTreeSettingsManager().getBool("barcodeSounds", true);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
});
|
});
|
||||||
@ -54,7 +54,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
|||||||
void setServerSounds(bool en) async {
|
void setServerSounds(bool en) async {
|
||||||
|
|
||||||
await InvenTreeSettingsManager().setValue("serverSounds", en);
|
await InvenTreeSettingsManager().setValue("serverSounds", en);
|
||||||
serverSounds = await InvenTreeSettingsManager().getValue("serverSounds", true);
|
serverSounds = await InvenTreeSettingsManager().getBool("serverSounds", true);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
});
|
});
|
||||||
@ -62,7 +62,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
|||||||
|
|
||||||
void setPartSubcategory(bool en) async {
|
void setPartSubcategory(bool en) async {
|
||||||
await InvenTreeSettingsManager().setValue("partSubcategory", en);
|
await InvenTreeSettingsManager().setValue("partSubcategory", en);
|
||||||
partSubcategory = await InvenTreeSettingsManager().getValue("partSubcategory", true);
|
partSubcategory = await InvenTreeSettingsManager().getBool("partSubcategory", true);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
});
|
});
|
||||||
@ -70,7 +70,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
|||||||
|
|
||||||
void setStockSublocation(bool en) async {
|
void setStockSublocation(bool en) async {
|
||||||
await InvenTreeSettingsManager().setValue("stockSublocation", en);
|
await InvenTreeSettingsManager().setValue("stockSublocation", en);
|
||||||
stockSublocation = await InvenTreeSettingsManager().getValue("stockSublocation", true);
|
stockSublocation = await InvenTreeSettingsManager().getBool("stockSublocation", true);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
});
|
});
|
||||||
|
@ -40,17 +40,6 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
|||||||
|
|
||||||
void _editProfile(BuildContext context, {UserProfile? userProfile, bool createNew = false}) {
|
void _editProfile(BuildContext context, {UserProfile? userProfile, bool createNew = false}) {
|
||||||
|
|
||||||
var _name;
|
|
||||||
var _server;
|
|
||||||
var _username;
|
|
||||||
var _password;
|
|
||||||
|
|
||||||
UserProfile? profile;
|
|
||||||
|
|
||||||
if (userProfile != null) {
|
|
||||||
profile = userProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
|
@ -38,10 +38,10 @@ class UserProfile {
|
|||||||
|
|
||||||
factory UserProfile.fromJson(int key, Map<String, dynamic> json, bool isSelected) => UserProfile(
|
factory UserProfile.fromJson(int key, Map<String, dynamic> json, bool isSelected) => UserProfile(
|
||||||
key: key,
|
key: key,
|
||||||
name: json['name'],
|
name: json['name'] as String,
|
||||||
server: json['server'],
|
server: json['server'] as String,
|
||||||
username: json['username'],
|
username: json['username'] as String,
|
||||||
password: json['password'],
|
password: json['password'] as String,
|
||||||
selected: isSelected,
|
selected: isSelected,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ class UserProfileDBManager {
|
|||||||
return profiles.length > 0;
|
return profiles.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future addProfile(UserProfile profile) async {
|
Future<void> addProfile(UserProfile profile) async {
|
||||||
|
|
||||||
// Check if a profile already exists with the name
|
// Check if a profile already exists with the name
|
||||||
final bool exists = await profileNameExists(profile.name);
|
final bool exists = await profileNameExists(profile.name);
|
||||||
@ -83,7 +83,7 @@ class UserProfileDBManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int key = await store.add(await _db, profile.toJson());
|
int key = await store.add(await _db, profile.toJson()) as int;
|
||||||
|
|
||||||
print("Added user profile <${key}> - '${profile.name}'");
|
print("Added user profile <${key}> - '${profile.name}'");
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class UserProfileDBManager {
|
|||||||
profile.key = key;
|
profile.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future selectProfile(int key) async {
|
Future<void> selectProfile(int key) async {
|
||||||
/*
|
/*
|
||||||
* Mark the particular profile as selected
|
* Mark the particular profile as selected
|
||||||
*/
|
*/
|
||||||
@ -101,7 +101,7 @@ class UserProfileDBManager {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future updateProfile(UserProfile profile) async {
|
Future<void> updateProfile(UserProfile profile) async {
|
||||||
|
|
||||||
if (profile.key == null) {
|
if (profile.key == null) {
|
||||||
await addProfile(profile);
|
await addProfile(profile);
|
||||||
@ -115,7 +115,7 @@ class UserProfileDBManager {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future deleteProfile(UserProfile profile) async {
|
Future<void> deleteProfile(UserProfile profile) async {
|
||||||
await store.record(profile.key).delete(await _db);
|
await store.record(profile.key).delete(await _db);
|
||||||
print("Deleted user profile <${profile.key}> - '${profile.name}'");
|
print("Deleted user profile <${profile.key}> - '${profile.name}'");
|
||||||
}
|
}
|
||||||
@ -135,8 +135,8 @@ class UserProfileDBManager {
|
|||||||
|
|
||||||
if (profiles[idx].key is int && profiles[idx].key == selected) {
|
if (profiles[idx].key is int && profiles[idx].key == selected) {
|
||||||
return UserProfile.fromJson(
|
return UserProfile.fromJson(
|
||||||
profiles[idx].key,
|
profiles[idx].key as int,
|
||||||
profiles[idx].value,
|
profiles[idx].value as Map<String, dynamic>,
|
||||||
profiles[idx].key == selected,
|
profiles[idx].key == selected,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -161,8 +161,8 @@ class UserProfileDBManager {
|
|||||||
if (profiles[idx].key is int) {
|
if (profiles[idx].key is int) {
|
||||||
profileList.add(
|
profileList.add(
|
||||||
UserProfile.fromJson(
|
UserProfile.fromJson(
|
||||||
profiles[idx].key,
|
profiles[idx].key as int,
|
||||||
profiles[idx].value,
|
profiles[idx].value as Map<String, dynamic>,
|
||||||
profiles[idx].key == selected,
|
profiles[idx].key == selected,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,9 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
|||||||
data: {
|
data: {
|
||||||
"parent": (pk > 0) ? pk : null,
|
"parent": (pk > 0) ? pk : null,
|
||||||
},
|
},
|
||||||
onSuccess: (data) async {
|
onSuccess: (result) async {
|
||||||
|
|
||||||
|
Map<String, dynamic> data = result as Map<String, dynamic>;
|
||||||
|
|
||||||
if (data.containsKey("pk")) {
|
if (data.containsKey("pk")) {
|
||||||
var cat = InvenTreePartCategory.fromJson(data);
|
var cat = InvenTreePartCategory.fromJson(data);
|
||||||
@ -252,7 +254,9 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
|||||||
data: {
|
data: {
|
||||||
"category": (pk > 0) ? pk : null
|
"category": (pk > 0) ? pk : null
|
||||||
},
|
},
|
||||||
onSuccess: (data) async {
|
onSuccess: (result) async {
|
||||||
|
|
||||||
|
Map<String, dynamic> data = result as Map<String, dynamic>;
|
||||||
|
|
||||||
if (data.containsKey("pk")) {
|
if (data.containsKey("pk")) {
|
||||||
var part = InvenTreePart.fromJson(data);
|
var part = InvenTreePart.fromJson(data);
|
||||||
@ -440,7 +444,8 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
|||||||
|
|
||||||
params["search"] = _searchTerm;
|
params["search"] = _searchTerm;
|
||||||
|
|
||||||
final bool cascade = await InvenTreeSettingsManager().getValue("partSubcategory", true);
|
final bool cascade = await InvenTreeSettingsManager().getBool("partSubcategory", true);
|
||||||
|
|
||||||
params["cascade"] = "${cascade}";
|
params["cascade"] = "${cascade}";
|
||||||
|
|
||||||
final page = await InvenTreePart().listPaginated(_pageSize, pageKey, filters: params);
|
final page = await InvenTreePart().listPaginated(_pageSize, pageKey, filters: params);
|
||||||
|
@ -146,7 +146,10 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
data: {
|
data: {
|
||||||
"parent": (pk > 0) ? pk : null,
|
"parent": (pk > 0) ? pk : null,
|
||||||
},
|
},
|
||||||
onSuccess: (data) async {
|
onSuccess: (result) async {
|
||||||
|
|
||||||
|
Map<String, dynamic> data = result as Map<String, dynamic>;
|
||||||
|
|
||||||
if (data.containsKey("pk")) {
|
if (data.containsKey("pk")) {
|
||||||
var loc = InvenTreeStockLocation.fromJson(data);
|
var loc = InvenTreeStockLocation.fromJson(data);
|
||||||
|
|
||||||
@ -175,7 +178,10 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
data: {
|
data: {
|
||||||
"location": pk,
|
"location": pk,
|
||||||
},
|
},
|
||||||
onSuccess: (data) async {
|
onSuccess: (result) async {
|
||||||
|
|
||||||
|
Map<String, dynamic> data = result as Map<String, dynamic>;
|
||||||
|
|
||||||
if (data.containsKey("pk")) {
|
if (data.containsKey("pk")) {
|
||||||
var item = InvenTreeStockItem.fromJson(data);
|
var item = InvenTreeStockItem.fromJson(data);
|
||||||
|
|
||||||
@ -515,7 +521,8 @@ class _PaginatedStockListState extends State<PaginatedStockList> {
|
|||||||
params["search"] = "${_searchTerm}";
|
params["search"] = "${_searchTerm}";
|
||||||
|
|
||||||
// Do we include stock items from sub-locations?
|
// Do we include stock items from sub-locations?
|
||||||
final bool cascade = await InvenTreeSettingsManager().getValue("stockSublocation", true);
|
final bool cascade = await InvenTreeSettingsManager().getBool("stockSublocation", true);
|
||||||
|
|
||||||
params["cascade"] = "${cascade}";
|
params["cascade"] = "${cascade}";
|
||||||
|
|
||||||
final page = await InvenTreeStockItem().listPaginated(_pageSize, pageKey, filters: params);
|
final page = await InvenTreeStockItem().listPaginated(_pageSize, pageKey, filters: params);
|
||||||
|
@ -405,7 +405,10 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
data: {
|
data: {
|
||||||
"part": "${part.pk}",
|
"part": "${part.pk}",
|
||||||
},
|
},
|
||||||
onSuccess: (data) async {
|
onSuccess: (result) async {
|
||||||
|
|
||||||
|
Map<String, dynamic> data = result as Map<String, dynamic>;
|
||||||
|
|
||||||
if (data.containsKey("pk")) {
|
if (data.containsKey("pk")) {
|
||||||
var item = InvenTreeStockItem.fromJson(data);
|
var item = InvenTreeStockItem.fromJson(data);
|
||||||
|
|
||||||
|
@ -349,13 +349,13 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
|||||||
hint: L10().searchLocation,
|
hint: L10().searchLocation,
|
||||||
onChanged: null,
|
onChanged: null,
|
||||||
itemAsString: (dynamic location) {
|
itemAsString: (dynamic location) {
|
||||||
return location['pathstring'];
|
return (location['pathstring'] ?? '') as String;
|
||||||
},
|
},
|
||||||
onSaved: (dynamic location) {
|
onSaved: (dynamic location) {
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
location_pk = null;
|
location_pk = null;
|
||||||
} else {
|
} else {
|
||||||
location_pk = location['pk'];
|
location_pk = location['pk'] as int;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isFilteredOnline: true,
|
isFilteredOnline: true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user