2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 13:36:50 +00:00

Merge pull request #20 from SchrodingersGat/supplier-list

Supplier list
This commit is contained in:
Oliver 2020-04-07 00:11:15 +10:00 committed by GitHub
commit 47208155ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 382 additions and 55 deletions

View File

@ -6,9 +6,9 @@ import 'package:InvenTree/inventree/stock.dart';
import 'package:InvenTree/inventree/part.dart'; import 'package:InvenTree/inventree/part.dart';
import 'package:InvenTree/widget/location_display.dart'; import 'package:InvenTree/widget/location_display.dart';
import 'package:InvenTree/widget/part_display.dart'; import 'package:InvenTree/widget/part_detail.dart';
import 'package:InvenTree/widget/category_display.dart'; import 'package:InvenTree/widget/category_display.dart';
import 'package:InvenTree/widget/stock_display.dart'; import 'package:InvenTree/widget/stock_detail.dart';
import 'dart:convert'; import 'dart:convert';
@ -59,12 +59,12 @@ void _handleInvenTreeBarcode(BuildContext context, Map<String, dynamic> data) {
} else if (codeType == 'stockitem') { } else if (codeType == 'stockitem') {
InvenTreeStockItem().get(pk).then((var item) { InvenTreeStockItem().get(pk).then((var item) {
Navigator.push(context, MaterialPageRoute(builder: (context) => StockItemDisplayWidget(item))); Navigator.push(context, MaterialPageRoute(builder: (context) => StockDetailWidget(item)));
}); });
} else if (codeType == 'part') { } else if (codeType == 'part') {
InvenTreePart().get(pk).then((var part) { InvenTreePart().get(pk).then((var part) {
Navigator.push(context, Navigator.push(context,
MaterialPageRoute(builder: (context) => PartDisplayWidget(part))); MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
}); });
} }
} }

View File

@ -10,6 +10,18 @@ class InvenTreeCompany extends InvenTreeModel {
InvenTreeCompany() : super(); InvenTreeCompany() : super();
String get image => jsondata['image'] ?? '';
String get website => jsondata['website'] ?? '';
String get phone => jsondata['phone'] ?? '';
String get email => jsondata['email'] ?? '';
bool get isSupplier => jsondata['is_supplier'] ?? false;
bool get isCustomer => jsondata['is_customer'] ?? false;
InvenTreeCompany.fromJson(Map<String, dynamic> json) : super.fromJson(json) { InvenTreeCompany.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
// TODO // TODO
} }

View File

