2
0
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:
Oliver 2021-09-28 20:24:55 +10:00
parent c1152ee286
commit ad0cc36540
50 changed files with 904 additions and 907 deletions

View File

@ -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

View File

@ -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 "";
}

View File

@ -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?

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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
);

View File

@ -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();

View File

@ -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();

View File

@ -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;
}

View File

@ -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();

View File

@ -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()

View File

@ -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
],
);

View File

@ -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.
*/

View File

@ -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");

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -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 {

View File

@ -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) {

View File

@ -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,

View File

@ -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 {

View File

@ -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 {

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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}";

View File

@ -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) {

View File

@ -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(

View File

@ -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),

View File

@ -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(

View File

@ -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),

View File

@ -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;

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import "package:flutter/material.dart";
/*
* Construct a circular progress indicator

View File

@ -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,

View File

@ -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(

View File

@ -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!));

View File

@ -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);
}
);
}

View File

@ -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}) {

View File

@ -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;

View File

@ -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();

View File

@ -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, ),
]
);
}

View File

@ -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) {

View File

@ -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),

View File

@ -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(

View File

@ -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:

View File

@ -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 {
});
}