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:
commit
47208155ae
@ -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)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -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"),
|
||||||
]
|
]
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
139
lib/widget/company_detail.dart
Normal file
139
lib/widget/company_detail.dart
Normal 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(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
131
lib/widget/company_list.dart
Normal file
131
lib/widget/company_list.dart
Normal 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)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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(
|
||||||
|
@ -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)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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
|
@ -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)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user