@ -172,7 +172,16 @@ class InvenTreeModel {
// TODO - Define a 'save' / 'update' function // TODO - Define a 'save' / 'update' function
// Override this function for each sub-class // Override this function for each sub-class
bool matchAgainstString(String filter) => false; bool matchAgainstString(String filter) {
// Default implementation matches name and description
// Override this behaviour in sub-class if required
if (name.toLowerCase().contains(filter)) return true;
if (description.toLowerCase().contains(filter)) return true;
// No matches!
return false;
}
// Filter this item against a list of provided filters // Filter this item against a list of provided filters
// Each filter must be matched // Each filter must be matched

View File

@ -195,13 +195,4 @@ class InvenTreeStockLocation extends InvenTreeModel {
return loc; return loc;
} }
@override
bool matchAgainstString(String filter) {
if (name.toLowerCase().contains(filter)) return true;
if (description.toLowerCase().contains(filter)) return true;
return false;
}
} }

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:InvenTree/inventree/stock.dart'; import 'package:InvenTree/inventree/stock.dart';
import 'package:InvenTree/widget/category_display.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/location_display.dart';
import 'package:InvenTree/widget/drawer.dart'; import 'package:InvenTree/widget/drawer.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -27,7 +28,7 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
// Load login details // Load login details
InvenTreeUserPreferences().loadLoginDetails(); InvenTreePreferences().loadLoginDetails();
runApp(MyApp()); runApp(MyApp());
} }
@ -207,12 +208,17 @@ class _MyHomePageState extends State<MyHomePage> {
} }
void _stock() { void _stock() {
if (!InvenTreeAPI().checkConnection(context)) return; if (!InvenTreeAPI().checkConnection(context)) return;
Navigator.push(context, MaterialPageRoute(builder: (context) => LocationDisplayWidget(null))); Navigator.push(context, MaterialPageRoute(builder: (context) => LocationDisplayWidget(null)));
} }
void _suppliers() {
if (!InvenTreeAPI().checkConnection(context)) return;
Navigator.push(context, MaterialPageRoute(builder: (context) => SupplierListWidget()));
}
void _unsupported() { void _unsupported() {
showDialog( showDialog(
context: context, context: context,
@ -243,7 +249,7 @@ class _MyHomePageState extends State<MyHomePage> {
title: Text(widget.title), title: Text(widget.title),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.search), icon: FaIcon(FontAwesomeIcons.search),
tooltip: 'Search', tooltip: 'Search',
onPressed: null, onPressed: null,
), ),
@ -311,7 +317,7 @@ class _MyHomePageState extends State<MyHomePage> {
IconButton( IconButton(
icon: new FaIcon(FontAwesomeIcons.industry), icon: new FaIcon(FontAwesomeIcons.industry),
tooltip: 'Suppliers', tooltip: 'Suppliers',
onPressed: _unsupported, onPressed: _suppliers,
), ),
Text("Suppliers"), Text("Suppliers"),
] ]

View File

@ -2,20 +2,37 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'api.dart'; import 'api.dart';
class InvenTreeUserPreferences { class InvenTreePreferences {
static const String _SERVER = 'server'; static const String _SERVER = 'server';
static const String _USERNAME = 'username'; static const String _USERNAME = 'username';
static const String _PASSWORD = 'password'; static const String _PASSWORD = 'password';
// Ensure we only ever create a single instance of the preferences class /* The following settings are not stored to persistent storage,
static final InvenTreeUserPreferences _api = new InvenTreeUserPreferences._internal(); * instead they are only used as 'session preferences'.
* They are kept here as a convenience only.
*/
factory InvenTreeUserPreferences() { // Expand subcategory list in PartCategory view
bool expandCategoryList = false;
// Expand part list in PartCategory view
bool expandPartList = true;
// Expand sublocation list in StockLocation view
bool expandLocationList = false;
// Expand item list in StockLocation view
bool expandStockList = true;
// Ensure we only ever create a single instance of the preferences class
static final InvenTreePreferences _api = new InvenTreePreferences._internal();
factory InvenTreePreferences() {
return _api; return _api;
} }
InvenTreeUserPreferences._internal(); InvenTreePreferences._internal();
// Load saved login details, and attempt connection // Load saved login details, and attempt connection
void loadLoginDetails() async { void loadLoginDetails() async {

View File

@ -130,7 +130,7 @@ class _InvenTreeLoginSettingsState extends State<InvenTreeLoginSettingsWidget> {
if (_formKey.currentState.validate()) { if (_formKey.currentState.validate()) {
_formKey.currentState.save(); _formKey.currentState.save();
await InvenTreeUserPreferences().saveLoginDetails(_server, _username, _password); await InvenTreePreferences().saveLoginDetails(_server, _username, _password);
} }
} }

View File

@ -1,8 +1,9 @@
import 'package:InvenTree/api.dart'; import 'package:InvenTree/api.dart';
import 'package:InvenTree/inventree/part.dart'; import 'package:InvenTree/inventree/part.dart';
import 'package:InvenTree/preferences.dart';
import 'package:InvenTree/widget/part_display.dart'; import 'package:InvenTree/widget/part_detail.dart';
import 'package:InvenTree/widget/drawer.dart'; import 'package:InvenTree/widget/drawer.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -83,9 +84,6 @@ class _CategoryDisplayState extends State<CategoryDisplayWidget> {
}); });
} }
bool _subcategoriesExpanded = false;
bool _partListExpanded = true;
Widget getCategoryDescriptionCard() { Widget getCategoryDescriptionCard() {
if (category == null) { if (category == null) {
return Card( return Card(
@ -144,10 +142,10 @@ class _CategoryDisplayState extends State<CategoryDisplayWidget> {
switch (index) { switch (index) {
case 0: case 0:
_subcategoriesExpanded = !isExpanded; InvenTreePreferences().expandCategoryList = !isExpanded;
break; break;
case 1: case 1:
_partListExpanded = !isExpanded; InvenTreePreferences().expandPartList = !isExpanded;
break; break;
default: default:
break; break;
@ -163,13 +161,16 @@ class _CategoryDisplayState extends State<CategoryDisplayWidget> {
trailing: Text("${_subcategories.length}"), trailing: Text("${_subcategories.length}"),
onTap: () { onTap: () {
setState(() { setState(() {
_subcategoriesExpanded = !_subcategoriesExpanded; InvenTreePreferences().expandCategoryList = !InvenTreePreferences().expandCategoryList;
}); });
}, },
onLongPress: () {
// TODO - Context menu for e.g. creating a new PartCategory
},
); );
}, },
body: SubcategoryList(_subcategories), body: SubcategoryList(_subcategories),
isExpanded: _subcategoriesExpanded && _subcategories.length > 0, isExpanded: InvenTreePreferences().expandCategoryList && _subcategories.length > 0,
), ),
ExpansionPanel( ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) { headerBuilder: (BuildContext context, bool isExpanded) {
@ -179,13 +180,16 @@ class _CategoryDisplayState extends State<CategoryDisplayWidget> {
trailing: Text("${_parts.length}"), trailing: Text("${_parts.length}"),
onTap: () { onTap: () {
setState(() { setState(() {
_partListExpanded = !_partListExpanded; InvenTreePreferences().expandPartList = !InvenTreePreferences().expandPartList;
}); });
}, },
onLongPress: () {
// TODO - Context menu for e.g. creating a new Part
},
); );
}, },
body: PartList(_parts), body: PartList(_parts),
isExpanded: _partListExpanded && _parts.length > 0, isExpanded: InvenTreePreferences().expandPartList && _parts.length > 0,
) )
], ],
), ),
@ -251,7 +255,7 @@ class PartList extends StatelessWidget {
InvenTreePart().get(pk).then((var part) { InvenTreePart().get(pk).then((var part) {
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDisplayWidget(part))); Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
} }
}); });
} }

