mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 21:16:48 +00:00
More linting work
This commit is contained in:
parent
c1152ee286
commit
ad0cc36540
@ -1,7 +1,9 @@
|
||||
include: package:lint/analysis_options.yaml
|
||||
|
||||
analyzer:
|
||||
exclude: [build/**]
|
||||
exclude:
|
||||
- [build/**]
|
||||
- lib/generated/**
|
||||
language:
|
||||
strict-raw-types: true
|
||||
strong-mode:
|
||||
@ -14,10 +16,44 @@ linter:
|
||||
# Turn off what you don't like. #
|
||||
# ------------------------------------- #
|
||||
|
||||
# Make constructors the first thing in every class
|
||||
sort_constructors_first: true
|
||||
# Make constructors the first thing in every class
|
||||
sort_constructors_first: true
|
||||
|
||||
prefer_single_quotes: true
|
||||
prefer_double_quotes: true
|
||||
|
||||
# Blindly follow the Flutter code style, which prefers types everywhere
|
||||
always_specify_types: true
|
||||
prefer_final_locals: false
|
||||
|
||||
prefer_const_constructors: false
|
||||
|
||||
prefer_final_in_for_each: false
|
||||
|
||||
use_build_context_synchronously: false
|
||||
|
||||
avoid_redundant_argument_values: false
|
||||
|
||||
unnecessary_brace_in_string_interps: false
|
||||
|
||||
unnecessary_string_interpolations: false
|
||||
|
||||
no_logic_in_create_state: false
|
||||
|
||||
parameter_assignments: false
|
||||
|
||||
non_constant_identifier_names: false
|
||||
|
||||
constant_identifier_names: false
|
||||
|
||||
package_prefixed_library_names: false
|
||||
|
||||
prefer_const_literals_to_create_immutables: false
|
||||
|
||||
avoid_print: false
|
||||
|
||||
avoid_positional_boolean_parameters: false
|
||||
|
||||
prefer_final_fields: false
|
||||
|
||||
sort_child_properties_last: false
|
||||
|
||||
# Blindly follow the Flutter code style, which prefers types everywhere
|
||||
always_specify_types: false
|
||||
|
147
lib/api.dart
147
lib/api.dart
@ -1,25 +1,25 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import "dart:async";
|
||||
import "dart:convert";
|
||||
import "dart:io";
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:http/http.dart" as http;
|
||||
import "package:intl/intl.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import "package:open_file/open_file.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:cached_network_image/cached_network_image.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:flutter_cache_manager/flutter_cache_manager.dart";
|
||||
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/user_profile.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/user_profile.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:path_provider/path_provider.dart";
|
||||
|
||||
|
||||
/*
|
||||
@ -158,11 +158,12 @@ class InvenTreeAPI {
|
||||
String _makeUrl(String url) {
|
||||
|
||||
// Strip leading slash
|
||||
if (url.startsWith('/')) {
|
||||
if (url.startsWith("/")) {
|
||||
url = url.substring(1, url.length);
|
||||
}
|
||||
|
||||
url = url.replaceAll('//', '/');
|
||||
// Prevent double-slash
|
||||
url = url.replaceAll("//", "/");
|
||||
|
||||
return baseUrl + url;
|
||||
}
|
||||
@ -175,7 +176,7 @@ class InvenTreeAPI {
|
||||
if (endpoint.startsWith("/api/") || endpoint.startsWith("api/")) {
|
||||
return _makeUrl(endpoint);
|
||||
} else {
|
||||
return _makeUrl("/api/" + endpoint);
|
||||
return _makeUrl("/api/${endpoint}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,10 +211,10 @@ class InvenTreeAPI {
|
||||
}
|
||||
|
||||
// Server instance information
|
||||
String instance = '';
|
||||
String instance = "";
|
||||
|
||||
// Server version information
|
||||
String _version = '';
|
||||
String _version = "";
|
||||
|
||||
// API version of the connected server
|
||||
int _apiVersion = 1;
|
||||
@ -272,8 +273,8 @@ class InvenTreeAPI {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!address.endsWith('/')) {
|
||||
address = address + '/';
|
||||
if (!address.endsWith("/")) {
|
||||
address = address + "/";
|
||||
}
|
||||
/* TODO: Better URL validation
|
||||
* - If not a valid URL, return error
|
||||
@ -307,11 +308,11 @@ class InvenTreeAPI {
|
||||
}
|
||||
|
||||
// Record server information
|
||||
_version = (data["version"] ?? '') as String;
|
||||
instance = (data['instance'] ?? '') as String;
|
||||
_version = (data["version"] ?? "") as String;
|
||||
instance = (data["instance"] ?? "") as String;
|
||||
|
||||
// Default API version is 1 if not provided
|
||||
_apiVersion = (data['apiVersion'] ?? 1) as int;
|
||||
_apiVersion = (data["apiVersion"] ?? 1) as int;
|
||||
|
||||
if (_apiVersion < _minApiVersion) {
|
||||
|
||||
@ -388,7 +389,7 @@ class InvenTreeAPI {
|
||||
|
||||
_connected = false;
|
||||
_connecting = false;
|
||||
_token = '';
|
||||
_token = "";
|
||||
profile = null;
|
||||
}
|
||||
|
||||
@ -435,7 +436,7 @@ class InvenTreeAPI {
|
||||
|
||||
// Next we request the permissions assigned to the current user
|
||||
// Note: 2021-02-27 this "roles" feature for the API was just introduced.
|
||||
// Any 'older' version of the server allows any API method for any logged in user!
|
||||
// Any "older" version of the server allows any API method for any logged in user!
|
||||
// We will return immediately, but request the user roles in the background
|
||||
|
||||
var response = await get(_URL_GET_ROLES, expectedStatusCode: 200);
|
||||
@ -446,9 +447,9 @@ class InvenTreeAPI {
|
||||
|
||||
var data = response.asMap();
|
||||
|
||||
if (data.containsKey('roles')) {
|
||||
if (data.containsKey("roles")) {
|
||||
// Save a local copy of the user roles
|
||||
roles = response.data['roles'] as Map<String, dynamic>;
|
||||
roles = response.data["roles"] as Map<String, dynamic>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,7 +457,7 @@ class InvenTreeAPI {
|
||||
/*
|
||||
* Check if the user has the given role.permission assigned
|
||||
*e
|
||||
* e.g. 'part', 'change'
|
||||
* e.g. "part", "change"
|
||||
*/
|
||||
|
||||
// If we do not have enough information, assume permission is allowed
|
||||
@ -489,9 +490,9 @@ class InvenTreeAPI {
|
||||
|
||||
if (request == null) {
|
||||
// Return an "invalid" APIResponse
|
||||
return new APIResponse(
|
||||
return APIResponse(
|
||||
url: url,
|
||||
method: 'PATCH',
|
||||
method: "PATCH",
|
||||
error: "HttpClientRequest is null"
|
||||
);
|
||||
}
|
||||
@ -535,7 +536,7 @@ class InvenTreeAPI {
|
||||
|
||||
HttpClientRequest? _request;
|
||||
|
||||
var client = createClient(true);
|
||||
var client = createClient(allowBadCert: true);
|
||||
|
||||
// Attempt to open a connection to the server
|
||||
try {
|
||||
@ -543,8 +544,8 @@ class InvenTreeAPI {
|
||||
|
||||
// Set headers
|
||||
_request.headers.set(HttpHeaders.authorizationHeader, _authorizationHeader());
|
||||
_request.headers.set(HttpHeaders.acceptHeader, 'application/json');
|
||||
_request.headers.set(HttpHeaders.contentTypeHeader, 'application/json');
|
||||
_request.headers.set(HttpHeaders.acceptHeader, "application/json");
|
||||
_request.headers.set(HttpHeaders.contentTypeHeader, "application/json");
|
||||
_request.headers.set(HttpHeaders.acceptLanguageHeader, Intl.getCurrentLocale());
|
||||
|
||||
} on SocketException catch (error) {
|
||||
@ -684,9 +685,9 @@ class InvenTreeAPI {
|
||||
|
||||
if (request == null) {
|
||||
// Return an "invalid" APIResponse
|
||||
return new APIResponse(
|
||||
return APIResponse(
|
||||
url: url,
|
||||
method: 'OPTIONS'
|
||||
method: "OPTIONS"
|
||||
);
|
||||
}
|
||||
|
||||
@ -703,9 +704,9 @@ class InvenTreeAPI {
|
||||
|
||||
if (request == null) {
|
||||
// Return an "invalid" APIResponse
|
||||
return new APIResponse(
|
||||
return APIResponse(
|
||||
url: url,
|
||||
method: 'POST'
|
||||
method: "POST"
|
||||
);
|
||||
}
|
||||
|
||||
@ -716,15 +717,13 @@ class InvenTreeAPI {
|
||||
);
|
||||
}
|
||||
|
||||
HttpClient createClient(bool allowBadCert) {
|
||||
HttpClient createClient({bool allowBadCert = true}) {
|
||||
|
||||
var client = new HttpClient();
|
||||
var client = HttpClient();
|
||||
|
||||
client.badCertificateCallback = ((X509Certificate cert, String host, int port) {
|
||||
client.badCertificateCallback = (X509Certificate cert, String host, int port) {
|
||||
// TODO - Introspection of actual certificate?
|
||||
|
||||
allowBadCert = true;
|
||||
|
||||
if (allowBadCert) {
|
||||
return true;
|
||||
} else {
|
||||
@ -734,7 +733,7 @@ class InvenTreeAPI {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Set the connection timeout
|
||||
client.connectionTimeout = Duration(seconds: 30);
|
||||
@ -746,7 +745,7 @@ class InvenTreeAPI {
|
||||
* Initiate a HTTP request to the server
|
||||
*
|
||||
* @param url is the API endpoint
|
||||
* @param method is the HTTP method e.g. 'POST' / 'PATCH' / 'GET' etc;
|
||||
* @param method is the HTTP method e.g. "POST" / "PATCH" / "GET" etc;
|
||||
* @param params is the request parameters
|
||||
*/
|
||||
Future<HttpClientRequest?> apiRequest(String url, String method, {Map<String, String> urlParams = const {}}) async {
|
||||
@ -763,7 +762,7 @@ class InvenTreeAPI {
|
||||
}
|
||||
|
||||
// Remove extraneous character if present
|
||||
if (_url.endsWith('&')) {
|
||||
if (_url.endsWith("&")) {
|
||||
_url = _url.substring(0, _url.length - 1);
|
||||
}
|
||||
|
||||
@ -781,7 +780,7 @@ class InvenTreeAPI {
|
||||
|
||||
HttpClientRequest? _request;
|
||||
|
||||
var client = createClient(true);
|
||||
var client = createClient(allowBadCert: true);
|
||||
|
||||
// Attempt to open a connection to the server
|
||||
try {
|
||||
@ -789,8 +788,8 @@ class InvenTreeAPI {
|
||||
|
||||
// Set headers
|
||||
_request.headers.set(HttpHeaders.authorizationHeader, _authorizationHeader());
|
||||
_request.headers.set(HttpHeaders.acceptHeader, 'application/json');
|
||||
_request.headers.set(HttpHeaders.contentTypeHeader, 'application/json');
|
||||
_request.headers.set(HttpHeaders.acceptHeader, "application/json");
|
||||
_request.headers.set(HttpHeaders.contentTypeHeader, "application/json");
|
||||
_request.headers.set(HttpHeaders.acceptLanguageHeader, Intl.getCurrentLocale());
|
||||
|
||||
return _request;
|
||||
@ -824,7 +823,7 @@ class InvenTreeAPI {
|
||||
request.add(encoded_data);
|
||||
}
|
||||
|
||||
APIResponse response = new APIResponse(
|
||||
APIResponse response = APIResponse(
|
||||
method: request.method,
|
||||
url: request.uri.toString()
|
||||
);
|
||||
@ -837,6 +836,19 @@ class InvenTreeAPI {
|
||||
// If the server returns a server error code, alert the user
|
||||
if (_response.statusCode >= 500) {
|
||||
showStatusCodeError(_response.statusCode);
|
||||
|
||||
sentryReportMessage(
|
||||
"Server error",
|
||||
context: {
|
||||
"url": request.uri.toString(),
|
||||
"method": request.method,
|
||||
"statusCode": _response.statusCode.toString(),
|
||||
"requestHeaders": request.headers.toString(),
|
||||
"responseHeaders": _response.headers.toString(),
|
||||
"responseData": response.data.toString(),
|
||||
}
|
||||
);
|
||||
|
||||
} else {
|
||||
response.data = await responseToJson(_response) ?? {};
|
||||
|
||||
@ -846,21 +858,6 @@ class InvenTreeAPI {
|
||||
if (statusCode != _response.statusCode) {
|
||||
showStatusCodeError(_response.statusCode);
|
||||
}
|
||||
|
||||
// Report any server errors
|
||||
if (_response.statusCode >= 500) {
|
||||
sentryReportMessage(
|
||||
"Server error",
|
||||
context: {
|
||||
"url": request.uri.toString(),
|
||||
"method": request.method,
|
||||
"statusCode": _response.statusCode.toString(),
|
||||
"requestHeaders": request.headers.toString(),
|
||||
"responseHeaders": _response.headers.toString(),
|
||||
"responseData": response.data.toString(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -930,9 +927,9 @@ class InvenTreeAPI {
|
||||
|
||||
if (request == null) {
|
||||
// Return an "invalid" APIResponse
|
||||
return new APIResponse(
|
||||
return APIResponse(
|
||||
url: url,
|
||||
method: 'GET',
|
||||
method: "GET",
|
||||
error: "HttpClientRequest is null",
|
||||
);
|
||||
}
|
||||
@ -945,8 +942,8 @@ class InvenTreeAPI {
|
||||
var headers = Map<String, String>();
|
||||
|
||||
headers[HttpHeaders.authorizationHeader] = _authorizationHeader();
|
||||
headers[HttpHeaders.acceptHeader] = 'application/json';
|
||||
headers[HttpHeaders.contentTypeHeader] = 'application/json';
|
||||
headers[HttpHeaders.acceptHeader] = "application/json";
|
||||
headers[HttpHeaders.contentTypeHeader] = "application/json";
|
||||
headers[HttpHeaders.acceptLanguageHeader] = Intl.getCurrentLocale();
|
||||
|
||||
return headers;
|
||||
@ -956,7 +953,7 @@ class InvenTreeAPI {
|
||||
if (_token.isNotEmpty) {
|
||||
return "Token $_token";
|
||||
} else if (profile != null) {
|
||||
return "Basic " + base64Encode(utf8.encode('${profile?.username}:${profile?.password}'));
|
||||
return "Basic " + base64Encode(utf8.encode("${profile?.username}:${profile?.password}"));
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
import 'dart:ui';
|
||||
import 'dart:io';
|
||||
import "dart:ui";
|
||||
import "dart:io";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:date_field/date_field.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:dropdown_search/dropdown_search.dart";
|
||||
import "package:date_field/date_field.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:inventree/widget/fields.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/widget/fields.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
|
||||
|
||||
|
||||
@ -41,24 +41,24 @@ class APIFormField {
|
||||
dynamic initial_data;
|
||||
|
||||
// Get the "api_url" associated with a related field
|
||||
String get api_url => (data["api_url"] ?? '') as String;
|
||||
String get api_url => (data["api_url"] ?? "") as String;
|
||||
|
||||
// Get the "model" associated with a related field
|
||||
String get model => (data["model"] ?? '') as String;
|
||||
String get model => (data["model"] ?? "") as String;
|
||||
|
||||
// Is this field hidden?
|
||||
bool get hidden => (data['hidden'] ?? false) as bool;
|
||||
bool get hidden => (data["hidden"] ?? false) as bool;
|
||||
|
||||
// Is this field read only?
|
||||
bool get readOnly => (data['read_only'] ?? false) as bool;
|
||||
bool get readOnly => (data["read_only"] ?? false) as bool;
|
||||
|
||||
bool get multiline => (data['multiline'] ?? false) as bool;
|
||||
bool get multiline => (data["multiline"] ?? false) as bool;
|
||||
|
||||
// Get the "value" as a string (look for "default" if not available)
|
||||
dynamic get value => (data['value'] ?? data['default']);
|
||||
dynamic get value => (data["value"] ?? data["default"]);
|
||||
|
||||
// Get the "default" as a string
|
||||
dynamic get defaultValue => data['default'];
|
||||
dynamic get defaultValue => data["default"];
|
||||
|
||||
Map<String, String> get filters {
|
||||
|
||||
@ -96,7 +96,7 @@ class APIFormField {
|
||||
|
||||
// Return the error message associated with this field
|
||||
List<String> errorMessages() {
|
||||
List<dynamic> errors = (data['errors'] ?? []) as List<dynamic>;
|
||||
List<dynamic> errors = (data["errors"] ?? []) as List<dynamic>;
|
||||
|
||||
List<String> messages = [];
|
||||
|
||||
@ -108,15 +108,15 @@ class APIFormField {
|
||||
}
|
||||
|
||||
// Is this field required?
|
||||
bool get required => (data['required'] ?? false) as bool;
|
||||
bool get required => (data["required"] ?? false) as bool;
|
||||
|
||||
String get type => (data['type'] ?? '').toString();
|
||||
String get type => (data["type"] ?? "").toString();
|
||||
|
||||
String get label => (data['label'] ?? '').toString();
|
||||
String get label => (data["label"] ?? "").toString();
|
||||
|
||||
String get helpText => (data['help_text'] ?? '').toString();
|
||||
String get helpText => (data["help_text"] ?? "").toString();
|
||||
|
||||
String get placeholderText => (data['placeholder'] ?? '').toString();
|
||||
String get placeholderText => (data["placeholder"] ?? "").toString();
|
||||
|
||||
List<dynamic> get choices => (data["choices"] ?? []) as List<dynamic>;
|
||||
|
||||
@ -193,13 +193,13 @@ class APIFormField {
|
||||
labelText: label,
|
||||
labelStyle: _labelStyle(),
|
||||
),
|
||||
initialValue: DateTime.tryParse((value ?? '') as String),
|
||||
initialValue: DateTime.tryParse((value ?? "") as String),
|
||||
autovalidateMode: AutovalidateMode.always,
|
||||
validator: (e) {
|
||||
// TODO
|
||||
},
|
||||
onDateSelected: (DateTime dt) {
|
||||
data['value'] = dt.toString().split(" ").first;
|
||||
data["value"] = dt.toString().split(" ").first;
|
||||
},
|
||||
);
|
||||
|
||||
@ -250,7 +250,7 @@ class APIFormField {
|
||||
|
||||
// Check if the current value is within the allowed values
|
||||
for (var opt in choices) {
|
||||
if (opt['value'] == value) {
|
||||
if (opt["value"] == value) {
|
||||
_initial = opt;
|
||||
break;
|
||||
}
|
||||
@ -267,13 +267,13 @@ class APIFormField {
|
||||
autoFocusSearchBox: true,
|
||||
showClearButton: !required,
|
||||
itemAsString: (dynamic item) {
|
||||
return (item['display_name'] ?? '') as String;
|
||||
return (item["display_name"] ?? "") as String;
|
||||
},
|
||||
onSaved: (item) {
|
||||
if (item == null) {
|
||||
data['value'] = null;
|
||||
data["value"] = null;
|
||||
} else {
|
||||
data['value'] = item['value'];
|
||||
data["value"] = item["value"];
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -294,7 +294,7 @@ class APIFormField {
|
||||
keyboardType: TextInputType.numberWithOptions(signed: true, decimal: true),
|
||||
validator: (value) {
|
||||
|
||||
double? quantity = double.tryParse(value.toString()) ?? null;
|
||||
double? quantity = double.tryParse(value.toString());
|
||||
|
||||
if (quantity == null) {
|
||||
return L10().numberInvalid;
|
||||
@ -335,7 +335,7 @@ class APIFormField {
|
||||
|
||||
List<dynamic> results = [];
|
||||
|
||||
for (var result in response.data['results'] ?? []) {
|
||||
for (var result in response.data["results"] ?? []) {
|
||||
results.add(result);
|
||||
}
|
||||
|
||||
@ -371,9 +371,9 @@ class APIFormField {
|
||||
},
|
||||
onSaved: (item) {
|
||||
if (item != null) {
|
||||
data['value'] = item['pk'] ?? null;
|
||||
data["value"] = item["pk"];
|
||||
} else {
|
||||
data['value'] = null;
|
||||
data["value"] = null;
|
||||
}
|
||||
},
|
||||
isFilteredOnline: true,
|
||||
@ -386,7 +386,7 @@ class APIFormField {
|
||||
return false;
|
||||
}
|
||||
|
||||
return item['pk'] == selectedItem['pk'];
|
||||
return item["pk"] == selectedItem["pk"];
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -443,7 +443,7 @@ class APIFormField {
|
||||
) : null,
|
||||
);
|
||||
case "owner":
|
||||
String name = (item["name"] ?? '') as String;
|
||||
String name = (item["name"] ?? "") as String;
|
||||
bool isGroup = (item["label"] ?? "") == "group";
|
||||
return ListTile(
|
||||
title: Text(name),
|
||||
@ -478,7 +478,7 @@ class APIFormField {
|
||||
readOnly: readOnly,
|
||||
maxLines: multiline ? null : 1,
|
||||
expands: false,
|
||||
initialValue: (value ?? '') as String,
|
||||
initialValue: (value ?? "") as String,
|
||||
onSaved: (val) {
|
||||
data["value"] = val;
|
||||
},
|
||||
@ -500,7 +500,7 @@ class APIFormField {
|
||||
helperStyle: _helperStyle(),
|
||||
initial: value as bool,
|
||||
onSaved: (val) {
|
||||
data['value'] = val;
|
||||
data["value"] = val;
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -631,7 +631,7 @@ Future<void> launchApiForm(BuildContext context, String title, String url, Map<S
|
||||
dynamic value = modelData[key];
|
||||
|
||||
if (availableFields.containsKey(key)) {
|
||||
availableFields[key]['value'] = value;
|
||||
availableFields[key]["value"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -874,7 +874,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
|
||||
|
||||
// Update field errors
|
||||
for (var field in fields) {
|
||||
field.data['errors'] = response.data[field.name];
|
||||
field.data["errors"] = response.data[field.name];
|
||||
}
|
||||
break;
|
||||
// TODO: Other status codes?
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
import 'dart:ui';
|
||||
import "dart:ui";
|
||||
|
||||
const Color COLOR_GRAY = Color.fromRGBO(50, 50, 50, 1);
|
||||
const Color COLOR_GRAY_LIGHT = Color.fromRGBO(150, 150, 150, 1);
|
||||
|
@ -2,8 +2,8 @@
|
||||
* Class for managing app-level configuration options
|
||||
*/
|
||||
|
||||
import 'package:sembast/sembast.dart';
|
||||
import 'package:inventree/preferences.dart';
|
||||
import "package:sembast/sembast.dart";
|
||||
import "package:inventree/preferences.dart";
|
||||
|
||||
class InvenTreeSettingsManager {
|
||||
|
||||
|
@ -1,26 +1,26 @@
|
||||
import 'package:inventree/app_settings.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:one_context/one_context.dart';
|
||||
import "dart:io";
|
||||
|
||||
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
||||
import "package:inventree/app_settings.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:audioplayers/audioplayers.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:qr_code_scanner/qr_code_scanner.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/widget/location_display.dart';
|
||||
import 'package:inventree/widget/part_detail.dart';
|
||||
import 'package:inventree/widget/stock_detail.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
import 'dart:io';
|
||||
import "package:inventree/widget/location_display.dart";
|
||||
import "package:inventree/widget/part_detail.dart";
|
||||
import "package:inventree/widget/stock_detail.dart";
|
||||
|
||||
|
||||
class BarcodeHandler {
|
||||
@ -38,7 +38,7 @@ class BarcodeHandler {
|
||||
|
||||
QRViewController? _controller;
|
||||
|
||||
void successTone() async {
|
||||
Future<void> successTone() async {
|
||||
|
||||
final bool en = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
|
||||
|
||||
@ -48,7 +48,7 @@ class BarcodeHandler {
|
||||
}
|
||||
}
|
||||
|
||||
void failureTone() async {
|
||||
Future <void> failureTone() async {
|
||||
|
||||
final bool en = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
|
||||
|
||||
@ -120,9 +120,9 @@ class BarcodeHandler {
|
||||
"errorDetail": response.errorDetail,
|
||||
}
|
||||
);
|
||||
} else if (data.containsKey('error')) {
|
||||
} else if (data.containsKey("error")) {
|
||||
onBarcodeUnknown(context, data);
|
||||
} else if (data.containsKey('success')) {
|
||||
} else if (data.containsKey("success")) {
|
||||
onBarcodeMatched(context, data);
|
||||
} else {
|
||||
onBarcodeUnhandled(context, data);
|
||||
@ -158,9 +158,9 @@ class BarcodeScanHandler extends BarcodeHandler {
|
||||
int pk = -1;
|
||||
|
||||
// A stocklocation has been passed?
|
||||
if (data.containsKey('stocklocation')) {
|
||||
if (data.containsKey("stocklocation")) {
|
||||
|
||||
pk = (data['stocklocation']?['pk'] ?? -1) as int;
|
||||
pk = (data["stocklocation"]?["pk"] ?? -1) as int;
|
||||
|
||||
if (pk > 0) {
|
||||
|
||||
@ -182,9 +182,9 @@ class BarcodeScanHandler extends BarcodeHandler {
|
||||
);
|
||||
}
|
||||
|
||||
} else if (data.containsKey('stockitem')) {
|
||||
} else if (data.containsKey("stockitem")) {
|
||||
|
||||
pk = (data['stockitem']?['pk'] ?? -1) as int;
|
||||
pk = (data["stockitem"]?["pk"] ?? -1) as int;
|
||||
|
||||
if (pk > 0) {
|
||||
|
||||
@ -208,9 +208,9 @@ class BarcodeScanHandler extends BarcodeHandler {
|
||||
success: false
|
||||
);
|
||||
}
|
||||
} else if (data.containsKey('part')) {
|
||||
} else if (data.containsKey("part")) {
|
||||
|
||||
pk = (data['part']?['pk'] ?? -1) as int;
|
||||
pk = (data["part"]?["pk"] ?? -1) as int;
|
||||
|
||||
if (pk > 0) {
|
||||
|
||||
@ -278,7 +278,7 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
||||
|
||||
failureTone();
|
||||
|
||||
// If the barcode is known, we can't assign it to the stock item!
|
||||
// If the barcode is known, we can"t assign it to the stock item!
|
||||
showSnackIcon(
|
||||
L10().barcodeInUse,
|
||||
icon: FontAwesomeIcons.qrcode,
|
||||
@ -296,7 +296,7 @@ class StockItemBarcodeAssignmentHandler extends BarcodeHandler {
|
||||
L10().barcodeMissingHash,
|
||||
);
|
||||
} else {
|
||||
String hash = (data['hash'] ?? '') as String;
|
||||
String hash = (data["hash"] ?? "") as String;
|
||||
|
||||
if (hash.isNotEmpty) {
|
||||
item.update(
|
||||
@ -343,10 +343,10 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler {
|
||||
|
||||
@override
|
||||
Future<void> onBarcodeMatched(BuildContext context, Map<String, dynamic> data) async {
|
||||
// If the barcode points to a 'stocklocation', great!
|
||||
if (data.containsKey('stocklocation')) {
|
||||
// If the barcode points to a "stocklocation", great!
|
||||
if (data.containsKey("stocklocation")) {
|
||||
// Extract location information
|
||||
int location = (data['stocklocation']['pk'] ?? -1) as int;
|
||||
int location = (data["stocklocation"]["pk"] ?? -1) as int;
|
||||
|
||||
if (location == -1) {
|
||||
showSnackIcon(
|
||||
@ -408,11 +408,11 @@ class StockLocationScanInItemsHandler extends BarcodeHandler {
|
||||
Future<void> onBarcodeMatched(BuildContext context, Map<String, dynamic> data) async {
|
||||
|
||||
// Returned barcode must match a stock item
|
||||
if (data.containsKey('stockitem')) {
|
||||
if (data.containsKey("stockitem")) {
|
||||
|
||||
int item_id = data['stockitem']['pk'] as int;
|
||||
int item_id = data["stockitem"]["pk"] as int;
|
||||
|
||||
final InvenTreeStockItem? item = await InvenTreeStockItem().get(item_id) as InvenTreeStockItem;
|
||||
final InvenTreeStockItem? item = await InvenTreeStockItem().get(item_id) as InvenTreeStockItem?;
|
||||
|
||||
if (item == null) {
|
||||
|
||||
@ -468,7 +468,7 @@ class InvenTreeQRView extends StatefulWidget {
|
||||
|
||||
final BarcodeHandler _handler;
|
||||
|
||||
InvenTreeQRView(this._handler, {Key? key}) : super(key: key);
|
||||
const InvenTreeQRView(this._handler, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _QRViewState(_handler);
|
||||
@ -477,7 +477,7 @@ class InvenTreeQRView extends StatefulWidget {
|
||||
|
||||
class _QRViewState extends State<InvenTreeQRView> {
|
||||
|
||||
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
||||
final GlobalKey qrKey = GlobalKey(debugLabel: "QR");
|
||||
|
||||
QRViewController? _controller;
|
||||
|
||||
|
@ -12,11 +12,9 @@ import 'package:flutter/material.dart';
|
||||
class S implements WidgetsLocalizations {
|
||||
const S();
|
||||
|
||||
static const GeneratedLocalizationsDelegate delegate =
|
||||
const GeneratedLocalizationsDelegate();
|
||||
static const GeneratedLocalizationsDelegate delegate = GeneratedLocalizationsDelegate();
|
||||
|
||||
static S of(BuildContext context) =>
|
||||
Localizations.of<S>(context, WidgetsLocalizations);
|
||||
static S of(BuildContext context) => Localizations.of<S>(context, WidgetsLocalizations);
|
||||
|
||||
@override
|
||||
TextDirection get textDirection => TextDirection.ltr;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:inventree/api.dart';
|
||||
|
||||
import 'model.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/inventree/model.dart";
|
||||
|
||||
|
||||
/*
|
||||
@ -9,6 +8,8 @@ import 'model.dart';
|
||||
|
||||
class InvenTreeCompany extends InvenTreeModel {
|
||||
|
||||
InvenTreeCompany() : super();
|
||||
|
||||
@override
|
||||
String get URL => "company/";
|
||||
|
||||
@ -25,23 +26,21 @@ class InvenTreeCompany extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
InvenTreeCompany() : super();
|
||||
String get image => (jsondata["image"] ?? jsondata["thumbnail"] ?? InvenTreeAPI.staticImage) as String;
|
||||
|
||||
String get image => (jsondata['image'] ?? jsondata['thumbnail'] ?? InvenTreeAPI.staticImage) as String;
|
||||
String get thumbnail => (jsondata["thumbnail"] ?? jsondata["image"] ?? InvenTreeAPI.staticThumb) as String;
|
||||
|
||||
String get thumbnail => (jsondata['thumbnail'] ?? jsondata['image'] ?? InvenTreeAPI.staticThumb) as String;
|
||||
String get website => (jsondata["website"] ?? "") as String;
|
||||
|
||||
String get website => (jsondata['website'] ?? '') as String;
|
||||
String get phone => (jsondata["phone"] ?? "") as String;
|
||||
|
||||
String get phone => (jsondata['phone'] ?? '') as String;
|
||||
String get email => (jsondata["email"] ?? "") as String;
|
||||
|
||||
String get email => (jsondata['email'] ?? '') as String;
|
||||
bool get isSupplier => (jsondata["is_supplier"] ?? false) as bool;
|
||||
|
||||
bool get isSupplier => (jsondata['is_supplier'] ?? false) as bool;
|
||||
bool get isManufacturer => (jsondata["is_manufacturer"] ?? false) as bool;
|
||||
|
||||
bool get isManufacturer => (jsondata['is_manufacturer'] ?? false) as bool;
|
||||
|
||||
bool get isCustomer => (jsondata['is_customer'] ?? false) as bool;
|
||||
bool get isCustomer => (jsondata["is_customer"] ?? false) as bool;
|
||||
|
||||
InvenTreeCompany.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
@ -83,29 +82,29 @@ class InvenTreeSupplierPart extends InvenTreeModel {
|
||||
|
||||
InvenTreeSupplierPart.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
int get manufacturerId => (jsondata['manufacturer'] ?? -1) as int;
|
||||
int get manufacturerId => (jsondata["manufacturer"] ?? -1) as int;
|
||||
|
||||
String get manufacturerName => (jsondata['manufacturer_detail']['name'] ?? '') as String;
|
||||
String get manufacturerName => (jsondata["manufacturer_detail"]["name"] ?? "") as String;
|
||||
|
||||
String get manufacturerImage => (jsondata['manufacturer_detail']['image'] ?? jsondata['manufacturer_detail']['thumbnail'] ?? InvenTreeAPI.staticThumb) as String;
|
||||
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'] ?? '') as String;
|
||||
String get supplierName => (jsondata["supplier_detail"]["name"] ?? "") as String;
|
||||
|
||||
String get supplierImage => (jsondata['supplier_detail']['image'] ?? jsondata['supplier_detail']['thumbnail'] ?? InvenTreeAPI.staticThumb) as String;
|
||||
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'] ?? '') as String;
|
||||
String get MPN => (jsondata["MPN"] ?? "") as String;
|
||||
|
||||
int get partId => (jsondata['part'] ?? -1) as int;
|
||||
int get partId => (jsondata["part"] ?? -1) as int;
|
||||
|
||||
String get partImage => (jsondata["part_detail"]["thumbnail"] ?? InvenTreeAPI.staticThumb) as String;
|
||||
|
||||
String get partName => (jsondata["part_detail"]["full_name"] ?? '') as String;
|
||||
String get partName => (jsondata["part_detail"]["full_name"] ?? "") as String;
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
@ -132,11 +131,11 @@ class InvenTreeManufacturerPart extends InvenTreeModel {
|
||||
|
||||
InvenTreeManufacturerPart.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
int get partId => (jsondata['part'] ?? -1) as int;
|
||||
int get partId => (jsondata["part"] ?? -1) as int;
|
||||
|
||||
int get manufacturerId => (jsondata['manufacturer'] ?? -1) as int;
|
||||
int get manufacturerId => (jsondata["manufacturer"] ?? -1) as int;
|
||||
|
||||
String get MPN => (jsondata['MPN'] ?? '') as String;
|
||||
String get MPN => (jsondata["MPN"] ?? "") as String;
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
|
@ -1,18 +1,17 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import "dart:async";
|
||||
import "dart:io";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:url_launcher/url_launcher.dart";
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:http/http.dart' as http;
|
||||
import "package:path/path.dart" as path;
|
||||
|
||||
import '../l10.dart';
|
||||
import '../api_form.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/api_form.dart";
|
||||
|
||||
|
||||
// Paginated response object
|
||||
@ -129,21 +128,21 @@ class InvenTreeModel {
|
||||
|
||||
}
|
||||
|
||||
int get pk => (jsondata['pk'] ?? -1) as int;
|
||||
int get pk => (jsondata["pk"] ?? -1) as int;
|
||||
|
||||
// Some common accessors
|
||||
String get name => (jsondata['name'] ?? '') as String;
|
||||
String get name => (jsondata["name"] ?? "") as String;
|
||||
|
||||
String get description => (jsondata['description'] ?? '') as String;
|
||||
String get description => (jsondata["description"] ?? "") as String;
|
||||
|
||||
String get notes => (jsondata['notes'] ?? '') as String;
|
||||
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"
|
||||
String get link => (jsondata['link'] ?? jsondata['URL'] ?? '') as String;
|
||||
String get link => (jsondata["link"] ?? jsondata["URL"] ?? "") as String;
|
||||
|
||||
void goToInvenTreePage() async {
|
||||
Future <void> goToInvenTreePage() async {
|
||||
|
||||
if (await canLaunch(webUrl)) {
|
||||
await launch(webUrl);
|
||||
@ -152,7 +151,7 @@ class InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
void openLink() async {
|
||||
Future <void> openLink() async {
|
||||
|
||||
if (link.isNotEmpty) {
|
||||
|
||||
@ -162,7 +161,7 @@ class InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get keywords => (jsondata['keywords'] ?? '') as String;
|
||||
String get keywords => (jsondata["keywords"] ?? "") as String;
|
||||
|
||||
// Create a new object from JSON data (not a constructor!)
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
@ -198,7 +197,7 @@ class InvenTreeModel {
|
||||
|
||||
var response = await api.get(url, params: defaultGetFilters(), expectedStatusCode: 200);
|
||||
|
||||
if (!response.isValid() || response.data == null || !(response.data is Map)) {
|
||||
if (!response.isValid() || response.data == null || (response.data is! Map)) {
|
||||
|
||||
// Report error
|
||||
if (response.statusCode > 0) {
|
||||
@ -267,12 +266,12 @@ class InvenTreeModel {
|
||||
|
||||
// Override any default values
|
||||
for (String key in filters.keys) {
|
||||
params[key] = filters[key] ?? '';
|
||||
params[key] = filters[key] ?? "";
|
||||
}
|
||||
|
||||
var response = await api.get(url, params: params);
|
||||
|
||||
if (!response.isValid() || response.data == null || !(response.data is Map)) {
|
||||
if (!response.isValid() || response.data == null || response.data is! Map) {
|
||||
|
||||
if (response.statusCode > 0) {
|
||||
await sentryReportMessage(
|
||||
@ -302,18 +301,18 @@ class InvenTreeModel {
|
||||
|
||||
Future<InvenTreeModel?> create(Map<String, dynamic> data) async {
|
||||
|
||||
if (data.containsKey('pk')) {
|
||||
data.remove('pk');
|
||||
if (data.containsKey("pk")) {
|
||||
data.remove("pk");
|
||||
}
|
||||
|
||||
if (data.containsKey('id')) {
|
||||
data.remove('id');
|
||||
if (data.containsKey("id")) {
|
||||
data.remove("id");
|
||||
}
|
||||
|
||||
var response = await api.post(URL, body: data);
|
||||
|
||||
// Invalid response returned from server
|
||||
if (!response.isValid() || response.data == null || !(response.data is Map)) {
|
||||
if (!response.isValid() || response.data == null || response.data is! Map) {
|
||||
|
||||
if (response.statusCode > 0) {
|
||||
await sentryReportMessage(
|
||||
@ -345,7 +344,7 @@ class InvenTreeModel {
|
||||
var params = defaultListFilters();
|
||||
|
||||
for (String key in filters.keys) {
|
||||
params[key] = filters[key] ?? '';
|
||||
params[key] = filters[key] ?? "";
|
||||
}
|
||||
|
||||
params["limit"] = "${limit}";
|
||||
@ -384,7 +383,7 @@ class InvenTreeModel {
|
||||
var params = defaultListFilters();
|
||||
|
||||
for (String key in filters.keys) {
|
||||
params[key] = filters[key] ?? '';
|
||||
params[key] = filters[key] ?? "";
|
||||
}
|
||||
|
||||
var response = await api.get(URL, params: params);
|
||||
@ -403,8 +402,8 @@ class InvenTreeModel {
|
||||
} else if (response.isMap()) {
|
||||
var mData = response.asMap();
|
||||
|
||||
if (mData.containsKey('results')) {
|
||||
data = (response.data['results'] ?? []) as List<dynamic>;
|
||||
if (mData.containsKey("results")) {
|
||||
data = (response.data["results"] ?? []) as List<dynamic>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,9 +422,9 @@ class InvenTreeModel {
|
||||
// Provide a listing of objects at the endpoint
|
||||
// TODO - Static function which returns a list of objects (of this class)
|
||||
|
||||
// TODO - Define a 'delete' function
|
||||
// TODO - Define a "delete" function
|
||||
|
||||
// TODO - Define a 'save' / 'update' function
|
||||
// TODO - Define a "save" / "update" function
|
||||
|
||||
// Override this function for each sub-class
|
||||
bool matchAgainstString(String filter) {
|
||||
@ -462,7 +461,7 @@ class InvenTreeAttachment extends InvenTreeModel {
|
||||
|
||||
InvenTreeAttachment() : super();
|
||||
|
||||
String get attachment => (jsondata["attachment"] ?? '') as String;
|
||||
String get attachment => (jsondata["attachment"] ?? "") as String;
|
||||
|
||||
// Return the filename of the attachment
|
||||
String get filename {
|
||||
@ -500,11 +499,11 @@ class InvenTreeAttachment extends InvenTreeModel {
|
||||
return FontAwesomeIcons.fileAlt;
|
||||
}
|
||||
|
||||
String get comment => (jsondata["comment"] ?? '') as String;
|
||||
String get comment => (jsondata["comment"] ?? "") as String;
|
||||
|
||||
DateTime? get uploadDate {
|
||||
if (jsondata.containsKey("upload_date")) {
|
||||
return DateTime.tryParse((jsondata["upload_date"] ?? '') as String);
|
||||
return DateTime.tryParse((jsondata["upload_date"] ?? "") as String);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -517,8 +516,8 @@ class InvenTreeAttachment extends InvenTreeModel {
|
||||
final APIResponse response = await InvenTreeAPI().uploadFile(
|
||||
URL,
|
||||
attachment,
|
||||
method: 'POST',
|
||||
name: 'attachment',
|
||||
method: "POST",
|
||||
name: "attachment",
|
||||
fields: fields
|
||||
);
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "dart:io";
|
||||
|
||||
import 'model.dart';
|
||||
import 'dart:io';
|
||||
import 'package:http/http.dart' as http;
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import "model.dart";
|
||||
|
||||
class InvenTreePartCategory extends InvenTreeModel {
|
||||
|
||||
@ -33,7 +33,7 @@ class InvenTreePartCategory extends InvenTreeModel {
|
||||
return filters;
|
||||
}
|
||||
|
||||
String get pathstring => (jsondata['pathstring'] ?? '') as String;
|
||||
String get pathstring => (jsondata["pathstring"] ?? "") as String;
|
||||
|
||||
String get parentpathstring {
|
||||
// TODO - Drive the refactor tractor through this
|
||||
@ -52,7 +52,7 @@ class InvenTreePartCategory extends InvenTreeModel {
|
||||
return p;
|
||||
}
|
||||
|
||||
int get partcount => (jsondata['parts'] ?? 0) as int;
|
||||
int get partcount => (jsondata["parts"] ?? 0) as int;
|
||||
|
||||
InvenTreePartCategory() : super();
|
||||
|
||||
@ -74,17 +74,15 @@ class InvenTreePartTestTemplate extends InvenTreeModel {
|
||||
@override
|
||||
String get URL => "part/test-template/";
|
||||
|
||||
String get key => (jsondata['key'] ?? '') as String;
|
||||
String get key => (jsondata["key"] ?? "") as String;
|
||||
|
||||
String get testName => (jsondata['test_name'] ?? '') as String;
|
||||
String get testName => (jsondata["test_name"] ?? "") as String;
|
||||
|
||||
String get description => (jsondata['description'] ?? '') as String;
|
||||
bool get required => (jsondata["required"] ?? false) as bool;
|
||||
|
||||
bool get required => (jsondata['required'] ?? false) as bool;
|
||||
bool get requiresValue => (jsondata["requires_value"] ?? false) as bool;
|
||||
|
||||
bool get requiresValue => (jsondata['requires_value'] ?? false) as bool;
|
||||
|
||||
bool get requiresAttachment => (jsondata['requires_attachment'] ?? false) as bool;
|
||||
bool get requiresAttachment => (jsondata["requires_attachment"] ?? false) as bool;
|
||||
|
||||
InvenTreePartTestTemplate() : super();
|
||||
|
||||
@ -195,7 +193,7 @@ class InvenTreePart extends InvenTreeModel {
|
||||
});
|
||||
}
|
||||
|
||||
int get supplierCount => (jsondata['suppliers'] ?? 0) as int;
|
||||
int get supplierCount => (jsondata["suppliers"] ?? 0) as int;
|
||||
|
||||
// Request supplier parts for this part
|
||||
Future<List<InvenTreeSupplierPart>> getSupplierParts() async {
|
||||
@ -242,7 +240,7 @@ 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"].toString()) ?? 0;
|
||||
|
||||
String get onOrderString {
|
||||
|
||||
@ -254,7 +252,7 @@ class InvenTreePart extends InvenTreeModel {
|
||||
}
|
||||
|
||||
// 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"].toString()) ?? 0;
|
||||
|
||||
String get inStockString {
|
||||
|
||||
@ -271,69 +269,69 @@ class InvenTreePart extends InvenTreeModel {
|
||||
return q;
|
||||
}
|
||||
|
||||
String get units => (jsondata["units"] as String) ?? "";
|
||||
String get units => (jsondata["units"] ?? "") as String;
|
||||
|
||||
// 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;
|
||||
|
||||
// Get the number of BOM items in this Part (if it is an assembly)
|
||||
int get bomItemCount => (jsondata['bom_items'] ?? 0) as int;
|
||||
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'] ?? 0) as int;
|
||||
int get usedInCount => (jsondata["used_in"] ?? 0) as int;
|
||||
|
||||
bool get isAssembly => (jsondata['assembly'] ?? false) as bool;
|
||||
bool get isAssembly => (jsondata["assembly"] ?? false) as bool;
|
||||
|
||||
bool get isComponent => (jsondata['component'] ?? false) as bool;
|
||||
bool get isComponent => (jsondata["component"] ?? false) as bool;
|
||||
|
||||
bool get isPurchaseable => (jsondata['purchaseable'] ?? false) as bool;
|
||||
bool get isPurchaseable => (jsondata["purchaseable"] ?? false) as bool;
|
||||
|
||||
bool get isSalable => (jsondata['salable'] ?? false) as bool;
|
||||
bool get isSalable => (jsondata["salable"] ?? false) as bool;
|
||||
|
||||
bool get isActive => (jsondata['active'] ?? false) as bool;
|
||||
bool get isActive => (jsondata["active"] ?? false) as bool;
|
||||
|
||||
bool get isVirtual => (jsondata['virtual'] ?? false) as bool;
|
||||
bool get isVirtual => (jsondata["virtual"] ?? false) as bool;
|
||||
|
||||
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
|
||||
String get IPN => (jsondata['IPN'] ?? '') as String;
|
||||
String get IPN => (jsondata["IPN"] ?? "") as String;
|
||||
|
||||
// Get the revision string for the Part instance
|
||||
String get revision => (jsondata['revision'] ?? '') as String;
|
||||
String get revision => (jsondata["revision"] ?? "") as String;
|
||||
|
||||
// Get the category ID for the Part instance (or 'null' if does not exist)
|
||||
int get categoryId => (jsondata['category'] ?? -1) as int;
|
||||
// Get the category ID for the Part instance (or "null" if does not exist)
|
||||
int get categoryId => (jsondata["category"] ?? -1) as int;
|
||||
|
||||
// Get the category name for the Part instance
|
||||
String get categoryName {
|
||||
// Inavlid category ID
|
||||
if (categoryId <= 0) return '';
|
||||
if (categoryId <= 0) return "";
|
||||
|
||||
if (!jsondata.containsKey('category_detail')) return '';
|
||||
if (!jsondata.containsKey("category_detail")) return "";
|
||||
|
||||
return (jsondata['category_detail']?['name'] ?? '') as String;
|
||||
return (jsondata["category_detail"]?["name"] ?? "") as String;
|
||||
}
|
||||
|
||||
// Get the category description for the Part instance
|
||||
String get categoryDescription {
|
||||
// Invalid category ID
|
||||
if (categoryId <= 0) return '';
|
||||
if (categoryId <= 0) return "";
|
||||
|
||||
if (!jsondata.containsKey('category_detail')) return '';
|
||||
if (!jsondata.containsKey("category_detail")) return "";
|
||||
|
||||
return (jsondata['category_detail']?['description'] ?? '') as String;
|
||||
return (jsondata["category_detail"]?["description"] ?? "") as String;
|
||||
}
|
||||
// Get the image URL for the Part instance
|
||||
String get _image => (jsondata['image'] ?? '') as String;
|
||||
String get _image => (jsondata["image"] ?? "") as String;
|
||||
|
||||
// Get the thumbnail URL for the Part instance
|
||||
String get _thumbnail => (jsondata['thumbnail'] ?? '') as String;
|
||||
String get _thumbnail => (jsondata["thumbnail"] ?? "") as String;
|
||||
|
||||
// Return the fully-qualified name for the Part instance
|
||||
String get fullname {
|
||||
|
||||
String fn = (jsondata['full_name'] ?? '') as String;
|
||||
String fn = (jsondata["full_name"] ?? "") as String;
|
||||
|
||||
if (fn.isNotEmpty) return fn;
|
||||
|
||||
@ -369,15 +367,15 @@ class InvenTreePart extends InvenTreeModel {
|
||||
final APIResponse response = await InvenTreeAPI().uploadFile(
|
||||
url,
|
||||
image,
|
||||
method: 'PATCH',
|
||||
name: 'image',
|
||||
method: "PATCH",
|
||||
name: "image",
|
||||
);
|
||||
|
||||
return response.successful();
|
||||
}
|
||||
|
||||
// Return the "starred" status of this part
|
||||
bool get starred => (jsondata['starred'] ?? false) as bool;
|
||||
bool get starred => (jsondata["starred"] ?? false) as bool;
|
||||
|
||||
InvenTreePart() : super();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
|
||||
import 'model.dart';
|
||||
import "package:inventree/inventree/model.dart";
|
||||
|
||||
// TODO: In the future, status codes should be retrieved from the server
|
||||
const int PO_STATUS_PENDING = 10;
|
||||
@ -44,27 +44,27 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
String get issueDate => (jsondata['issue_date'] ?? '') as String;
|
||||
String get issueDate => (jsondata["issue_date"] ?? "") as String;
|
||||
|
||||
String get completeDate => (jsondata['complete_date'] ?? '') as String;
|
||||
String get completeDate => (jsondata["complete_date"] ?? "") as String;
|
||||
|
||||
String get creationDate => (jsondata['creation_date'] ?? '') as String;
|
||||
String get creationDate => (jsondata["creation_date"] ?? "") as String;
|
||||
|
||||
String get targetDate => (jsondata['target_date'] ?? '') as String;
|
||||
String get targetDate => (jsondata["target_date"] ?? "") as String;
|
||||
|
||||
int get lineItemCount => (jsondata['line_items'] ?? 0) as int;
|
||||
int get lineItemCount => (jsondata["line_items"] ?? 0) as int;
|
||||
|
||||
bool get overdue => (jsondata['overdue'] ?? false) as bool;
|
||||
bool get overdue => (jsondata["overdue"] ?? false) as bool;
|
||||
|
||||
String get reference => (jsondata['reference'] ?? '') as String;
|
||||
String get reference => (jsondata["reference"] ?? "") as String;
|
||||
|
||||
int get responsibleId => (jsondata['responsible'] ?? -1) as int;
|
||||
int get responsibleId => (jsondata["responsible"] ?? -1) as int;
|
||||
|
||||
int get supplierId => (jsondata['supplier'] ?? -1) as int;
|
||||
int get supplierId => (jsondata["supplier"] ?? -1) as int;
|
||||
|
||||
InvenTreeCompany? get supplier {
|
||||
|
||||
dynamic supplier_detail = jsondata["supplier_detail"] ?? null;
|
||||
dynamic supplier_detail = jsondata["supplier_detail"];
|
||||
|
||||
if (supplier_detail == null) {
|
||||
return null;
|
||||
@ -73,15 +73,15 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get supplierReference => (jsondata['supplier_reference'] ?? '') as String;
|
||||
String get supplierReference => (jsondata["supplier_reference"] ?? "") as String;
|
||||
|
||||
int get status => (jsondata['status'] ?? -1) as int;
|
||||
int get status => (jsondata["status"] ?? -1) as int;
|
||||
|
||||
String get statusText => (jsondata['status_text'] ?? '') as String;
|
||||
String get statusText => (jsondata["status_text"] ?? "") as String;
|
||||
|
||||
bool get isOpen => this.status == PO_STATUS_PENDING || this.status == PO_STATUS_PLACED;
|
||||
bool get isOpen => status == PO_STATUS_PENDING || status == PO_STATUS_PLACED;
|
||||
|
||||
bool get isFailed => this.status == PO_STATUS_CANCELLED || this.status == PO_STATUS_LOST || this.status == PO_STATUS_RETURNED;
|
||||
bool get isFailed => status == PO_STATUS_CANCELLED || status == PO_STATUS_LOST || status == PO_STATUS_RETURNED;
|
||||
|
||||
Future<List<InvenTreePOLineItem>> getLineItems() async {
|
||||
|
||||
@ -146,17 +146,17 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
||||
|
||||
bool get isComplete => received >= quantity;
|
||||
|
||||
double get quantity => (jsondata['quantity'] ?? 0) as double;
|
||||
double get quantity => (jsondata["quantity"] ?? 0) as double;
|
||||
|
||||
double get received => (jsondata['received'] ?? 0) as double;
|
||||
double get received => (jsondata["received"] ?? 0) as double;
|
||||
|
||||
double get outstanding => quantity - received;
|
||||
|
||||
String get reference => (jsondata['reference'] ?? '') as String;
|
||||
String get reference => (jsondata["reference"] ?? "") as String;
|
||||
|
||||
int get orderId => (jsondata['order'] ?? -1) as int;
|
||||
int get orderId => (jsondata["order"] ?? -1) as int;
|
||||
|
||||
int get supplierPartId => (jsondata['part'] ?? -1) as int;
|
||||
int get supplierPartId => (jsondata["part"] ?? -1) as int;
|
||||
|
||||
InvenTreePart? get part {
|
||||
dynamic part_detail = jsondata["part_detail"];
|
||||
@ -170,7 +170,7 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
||||
|
||||
InvenTreeSupplierPart? get supplierPart {
|
||||
|
||||
dynamic detail = jsondata["supplier_part_detail"] ?? null;
|
||||
dynamic detail = jsondata["supplier_part_detail"];
|
||||
|
||||
if (detail == null) {
|
||||
return null;
|
||||
@ -179,15 +179,15 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
double get purchasePrice => double.parse((jsondata['purchase_price'] ?? '') as String);
|
||||
double get purchasePrice => double.parse((jsondata["purchase_price"] ?? "") as String);
|
||||
|
||||
String get purchasePriceCurrency => (jsondata['purchase_price_currency'] ?? '') as String;
|
||||
String get purchasePriceCurrency => (jsondata["purchase_price_currency"] ?? "") as String;
|
||||
|
||||
String get purchasePriceString => (jsondata['purchase_price_string'] ?? '') as String;
|
||||
String get purchasePriceString => (jsondata["purchase_price_string"] ?? "") as String;
|
||||
|
||||
int get destination => (jsondata['destination'] ?? -1) as int;
|
||||
int get destination => (jsondata["destination"] ?? -1) as int;
|
||||
|
||||
Map<String, dynamic> get destinationDetail => (jsondata['destination_detail'] ?? {}) as Map<String, dynamic>;
|
||||
Map<String, dynamic> get destinationDetail => (jsondata["destination_detail"] ?? {}) as Map<String, dynamic>;
|
||||
|
||||
InvenTreePOLineItem() : super();
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'dart:io';
|
||||
import "dart:io";
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import "package:device_info_plus/device_info_plus.dart";
|
||||
import "package:package_info_plus/package_info_plus.dart";
|
||||
import "package:sentry_flutter/sentry_flutter.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
Future<Map<String, dynamic>> getDeviceInfo() async {
|
||||
|
||||
@ -18,35 +18,35 @@ Future<Map<String, dynamic>> getDeviceInfo() async {
|
||||
final iosDeviceInfo = await deviceInfo.iosInfo;
|
||||
|
||||
device_info = {
|
||||
'name': iosDeviceInfo.name,
|
||||
'model': iosDeviceInfo.model,
|
||||
'systemName': iosDeviceInfo.systemName,
|
||||
'systemVersion': iosDeviceInfo.systemVersion,
|
||||
'localizedModel': iosDeviceInfo.localizedModel,
|
||||
'utsname': iosDeviceInfo.utsname.sysname,
|
||||
'identifierForVendor': iosDeviceInfo.identifierForVendor,
|
||||
'isPhysicalDevice': iosDeviceInfo.isPhysicalDevice,
|
||||
"name": iosDeviceInfo.name,
|
||||
"model": iosDeviceInfo.model,
|
||||
"systemName": iosDeviceInfo.systemName,
|
||||
"systemVersion": iosDeviceInfo.systemVersion,
|
||||
"localizedModel": iosDeviceInfo.localizedModel,
|
||||
"utsname": iosDeviceInfo.utsname.sysname,
|
||||
"identifierForVendor": iosDeviceInfo.identifierForVendor,
|
||||
"isPhysicalDevice": iosDeviceInfo.isPhysicalDevice,
|
||||
};
|
||||
|
||||
} else if (Platform.isAndroid) {
|
||||
final androidDeviceInfo = await deviceInfo.androidInfo;
|
||||
|
||||
device_info = {
|
||||
'type': androidDeviceInfo.type,
|
||||
'model': androidDeviceInfo.model,
|
||||
'device': androidDeviceInfo.device,
|
||||
'id': androidDeviceInfo.id,
|
||||
'androidId': androidDeviceInfo.androidId,
|
||||
'brand': androidDeviceInfo.brand,
|
||||
'display': androidDeviceInfo.display,
|
||||
'hardware': androidDeviceInfo.hardware,
|
||||
'manufacturer': androidDeviceInfo.manufacturer,
|
||||
'product': androidDeviceInfo.product,
|
||||
'version': androidDeviceInfo.version.release,
|
||||
'supported32BitAbis': androidDeviceInfo.supported32BitAbis,
|
||||
'supported64BitAbis': androidDeviceInfo.supported64BitAbis,
|
||||
'supportedAbis': androidDeviceInfo.supportedAbis,
|
||||
'isPhysicalDevice': androidDeviceInfo.isPhysicalDevice,
|
||||
"type": androidDeviceInfo.type,
|
||||
"model": androidDeviceInfo.model,
|
||||
"device": androidDeviceInfo.device,
|
||||
"id": androidDeviceInfo.id,
|
||||
"androidId": androidDeviceInfo.androidId,
|
||||
"brand": androidDeviceInfo.brand,
|
||||
"display": androidDeviceInfo.display,
|
||||
"hardware": androidDeviceInfo.hardware,
|
||||
"manufacturer": androidDeviceInfo.manufacturer,
|
||||
"product": androidDeviceInfo.product,
|
||||
"version": androidDeviceInfo.version.release,
|
||||
"supported32BitAbis": androidDeviceInfo.supported32BitAbis,
|
||||
"supported64BitAbis": androidDeviceInfo.supported64BitAbis,
|
||||
"supportedAbis": androidDeviceInfo.supportedAbis,
|
||||
"isPhysicalDevice": androidDeviceInfo.isPhysicalDevice,
|
||||
};
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ Future<bool> sentryReportMessage(String message, {Map<String, String>? context})
|
||||
|
||||
if (isInDebugMode()) {
|
||||
|
||||
print('----- In dev mode. Not sending message to Sentry.io -----');
|
||||
print("----- In dev mode. Not sending message to Sentry.io -----");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ Future<bool> sentryReportMessage(String message, {Map<String, String>? context})
|
||||
|
||||
Future<void> sentryReportError(dynamic error, dynamic stackTrace) async {
|
||||
|
||||
print('----- Sentry Intercepted error: $error -----');
|
||||
print("----- Sentry Intercepted error: $error -----");
|
||||
print(stackTrace);
|
||||
|
||||
// Errors thrown in development mode are unlikely to be interesting. You can
|
||||
@ -125,7 +125,7 @@ Future<void> sentryReportError(dynamic error, dynamic stackTrace) async {
|
||||
// the report.
|
||||
if (isInDebugMode()) {
|
||||
|
||||
print('----- In dev mode. Not sending report to Sentry.io -----');
|
||||
print("----- In dev mode. Not sending report to Sentry.io -----");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,13 @@
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'model.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "dart:async";
|
||||
|
||||
import "package:intl/intl.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import "package:inventree/inventree/model.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
|
||||
class InvenTreeStockItemTestResult extends InvenTreeModel {
|
||||
@ -31,19 +29,17 @@ class InvenTreeStockItemTestResult extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
String get key => (jsondata['key'] ?? '') as String;
|
||||
String get key => (jsondata["key"] ?? "") as String;
|
||||
|
||||
String get testName => (jsondata['test'] ?? '') as String;
|
||||
String get testName => (jsondata["test"] ?? "") as String;
|
||||
|
||||
bool get result => (jsondata['result'] ?? false) as bool;
|
||||
bool get result => (jsondata["result"] ?? false) as bool;
|
||||
|
||||
String get value => (jsondata['value'] ?? '') as String;
|
||||
String get value => (jsondata["value"] ?? "") as String;
|
||||
|
||||
String get notes => (jsondata['notes'] ?? '') as String;
|
||||
String get attachment => (jsondata["attachment"] ?? "") as String;
|
||||
|
||||
String get attachment => (jsondata['attachment'] ?? '') as String;
|
||||
|
||||
String get date => (jsondata['date'] ?? '') as String;
|
||||
String get date => (jsondata["date"] ?? "") as String;
|
||||
|
||||
InvenTreeStockItemTestResult() : super();
|
||||
|
||||
@ -204,17 +200,17 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
});
|
||||
}
|
||||
|
||||
String get uid => (jsondata['uid'] ?? '') as String;
|
||||
String get uid => (jsondata["uid"] ?? "") as String;
|
||||
|
||||
int get status => (jsondata['status'] ?? -1) as int;
|
||||
int get status => (jsondata["status"] ?? -1) as int;
|
||||
|
||||
String get packaging => (jsondata["packaging"] ?? '') as String;
|
||||
String get packaging => (jsondata["packaging"] ?? "") as String;
|
||||
|
||||
String get batch => (jsondata["batch"] ?? '') as String;
|
||||
String get batch => (jsondata["batch"] ?? "") as String;
|
||||
|
||||
int get partId => (jsondata['part'] ?? -1) as int;
|
||||
int get partId => (jsondata["part"] ?? -1) as int;
|
||||
|
||||
String get purchasePrice => (jsondata['purchase_price'] ?? '') as String;
|
||||
String get purchasePrice => (jsondata["purchase_price"] ?? "") as String;
|
||||
|
||||
bool get hasPurchasePrice {
|
||||
|
||||
@ -223,14 +219,14 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
return pp.isNotEmpty && pp.trim() != "-";
|
||||
}
|
||||
|
||||
int get purchaseOrderId => (jsondata['purchase_order'] ?? -1) as int;
|
||||
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
|
||||
DateTime? get updatedDate {
|
||||
if (jsondata.containsKey("updated")) {
|
||||
return DateTime.tryParse((jsondata["updated"] ?? '') as String);
|
||||
return DateTime.tryParse((jsondata["updated"] ?? "") as String);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -250,7 +246,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
DateTime? get stocktakeDate {
|
||||
if (jsondata.containsKey("stocktake_date")) {
|
||||
return DateTime.tryParse((jsondata["stocktake_date"] ?? '') as String);
|
||||
return DateTime.tryParse((jsondata["stocktake_date"] ?? "") as String);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -270,45 +266,45 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
String get partName {
|
||||
|
||||
String nm = '';
|
||||
String nm = "";
|
||||
|
||||
// Use the detailed part information as priority
|
||||
if (jsondata.containsKey('part_detail')) {
|
||||
nm = (jsondata['part_detail']['full_name'] ?? '') as String;
|
||||
if (jsondata.containsKey("part_detail")) {
|
||||
nm = (jsondata["part_detail"]["full_name"] ?? "") as String;
|
||||
}
|
||||
|
||||
// Backup if first value fails
|
||||
if (nm.isEmpty) {
|
||||
nm = (jsondata['part__name'] ?? '') as String;
|
||||
nm = (jsondata["part__name"] ?? "") as String;
|
||||
}
|
||||
|
||||
return nm;
|
||||
}
|
||||
|
||||
String get partDescription {
|
||||
String desc = '';
|
||||
String desc = "";
|
||||
|
||||
// Use the detailed part description as priority
|
||||
if (jsondata.containsKey('part_detail')) {
|
||||
desc = (jsondata['part_detail']['description'] ?? '') as String;
|
||||
if (jsondata.containsKey("part_detail")) {
|
||||
desc = (jsondata["part_detail"]["description"] ?? "") as String;
|
||||
}
|
||||
|
||||
if (desc.isEmpty) {
|
||||
desc = (jsondata['part__description'] ?? '') as String;
|
||||
desc = (jsondata["part__description"] ?? "") as String;
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
String get partImage {
|
||||
String img = '';
|
||||
String img = "";
|
||||
|
||||
if (jsondata.containsKey('part_detail')) {
|
||||
img = (jsondata['part_detail']['thumbnail'] ?? '') as String;
|
||||
if (jsondata.containsKey("part_detail")) {
|
||||
img = (jsondata["part_detail"]["thumbnail"] ?? "") as String;
|
||||
}
|
||||
|
||||
if (img.isEmpty) {
|
||||
img = (jsondata['part__thumbnail'] ?? '') as String;
|
||||
img = (jsondata["part__thumbnail"] ?? "") as String;
|
||||
}
|
||||
|
||||
return img;
|
||||
@ -321,63 +317,63 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
String thumb = "";
|
||||
|
||||
thumb = (jsondata['part_detail']?['thumbnail'] ?? '') as String;
|
||||
thumb = (jsondata["part_detail"]?["thumbnail"] ?? "") as String;
|
||||
|
||||
// Use 'image' as a backup
|
||||
// Use "image" as a backup
|
||||
if (thumb.isEmpty) {
|
||||
thumb = (jsondata['part_detail']?['image'] ?? '') as String;
|
||||
thumb = (jsondata["part_detail"]?["image"] ?? "") as String;
|
||||
}
|
||||
|
||||
// Try a different approach
|
||||
if (thumb.isEmpty) {
|
||||
thumb = (jsondata['part__thumbnail'] ?? '') as String;
|
||||
thumb = (jsondata["part__thumbnail"] ?? "") as String;
|
||||
}
|
||||
|
||||
// Still no thumbnail? Use the 'no image' image
|
||||
// Still no thumbnail? Use the "no image" image
|
||||
if (thumb.isEmpty) thumb = InvenTreeAPI.staticThumb;
|
||||
|
||||
return thumb;
|
||||
}
|
||||
|
||||
int get supplierPartId => (jsondata['supplier_part'] ?? -1) as int;
|
||||
int get supplierPartId => (jsondata["supplier_part"] ?? -1) as int;
|
||||
|
||||
String get supplierImage {
|
||||
String thumb = '';
|
||||
String thumb = "";
|
||||
|
||||
if (jsondata.containsKey("supplier_detail")) {
|
||||
thumb = (jsondata['supplier_detail']['supplier_logo'] ?? '') as String;
|
||||
thumb = (jsondata["supplier_detail"]["supplier_logo"] ?? "") as String;
|
||||
}
|
||||
|
||||
return thumb;
|
||||
}
|
||||
|
||||
String get supplierName {
|
||||
String sname = '';
|
||||
String sname = "";
|
||||
|
||||
if (jsondata.containsKey("supplier_detail")) {
|
||||
sname = (jsondata["supplier_detail"]["supplier_name"] ?? '') as String;
|
||||
sname = (jsondata["supplier_detail"]["supplier_name"] ?? "") as String;
|
||||
}
|
||||
|
||||
return sname;
|
||||
}
|
||||
|
||||
String get units {
|
||||
return (jsondata['part_detail']?['units'] ?? '') as String;
|
||||
return (jsondata["part_detail"]?["units"] ?? "") as String;
|
||||
}
|
||||
|
||||
String get supplierSKU {
|
||||
String sku = '';
|
||||
String sku = "";
|
||||
|
||||
if (jsondata.containsKey("supplier_detail")) {
|
||||
sku = (jsondata["supplier_detail"]["SKU"] ?? '') as String;
|
||||
sku = (jsondata["supplier_detail"]["SKU"] ?? "") as String;
|
||||
}
|
||||
|
||||
return sku;
|
||||
}
|
||||
|
||||
String get serialNumber => (jsondata['serial'] ?? '') as String;
|
||||
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;
|
||||
|
||||
String get quantityString {
|
||||
|
||||
@ -395,33 +391,33 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
return q;
|
||||
}
|
||||
|
||||
int get locationId => (jsondata['location'] ?? -1) as int;
|
||||
int get locationId => (jsondata["location"] ?? -1) as int;
|
||||
|
||||
bool isSerialized() => serialNumber.isNotEmpty && quantity.toInt() == 1;
|
||||
|
||||
String serialOrQuantityDisplay() {
|
||||
if (isSerialized()) {
|
||||
return 'SN ${serialNumber}';
|
||||
return "SN ${serialNumber}";
|
||||
}
|
||||
|
||||
// Is an integer?
|
||||
if (quantity.toInt() == quantity) {
|
||||
return '${quantity.toInt()}';
|
||||
return "${quantity.toInt()}";
|
||||
}
|
||||
|
||||
return '${quantity}';
|
||||
return "${quantity}";
|
||||
}
|
||||
|
||||
String get locationName {
|
||||
String loc = '';
|
||||
String loc = "";
|
||||
|
||||
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'] ?? '') as String;
|
||||
loc = (jsondata["location_detail"]["name"] ?? "") as String;
|
||||
|
||||
// Old-style name
|
||||
if (loc.isEmpty) {
|
||||
loc = (jsondata['location__name'] ?? '') as String;
|
||||
loc = (jsondata["location__name"] ?? "") as String;
|
||||
}
|
||||
|
||||
return loc;
|
||||
@ -429,9 +425,9 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
String get locationPathString {
|
||||
|
||||
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'] ?? '') as String;
|
||||
String _loc = (jsondata["location_detail"]["pathstring"] ?? "") as String;
|
||||
|
||||
if (_loc.isNotEmpty) {
|
||||
return _loc;
|
||||
@ -483,7 +479,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
"pk": "${pk}",
|
||||
"quantity": "${q}",
|
||||
},
|
||||
"notes": notes ?? '',
|
||||
"notes": notes ?? "",
|
||||
},
|
||||
expectedStatusCode: 200
|
||||
);
|
||||
@ -540,7 +536,7 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
||||
@override
|
||||
String get URL => "stock/location/";
|
||||
|
||||
String get pathstring => (jsondata['pathstring'] ?? '') as String;
|
||||
String get pathstring => (jsondata["pathstring"] ?? "") as String;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> formFields() {
|
||||
@ -553,13 +549,13 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
||||
|
||||
String get parentpathstring {
|
||||
// TODO - Drive the refactor tractor through this
|
||||
List<String> psplit = pathstring.split('/');
|
||||
List<String> psplit = pathstring.split("/");
|
||||
|
||||
if (psplit.length > 0) {
|
||||
psplit.removeLast();
|
||||
}
|
||||
|
||||
String p = psplit.join('/');
|
||||
String p = psplit.join("/");
|
||||
|
||||
if (p.isEmpty) {
|
||||
p = "Top level stock location";
|
||||
@ -568,7 +564,7 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
||||
return p;
|
||||
}
|
||||
|
||||
int get itemcount => (jsondata['items'] ?? 0) as int;
|
||||
int get itemcount => (jsondata["items"] ?? 0) as int;
|
||||
|
||||
InvenTreeStockLocation() : super();
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations_en.dart';
|
||||
import "package:flutter_gen/gen_l10n/app_localizations.dart";
|
||||
import "package:flutter_gen/gen_l10n/app_localizations_en.dart";
|
||||
|
||||
import 'package:one_context/one_context.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:one_context/one_context.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
// Shortcut function to reduce boilerplate!
|
||||
I18N L10()
|
||||
|
@ -1,19 +1,18 @@
|
||||
import 'dart:async';
|
||||
import "dart:async";
|
||||
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import "package:flutter_localizations/flutter_localizations.dart";
|
||||
import "package:flutter_gen/gen_l10n/app_localizations.dart";
|
||||
|
||||
import 'package:inventree/widget/home.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:one_context/one_context.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
import "package:package_info_plus/package_info_plus.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:sentry_flutter/sentry_flutter.dart";
|
||||
|
||||
import 'dsn.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/dsn.dart";
|
||||
import "package:inventree/widget/home.dart";
|
||||
|
||||
|
||||
Future<void> main() async {
|
||||
@ -75,24 +74,24 @@ class InvenTreeApp extends StatelessWidget {
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: [
|
||||
const Locale('de', ''), // German
|
||||
const Locale('el', ''), // Greek
|
||||
const Locale('en', ''), // English
|
||||
const Locale('es', ''), // Spanish
|
||||
const Locale('fr', ''), // French
|
||||
const Locale('he', ''), // Hebrew
|
||||
const Locale('it', ''), // Italian
|
||||
const Locale('ja', ''), // Japanese
|
||||
const Locale('ko', ''), // Korean
|
||||
const Locale('nl', ''), // Dutch
|
||||
const Locale('no', ''), // Norwegian
|
||||
const Locale('pl', ''), // Polish
|
||||
const Locale('ru', ''), // Russian
|
||||
const Locale('sv', ''), // Swedish
|
||||
const Locale('th', ''), // Thai
|
||||
const Locale('tr', ''), // Turkish
|
||||
const Locale('vi', ''), // Vietnamese
|
||||
const Locale('zh-CN', ''), // Chinese
|
||||
const Locale("de", ""), // German
|
||||
const Locale("el", ""), // Greek
|
||||
const Locale("en", ""), // English
|
||||
const Locale("es", ""), // Spanish
|
||||
const Locale("fr", ""), // French
|
||||
const Locale("he", ""), // Hebrew
|
||||
const Locale("it", ""), // Italian
|
||||
const Locale("ja", ""), // Japanese
|
||||
const Locale("ko", ""), // Korean
|
||||
const Locale("nl", ""), // Dutch
|
||||
const Locale("no", ""), // Norwegian
|
||||
const Locale("pl", ""), // Polish
|
||||
const Locale("ru", ""), // Russian
|
||||
const Locale("sv", ""), // Swedish
|
||||
const Locale("th", ""), // Thai
|
||||
const Locale("tr", ""), // Turkish
|
||||
const Locale("vi", ""), // Vietnamese
|
||||
const Locale("zh-CN", ""), // Chinese
|
||||
],
|
||||
|
||||
);
|
||||
|
@ -1,8 +1,10 @@
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sembast/sembast.dart';
|
||||
import 'package:sembast/sembast_io.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'dart:async';
|
||||
import "dart:async";
|
||||
|
||||
import "package:path_provider/path_provider.dart";
|
||||
import "package:sembast/sembast.dart";
|
||||
import "package:sembast/sembast_io.dart";
|
||||
import "package:path/path.dart";
|
||||
|
||||
|
||||
/*
|
||||
* Class for storing InvenTree preferences in a NoSql DB
|
||||
@ -43,7 +45,7 @@ class InvenTreePreferencesDB {
|
||||
print("Path: ${appDocumentDir.path}");
|
||||
|
||||
// Path with the form: /platform-specific-directory/demo.db
|
||||
final dbPath = join(appDocumentDir.path, 'InvenTreeSettings.db');
|
||||
final dbPath = join(appDocumentDir.path, "InvenTreeSettings.db");
|
||||
|
||||
final database = await databaseFactoryIo.openDatabase(dbPath);
|
||||
|
||||
@ -55,7 +57,7 @@ class InvenTreePreferencesDB {
|
||||
class InvenTreePreferences {
|
||||
|
||||
/* The following settings are not stored to persistent storage,
|
||||
* instead they are only used as 'session preferences'.
|
||||
* instead they are only used as "session preferences".
|
||||
* They are kept here as a convenience only.
|
||||
*/
|
||||
|
||||
|
@ -1,22 +1,22 @@
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/settings/release.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/settings/release.dart";
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter/services.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:package_info_plus/package_info_plus.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
class InvenTreeAboutWidget extends StatelessWidget {
|
||||
|
||||
final PackageInfo info;
|
||||
|
||||
InvenTreeAboutWidget(this.info) : super();
|
||||
const InvenTreeAboutWidget(this.info) : super();
|
||||
|
||||
void _releaseNotes(BuildContext context) async {
|
||||
Future <void> _releaseNotes(BuildContext context) async {
|
||||
|
||||
// Load release notes from external file
|
||||
String notes = await rootBundle.loadString("assets/release_notes.md");
|
||||
@ -27,7 +27,7 @@ class InvenTreeAboutWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _credits(BuildContext context) async {
|
||||
Future <void> _credits(BuildContext context) async {
|
||||
|
||||
String notes = await rootBundle.loadString("assets/credits.md");
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
import 'package:inventree/app_settings.dart';
|
||||
import "package:inventree/app_settings.dart";
|
||||
|
||||
class InvenTreeAppSettingsWidget extends StatefulWidget {
|
||||
@override
|
||||
@ -31,7 +31,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
void loadSettings() async {
|
||||
Future <void> loadSettings() async {
|
||||
barcodeSounds = await InvenTreeSettingsManager().getValue("barcodeSounds", true) as bool;
|
||||
serverSounds = await InvenTreeSettingsManager().getValue("serverSounds", true) as bool;
|
||||
|
||||
@ -42,7 +42,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void setBarcodeSounds(bool en) async {
|
||||
Future <void> setBarcodeSounds(bool en) async {
|
||||
|
||||
await InvenTreeSettingsManager().setValue("barcodeSounds", en);
|
||||
barcodeSounds = await InvenTreeSettingsManager().getBool("barcodeSounds", true);
|
||||
@ -51,7 +51,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void setServerSounds(bool en) async {
|
||||
Future <void> setServerSounds(bool en) async {
|
||||
|
||||
await InvenTreeSettingsManager().setValue("serverSounds", en);
|
||||
serverSounds = await InvenTreeSettingsManager().getBool("serverSounds", true);
|
||||
@ -60,7 +60,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void setPartSubcategory(bool en) async {
|
||||
Future <void> setPartSubcategory(bool en) async {
|
||||
await InvenTreeSettingsManager().setValue("partSubcategory", en);
|
||||
partSubcategory = await InvenTreeSettingsManager().getBool("partSubcategory", true);
|
||||
|
||||
@ -68,7 +68,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void setStockSublocation(bool en) async {
|
||||
Future <void> setStockSublocation(bool en) async {
|
||||
await InvenTreeSettingsManager().setValue("stockSublocation", en);
|
||||
stockSublocation = await InvenTreeSettingsManager().getBool("stockSublocation", true);
|
||||
|
||||
|
@ -1,15 +1,12 @@
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:inventree/widget/fields.dart';
|
||||
import 'package:inventree/widget/spinner.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
|
||||
import '../api.dart';
|
||||
import '../user_profile.dart';
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/widget/spinner.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/user_profile.dart";
|
||||
|
||||
class InvenTreeLoginSettingsWidget extends StatefulWidget {
|
||||
|
||||
@ -22,15 +19,13 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
|
||||
final GlobalKey<_InvenTreeLoginSettingsState> _loginKey = GlobalKey<_InvenTreeLoginSettingsState>();
|
||||
|
||||
final GlobalKey<FormState> _addProfileKey = new GlobalKey<FormState>();
|
||||
|
||||
List<UserProfile> profiles = [];
|
||||
|
||||
_InvenTreeLoginSettingsState() {
|
||||
_reload();
|
||||
}
|
||||
|
||||
void _reload() async {
|
||||
Future <void> _reload() async {
|
||||
|
||||
profiles = await UserProfileDBManager().getAllProfiles();
|
||||
|
||||
@ -50,7 +45,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void _selectProfile(BuildContext context, UserProfile profile) async {
|
||||
Future <void> _selectProfile(BuildContext context, UserProfile profile) async {
|
||||
|
||||
// Disconnect InvenTree
|
||||
InvenTreeAPI().disconnectFromServer();
|
||||
@ -73,18 +68,18 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
_reload();
|
||||
}
|
||||
|
||||
void _deleteProfile(UserProfile profile) async {
|
||||
Future <void> _deleteProfile(UserProfile profile) async {
|
||||
|
||||
await UserProfileDBManager().deleteProfile(profile);
|
||||
|
||||
_reload();
|
||||
|
||||
if (InvenTreeAPI().isConnected() && profile.key == (InvenTreeAPI().profile?.key ?? '')) {
|
||||
if (InvenTreeAPI().isConnected() && profile.key == (InvenTreeAPI().profile?.key ?? "")) {
|
||||
InvenTreeAPI().disconnectFromServer();
|
||||
}
|
||||
}
|
||||
|
||||
void _updateProfile(UserProfile? profile) async {
|
||||
Future <void> _updateProfile(UserProfile? profile) async {
|
||||
|
||||
if (profile == null) {
|
||||
return;
|
||||
@ -92,7 +87,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
|
||||
_reload();
|
||||
|
||||
if (InvenTreeAPI().isConnected() && InvenTreeAPI().profile != null && profile.key == (InvenTreeAPI().profile?.key ?? '')) {
|
||||
if (InvenTreeAPI().isConnected() && InvenTreeAPI().profile != null && profile.key == (InvenTreeAPI().profile?.key ?? "")) {
|
||||
// Attempt server login (this will load the newly selected profile
|
||||
|
||||
InvenTreeAPI().connectToServer().then((result) {
|
||||
@ -108,7 +103,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
|
||||
if (!profile.selected) return null;
|
||||
|
||||
// Selected, but (for some reason) not the same as the API...
|
||||
if ((InvenTreeAPI().profile?.key ?? '') != profile.key) {
|
||||
if ((InvenTreeAPI().profile?.key ?? "") != profile.key) {
|
||||
return FaIcon(
|
||||
FontAwesomeIcons.questionCircle,
|
||||
color: COLOR_WARNING
|
||||
|
@ -1,14 +1,14 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_markdown/flutter_markdown.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
|
||||
class ReleaseNotesWidget extends StatelessWidget {
|
||||
|
||||
final String releaseNotes;
|
||||
|
||||
ReleaseNotesWidget(this.releaseNotes);
|
||||
const ReleaseNotesWidget(this.releaseNotes);
|
||||
|
||||
@override
|
||||
Widget build (BuildContext context) {
|
||||
@ -29,7 +29,7 @@ class CreditsWidget extends StatelessWidget {
|
||||
|
||||
final String credits;
|
||||
|
||||
CreditsWidget(this.credits);
|
||||
const CreditsWidget(this.credits);
|
||||
|
||||
@override
|
||||
Widget build (BuildContext context) {
|
||||
|
@ -1,18 +1,16 @@
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/settings/about.dart';
|
||||
import 'package:inventree/settings/app_settings.dart';
|
||||
import 'package:inventree/settings/login.dart';
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/settings/about.dart";
|
||||
import "package:inventree/settings/app_settings.dart";
|
||||
import "package:inventree/settings/login.dart";
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import 'package:inventree/widget/submit_feedback.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/widget/submit_feedback.dart";
|
||||
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import "package:url_launcher/url_launcher.dart";
|
||||
|
||||
import 'login.dart';
|
||||
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import "package:package_info_plus/package_info_plus.dart";
|
||||
|
||||
class InvenTreeSettingsWidget extends StatefulWidget {
|
||||
// InvenTree settings view
|
||||
@ -95,30 +93,30 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
|
||||
}
|
||||
|
||||
|
||||
void _openDocs() async {
|
||||
Future <void> _openDocs() async {
|
||||
if (await canLaunch(docsUrl)) {
|
||||
await launch(docsUrl);
|
||||
}
|
||||
}
|
||||
|
||||
void _translate() async {
|
||||
final String url = "https://crowdin.com/project/inventree";
|
||||
Future <void> _translate() async {
|
||||
const String url = "https://crowdin.com/project/inventree";
|
||||
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
}
|
||||
}
|
||||
|
||||
void _editServerSettings() async {
|
||||
Future <void> _editServerSettings() async {
|
||||
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeLoginSettingsWidget()));
|
||||
}
|
||||
|
||||
void _editAppSettings() async {
|
||||
Future <void> _editAppSettings() async {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeAppSettingsWidget()));
|
||||
}
|
||||
|
||||
void _about() async {
|
||||
Future <void> _about() async {
|
||||
|
||||
PackageInfo.fromPlatform().then((PackageInfo info) {
|
||||
Navigator.push(context,
|
||||
@ -126,7 +124,7 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
|
||||
});
|
||||
}
|
||||
|
||||
void _submitFeedback(BuildContext context) async {
|
||||
Future <void> _submitFeedback(BuildContext context) async {
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -2,8 +2,8 @@
|
||||
/*
|
||||
* Class for InvenTree user / login details
|
||||
*/
|
||||
import 'package:sembast/sembast.dart';
|
||||
import 'preferences.dart';
|
||||
import "package:sembast/sembast.dart";
|
||||
import "preferences.dart";
|
||||
|
||||
class UserProfile {
|
||||
|
||||
@ -38,10 +38,10 @@ class UserProfile {
|
||||
|
||||
factory UserProfile.fromJson(int key, Map<String, dynamic> json, bool isSelected) => UserProfile(
|
||||
key: key,
|
||||
name: json['name'] as String,
|
||||
server: json['server'] as String,
|
||||
username: json['username'] as String,
|
||||
password: json['password'] as String,
|
||||
name: json["name"] as String,
|
||||
server: json["server"] as String,
|
||||
username: json["username"] as String,
|
||||
password: json["password"] as String,
|
||||
selected: isSelected,
|
||||
);
|
||||
|
||||
@ -70,7 +70,7 @@ class UserProfileDBManager {
|
||||
|
||||
final profiles = await store.find(await _db, finder: finder);
|
||||
|
||||
return profiles.length > 0;
|
||||
return profiles.isNotEmpty;
|
||||
}
|
||||
|
||||
Future<void> addProfile(UserProfile profile) async {
|
||||
|
@ -1,27 +1,27 @@
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/app_settings.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/app_settings.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/widget/part_detail.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/paginator.dart';
|
||||
import "package:inventree/widget/part_detail.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/paginator.dart";
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:infinite_scroll_pagination/infinite_scroll_pagination.dart";
|
||||
|
||||
class CategoryDisplayWidget extends StatefulWidget {
|
||||
|
||||
CategoryDisplayWidget(this.category, {Key? key}) : super(key: key);
|
||||
const CategoryDisplayWidget(this.category, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreePartCategory? category;
|
||||
|
||||
@ -41,7 +41,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
||||
|
||||
List<Widget> actions = [];
|
||||
|
||||
if ((category != null) && InvenTreeAPI().checkPermission('part_category', 'change')) {
|
||||
if ((category != null) && InvenTreeAPI().checkPermission("part_category", "change")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.edit),
|
||||
@ -278,7 +278,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
||||
getCategoryDescriptionCard(extra: false),
|
||||
];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'add')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "add")) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().categoryCreate),
|
||||
@ -331,7 +331,9 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
||||
);
|
||||
case 1:
|
||||
return PaginatedPartList(
|
||||
{"category": "${category?.pk ?? null}"},
|
||||
{
|
||||
"category": "${category?.pk ?? 'null'}"
|
||||
},
|
||||
);
|
||||
case 2:
|
||||
return ListView(
|
||||
@ -350,7 +352,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
||||
class SubcategoryList extends StatelessWidget {
|
||||
final List<InvenTreePartCategory> _categories;
|
||||
|
||||
SubcategoryList(this._categories);
|
||||
const SubcategoryList(this._categories);
|
||||
|
||||
void _openCategory(BuildContext context, int pk) {
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
class CompanyDetailWidget extends StatefulWidget {
|
||||
|
||||
final InvenTreeCompany company;
|
||||
|
||||
CompanyDetailWidget(this.company, {Key? key}) : super(key: key);
|
||||
const CompanyDetailWidget(this.company, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CompanyDetailState createState() => _CompanyDetailState(company);
|
||||
@ -62,7 +62,7 @@ class _CompanyDetailState extends RefreshableState<CompanyDetailWidget> {
|
||||
await company.reload();
|
||||
}
|
||||
|
||||
void editCompany(BuildContext context) async {
|
||||
Future <void> editCompany(BuildContext context) async {
|
||||
|
||||
company.editForm(
|
||||
context,
|
||||
|
@ -1,16 +1,16 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:infinite_scroll_pagination/infinite_scroll_pagination.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/widget/paginator.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/company_detail.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/widget/paginator.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/company_detail.dart";
|
||||
|
||||
import '../l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
|
||||
class CompanyListWidget extends StatefulWidget {
|
||||
|
@ -1,12 +1,12 @@
|
||||
|
||||
import 'package:inventree/app_settings.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import 'package:one_context/one_context.dart';
|
||||
import "package:inventree/app_settings.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:audioplayers/audioplayers.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
|
||||
Future<void> confirmationDialog(String title, String text, {String? acceptText, String? rejectText, Function? onAccept, Function? onReject}) async {
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/barcode.dart';
|
||||
import 'package:inventree/widget/company_list.dart';
|
||||
import 'package:inventree/widget/search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/barcode.dart";
|
||||
import "package:inventree/widget/company_list.dart";
|
||||
import "package:inventree/widget/search.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/widget/category_display.dart';
|
||||
import 'package:inventree/widget/location_display.dart';
|
||||
import "package:inventree/widget/category_display.dart";
|
||||
import "package:inventree/widget/location_display.dart";
|
||||
|
||||
import 'package:inventree/settings/settings.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import "package:inventree/settings/settings.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
class InvenTreeDrawer extends StatelessWidget {
|
||||
|
||||
final BuildContext context;
|
||||
|
||||
InvenTreeDrawer(this.context);
|
||||
const InvenTreeDrawer(this.context);
|
||||
|
||||
void _closeDrawer() {
|
||||
// Close the drawer
|
||||
@ -50,7 +50,7 @@ class InvenTreeDrawer extends StatelessWidget {
|
||||
* Launch the camera to scan a QR code.
|
||||
* Upon successful scan, data are passed off to be decoded.
|
||||
*/
|
||||
void _scan() async {
|
||||
Future <void> _scan() async {
|
||||
if (!InvenTreeAPI().checkConnection(context)) return;
|
||||
|
||||
_closeDrawer();
|
||||
|
@ -1,15 +1,13 @@
|
||||
import "dart:async";
|
||||
import "dart:io";
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:one_context/one_context.dart';
|
||||
import "package:file_picker/file_picker.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:image_picker/image_picker.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
|
||||
class FilePickerDialog {
|
||||
@ -167,7 +165,7 @@ class CheckBoxField extends FormField<bool> {
|
||||
|
||||
class StringField extends TextFormField {
|
||||
|
||||
StringField({String label = "", String? hint, String? initial, Function(String?)? onSaved, Function? validator, bool allowEmpty = false, bool isEnabled = true}) :
|
||||
StringField({String label = "", String? hint, String? initial, Function(String?)? onSaved, Function(String?)? validator, bool allowEmpty = false, bool isEnabled = true}) :
|
||||
super(
|
||||
decoration: InputDecoration(
|
||||
labelText: allowEmpty ? label : label + "*",
|
||||
@ -182,7 +180,7 @@ class StringField extends TextFormField {
|
||||
}
|
||||
|
||||
if (validator != null) {
|
||||
return validator(value);
|
||||
return validator(value) as String?;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -1,29 +1,29 @@
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/user_profile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/user_profile.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
import 'package:inventree/barcode.dart';
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:inventree/barcode.dart";
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
import 'package:inventree/settings/login.dart';
|
||||
import "package:inventree/settings/login.dart";
|
||||
|
||||
import 'package:inventree/widget/category_display.dart';
|
||||
import 'package:inventree/widget/company_list.dart';
|
||||
import 'package:inventree/widget/location_display.dart';
|
||||
import 'package:inventree/widget/purchase_order_list.dart';
|
||||
import 'package:inventree/widget/search.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import 'package:inventree/widget/spinner.dart';
|
||||
import 'package:inventree/widget/drawer.dart';
|
||||
import "package:inventree/widget/category_display.dart";
|
||||
import "package:inventree/widget/company_list.dart";
|
||||
import "package:inventree/widget/location_display.dart";
|
||||
import "package:inventree/widget/purchase_order_list.dart";
|
||||
import "package:inventree/widget/search.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:inventree/widget/spinner.dart";
|
||||
import "package:inventree/widget/drawer.dart";
|
||||
|
||||
class InvenTreeHomePage extends StatefulWidget {
|
||||
|
||||
InvenTreeHomePage({Key? key}) : super(key: key);
|
||||
const InvenTreeHomePage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_InvenTreeHomePageState createState() => _InvenTreeHomePageState();
|
||||
@ -125,7 +125,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
||||
});
|
||||
}
|
||||
|
||||
void _loadProfile() async {
|
||||
Future <void> _loadProfile() async {
|
||||
|
||||
_profile = await UserProfileDBManager().getSelectedProfile();
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/app_settings.dart';
|
||||
import 'package:inventree/barcode.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/app_settings.dart";
|
||||
import "package:inventree/barcode.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/stock_detail.dart';
|
||||
import 'package:inventree/widget/paginator.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/stock_detail.dart";
|
||||
import "package:inventree/widget/paginator.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:infinite_scroll_pagination/infinite_scroll_pagination.dart";
|
||||
|
||||
class LocationDisplayWidget extends StatefulWidget {
|
||||
|
||||
@ -62,7 +62,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
||||
);
|
||||
*/
|
||||
|
||||
if ((location != null) && (InvenTreeAPI().checkPermission('stock_location', 'change'))) {
|
||||
if ((location != null) && (InvenTreeAPI().checkPermission("stock_location", "change"))) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.edit),
|
||||
@ -96,7 +96,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
||||
|
||||
List<InvenTreeStockLocation> _sublocations = [];
|
||||
|
||||
String _locationFilter = '';
|
||||
String _locationFilter = "";
|
||||
|
||||
List<InvenTreeStockLocation> get sublocations {
|
||||
|
||||
@ -340,7 +340,7 @@ List<Widget> detailTiles() {
|
||||
|
||||
tiles.add(locationDescriptionCard(includeActions: false));
|
||||
|
||||
if (InvenTreeAPI().checkPermission('stock', 'add')) {
|
||||
if (InvenTreeAPI().checkPermission("stock", "add")) {
|
||||
|
||||
tiles.add(
|
||||
ListTile(
|
||||
@ -368,7 +368,7 @@ List<Widget> detailTiles() {
|
||||
|
||||
if (location != null) {
|
||||
// Stock adjustment actions
|
||||
if (InvenTreeAPI().checkPermission('stock', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("stock", "change")) {
|
||||
// Scan items into location
|
||||
tiles.add(
|
||||
ListTile(
|
||||
@ -430,7 +430,7 @@ List<Widget> detailTiles() {
|
||||
class SublocationList extends StatelessWidget {
|
||||
final List<InvenTreeStockLocation> _locations;
|
||||
|
||||
SublocationList(this._locations);
|
||||
const SublocationList(this._locations);
|
||||
|
||||
void _openLocation(BuildContext context, int pk) {
|
||||
|
||||
@ -446,7 +446,7 @@ class SublocationList extends StatelessWidget {
|
||||
InvenTreeStockLocation loc = _locations[index];
|
||||
|
||||
return ListTile(
|
||||
title: Text('${loc.name}'),
|
||||
title: Text("${loc.name}"),
|
||||
subtitle: Text("${loc.description}"),
|
||||
trailing: Text("${loc.itemcount}"),
|
||||
onTap: () {
|
||||
@ -477,7 +477,7 @@ class PaginatedStockList extends StatefulWidget {
|
||||
|
||||
final Map<String, String> filters;
|
||||
|
||||
PaginatedStockList(this.filters);
|
||||
const PaginatedStockList(this.filters);
|
||||
|
||||
@override
|
||||
_PaginatedStockListState createState() => _PaginatedStockListState(filters);
|
||||
@ -516,7 +516,7 @@ class _PaginatedStockListState extends State<PaginatedStockList> {
|
||||
Future<void> _fetchPage(int pageKey) async {
|
||||
try {
|
||||
|
||||
Map<String, String> params = this.filters;
|
||||
Map<String, String> params = filters;
|
||||
|
||||
params["search"] = "${_searchTerm}";
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Pagination related widgets
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
|
||||
class PaginatedSearchWidget extends StatelessWidget {
|
||||
@ -44,9 +42,9 @@ class PaginatedSearchWidget extends StatelessWidget {
|
||||
|
||||
class NoResultsWidget extends StatelessWidget {
|
||||
|
||||
final String description;
|
||||
const NoResultsWidget(this.description);
|
||||
|
||||
NoResultsWidget(this.description);
|
||||
final String description;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -1,23 +1,19 @@
|
||||
import "dart:io";
|
||||
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/widget/fields.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/widget/fields.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import '../api.dart';
|
||||
import '../l10.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
class PartAttachmentsWidget extends StatefulWidget {
|
||||
|
||||
PartAttachmentsWidget(this.part, {Key? key}) : super(key: key);
|
||||
const PartAttachmentsWidget(this.part, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreePart part;
|
||||
|
||||
@ -42,7 +38,7 @@ class _PartAttachmentDisplayState extends RefreshableState<PartAttachmentsWidget
|
||||
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "change")) {
|
||||
|
||||
// File upload
|
||||
actions.add(
|
||||
|
@ -1,28 +1,28 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import 'package:inventree/widget/part_attachments_widget.dart';
|
||||
import 'package:inventree/widget/part_notes.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/widget/category_display.dart';
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/part_image_widget.dart';
|
||||
import 'package:inventree/widget/stock_detail.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/widget/part_attachments_widget.dart";
|
||||
import "package:inventree/widget/part_notes.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/widget/category_display.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/part_image_widget.dart";
|
||||
import "package:inventree/widget/stock_detail.dart";
|
||||
|
||||
import 'location_display.dart';
|
||||
import "pcakage:inventree/widget/location_display.dart";
|
||||
|
||||
|
||||
class PartDetailWidget extends StatefulWidget {
|
||||
|
||||
PartDetailWidget(this.part, {Key? key}) : super(key: key);
|
||||
const PartDetailWidget(this.part, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreePart part;
|
||||
|
||||
@ -46,7 +46,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'view')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "view")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.globe),
|
||||
@ -55,7 +55,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "change")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.edit),
|
||||
@ -89,9 +89,9 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
await part.getTestTemplates();
|
||||
}
|
||||
|
||||
void _toggleStar() async {
|
||||
Future <void> _toggleStar() async {
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'view')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "view")) {
|
||||
await part.update(values: {"starred": "${!part.starred}"});
|
||||
refresh();
|
||||
}
|
||||
@ -327,7 +327,8 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
}
|
||||
|
||||
// TODO - Add request tests?
|
||||
if (false && part.isTrackable) {
|
||||
/*
|
||||
if (part.isTrackable) {
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().testsRequired),
|
||||
leading: FaIcon(FontAwesomeIcons.tasks),
|
||||
@ -336,6 +337,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// Notes field
|
||||
tiles.add(
|
||||
@ -453,7 +455,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
if (false && !part.isActive && InvenTreeAPI().checkPermission('part', 'delete')) {
|
||||
if (false && !part.isActive && InvenTreeAPI().checkPermission("part", "delete")) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().deletePart),
|
||||
|
@ -1,23 +1,21 @@
|
||||
import 'dart:io';
|
||||
import "dart:io";
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/widget/fields.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
|
||||
import '../l10.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/widget/fields.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
class PartImageWidget extends StatefulWidget {
|
||||
|
||||
PartImageWidget(this.part, {Key? key}) : super(key: key);
|
||||
const PartImageWidget(this.part, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreePart part;
|
||||
|
||||
@ -46,7 +44,7 @@ class _PartImageState extends RefreshableState<PartImageWidget> {
|
||||
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "change")) {
|
||||
|
||||
// File upload
|
||||
actions.add(
|
||||
|
@ -1,18 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter_markdown/flutter_markdown.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
|
||||
class PartNotesWidget extends StatefulWidget {
|
||||
|
||||
final InvenTreePart part;
|
||||
|
||||
PartNotesWidget(this.part, {Key? key}) : super(key: key);
|
||||
const PartNotesWidget(this.part, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_PartNotesState createState() => _PartNotesState(part);
|
||||
@ -38,7 +38,7 @@ class _PartNotesState extends RefreshableState<PartNotesWidget> {
|
||||
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('part', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("part", "change")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.edit),
|
||||
|
@ -1,19 +1,19 @@
|
||||
import 'package:inventree/l10.dart';
|
||||
import "dart:core";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'dart:core';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:inventree/widget/company_detail.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/widget/company_detail.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
|
||||
class PartSupplierWidget extends StatefulWidget {
|
||||
|
||||
PartSupplierWidget(this.part, {Key? key}) : super(key: key);
|
||||
const PartSupplierWidget(this.part, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreePart part;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
/*
|
||||
* Construct a circular progress indicator
|
||||
|
@ -1,21 +1,20 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/inventree/purchase_order.dart';
|
||||
import 'package:inventree/widget/company_detail.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
import '../l10.dart';
|
||||
import 'location_display.dart';
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/inventree/purchase_order.dart";
|
||||
import "package:inventree/widget/company_detail.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/widget/location_display.dart";
|
||||
|
||||
|
||||
class PurchaseOrderDetailWidget extends StatefulWidget {
|
||||
|
||||
PurchaseOrderDetailWidget(this.order, {Key? key}): super(key: key);
|
||||
const PurchaseOrderDetailWidget(this.order, {Key? key}): super(key: key);
|
||||
|
||||
final InvenTreePurchaseOrder order;
|
||||
|
||||
@ -72,7 +71,7 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
|
||||
|
||||
}
|
||||
|
||||
void editOrder(BuildContext context) async {
|
||||
Future <void> editOrder(BuildContext context) async {
|
||||
|
||||
order.editForm(
|
||||
context,
|
||||
|
@ -1,23 +1,22 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
import 'package:inventree/inventree/company.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/widget/paginator.dart';
|
||||
import 'package:inventree/widget/purchase_order_detail.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:infinite_scroll_pagination/infinite_scroll_pagination.dart";
|
||||
|
||||
import '../l10.dart';
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/inventree/purchase_order.dart';
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/widget/paginator.dart";
|
||||
import "package:inventree/widget/purchase_order_detail.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/inventree/purchase_order.dart";
|
||||
|
||||
/*
|
||||
* Widget class for displaying a list of Purchase Orders
|
||||
*/
|
||||
class PurchaseOrderListWidget extends StatefulWidget {
|
||||
|
||||
PurchaseOrderListWidget({this.filters = const {}, Key? key}) : super(key: key);
|
||||
const PurchaseOrderListWidget({this.filters = const {}, Key? key}) : super(key: key);
|
||||
|
||||
final Map<String, String> filters;
|
||||
|
||||
@ -100,7 +99,7 @@ class _PaginatedPurchaseOrderListState extends State<_PaginatedPurchaseOrderList
|
||||
|
||||
// Copy across provided filters
|
||||
for (String key in filters.keys) {
|
||||
params[key] = filters[key] ?? '';
|
||||
params[key] = filters[key] ?? "";
|
||||
}
|
||||
|
||||
final page = await InvenTreePurchaseOrder().listPaginated(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:inventree/widget/drawer.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import "package:inventree/widget/drawer.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter/widgets.dart";
|
||||
|
||||
|
||||
abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
|
||||
@ -32,6 +32,7 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> {
|
||||
|
||||
String getAppBarTitle(BuildContext context) { return "App Bar Title"; }
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) => onBuild(_context!));
|
||||
|
@ -1,17 +1,17 @@
|
||||
|
||||
import 'package:inventree/widget/part_detail.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import 'package:inventree/widget/stock_detail.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/widget/part_detail.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:inventree/widget/stock_detail.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
|
||||
import '../api.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
// TODO - Refactor duplicate code in this file!
|
||||
|
||||
@ -101,7 +101,7 @@ class PartSearchDelegate extends SearchDelegate<InvenTreePart?> {
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.backspace),
|
||||
onPressed: () {
|
||||
query = '';
|
||||
query = "";
|
||||
search(context);
|
||||
},
|
||||
),
|
||||
@ -119,7 +119,7 @@ class PartSearchDelegate extends SearchDelegate<InvenTreePart?> {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
this.close(context, null);
|
||||
close(context, null);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -289,7 +289,7 @@ class StockSearchDelegate extends SearchDelegate<InvenTreeStockItem?> {
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.backspace),
|
||||
onPressed: () {
|
||||
query = '';
|
||||
query = "";
|
||||
search(context);
|
||||
},
|
||||
),
|
||||
@ -307,7 +307,7 @@ class StockSearchDelegate extends SearchDelegate<InvenTreeStockItem?> {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
this.close(context, null);
|
||||
close(context, null);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -8,11 +8,11 @@
|
||||
* | Text <icon> |
|
||||
*/
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:one_context/one_context.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:one_context/one_context.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
|
||||
void showSnackIcon(String text, {IconData? icon, Function()? onAction, bool? success, String? actionText}) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/app_colors.dart";
|
||||
|
||||
class Spinner extends StatefulWidget {
|
||||
final IconData? icon;
|
||||
|
@ -1,20 +1,18 @@
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/widget/part_detail.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/widget/part_detail.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
|
||||
import '../api.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
|
||||
class StarredPartWidget extends StatefulWidget {
|
||||
|
||||
StarredPartWidget({Key? key}) : super(key: key);
|
||||
const StarredPartWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_StarredPartState createState() => _StarredPartState();
|
||||
|
@ -1,30 +1,30 @@
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/barcode.dart';
|
||||
import 'package:inventree/inventree/model.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:inventree/widget/fields.dart';
|
||||
import 'package:inventree/widget/location_display.dart';
|
||||
import 'package:inventree/widget/part_detail.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import 'package:inventree/widget/stock_item_test_results.dart';
|
||||
import 'package:inventree/widget/stock_notes.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/barcode.dart";
|
||||
import "package:inventree/inventree/model.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/widget/dialogs.dart";
|
||||
import "package:inventree/widget/fields.dart";
|
||||
import "package:inventree/widget/location_display.dart";
|
||||
import "package:inventree/widget/part_detail.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
import "package:inventree/widget/stock_item_test_results.dart";
|
||||
import "package:inventree/widget/stock_notes.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'package:inventree/api.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import "package:dropdown_search/dropdown_search.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
class StockDetailWidget extends StatefulWidget {
|
||||
|
||||
StockDetailWidget(this.item, {Key? key}) : super(key: key);
|
||||
const StockDetailWidget(this.item, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreeStockItem item;
|
||||
|
||||
@ -53,7 +53,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('stock', 'view')) {
|
||||
if (InvenTreeAPI().checkPermission("stock", "view")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.globe),
|
||||
@ -62,7 +62,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
if (InvenTreeAPI().checkPermission('stock', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("stock", "change")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.edit),
|
||||
@ -99,13 +99,13 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
await item.reload();
|
||||
|
||||
// Request part information
|
||||
part = await InvenTreePart().get(item.partId) as InvenTreePart;
|
||||
part = await InvenTreePart().get(item.partId) as InvenTreePart?;
|
||||
|
||||
// Request test results...
|
||||
await item.getTestResults();
|
||||
}
|
||||
|
||||
void _editStockItem(BuildContext context) async {
|
||||
Future <void> _editStockItem(BuildContext context) async {
|
||||
|
||||
var fields = InvenTreeStockItem().formFields();
|
||||
|
||||
@ -125,7 +125,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
|
||||
}
|
||||
|
||||
void _addStock() async {
|
||||
Future <void> _addStock() async {
|
||||
|
||||
double quantity = double.parse(_quantityController.text);
|
||||
_quantityController.clear();
|
||||
@ -138,7 +138,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
refresh();
|
||||
}
|
||||
|
||||
void _addStockDialog() async {
|
||||
Future <void> _addStockDialog() async {
|
||||
|
||||
_quantityController.clear();
|
||||
_notesController.clear();
|
||||
@ -171,7 +171,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
void _removeStock() async {
|
||||
Future <void> _removeStock() async {
|
||||
|
||||
double quantity = double.parse(_quantityController.text);
|
||||
_quantityController.clear();
|
||||
@ -211,7 +211,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
void _countStock() async {
|
||||
Future <void> _countStock() async {
|
||||
|
||||
double quantity = double.parse(_quantityController.text);
|
||||
_quantityController.clear();
|
||||
@ -223,7 +223,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
refresh();
|
||||
}
|
||||
|
||||
void _countStockDialog() async {
|
||||
Future <void> _countStockDialog() async {
|
||||
|
||||
_quantityController.text = item.quantity.toString();
|
||||
_notesController.clear();
|
||||
@ -251,9 +251,9 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
}
|
||||
|
||||
|
||||
void _unassignBarcode(BuildContext context) async {
|
||||
Future<void> _unassignBarcode(BuildContext context) async {
|
||||
|
||||
final bool result = await item.update(values: {'uid': ''});
|
||||
final bool result = await item.update(values: {"uid": ""});
|
||||
|
||||
if (result) {
|
||||
showSnackIcon(
|
||||
@ -271,7 +271,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
}
|
||||
|
||||
|
||||
void _transferStock(int locationId) async {
|
||||
Future <void> _transferStock(int locationId) async {
|
||||
|
||||
double quantity = double.tryParse(_quantityController.text) ?? item.quantity;
|
||||
String notes = _notesController.text;
|
||||
@ -288,7 +288,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
void _transferStockDialog(BuildContext context) async {
|
||||
Future <void> _transferStockDialog(BuildContext context) async {
|
||||
|
||||
int? location_pk;
|
||||
|
||||
@ -349,13 +349,13 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
hint: L10().searchLocation,
|
||||
onChanged: null,
|
||||
itemAsString: (dynamic location) {
|
||||
return (location['pathstring'] ?? '') as String;
|
||||
return (location["pathstring"] ?? "") as String;
|
||||
},
|
||||
onSaved: (dynamic location) {
|
||||
if (location == null) {
|
||||
location_pk = null;
|
||||
} else {
|
||||
location_pk = location['pk'] as int;
|
||||
location_pk = location["pk"] as int;
|
||||
}
|
||||
},
|
||||
isFilteredOnline: true,
|
||||
@ -503,7 +503,8 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
|
||||
// Supplier part?
|
||||
// TODO: Display supplier part info page?
|
||||
if (false && item.supplierPartId > 0) {
|
||||
/*
|
||||
if (item.supplierPartId > 0) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text("${item.supplierName}"),
|
||||
@ -514,6 +515,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
if (item.link.isNotEmpty) {
|
||||
tiles.add(
|
||||
@ -559,7 +561,8 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
// TODO - Is this stock item linked to a PurchaseOrder?
|
||||
|
||||
// TODO - Re-enable stock item history display
|
||||
if (false && item.trackingItemCount > 0) {
|
||||
/*
|
||||
if (item.trackingItemCount > 0) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().history),
|
||||
@ -574,6 +577,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// Notes field
|
||||
tiles.add(
|
||||
@ -600,7 +604,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
tiles.add(headerTile());
|
||||
|
||||
// First check that the user has the required permissions to adjust stock
|
||||
if (!InvenTreeAPI().checkPermission('stock', 'change')) {
|
||||
if (!InvenTreeAPI().checkPermission("stock", "change")) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().permissionRequired),
|
||||
@ -710,12 +714,11 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
items: <BottomNavigationBarItem> [
|
||||
BottomNavigationBarItem(
|
||||
icon: FaIcon(FontAwesomeIcons.infoCircle),
|
||||
title: Text(L10().details),
|
||||
label: L10().details,
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: FaIcon(FontAwesomeIcons.wrench),
|
||||
title: Text(L10().actions),
|
||||
),
|
||||
label: L10().actions, ),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -1,27 +1,21 @@
|
||||
import 'package:inventree/api_form.dart';
|
||||
import 'package:inventree/app_colors.dart';
|
||||
import 'package:inventree/inventree/part.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/inventree/model.dart';
|
||||
import 'package:inventree/api.dart';
|
||||
import 'package:inventree/widget/dialogs.dart';
|
||||
import 'package:inventree/widget/fields.dart';
|
||||
import 'package:inventree/widget/progress.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/inventree/model.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/widget/progress.dart";
|
||||
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
|
||||
|
||||
class StockItemTestResultsWidget extends StatefulWidget {
|
||||
|
||||
StockItemTestResultsWidget(this.item, {Key? key}) : super(key: key);
|
||||
const StockItemTestResultsWidget(this.item, {Key? key}) : super(key: key);
|
||||
|
||||
final InvenTreeStockItem item;
|
||||
|
||||
@ -32,8 +26,6 @@ class StockItemTestResultsWidget extends StatefulWidget {
|
||||
|
||||
class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestResultsWidget> {
|
||||
|
||||
final _addResultKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
String getAppBarTitle(BuildContext context) => L10().testResults;
|
||||
|
||||
@ -59,7 +51,7 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
|
||||
_StockItemTestResultDisplayState(this.item);
|
||||
|
||||
void addTestResult(BuildContext context, {String name = '', bool nameIsEditable = true, bool result = false, String value = '', bool valueRequired = false, bool attachmentRequired = false}) async {
|
||||
Future <void> addTestResult(BuildContext context, {String name = "", bool nameIsEditable = true, bool result = false, String value = "", bool valueRequired = false, bool attachmentRequired = false}) async {
|
||||
|
||||
InvenTreeStockItemTestResult().createForm(
|
||||
context,
|
||||
@ -165,7 +157,6 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
String _test = "";
|
||||
bool _result = false;
|
||||
String _value = "";
|
||||
String _notes = "";
|
||||
|
||||
FaIcon _icon = FaIcon(FontAwesomeIcons.questionCircle, color: COLOR_BLUE);
|
||||
bool _valueRequired = false;
|
||||
@ -175,8 +166,7 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
_result = item.passFailStatus();
|
||||
_test = item.testName;
|
||||
_required = item.required;
|
||||
_value = item.latestResult()?.value ?? '';
|
||||
_notes = item.latestResult()?.notes ?? '';
|
||||
_value = item.latestResult()?.value ?? "";
|
||||
_valueRequired = item.requiresValue;
|
||||
_attachmentRequired = item.requiresAttachment;
|
||||
} else if (item is InvenTreeStockItemTestResult) {
|
||||
@ -184,7 +174,6 @@ class _StockItemTestResultDisplayState extends RefreshableState<StockItemTestRes
|
||||
_test = item.testName;
|
||||
_required = false;
|
||||
_value = item.value;
|
||||
_notes = item.notes;
|
||||
}
|
||||
|
||||
if (_result == true) {
|
||||
|
@ -1,20 +1,20 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/inventree/stock.dart';
|
||||
import 'package:inventree/widget/refreshable_state.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:inventree/l10.dart';
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
import "package:inventree/widget/refreshable_state.dart";
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter_markdown/flutter_markdown.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
import '../api.dart';
|
||||
import "package:inventree/api.dart";
|
||||
|
||||
|
||||
class StockNotesWidget extends StatefulWidget {
|
||||
|
||||
final InvenTreeStockItem item;
|
||||
|
||||
StockNotesWidget(this.item, {Key? key}) : super(key: key);
|
||||
const StockNotesWidget(this.item, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_StockNotesState createState() => _StockNotesState(item);
|
||||
@ -39,7 +39,7 @@ class _StockNotesState extends RefreshableState<StockNotesWidget> {
|
||||
List<Widget> getAppBarActions(BuildContext context) {
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (InvenTreeAPI().checkPermission('stock', 'change')) {
|
||||
if (InvenTreeAPI().checkPermission("stock", "change")) {
|
||||
actions.add(
|
||||
IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.edit),
|
||||
|
@ -1,12 +1,10 @@
|
||||
import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/widget/snacks.dart";
|
||||
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:inventree/inventree/sentry.dart';
|
||||
import 'package:inventree/widget/snacks.dart';
|
||||
|
||||
import '../l10.dart';
|
||||
import "package:inventree/l10.dart";
|
||||
|
||||
class SubmitFeedbackWidget extends StatefulWidget {
|
||||
|
||||
@ -18,7 +16,7 @@ class SubmitFeedbackWidget extends StatefulWidget {
|
||||
|
||||
class _SubmitFeedbackState extends State<SubmitFeedbackWidget> {
|
||||
|
||||
final _formkey = new GlobalKey<FormState>();
|
||||
final _formkey = GlobalKey<FormState>();
|
||||
|
||||
String message = "";
|
||||
|
||||
@ -61,8 +59,6 @@ class _SubmitFeedbackState extends State<SubmitFeedbackWidget> {
|
||||
key: _formkey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextFormField(
|
||||
|
45
pubspec.yaml
45
pubspec.yaml
@ -13,41 +13,42 @@ environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
|
||||
audioplayers: ^0.20.1 # Play audio files
|
||||
cached_network_image: ^3.1.0 # Download and cache remote images
|
||||
camera: # Camera
|
||||
cupertino_icons: ^1.0.3
|
||||
date_field: ^2.1.2 # Date / time picker
|
||||
device_info_plus: ^2.1.0 # Information about the device
|
||||
dropdown_search: 0.6.3 # Dropdown autocomplete form fields
|
||||
file_picker: ^4.0.0 # Select files from the device
|
||||
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
|
||||
intl: ^0.17.0
|
||||
|
||||
cupertino_icons: ^1.0.3
|
||||
http: ^0.13.0
|
||||
cached_network_image: ^3.1.0 # Download and cache remote images
|
||||
qr_code_scanner: ^0.5.2 # Barcode scanning
|
||||
package_info_plus: ^1.0.4 # App information introspection
|
||||
device_info_plus: ^2.1.0 # Information about the device
|
||||
font_awesome_flutter: ^9.1.0 # FontAwesome icon set
|
||||
sentry_flutter: 5.0.0 # Error reporting
|
||||
image_picker: ^0.8.3 # Select or take photos
|
||||
file_picker: ^4.0.0 # Select files from the device
|
||||
date_field: ^2.1.2 # Date / time picker
|
||||
url_launcher: 6.0.9 # Open link in system browser
|
||||
open_file: 3.2.1 # Open local files
|
||||
flutter_markdown: ^0.6.2 # Rendering markdown
|
||||
camera: # Camera
|
||||
path_provider: 2.0.2 # Local file storage
|
||||
sembast: ^3.1.0+2 # NoSQL data storage
|
||||
one_context: ^1.1.0 # Dialogs without requiring context
|
||||
font_awesome_flutter: ^9.1.0 # FontAwesome icon set
|
||||
http: ^0.13.0
|
||||
image_picker: ^0.8.3 # Select or take photos
|
||||
infinite_scroll_pagination: ^3.1.0 # Let the server do all the work!
|
||||
audioplayers: ^0.20.1 # Play audio files
|
||||
dropdown_search: 0.6.3 # Dropdown autocomplete form fields
|
||||
intl: ^0.17.0
|
||||
one_context: ^1.1.0 # Dialogs without requiring context
|
||||
open_file: 3.2.1 # Open local files
|
||||
package_info_plus: ^1.0.4 # App information introspection
|
||||
path:
|
||||
path_provider: 2.0.2 # Local file storage
|
||||
qr_code_scanner: ^0.5.2 # Barcode scanning
|
||||
sembast: ^3.1.0+2 # NoSQL data storage
|
||||
sentry_flutter: 5.0.0 # Error reporting
|
||||
url_launcher: 6.0.9 # Open link in system browser
|
||||
|
||||
dev_dependencies:
|
||||
flutter_launcher_icons:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_launcher_icons:
|
||||
lint: ^1.0.0
|
||||
|
||||
flutter_icons:
|
||||
|
@ -5,9 +5,9 @@
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
testWidgets("Counter increments smoke test", (WidgetTester tester) async {
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user