mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +00:00
Project code support (#336)
* Determine if project codes are supported * Add helpers for boolean functions * Adds helper methods for generic "model" class - Will allow us to do some good refactoring * Refactor the refactor * Add debug support and getMap function * Major refactoring for model data accessors * Handle null values * Add sentry reporting if key is used incorrectly * Fix typo * Refactor createFromJson function * Add model for ProjectCode * Display and edit project code for purchase orders
This commit is contained in:
parent
95573a2784
commit
e23a8b4d5e
@ -1,6 +1,7 @@
|
||||
### 0.11.6 - April 2023
|
||||
---
|
||||
|
||||
- Add support for Project Codes
|
||||
- Fix action button colors
|
||||
- Added Norwegian translations
|
||||
- Fix serial number field when creating stock item
|
||||
|
15
lib/api.dart
15
lib/api.dart
@ -300,6 +300,9 @@ class InvenTreeAPI {
|
||||
// Order barcodes API v107 or newer
|
||||
bool get supportsOrderBarcodes => isConnected() && apiVersion >= 107;
|
||||
|
||||
// Project codes require v109 or newer
|
||||
bool get supportsProjectCodes => isConnected() && apiVersion >= 109;
|
||||
|
||||
// Are plugins enabled on the server?
|
||||
bool _pluginsEnabled = false;
|
||||
|
||||
@ -1362,6 +1365,12 @@ class InvenTreeAPI {
|
||||
}
|
||||
}
|
||||
|
||||
// Return a boolean global setting value
|
||||
Future<bool> getGlobalBooleanSetting(String key) async {
|
||||
String value = await getGlobalSetting(key);
|
||||
return value.toLowerCase() == "true";
|
||||
}
|
||||
|
||||
Future<String> getUserSetting(String key) async {
|
||||
if (!supportsSettings) return "";
|
||||
|
||||
@ -1382,6 +1391,12 @@ class InvenTreeAPI {
|
||||
}
|
||||
}
|
||||
|
||||
// Return a boolean user setting value
|
||||
Future<bool> getUserBooleanSetting(String key) async {
|
||||
String value = await getUserSetting(key);
|
||||
return value.toLowerCase() == "true";
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a request to the server to locate / identify either a StockItem or StockLocation
|
||||
*/
|
||||
|
@ -15,6 +15,7 @@ import "package:inventree/l10.dart";
|
||||
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/inventree/part.dart";
|
||||
import "package:inventree/inventree/project_code.dart";
|
||||
import "package:inventree/inventree/sentry.dart";
|
||||
import "package:inventree/inventree/stock.dart";
|
||||
|
||||
@ -667,6 +668,13 @@ class APIFormField {
|
||||
height: 40
|
||||
)
|
||||
);
|
||||
case "projectcode":
|
||||
var project_code = InvenTreeProjectCode.fromJson(data);
|
||||
return ListTile(
|
||||
title: Text(project_code.code),
|
||||
subtitle: Text(project_code.description),
|
||||
leading: FaIcon(FontAwesomeIcons.list)
|
||||
);
|
||||
default:
|
||||
return ListTile(
|
||||
title: Text(
|
||||
|
@ -12,9 +12,7 @@ class InvenTreeBomItem extends InvenTreeModel {
|
||||
InvenTreeBomItem.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreeBomItem.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeBomItem.fromJson(json);
|
||||
|
||||
@override
|
||||
String get URL => "bom/";
|
||||
@ -36,13 +34,13 @@ class InvenTreeBomItem extends InvenTreeModel {
|
||||
}
|
||||
|
||||
// Extract the 'reference' value associated with this BomItem
|
||||
String get reference => (jsondata["reference"] ?? "") as String;
|
||||
String get reference => getString("reference");
|
||||
|
||||
// Extract the 'quantity' value associated with this BomItem
|
||||
double get quantity => double.tryParse(jsondata["quantity"].toString()) ?? 0;
|
||||
double get quantity => getDouble("quantity");
|
||||
|
||||
// Extract the ID of the related part
|
||||
int get partId => int.tryParse(jsondata["part"].toString()) ?? -1;
|
||||
int get partId => getInt("part");
|
||||
|
||||
// Return a Part instance for the referenced part
|
||||
InvenTreePart? get part {
|
||||
@ -69,5 +67,5 @@ class InvenTreeBomItem extends InvenTreeModel {
|
||||
}
|
||||
|
||||
// Extract the ID of the related sub-part
|
||||
int get subPartId => int.tryParse(jsondata["sub_part"].toString()) ?? -1;
|
||||
int get subPartId => getInt("sub_part");
|
||||
}
|
@ -38,21 +38,21 @@ class InvenTreeCompany extends InvenTreeModel {
|
||||
|
||||
String get thumbnail => (jsondata["thumbnail"] ?? jsondata["image"] ?? InvenTreeAPI.staticThumb) as String;
|
||||
|
||||
String get website => (jsondata["website"] ?? "") as String;
|
||||
String get website => getString("website");
|
||||
|
||||
String get phone => (jsondata["phone"] ?? "") as String;
|
||||
String get phone => getString("phone");
|
||||
|
||||
String get email => (jsondata["email"] ?? "") as String;
|
||||
String get email => getString("email");
|
||||
|
||||
bool get isSupplier => (jsondata["is_supplier"] ?? false) as bool;
|
||||
bool get isSupplier => getBool("is_supplier");
|
||||
|
||||
bool get isManufacturer => (jsondata["is_manufacturer"] ?? false) as bool;
|
||||
bool get isManufacturer => getBool("is_manufacturer");
|
||||
|
||||
bool get isCustomer => (jsondata["is_customer"] ?? false) as bool;
|
||||
bool get isCustomer => getBool("is_customer");
|
||||
|
||||
int get partSuppliedCount => (jsondata["parts_supplied"] ?? 0) as int;
|
||||
int get partSuppliedCount => getInt("part_supplied");
|
||||
|
||||
int get partManufacturedCount => (jsondata["parts_manufactured"] ?? 0) as int;
|
||||
int get partManufacturedCount => getInt("parts_manufactured");
|
||||
|
||||
// Request a list of purchase orders against this company
|
||||
Future<List<InvenTreePurchaseOrder>> getPurchaseOrders({bool? outstanding}) async {
|
||||
@ -81,11 +81,7 @@ class InvenTreeCompany extends InvenTreeModel {
|
||||
}
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
var company = InvenTreeCompany.fromJson(json);
|
||||
|
||||
return company;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeCompany.fromJson(json);
|
||||
}
|
||||
|
||||
|
||||
@ -154,40 +150,36 @@ class InvenTreeSupplierPart extends InvenTreeModel {
|
||||
return _filters();
|
||||
}
|
||||
|
||||
int get manufacturerId => (jsondata["manufacturer_detail"]["pk"] ?? -1) as int;
|
||||
int get manufacturerId => getInt("pk", subKey: "manufacturer_detail");
|
||||
|
||||
String get manufacturerName => (jsondata["manufacturer_detail"]?["name"] ?? "") as String;
|
||||
String get manufacturerName => getString("name", subKey: "manufacturer_detail");
|
||||
|
||||
String get MPN => (jsondata["manufacturer_part_detail"]?["MPN"] ?? "") as String;
|
||||
String get MPN => getString("MPN", subKey: "manufacturer_part_detail");
|
||||
|
||||
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 => getInt("manufacturer_part");
|
||||
|
||||
int get supplierId => (jsondata["supplier"] ?? -1) as int;
|
||||
int get supplierId => getInt("supplier");
|
||||
|
||||
String get supplierName => (jsondata["supplier_detail"]?["name"] ?? "") as String;
|
||||
String get supplierName => getString("name", subKey: "supplier_detail");
|
||||
|
||||
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 => getString("SKU");
|
||||
|
||||
int get partId => (jsondata["part"] ?? -1) as int;
|
||||
int get partId => getInt("part");
|
||||
|
||||
String get partImage => (jsondata["part_detail"]?["thumbnail"] ?? InvenTreeAPI.staticThumb) as String;
|
||||
|
||||
String get partName => (jsondata["part_detail"]?["full_name"] ?? "") as String;
|
||||
String get partName => getString("full_name", subKey: "part_detail");
|
||||
|
||||
String get partDescription => (jsondata["part_detail"]?["description"] ?? "") as String;
|
||||
String get partDescription => getString("description", subKey: "part_detail");
|
||||
|
||||
String get note => (jsondata["note"] ?? "") as String;
|
||||
String get note => getString("note");
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
var part = InvenTreeSupplierPart.fromJson(json);
|
||||
|
||||
return part;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeSupplierPart.fromJson(json);
|
||||
}
|
||||
|
||||
|
||||
@ -207,16 +199,12 @@ class InvenTreeManufacturerPart extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
int get partId => (jsondata["part"] ?? -1) as int;
|
||||
int get partId => getInt("part");
|
||||
|
||||
int get manufacturerId => (jsondata["manufacturer"] ?? -1) as int;
|
||||
int get manufacturerId => getInt("manufacturer");
|
||||
|
||||
String get MPN => (jsondata["MPN"] ?? "") as String;
|
||||
String get MPN => getString("MPN");
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
var part = InvenTreeManufacturerPart.fromJson(json);
|
||||
|
||||
return part;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeManufacturerPart.fromJson(json);
|
||||
}
|
||||
|
@ -63,6 +63,96 @@ class InvenTreeModel {
|
||||
// Note: If the WEB_URL is the same (except for /api/) as URL then just leave blank
|
||||
String get WEB_URL => "";
|
||||
|
||||
// Helper function to set a value in the JSON data
|
||||
void setValue(String key, dynamic value) {
|
||||
jsondata[key] = value;
|
||||
}
|
||||
|
||||
// return a dynamic value from the JSON data
|
||||
// optionally we can specifiy a "subKey" to get a value from a sub-dictionary
|
||||
dynamic getValue(String key, {dynamic backup, String subKey = ""}) {
|
||||
Map<String, dynamic> data = jsondata;
|
||||
|
||||
// If a subKey is specified, we need to dig deeper into the JSON data
|
||||
if (subKey.isNotEmpty) {
|
||||
|
||||
if (!data.containsKey(subKey)) {
|
||||
debug("JSON data does not contain subKey '$subKey' for key '$key'");
|
||||
return backup;
|
||||
}
|
||||
|
||||
dynamic sub_data = data[subKey];
|
||||
|
||||
if (sub_data is Map<String, dynamic>) {
|
||||
data = (data[subKey] ?? {}) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (data.containsKey(key)) {
|
||||
return data[key];
|
||||
} else {
|
||||
debug("JSON data does not contain key '$key' (subKey '${subKey}')");
|
||||
return backup;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to get sub-map from JSON data
|
||||
Map<String, dynamic> getMap(String key, {Map<String, dynamic> backup = const {}, String subKey = ""}) {
|
||||
dynamic value = getValue(key, backup: backup, subKey: subKey);
|
||||
|
||||
if (value == null) {
|
||||
return backup;
|
||||
}
|
||||
|
||||
return value as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
// Helper function to get string value from JSON data
|
||||
String getString(String key, {String backup = "", String subKey = ""}) {
|
||||
dynamic value = getValue(key, backup: backup, subKey: subKey);
|
||||
|
||||
if (value == null) {
|
||||
return backup;
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
// Helper function to get integer value from JSON data
|
||||
int getInt(String key, {int backup = -1, String subKey = ""}) {
|
||||
dynamic value = getValue(key, backup: backup, subKey: subKey);
|
||||
|
||||
if (value == null) {
|
||||
return backup;
|
||||
}
|
||||
|
||||
return int.tryParse(value.toString()) ?? backup;
|
||||
}
|
||||
|
||||
// Helper function to get double value from JSON data
|
||||
double getDouble(String key, {double backup = 0.0, String subKey = ""}) {
|
||||
dynamic value = getValue(key, backup: backup, subKey: subKey);
|
||||
|
||||
if (value == null) {
|
||||
return backup;
|
||||
}
|
||||
|
||||
return double.tryParse(value.toString()) ?? backup;
|
||||
}
|
||||
|
||||
// Helper function to get boolean value from json data
|
||||
bool getBool(String key, {bool backup = false, String subKey = ""}) {
|
||||
dynamic value = getValue(key, backup: backup, subKey: subKey);
|
||||
|
||||
if (value == null) {
|
||||
return backup;
|
||||
}
|
||||
|
||||
return value.toString().toLowerCase() == "true";
|
||||
}
|
||||
|
||||
// Return the InvenTree web server URL for this object
|
||||
String get webUrl {
|
||||
|
||||
if (api.isConnected()) {
|
||||
@ -191,16 +281,16 @@ class InvenTreeModel {
|
||||
// Accessor for the API
|
||||
InvenTreeAPI get api => InvenTreeAPI();
|
||||
|
||||
int get pk => (jsondata["pk"] ?? -1) as int;
|
||||
int get pk => getInt("pk");
|
||||
|
||||
// Some common accessors
|
||||
String get name => (jsondata["name"] ?? "") as String;
|
||||
String get name => getString("name");
|
||||
|
||||
String get description => (jsondata["description"] ?? "") as String;
|
||||
String get description => getString("description");
|
||||
|
||||
String get notes => (jsondata["notes"] ?? "") as String;
|
||||
String get notes => getString("notes");
|
||||
|
||||
int get parentId => (jsondata["parent"] ?? -1) as int;
|
||||
int get parentId => getInt("parent");
|
||||
|
||||
// Legacy API provided external link as "URL", while newer API uses "link"
|
||||
String get link => (jsondata["link"] ?? jsondata["URL"] ?? "") as String;
|
||||
@ -297,15 +387,10 @@ class InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get keywords => (jsondata["keywords"] ?? "") as String;
|
||||
String get keywords => getString("keywords");
|
||||
|
||||
// Create a new object from JSON data (not a constructor!)
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
|
||||
var obj = InvenTreeModel.fromJson(json);
|
||||
|
||||
return obj;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeModel.fromJson(json);
|
||||
|
||||
// Return the API detail endpoint for this Model object
|
||||
String get url => "${URL}/${pk}/".replaceAll("//", "/");
|
||||
@ -746,9 +831,7 @@ class InvenTreePlugin extends InvenTreeModel {
|
||||
InvenTreePlugin.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreePlugin.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePlugin.fromJson(json);
|
||||
|
||||
@override
|
||||
String get URL {
|
||||
@ -765,9 +848,9 @@ class InvenTreePlugin extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get key => (jsondata["key"] ?? "") as String;
|
||||
String get key => getString("key");
|
||||
|
||||
bool get active => (jsondata["active"] ?? false) as bool;
|
||||
bool get active => getBool("active");
|
||||
|
||||
// Return the metadata struct for this plugin
|
||||
Map<String, dynamic> get _meta => (jsondata["meta"] ?? {}) as Map<String, dynamic>;
|
||||
@ -803,11 +886,11 @@ class InvenTreeGlobalSetting extends InvenTreeModel {
|
||||
@override
|
||||
String get URL => "settings/global/";
|
||||
|
||||
String get key => (jsondata["key"] ?? "") as String;
|
||||
String get key => getString("key");
|
||||
|
||||
String get value => (jsondata["value"] ?? "") as String;
|
||||
String get value => getString("value");
|
||||
|
||||
String get type => (jsondata["type"] ?? "") as String;
|
||||
String get type => getString("type");
|
||||
|
||||
}
|
||||
|
||||
@ -836,7 +919,7 @@ class InvenTreeAttachment extends InvenTreeModel {
|
||||
// Override this reference field for any subclasses
|
||||
String get REFERENCE_FIELD => "";
|
||||
|
||||
String get attachment => (jsondata["attachment"] ?? "") as String;
|
||||
String get attachment => getString("attachment");
|
||||
|
||||
// Return the filename of the attachment
|
||||
String get filename {
|
||||
@ -874,7 +957,7 @@ class InvenTreeAttachment extends InvenTreeModel {
|
||||
return FontAwesomeIcons.fileLines;
|
||||
}
|
||||
|
||||
String get comment => (jsondata["comment"] ?? "") as String;
|
||||
String get comment => getString("comment");
|
||||
|
||||
DateTime? get uploadDate {
|
||||
if (jsondata.containsKey("upload_date")) {
|
||||
|
@ -27,7 +27,7 @@ class InvenTreeNotification extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
String get message => (jsondata["message"] ?? "") as String;
|
||||
String get message => getString("message");
|
||||
|
||||
DateTime? get creationDate {
|
||||
if (jsondata.containsKey("creation")) {
|
||||
|
@ -43,7 +43,7 @@ class InvenTreePartCategory extends InvenTreeModel {
|
||||
return fields;
|
||||
}
|
||||
|
||||
String get pathstring => (jsondata["pathstring"] ?? "") as String;
|
||||
String get pathstring => getString("pathstring");
|
||||
|
||||
String get parentPathString {
|
||||
|
||||
@ -67,11 +67,7 @@ class InvenTreePartCategory extends InvenTreeModel {
|
||||
int get partcount => (jsondata["part_count"] ?? jsondata["parts"] ?? 0) as int;
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
var cat = InvenTreePartCategory.fromJson(json);
|
||||
|
||||
return cat;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePartCategory.fromJson(json);
|
||||
}
|
||||
|
||||
|
||||
@ -87,22 +83,18 @@ class InvenTreePartTestTemplate extends InvenTreeModel {
|
||||
@override
|
||||
String get URL => "part/test-template/";
|
||||
|
||||
String get key => (jsondata["key"] ?? "") as String;
|
||||
String get key => getString("key");
|
||||
|
||||
String get testName => (jsondata["test_name"] ?? "") as String;
|
||||
String get testName => getString("test_name");
|
||||
|
||||
bool get required => (jsondata["required"] ?? false) as bool;
|
||||
bool get required => getBool("required");
|
||||
|
||||
bool get requiresValue => (jsondata["requires_value"] ?? false) as bool;
|
||||
bool get requiresValue => getBool("requires_value");
|
||||
|
||||
bool get requiresAttachment => (jsondata["requires_attachment"] ?? false) as bool;
|
||||
bool get requiresAttachment => getBool("requires_attachment");
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
var template = InvenTreePartTestTemplate.fromJson(json);
|
||||
|
||||
return template;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePartTestTemplate.fromJson(json);
|
||||
|
||||
bool passFailStatus() {
|
||||
|
||||
@ -142,9 +134,7 @@ class InvenTreePartParameter extends InvenTreeModel {
|
||||
String get URL => "part/parameter/";
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreePartParameter.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePartParameter.fromJson(json);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> formFields() {
|
||||
@ -152,12 +142,12 @@ class InvenTreePartParameter extends InvenTreeModel {
|
||||
}
|
||||
|
||||
@override
|
||||
String get name => (jsondata["template_detail"]?["name"] ?? "") as String;
|
||||
String get name => getString("name", subKey: "template_detail");
|
||||
|
||||
@override
|
||||
String get description => (jsondata["template_detail"]?["description"] ?? "") as String;
|
||||
String get description => getString("description", subKey: "template_detail");
|
||||
|
||||
String get value => jsondata["data"] as String;
|
||||
String get value => getString("data");
|
||||
|
||||
String get valueString {
|
||||
String v = value;
|
||||
@ -170,7 +160,7 @@ class InvenTreePartParameter extends InvenTreeModel {
|
||||
return v;
|
||||
}
|
||||
|
||||
String get units => (jsondata["template_detail"]?["units"] ?? "") as String;
|
||||
String get units => getString("units", subKey: "template_detail");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -254,7 +244,7 @@ class InvenTreePart extends InvenTreeModel {
|
||||
});
|
||||
}
|
||||
|
||||
int get supplierCount => (jsondata["suppliers"] ?? 0) as int;
|
||||
int get supplierCount => getInt("suppliers", backup: 0);
|
||||
|
||||
// Request supplier parts for this part
|
||||
Future<List<InvenTreeSupplierPart>> getSupplierParts() async {
|
||||
@ -301,23 +291,13 @@ class InvenTreePart extends InvenTreeModel {
|
||||
|
||||
int? get defaultLocation => jsondata["default_location"] as int?;
|
||||
|
||||
// Get the number of stock on order for this Part
|
||||
double get onOrder => double.tryParse(jsondata["ordering"].toString()) ?? 0;
|
||||
double get onOrder => getDouble("ordering");
|
||||
|
||||
String get onOrderString {
|
||||
String get onOrderString => simpleNumberString(onOrder);
|
||||
|
||||
return simpleNumberString(onOrder);
|
||||
}
|
||||
double get inStock => getDouble("in_stock");
|
||||
|
||||
// Get the stock count for this Part
|
||||
double get inStock => double.tryParse(jsondata["in_stock"].toString()) ?? 0;
|
||||
|
||||
String get inStockString {
|
||||
|
||||
String q = simpleNumberString(inStock);
|
||||
|
||||
return q;
|
||||
}
|
||||
String get inStockString => simpleNumberString(inStock);
|
||||
|
||||
// Get the 'available stock' for this Part
|
||||
double get unallocatedStock {
|
||||
@ -330,11 +310,7 @@ class InvenTreePart extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get unallocatedStockString {
|
||||
String q = simpleNumberString(unallocatedStock);
|
||||
|
||||
return q;
|
||||
}
|
||||
String get unallocatedStockString => simpleNumberString(unallocatedStock);
|
||||
|
||||
String stockString({bool includeUnits = true}) {
|
||||
String q = unallocatedStockString;
|
||||
@ -350,39 +326,39 @@ class InvenTreePart extends InvenTreeModel {
|
||||
return q;
|
||||
}
|
||||
|
||||
String get units => (jsondata["units"] ?? "") as String;
|
||||
String get units => getString("units");
|
||||
|
||||
// Get the ID of the Part that this part is a variant of (or null)
|
||||
int? get variantOf => jsondata["variant_of"] as int?;
|
||||
|
||||
// Get the number of units being build for this Part
|
||||
double get building => double.tryParse(jsondata["building"].toString()) ?? 0;
|
||||
double get building => getDouble("building");
|
||||
|
||||
// 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.containsKey("used_in") ? getInt("used_in", backup: 0) : 0;
|
||||
|
||||
bool get isAssembly => (jsondata["assembly"] ?? false) as bool;
|
||||
bool get isAssembly => getBool("assembly");
|
||||
|
||||
bool get isComponent => (jsondata["component"] ?? false) as bool;
|
||||
bool get isComponent => getBool("component");
|
||||
|
||||
bool get isPurchaseable => (jsondata["purchaseable"] ?? false) as bool;
|
||||
bool get isPurchaseable => getBool("purchaseable");
|
||||
|
||||
bool get isSalable => (jsondata["salable"] ?? false) as bool;
|
||||
bool get isSalable => getBool("salable");
|
||||
|
||||
bool get isActive => (jsondata["active"] ?? false) as bool;
|
||||
bool get isActive => getBool("active");
|
||||
|
||||
bool get isVirtual => (jsondata["virtual"] ?? false) as bool;
|
||||
bool get isVirtual => getBool("virtual");
|
||||
|
||||
bool get isTrackable => (jsondata["trackable"] ?? false) as bool;
|
||||
bool get isTrackable => getBool("trackable");
|
||||
|
||||
// Get the IPN (internal part number) for the Part instance
|
||||
String get IPN => (jsondata["IPN"] ?? "") as String;
|
||||
String get IPN => getString("IPN");
|
||||
|
||||
// Get the revision string for the Part instance
|
||||
String get revision => (jsondata["revision"] ?? "") as String;
|
||||
String get revision => getString("revision");
|
||||
|
||||
// Get the category ID for the Part instance (or "null" if does not exist)
|
||||
int get categoryId => (jsondata["category"] ?? -1) as int;
|
||||
int get categoryId => getInt("category");
|
||||
|
||||
// Get the category name for the Part instance
|
||||
String get categoryName {
|
||||
@ -404,15 +380,15 @@ class InvenTreePart extends InvenTreeModel {
|
||||
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 => getString("image");
|
||||
|
||||
// Get the thumbnail URL for the Part instance
|
||||
String get _thumbnail => (jsondata["thumbnail"] ?? "") as String;
|
||||
String get _thumbnail => getString("thumbnail");
|
||||
|
||||
// Return the fully-qualified name for the Part instance
|
||||
String get fullname {
|
||||
|
||||
String fn = (jsondata["full_name"] ?? "") as String;
|
||||
String fn = getString("full_name");
|
||||
|
||||
if (fn.isNotEmpty) return fn;
|
||||
|
||||
@ -456,15 +432,10 @@ class InvenTreePart extends InvenTreeModel {
|
||||
}
|
||||
|
||||
// Return the "starred" status of this part
|
||||
bool get starred => (jsondata["starred"] ?? false) as bool;
|
||||
bool get starred => getBool("starred");
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
|
||||
var part = InvenTreePart.fromJson(json);
|
||||
|
||||
return part;
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePart.fromJson(json);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -483,8 +454,6 @@ class InvenTreePartAttachment extends InvenTreeAttachment {
|
||||
String get URL => "part/attachment/";
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreePartAttachment.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePartAttachment.fromJson(json);
|
||||
|
||||
}
|
||||
|
28
lib/inventree/project_code.dart
Normal file
28
lib/inventree/project_code.dart
Normal file
@ -0,0 +1,28 @@
|
||||
import "package:inventree/inventree/model.dart";
|
||||
|
||||
|
||||
/*
|
||||
* Class representing the ProjectCode database model
|
||||
*/
|
||||
class InvenTreeProjectCode extends InvenTreeModel {
|
||||
|
||||
InvenTreeProjectCode() : super();
|
||||
|
||||
InvenTreeProjectCode.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeProjectCode.fromJson(json);
|
||||
|
||||
@override
|
||||
String get URL => "project-code/";
|
||||
|
||||
@override
|
||||
Map<String, dynamic> formFields() {
|
||||
return {
|
||||
"code": {},
|
||||
"description": {},
|
||||
};
|
||||
}
|
||||
|
||||
String get code => getString("code");
|
||||
}
|
@ -34,6 +34,7 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
},
|
||||
"supplier_reference": {},
|
||||
"description": {},
|
||||
"project_code": {},
|
||||
"target_date": {},
|
||||
"link": {},
|
||||
"responsible": {},
|
||||
@ -59,23 +60,32 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
String get issueDate => (jsondata["issue_date"] ?? "") as String;
|
||||
String get issueDate => getString("issue_date");
|
||||
|
||||
String get completeDate => (jsondata["complete_date"] ?? "") as String;
|
||||
String get completeDate => getString("complete_date");
|
||||
|
||||
String get creationDate => (jsondata["creation_date"] ?? "") as String;
|
||||
String get creationDate => getString("creation_date");
|
||||
|
||||
String get targetDate => (jsondata["target_date"] ?? "") as String;
|
||||
String get targetDate => getString("target_date");
|
||||
|
||||
int get lineItemCount => (jsondata["line_items"] ?? 0) as int;
|
||||
int get lineItemCount => getInt("line_items", backup: 0);
|
||||
|
||||
bool get overdue => (jsondata["overdue"] ?? false) as bool;
|
||||
bool get overdue => getBool("overdue");
|
||||
|
||||
String get reference => (jsondata["reference"] ?? "") as String;
|
||||
String get reference => getString("reference");
|
||||
|
||||
int get responsibleId => (jsondata["responsible"] ?? -1) as int;
|
||||
int get responsibleId => getInt("responsible");
|
||||
|
||||
int get supplierId => (jsondata["supplier"] ?? -1) as int;
|
||||
int get supplierId => getInt("supplier");
|
||||
|
||||
// Project code information
|
||||
int get projectCodeId => getInt("project_code");
|
||||
|
||||
String get projectCode => getString("code", subKey: "project_code_detail");
|
||||
|
||||
String get projectCodeDescription => getString("description", subKey: "project_code_detail");
|
||||
|
||||
bool get hasProjectCode => projectCode.isNotEmpty;
|
||||
|
||||
InvenTreeCompany? get supplier {
|
||||
|
||||
@ -88,11 +98,11 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get supplierReference => (jsondata["supplier_reference"] ?? "") as String;
|
||||
String get supplierReference => getString("supplier_reference");
|
||||
|
||||
int get status => (jsondata["status"] ?? -1) as int;
|
||||
int get status => getInt("status");
|
||||
|
||||
String get statusText => (jsondata["status_text"] ?? "") as String;
|
||||
String get statusText => getString("status_text");
|
||||
|
||||
bool get isOpen => status == PO_STATUS_PENDING || status == PO_STATUS_PLACED;
|
||||
|
||||
@ -103,7 +113,7 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
bool get isFailed => status == PO_STATUS_CANCELLED || status == PO_STATUS_LOST || status == PO_STATUS_RETURNED;
|
||||
|
||||
double? get totalPrice {
|
||||
String price = (jsondata["total_price"] ?? "") as String;
|
||||
String price = getString("total_price");
|
||||
|
||||
if (price.isEmpty) {
|
||||
return null;
|
||||
@ -112,7 +122,7 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get totalPriceCurrency => (jsondata["total_price_currency"] ?? "") as String;
|
||||
String get totalPriceCurrency => getString("total_price_currency");
|
||||
|
||||
Future<List<InvenTreePOLineItem>> getLineItems() async {
|
||||
|
||||
@ -134,9 +144,7 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
|
||||
}
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreePurchaseOrder.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePurchaseOrder.fromJson(json);
|
||||
|
||||
/// Mark this order as "placed" / "issued"
|
||||
Future<void> issueOrder() async {
|
||||
@ -199,17 +207,17 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
||||
|
||||
bool get isComplete => received >= quantity;
|
||||
|
||||
double get quantity => (jsondata["quantity"] ?? 0) as double;
|
||||
double get quantity => getDouble("quantity");
|
||||
|
||||
double get received => (jsondata["received"] ?? 0) as double;
|
||||
double get received => getDouble("received");
|
||||
|
||||
double get outstanding => quantity - received;
|
||||
|
||||
String get reference => (jsondata["reference"] ?? "") as String;
|
||||
String get reference => getString("reference");
|
||||
|
||||
int get orderId => (jsondata["order"] ?? -1) as int;
|
||||
int get orderId => getInt("order");
|
||||
|
||||
int get supplierPartId => (jsondata["part"] ?? -1) as int;
|
||||
int get supplierPartId => getInt("part");
|
||||
|
||||
InvenTreePart? get part {
|
||||
dynamic part_detail = jsondata["part_detail"];
|
||||
@ -232,20 +240,19 @@ class InvenTreePOLineItem extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
double get purchasePrice => double.parse((jsondata["purchase_price"] ?? "") as String);
|
||||
double get purchasePrice => getDouble("purchase_price");
|
||||
|
||||
String get purchasePriceCurrency => (jsondata["purchase_price_currency"] ?? "") as String;
|
||||
String get purchasePriceCurrency => getString("purchase_price_currency");
|
||||
|
||||
String get purchasePriceString => (jsondata["purchase_price_string"] ?? "") as String;
|
||||
String get purchasePriceString => getString("purchase_price_string");
|
||||
|
||||
int get destination => (jsondata["destination"] ?? -1) as int;
|
||||
int get destination => getInt("destination");
|
||||
|
||||
Map<String, dynamic> get destinationDetail => (jsondata["destination_detail"] ?? {}) as Map<String, dynamic>;
|
||||
Map<String, dynamic> get destinationDetail => getMap("destination_detail");
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreePOLineItem.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePOLineItem.fromJson(json);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -264,7 +271,6 @@ class InvenTreePurchaseOrderAttachment extends InvenTreeAttachment {
|
||||
String get URL => "order/po/attachment/";
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreePurchaseOrderAttachment.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePurchaseOrderAttachment.fromJson(json);
|
||||
|
||||
}
|
||||
|
@ -35,17 +35,17 @@ class InvenTreeStockItemTestResult extends InvenTreeModel {
|
||||
};
|
||||
}
|
||||
|
||||
String get key => (jsondata["key"] ?? "") as String;
|
||||
String get key => getString("key");
|
||||
|
||||
String get testName => (jsondata["test"] ?? "") as String;
|
||||
String get testName => getString("test");
|
||||
|
||||
bool get result => (jsondata["result"] ?? false) as bool;
|
||||
bool get result => getBool("result");
|
||||
|
||||
String get value => (jsondata["value"] ?? "") as String;
|
||||
String get value => getString("value");
|
||||
|
||||
String get attachment => (jsondata["attachment"] ?? "") as String;
|
||||
String get attachment => getString("attachment");
|
||||
|
||||
String get date => (jsondata["date"] ?? "") as String;
|
||||
String get date => getString("date");
|
||||
|
||||
@override
|
||||
InvenTreeStockItemTestResult createFromJson(Map<String, dynamic> json) {
|
||||
@ -63,9 +63,7 @@ class InvenTreeStockItemHistory extends InvenTreeModel {
|
||||
InvenTreeStockItemHistory.fromJson(Map<String, dynamic> json) : super.fromJson(json);
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreeStockItemHistory.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeStockItemHistory.fromJson(json);
|
||||
|
||||
@override
|
||||
String get URL => "stock/track/";
|
||||
@ -98,16 +96,10 @@ class InvenTreeStockItemHistory extends InvenTreeModel {
|
||||
return DateFormat("yyyy-MM-dd").format(d);
|
||||
}
|
||||
|
||||
String get label => (jsondata["label"] ?? "") as String;
|
||||
String get label => getString("label");
|
||||
|
||||
// Return the "deltas" associated with this historical object
|
||||
Map<String, dynamic> get deltas {
|
||||
if (jsondata.containsKey("deltas")) {
|
||||
return jsondata["deltas"] as Map<String, dynamic>;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> get deltas => getMap("deltas");
|
||||
|
||||
// Return the quantity string for this historical object
|
||||
String get quantityString {
|
||||
@ -122,12 +114,13 @@ class InvenTreeStockItemHistory extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get userString {
|
||||
return (jsondata["user_detail"]?["username"] ?? "") as String;
|
||||
}
|
||||
String get userString => getString("username", subKey: "user_detail");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class representing a StockItem database instance
|
||||
*/
|
||||
class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
InvenTreeStockItem() : super();
|
||||
@ -237,16 +230,16 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
});
|
||||
}
|
||||
|
||||
int get status => (jsondata["status"] ?? -1) as int;
|
||||
int get status => getInt("status");
|
||||
|
||||
String get packaging => (jsondata["packaging"] ?? "") as String;
|
||||
String get packaging => getString("packaging");
|
||||
|
||||
String get batch => (jsondata["batch"] ?? "") as String;
|
||||
String get batch => getString("batch");
|
||||
|
||||
int get partId => (jsondata["part"] ?? -1) as int;
|
||||
int get partId => getInt("part");
|
||||
|
||||
double? get purchasePrice {
|
||||
String pp = (jsondata["purchase_price"] ?? "") as String;
|
||||
String pp = getString("purchase_price");
|
||||
|
||||
if (pp.isEmpty) {
|
||||
return null;
|
||||
@ -255,18 +248,18 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
String get purchasePriceCurrency => (jsondata["purchase_price_currency"] ?? "") as String;
|
||||
String get purchasePriceCurrency => getString("purchase_price_currency");
|
||||
|
||||
bool get hasPurchasePrice {
|
||||
double? pp = purchasePrice;
|
||||
return pp != null && pp > 0;
|
||||
}
|
||||
|
||||
int get purchaseOrderId => (jsondata["purchase_order"] ?? -1) as int;
|
||||
int get purchaseOrderId => getInt("purchase_order");
|
||||
|
||||
int get trackingItemCount => (jsondata["tracking_items"] ?? 0) as int;
|
||||
int get trackingItemCount => getInt("tracking_items", backup: 0);
|
||||
|
||||
bool get isBuilding => (jsondata["is_building"] ?? false) as bool;
|
||||
bool get isBuilding => getBool("is_building");
|
||||
|
||||
// Date of last update
|
||||
DateTime? get updatedDate {
|
||||
@ -320,7 +313,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
// Backup if first value fails
|
||||
if (nm.isEmpty) {
|
||||
nm = (jsondata["part__name"] ?? "") as String;
|
||||
nm = getString("part__name");
|
||||
}
|
||||
|
||||
return nm;
|
||||
@ -335,7 +328,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
}
|
||||
|
||||
if (desc.isEmpty) {
|
||||
desc = (jsondata["part__description"] ?? "") as String;
|
||||
desc = getString("part__description");
|
||||
}
|
||||
|
||||
return desc;
|
||||
@ -349,7 +342,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
}
|
||||
|
||||
if (img.isEmpty) {
|
||||
img = (jsondata["part__thumbnail"] ?? "") as String;
|
||||
img = getString("part__thumbnail");
|
||||
}
|
||||
|
||||
return img;
|
||||
@ -371,7 +364,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
// Try a different approach
|
||||
if (thumb.isEmpty) {
|
||||
thumb = (jsondata["part__thumbnail"] ?? "") as String;
|
||||
thumb = getString("part__thumbnail");
|
||||
}
|
||||
|
||||
// Still no thumbnail? Use the "no image" image
|
||||
@ -380,7 +373,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
return thumb;
|
||||
}
|
||||
|
||||
int get supplierPartId => (jsondata["supplier_part"] ?? -1) as int;
|
||||
int get supplierPartId => getInt("supplier_part");
|
||||
|
||||
String get supplierImage {
|
||||
String thumb = "";
|
||||
@ -394,33 +387,15 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
return thumb;
|
||||
}
|
||||
|
||||
String get supplierName {
|
||||
String sname = "";
|
||||
String get supplierName => getString("supplier_name", subKey: "supplier_detail");
|
||||
|
||||
if (jsondata.containsKey("supplier_detail")) {
|
||||
sname = (jsondata["supplier_detail"]["supplier_name"] ?? "") as String;
|
||||
}
|
||||
String get units => getString("units", subKey: "part_detail");
|
||||
|
||||
return sname;
|
||||
}
|
||||
String get supplierSKU => getString("SKU", subKey: "supplier_part_detail");
|
||||
|
||||
String get units {
|
||||
return (jsondata["part_detail"]?["units"] ?? "") as String;
|
||||
}
|
||||
String get serialNumber => getString("serial");
|
||||
|
||||
String get supplierSKU {
|
||||
String sku = "";
|
||||
|
||||
if (jsondata.containsKey("supplier_part_detail")) {
|
||||
sku = (jsondata["supplier_part_detail"]["SKU"] ?? "") as String;
|
||||
}
|
||||
|
||||
return sku;
|
||||
}
|
||||
|
||||
String get serialNumber => (jsondata["serial"] ?? "") as String;
|
||||
|
||||
double get quantity => double.tryParse(jsondata["quantity"].toString()) ?? 0;
|
||||
double get quantity => getDouble("quantity");
|
||||
|
||||
String quantityString({bool includeUnits = false}){
|
||||
|
||||
@ -440,11 +415,11 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
return q;
|
||||
}
|
||||
|
||||
double get allocated => double.tryParse(jsondata["allocated"].toString()) ?? 0;
|
||||
double get allocated => getDouble("allocated");
|
||||
|
||||
double get available => quantity - allocated;
|
||||
|
||||
int get locationId => (jsondata["location"] ?? -1) as int;
|
||||
int get locationId => getInt("location");
|
||||
|
||||
bool isSerialized() => serialNumber.isNotEmpty && quantity.toInt() == 1;
|
||||
|
||||
@ -459,15 +434,14 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
}
|
||||
|
||||
String get locationName {
|
||||
String loc = "";
|
||||
|
||||
if (locationId == -1 || !jsondata.containsKey("location_detail")) return "Unknown Location";
|
||||
|
||||
loc = (jsondata["location_detail"]["name"] ?? "") as String;
|
||||
String loc = getString("name", subKey: "location_detail");
|
||||
|
||||
// Old-style name
|
||||
if (loc.isEmpty) {
|
||||
loc = (jsondata["location__name"] ?? "") as String;
|
||||
loc = getString("location__name");
|
||||
}
|
||||
|
||||
return loc;
|
||||
@ -477,8 +451,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
|
||||
if (locationId == -1 || !jsondata.containsKey("location_detail")) return L10().locationNotSet;
|
||||
|
||||
String _loc = (jsondata["location_detail"]["pathstring"] ?? "") as String;
|
||||
|
||||
String _loc = getString("pathstring", subKey: "location_detail");
|
||||
if (_loc.isNotEmpty) {
|
||||
return _loc;
|
||||
} else {
|
||||
@ -497,9 +470,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
||||
}
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreeStockItem.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeStockItem.fromJson(json);
|
||||
|
||||
/*
|
||||
* Perform stocktake action:
|
||||
@ -601,9 +572,7 @@ class InvenTreeStockItemAttachment extends InvenTreeAttachment {
|
||||
String get URL => "stock/attachment/";
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
return InvenTreeStockItemAttachment.fromJson(json);
|
||||
}
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeStockItemAttachment.fromJson(json);
|
||||
|
||||
}
|
||||
|
||||
@ -620,7 +589,7 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
||||
@override
|
||||
List<String> get rolesRequired => ["stock_location"];
|
||||
|
||||
String get pathstring => (jsondata["pathstring"] ?? "") as String;
|
||||
String get pathstring => getString("pathstring");
|
||||
|
||||
@override
|
||||
Map<String, dynamic> formFields() {
|
||||
@ -658,10 +627,6 @@ class InvenTreeStockLocation extends InvenTreeModel {
|
||||
int get itemcount => (jsondata["items"] ?? 0) as int;
|
||||
|
||||
@override
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) {
|
||||
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeStockLocation.fromJson(json);
|
||||
|
||||
var loc = InvenTreeStockLocation.fromJson(json);
|
||||
|
||||
return loc;
|
||||
}
|
||||
}
|
@ -759,6 +759,9 @@
|
||||
"profileTapToCreate": "Tap to create or select a profile",
|
||||
"@profileTapToCreate": {},
|
||||
|
||||
"projectCode": "Project Code",
|
||||
"@projectCode": {},
|
||||
|
||||
"purchaseOrder": "Purchase Order",
|
||||
"@purchaseOrder": {},
|
||||
|
||||
|
@ -43,6 +43,8 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
|
||||
|
||||
int attachmentCount = 0;
|
||||
|
||||
bool supportProjectCodes = false;
|
||||
|
||||
@override
|
||||
String getAppBarTitle() => L10().purchaseOrder;
|
||||
|
||||
@ -139,6 +141,8 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
|
||||
|
||||
lines = await order.getLineItems();
|
||||
|
||||
supportProjectCodes = api.supportsProjectCodes && await api.getGlobalBooleanSetting("PROJECT_CODES_ENABLED");
|
||||
|
||||
completedLines = 0;
|
||||
|
||||
for (var line in lines) {
|
||||
@ -157,12 +161,20 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
|
||||
// Edit the currently displayed PurchaseOrder
|
||||
Future <void> editOrder(BuildContext context) async {
|
||||
var fields = order.formFields();
|
||||
|
||||
// Cannot edit supplier field from here
|
||||
fields.remove("supplier");
|
||||
|
||||
// Contact model not supported by server
|
||||
if (!api.supportsContactModel) {
|
||||
fields.remove("contact");
|
||||
}
|
||||
|
||||
// ProjectCode model not supported by server
|
||||
if (!supportProjectCodes) {
|
||||
fields.remove("project_code");
|
||||
}
|
||||
|
||||
order.editForm(
|
||||
context,
|
||||
L10().purchaseOrderEdit,
|
||||
@ -202,6 +214,14 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
|
||||
|
||||
tiles.add(headerTile(context));
|
||||
|
||||
if (supportProjectCodes && order.hasProjectCode) {
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().projectCode),
|
||||
subtitle: Text("${order.projectCode} - ${order.projectCodeDescription}"),
|
||||
leading: FaIcon(FontAwesomeIcons.list),
|
||||
));
|
||||
}
|
||||
|
||||
if (supplier != null) {
|
||||
tiles.add(ListTile(
|
||||
title: Text(L10().supplier),
|
||||
|
Loading…
x
Reference in New Issue
Block a user