View File

@ -0,0 +1,139 @@
import 'package:InvenTree/api.dart';
import 'package:InvenTree/inventree/company.dart';
import 'package:InvenTree/widget/drawer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class CompanyDetailWidget extends StatefulWidget {
final InvenTreeCompany company;
CompanyDetailWidget(this.company, {Key key}) : super(key: key);
@override
_CompanyDetailState createState() => _CompanyDetailState(company);
}
class _CompanyDetailState extends State<CompanyDetailWidget> {
final InvenTreeCompany company;
_CompanyDetailState(this.company) {
// TODO
}
List<Widget> _companyTiles() {
var tiles = List<Widget>();
bool sep = false;
tiles.add(Card(
child: ListTile(
title: Text("${company.name}"),
subtitle: Text("${company.description}"),
leading: Image(
image: InvenTreeAPI().getImage(company.image),
width: 48,
),
),
));
if (company.website.isNotEmpty) {
tiles.add(ListTile(
title: Text("${company.website}"),
leading: FaIcon(FontAwesomeIcons.globe),
onTap: () {
// TODO - Open website
},
));
sep = true;
}
if (company.email.isNotEmpty) {
tiles.add(ListTile(
title: Text("${company.email}"),
leading: FaIcon(FontAwesomeIcons.at),
onTap: () {
// TODO - Open email
},
));
sep = true;
}
if (company.phone.isNotEmpty) {
tiles.add(ListTile(
title: Text("${company.phone}"),
leading: FaIcon(FontAwesomeIcons.phone),
onTap: () {
// TODO - Call phone number
},
));
sep = true;
}
// External link
if (company.link.isNotEmpty) {
tiles.add(ListTile(
title: Text("${company.link}"),
leading: FaIcon(FontAwesomeIcons.link),
onTap: () {
// TODO - Open external link
},
));
sep = true;
}
if (sep) {
tiles.add(Divider());
}
if (company.isSupplier) {
// TODO - Add list of supplier parts
// TODO - Add list of purchase orders
tiles.add(Divider());
}
if (company.isCustomer) {
// TODO - Add list of sales orders
tiles.add(Divider());
}
if (company.notes.isNotEmpty) {
tiles.add(ListTile(
title: Text("Notes"),
leading: FaIcon(FontAwesomeIcons.stickyNote),
onTap: null,
));
}
return tiles;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("${company.name}"),
),
drawer: new InvenTreeDrawer(context),
body: Center(
child: ListView(
children: _companyTiles(),
)
)
);
}
}

View File

@ -0,0 +1,131 @@
import 'package:InvenTree/widget/company_detail.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:InvenTree/api.dart';
import 'package:InvenTree/inventree/company.dart';
import 'package:InvenTree/widget/drawer.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
abstract class CompanyListWidget extends StatefulWidget {
String title;
Map<String, String> filters;
@override
_CompanyListState createState() => _CompanyListState(title, filters);
}
class SupplierListWidget extends CompanyListWidget {
@override
_CompanyListState createState() => _CompanyListState("Suppliers", {"is_supplier": "true"});
}
class CustomerListWidget extends CompanyListWidget {
@override
_CompanyListState createState() => _CompanyListState("Customers", {"is_customer": "true"});
}
class _CompanyListState extends State<CompanyListWidget> {
var _companies = new List<InvenTreeCompany>();
var _filteredCompanies = new List<InvenTreeCompany>();
var _title = "Companies";
Map<String, String> _filters = Map<String, String>();
_CompanyListState(this._title, this._filters) {
_requestData();
}
void _requestData() {
InvenTreeCompany().list(filters: _filters).then((var companies) {
_companies.clear();
for (var c in companies) {
if (c is InvenTreeCompany) {
_companies.add(c);
}
}
setState(() {
_filterResults("");
});
});
}
void _filterResults(String text) {
if (text.isEmpty) {
_filteredCompanies = _companies;
} else {
_filteredCompanies = _companies.where((c) => c.filter(text)).toList();
}
}
Widget _showCompany(BuildContext context, int index) {
InvenTreeCompany company = _filteredCompanies[index];
return ListTile(
title: Text("${company.name}"),
subtitle: Text("${company.description}"),
leading: Image(
image: InvenTreeAPI().getImage(company.image),
width: 40,
),
onTap: () {
if (company.pk > 0) {
InvenTreeCompany().get(company.pk).then((var c) {
Navigator.push(context, MaterialPageRoute(builder: (context) => CompanyDetailWidget(c)));
});
}
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("$_title"),
actions: <Widget>[
IconButton(
icon: FaIcon(FontAwesomeIcons.plus),
tooltip: 'New',
onPressed: null,
)
],
),
drawer: new InvenTreeDrawer(context),
body: ListView(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'Filter results',
),
onChanged: (String text) {
setState(() {
_filterResults(text);
});
},
),
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemBuilder: _showCompany, itemCount: _filteredCompanies.length)
],
)
);
}
}

View File

@ -1,5 +1,6 @@
import 'package:InvenTree/api.dart'; import 'package:InvenTree/api.dart';
import 'package:InvenTree/barcode.dart'; import 'package:InvenTree/barcode.dart';
import 'package:InvenTree/widget/company_list.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:InvenTree/api.dart'; import 'package:InvenTree/api.dart';
@ -61,6 +62,20 @@ class InvenTreeDrawer extends StatelessWidget {
Navigator.push(context, MaterialPageRoute(builder: (context) => LocationDisplayWidget(null))); Navigator.push(context, MaterialPageRoute(builder: (context) => LocationDisplayWidget(null)));
} }
void _showSuppliers() {
if (!InvenTreeAPI().checkConnection(context)) return;
_closeDrawer();
Navigator.push(context, MaterialPageRoute(builder: (context) => SupplierListWidget()));
}
void _showCustomers() {
if (!InvenTreeAPI().checkConnection(context)) return;
_closeDrawer();
Navigator.push(context, MaterialPageRoute(builder: (context) => CustomerListWidget()));
}
/* /*
* Load settings widget * Load settings widget
*/ */
@ -108,7 +123,12 @@ class InvenTreeDrawer extends StatelessWidget {
new ListTile( new ListTile(
title: new Text("Suppliers"), title: new Text("Suppliers"),
leading: new FaIcon(FontAwesomeIcons.industry), leading: new FaIcon(FontAwesomeIcons.industry),
onTap: null, onTap: _showSuppliers,
),
new ListTile(
title: new Text("Customers"),
leading: new FaIcon(FontAwesomeIcons.users),
onTap: _showCustomers,
), ),
new Divider(), new Divider(),
new ListTile( new ListTile(

View File

@ -1,7 +1,8 @@
import 'package:InvenTree/api.dart'; import 'package:InvenTree/api.dart';
import 'package:InvenTree/inventree/stock.dart'; import 'package:InvenTree/inventree/stock.dart';
import 'package:InvenTree/preferences.dart';
import 'package:InvenTree/widget/drawer.dart'; import 'package:InvenTree/widget/drawer.dart';
import 'package:InvenTree/widget/stock_display.dart'; import 'package:InvenTree/widget/stock_detail.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -91,9 +92,6 @@ class _LocationDisplayState extends State<LocationDisplayWidget> {
}); });
} }
bool _locationListExpanded = false;
bool _stockListExpanded = true;
Widget locationDescriptionCard() { Widget locationDescriptionCard() {
if (location == null) { if (location == null) {
return Card( return Card(
@ -150,10 +148,10 @@ class _LocationDisplayState extends State<LocationDisplayWidget> {
setState(() { setState(() {
switch (index) { switch (index) {
case 0: case 0:
_locationListExpanded = !isExpanded; InvenTreePreferences().expandLocationList = !isExpanded;
break; break;
case 1: case 1:
_stockListExpanded = !isExpanded; InvenTreePreferences().expandStockList = !isExpanded;
break; break;
default: default:
break; break;
@ -170,13 +168,13 @@ class _LocationDisplayState extends State<LocationDisplayWidget> {
trailing: Text("${_sublocations.length}"), trailing: Text("${_sublocations.length}"),
onTap: () { onTap: () {
setState(() { setState(() {
_locationListExpanded = !_locationListExpanded; InvenTreePreferences().expandLocationList = !InvenTreePreferences().expandLocationList;
}); });
}, },
); );
}, },
body: SublocationList(_sublocations), body: SublocationList(_sublocations),
isExpanded: _locationListExpanded && _sublocations.length > 0, isExpanded: InvenTreePreferences().expandLocationList && _sublocations.length > 0,
), ),
ExpansionPanel( ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) { headerBuilder: (BuildContext context, bool isExpanded) {
@ -186,13 +184,13 @@ class _LocationDisplayState extends State<LocationDisplayWidget> {
trailing: Text("${_items.length}"), trailing: Text("${_items.length}"),
onTap: () { onTap: () {
setState(() { setState(() {
_stockListExpanded = !_stockListExpanded; InvenTreePreferences().expandStockList = !InvenTreePreferences().expandStockList;
}); });
}, },
); );
}, },
body: StockList(_items), body: StockList(_items),
isExpanded: _stockListExpanded && _items.length > 0, isExpanded: InvenTreePreferences().expandStockList && _items.length > 0,
) )
] ]
), ),
@ -248,7 +246,7 @@ class StockList extends StatelessWidget {
void _openItem(BuildContext context, int pk) { void _openItem(BuildContext context, int pk) {
InvenTreeStockItem().get(pk).then((var item) { InvenTreeStockItem().get(pk).then((var item) {
if (item is InvenTreeStockItem) { if (item is InvenTreeStockItem) {
Navigator.push(context, MaterialPageRoute(builder: (context) => StockItemDisplayWidget(item))); Navigator.push(context, MaterialPageRoute(builder: (context) => StockDetailWidget(item)));
} }
}); });
} }

View File

@ -9,9 +9,9 @@ import 'package:InvenTree/api.dart';
import 'package:InvenTree/widget/drawer.dart'; import 'package:InvenTree/widget/drawer.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class PartDisplayWidget extends StatefulWidget { class PartDetailWidget extends StatefulWidget {
PartDisplayWidget(this.part, {Key key}) : super(key: key); PartDetailWidget(this.part, {Key key}) : super(key: key);
final InvenTreePart part; final InvenTreePart part;
@ -21,7 +21,7 @@ class PartDisplayWidget extends StatefulWidget {
} }
class _PartDisplayState extends State<PartDisplayWidget> { class _PartDisplayState extends State<PartDetailWidget> {
_PartDisplayState(this.part) { _PartDisplayState(this.part) {
// TODO // TODO

View File

@ -3,7 +3,7 @@
import 'package:InvenTree/inventree/stock.dart'; import 'package:InvenTree/inventree/stock.dart';
import 'package:InvenTree/inventree/part.dart'; import 'package:InvenTree/inventree/part.dart';
import 'package:InvenTree/widget/location_display.dart'; import 'package:InvenTree/widget/location_display.dart';
import 'package:InvenTree/widget/part_display.dart'; import 'package:InvenTree/widget/part_detail.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -12,9 +12,9 @@ import 'package:InvenTree/api.dart';
import 'package:InvenTree/widget/drawer.dart'; import 'package:InvenTree/widget/drawer.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class StockItemDisplayWidget extends StatefulWidget { class StockDetailWidget extends StatefulWidget {
StockItemDisplayWidget(this.item, {Key key}) : super(key: key); StockDetailWidget(this.item, {Key key}) : super(key: key);
final InvenTreeStockItem item; final InvenTreeStockItem item;
@ -23,7 +23,7 @@ class StockItemDisplayWidget extends StatefulWidget {
} }
class _StockItemDisplayState extends State<StockItemDisplayWidget> { class _StockItemDisplayState extends State<StockDetailWidget> {
_StockItemDisplayState(this.item) { _StockItemDisplayState(this.item) {
// TODO // TODO
@ -64,7 +64,7 @@ class _StockItemDisplayState extends State<StockItemDisplayWidget> {
if (item.partId > 0) { if (item.partId > 0) {
InvenTreePart().get(item.partId).then((var part) { InvenTreePart().get(item.partId).then((var part) {
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDisplayWidget(part))); Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part)));
} }
}); });
} }