2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-27 21:16:48 +00:00

Order extra lines (#632)

* Define classes for extra line item

* Display PO extra line items

- Also, some refactoring

* Support extra line items for sales order

* linting fixes

* Update release notes
This commit is contained in:
Oliver 2025-04-15 20:49:05 +10:00 committed by GitHub
parent 25d7ac9189
commit 72a78291b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 642 additions and 193 deletions

View File

@ -2,6 +2,8 @@
--- ---
- Adds ability to create new companies from the app - Adds ability to create new companies from the app
- Allow creation of line items against pending sales orders - Allow creation of line items against pending sales orders
- Support "extra line items" for purchase orders
- Support "extra line items" for sales orders
- Display start date for purchase orders - Display start date for purchase orders
- Display start date for sales orders - Display start date for sales orders
- Updated search functionality - Updated search functionality

View File

@ -1463,7 +1463,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
// Form submission / validation error // Form submission / validation error
showSnackIcon( showSnackIcon(
L10().formError, L10().formError,
success: false success: false,
); );
// Update field errors // Update field errors

View File

@ -1,12 +1,14 @@
import "dart:async"; import "dart:async";
import "package:flutter/material.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/purchase_order.dart"; import "package:inventree/inventree/purchase_order.dart";
import "package:inventree/widget/company/company_detail.dart";
/* /*
* The InvenTreeCompany class repreents the Company model in the InvenTree database. * The InvenTreeCompany class represents the Company model in the InvenTree database.
*/ */
class InvenTreeCompany extends InvenTreeModel { class InvenTreeCompany extends InvenTreeModel {
@ -20,6 +22,16 @@ class InvenTreeCompany extends InvenTreeModel {
static const String MODEL_TYPE = "company"; static const String MODEL_TYPE = "company";
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CompanyDetailWidget(this)
)
);
}
@override @override
List<String> get rolesRequired => ["purchase_order", "sales_order", "return_order"]; List<String> get rolesRequired => ["purchase_order", "sales_order", "return_order"];

View File

@ -48,6 +48,12 @@ class InvenTreeModel {
// Construct an InvenTreeModel from a JSON data object // Construct an InvenTreeModel from a JSON data object
InvenTreeModel.fromJson(this.jsondata); InvenTreeModel.fromJson(this.jsondata);
// Navigate to a detail page for this item
Future<Object?> goToDetailPage(BuildContext context) async {
// Default implementation does not do anything...
return null;
}
// Update whenever the model is loaded from the server // Update whenever the model is loaded from the server
DateTime? lastReload; DateTime? lastReload;
@ -311,6 +317,8 @@ class InvenTreeModel {
InvenTreeAPI get api => InvenTreeAPI(); InvenTreeAPI get api => InvenTreeAPI();
int get pk => getInt("pk"); int get pk => getInt("pk");
String get pkString => pk.toString();
// Some common accessors // Some common accessors
String get name => getString("name"); String get name => getString("name");

View File

@ -119,4 +119,43 @@ class InvenTreeOrderLine extends InvenTreeModel {
String get partImage => getString("thumbnail", subKey: "part_detail"); String get partImage => getString("thumbnail", subKey: "part_detail");
String get targetDate => getDateString("target_date"); String get targetDate => getDateString("target_date");
}
/*
* Generic class representing an "ExtraLineItem"
*/
class InvenTreeExtraLineItem extends InvenTreeModel {
InvenTreeExtraLineItem() : super();
InvenTreeExtraLineItem.fromJson(Map<String, dynamic> json) : super.fromJson(json);
int get orderId => getInt("order");
double get quantity => getDouble("quantity");
String get reference => getString("reference");
double get price => getDouble("price");
String get priceCurrency => getString("price_currency");
@override
Map<String, Map<String, dynamic>> formFields() {
return {
"order": {
// The order cannot be edited
"hidden": true,
},
"reference": {},
"description": {},
"quantity": {},
"price": {},
"price_currency": {},
"link": {},
"notes": {},
};
}
} }

View File

@ -10,6 +10,8 @@ import "package:inventree/l10.dart";
import "package:inventree/inventree/stock.dart"; import "package:inventree/inventree/stock.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/widget/part/category_display.dart";
import "package:inventree/widget/part/part_detail.dart";
/* /*
@ -29,6 +31,18 @@ class InvenTreePartCategory extends InvenTreeModel {
@override @override
List<String> get rolesRequired => ["part"]; List<String> get rolesRequired => ["part"];
// Navigate to a detail page for this item
@override
Future<Object?> goToDetailPage(BuildContext context) async {
// Default implementation does not do anything...
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CategoryDisplayWidget(this)
)
);
}
@override @override
Map<String, Map<String, dynamic>> formFields() { Map<String, Map<String, dynamic>> formFields() {
@ -202,6 +216,18 @@ class InvenTreePart extends InvenTreeModel {
@override @override
List<String> get rolesRequired => ["part"]; List<String> get rolesRequired => ["part"];
// Navigate to a detail page for this item
@override
Future<Object?> goToDetailPage(BuildContext context) async {
// Default implementation does not do anything...
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PartDetailWidget(this)
)
);
}
@override @override
Map<String, Map<String, dynamic>> formFields() { Map<String, Map<String, dynamic>> formFields() {
return { return {

View File

@ -1,10 +1,12 @@
import "package:flutter/cupertino.dart"; import "package:flutter/material.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart"; import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
import "package:inventree/helpers.dart"; import "package:inventree/helpers.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/orders.dart"; import "package:inventree/inventree/orders.dart";
import "package:inventree/widget/order/extra_line_detail.dart";
import "package:inventree/widget/order/purchase_order_detail.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/api_form.dart"; import "package:inventree/api_form.dart";
@ -26,6 +28,16 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
@override @override
String get URL => "order/po/"; String get URL => "order/po/";
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PurchaseOrderDetailWidget(this)
)
);
}
static const String MODEL_TYPE = "purchaseorder"; static const String MODEL_TYPE = "purchaseorder";
@override @override
@ -310,6 +322,35 @@ class InvenTreePOLineItem extends InvenTreeOrderLine {
} }
} }
class InvenTreePOExtraLineItem extends InvenTreeExtraLineItem {
InvenTreePOExtraLineItem() : super();
InvenTreePOExtraLineItem.fromJson(Map<String, dynamic> json) : super.fromJson(json);
@override
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreePOExtraLineItem.fromJson(json);
@override
String get URL => "order/po-extra-line/";
@override
List<String> get rolesRequired => ["purchase_order"];
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExtraLineDetailWidget(this)
)
);
}
}
/* /*
* Class representing an attachment file against a PurchaseOrder object * Class representing an attachment file against a PurchaseOrder object
*/ */

View File

@ -1,12 +1,15 @@
import "package:flutter/material.dart";
import "package:inventree/api.dart";
import "package:inventree/helpers.dart"; import "package:inventree/helpers.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/orders.dart"; import "package:inventree/inventree/orders.dart";
import "package:inventree/api.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/order/extra_line_detail.dart";
import "package:inventree/widget/order/sales_order_detail.dart";
/* /*
@ -31,6 +34,16 @@ class InvenTreeSalesOrder extends InvenTreeOrder {
String get allocate_url => "${url}allocate/"; String get allocate_url => "${url}allocate/";
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SalesOrderDetailWidget(this)
)
);
}
@override @override
Map<String, Map<String, dynamic>> formFields() { Map<String, Map<String, dynamic>> formFields() {
Map<String, Map<String, dynamic>> fields = { Map<String, Map<String, dynamic>> fields = {
@ -239,6 +252,31 @@ class InvenTreeSOLineItem extends InvenTreeOrderLine {
} }
class InvenTreeSOExtraLineItem extends InvenTreeExtraLineItem {
InvenTreeSOExtraLineItem() : super();
InvenTreeSOExtraLineItem.fromJson(Map<String, dynamic> json) : super.fromJson(json);
@override
InvenTreeModel createFromJson(Map<String, dynamic> json) => InvenTreeSOExtraLineItem.fromJson(json);
@override
String get URL => "order/so-extra-line/";
@override
List<String> get rolesRequired => ["sales_order"];
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExtraLineDetailWidget(this)
)
);
}
}
/* /*
* Class representing a sales order shipment * Class representing a sales order shipment
*/ */

View File

@ -1,11 +1,14 @@
import "dart:async"; import "dart:async";
import "package:flutter/material.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
import "package:inventree/helpers.dart"; import "package:inventree/helpers.dart";
import "package:inventree/l10.dart"; import "package:inventree/l10.dart";
import "package:inventree/inventree/part.dart"; import "package:inventree/inventree/part.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/widget/stock/location_display.dart";
import "package:inventree/widget/stock/stock_detail.dart";
@ -157,6 +160,16 @@ class InvenTreeStockItem extends InvenTreeModel {
@override @override
List<String> get rolesRequired => ["stock"]; List<String> get rolesRequired => ["stock"];
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StockDetailWidget(this)
)
);
}
// Return a set of fields to transfer this stock item via dialog // Return a set of fields to transfer this stock item via dialog
Map<String, dynamic> transferFields() { Map<String, dynamic> transferFields() {
Map<String, dynamic> fields = { Map<String, dynamic> fields = {
@ -648,6 +661,16 @@ class InvenTreeStockLocation extends InvenTreeModel {
String get pathstring => getString("pathstring"); String get pathstring => getString("pathstring");
@override
Future<Object?> goToDetailPage(BuildContext context) async {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LocationDisplayWidget(this)
)
);
}
@override @override
Map<String, Map<String, dynamic>> formFields() { Map<String, Map<String, dynamic>> formFields() {
Map<String, Map<String, dynamic>> fields = { Map<String, Map<String, dynamic>> fields = {

View File

@ -417,6 +417,12 @@
"expiryStale": "Stale", "expiryStale": "Stale",
"@expiryStale": {}, "@expiryStale": {},
"extraLineItem": "Extra Line Item",
"@extraLineItem": {},
"extraLineItems": "Extra Line Items",
"@extraLineItems": {},
"feedback": "Feedback", "feedback": "Feedback",
"@feedback": {}, "@feedback": {},

View File

@ -6,19 +6,15 @@ import "package:inventree/l10.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
import "package:inventree/app_colors.dart"; import "package:inventree/app_colors.dart";
import "package:inventree/helpers.dart"; import "package:inventree/helpers.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/purchase_order.dart"; import "package:inventree/inventree/purchase_order.dart";
import "package:inventree/inventree/sales_order.dart"; import "package:inventree/inventree/sales_order.dart";
import "package:inventree/widget/attachment_widget.dart"; import "package:inventree/widget/attachment_widget.dart";
import "package:inventree/widget/order/purchase_order_list.dart"; import "package:inventree/widget/order/purchase_order_list.dart";
import "package:inventree/widget/order/sales_order_list.dart"; import "package:inventree/widget/order/sales_order_list.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/company/supplier_part_list.dart"; import "package:inventree/widget/company/supplier_part_list.dart";
import "package:inventree/widget/order/sales_order_detail.dart";
import "package:inventree/widget/order/purchase_order_detail.dart";
/* /*
@ -121,13 +117,7 @@ class _CompanyDetailState extends RefreshableState<CompanyDetailWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var order = InvenTreeSalesOrder.fromJson(data); var order = InvenTreeSalesOrder.fromJson(data);
order.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SalesOrderDetailWidget(order)
)
);
} }
} }
); );
@ -150,13 +140,7 @@ class _CompanyDetailState extends RefreshableState<CompanyDetailWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var order = InvenTreePurchaseOrder.fromJson(data); var order = InvenTreePurchaseOrder.fromJson(data);
order.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PurchaseOrderDetailWidget(order)
)
);
} }
} }
); );

View File

@ -11,7 +11,6 @@ import "package:inventree/inventree/model.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/company/company_detail.dart";
/* /*
@ -48,13 +47,7 @@ class _CompanyListWidgetState extends RefreshableState<CompanyListWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var company = InvenTreeCompany.fromJson(data); var company = InvenTreeCompany.fromJson(data);
company.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CompanyDetailWidget(company)
)
);
} }
} }
); );
@ -137,7 +130,7 @@ class _CompanyListState extends PaginatedSearchState<PaginatedCompanyList> {
subtitle: Text(company.description), subtitle: Text(company.description),
leading: InvenTreeAPI().getThumbnail(company.image), leading: InvenTreeAPI().getThumbnail(company.image),
onTap: () async { onTap: () async {
Navigator.push(context, MaterialPageRoute(builder: (context) => CompanyDetailWidget(company))); company.goToDetailPage(context);
}, },
); );
} }

View File

@ -13,9 +13,6 @@ import "package:inventree/inventree/part.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/company/company_detail.dart";
import "package:url_launcher/url_launcher.dart"; import "package:url_launcher/url_launcher.dart";
/* /*
@ -114,8 +111,7 @@ class _ManufacturerPartDisplayState extends RefreshableState<ManufacturerPartDet
hideLoadingOverlay(); hideLoadingOverlay();
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute( part.goToDetailPage(context);
builder: (context) => PartDetailWidget(part)));
} }
}, },
) )
@ -134,9 +130,7 @@ class _ManufacturerPartDisplayState extends RefreshableState<ManufacturerPartDet
hideLoadingOverlay(); hideLoadingOverlay();
if (supplier is InvenTreeCompany) { if (supplier is InvenTreeCompany) {
Navigator.push(context, MaterialPageRoute( supplier.goToDetailPage(context);
builder: (context) => CompanyDetailWidget(supplier)
));
} }
} }
) )

View File

@ -15,9 +15,7 @@ import "package:inventree/inventree/company.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/company/company_detail.dart";
import "package:inventree/widget/company/manufacturer_part_detail.dart"; import "package:inventree/widget/company/manufacturer_part_detail.dart";
import "package:inventree/widget/part/part_detail.dart";
/* /*
@ -126,8 +124,7 @@ class _SupplierPartDisplayState extends RefreshableState<SupplierPartDetailWidge
hideLoadingOverlay(); hideLoadingOverlay();
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute( part.goToDetailPage(context);
builder: (context) => PartDetailWidget(part)));
} }
}, },
) )
@ -169,9 +166,7 @@ class _SupplierPartDisplayState extends RefreshableState<SupplierPartDetailWidge
hideLoadingOverlay(); hideLoadingOverlay();
if (supplier is InvenTreeCompany) { if (supplier is InvenTreeCompany) {
Navigator.push(context, MaterialPageRoute( supplier.goToDetailPage(context);
builder: (context) => CompanyDetailWidget(supplier)
));
} }
} }
) )
@ -200,9 +195,7 @@ class _SupplierPartDisplayState extends RefreshableState<SupplierPartDetailWidge
hideLoadingOverlay(); hideLoadingOverlay();
if (supplier is InvenTreeCompany) { if (supplier is InvenTreeCompany) {
Navigator.push(context, MaterialPageRoute( supplier.goToDetailPage(context);
builder: (context) => CompanyDetailWidget(supplier)
));
} }
} }
) )

View File

@ -0,0 +1,112 @@
import "package:flutter/material.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/helpers.dart";
import "package:inventree/l10.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart";
import "package:inventree/inventree/orders.dart";
class ExtraLineDetailWidget extends StatefulWidget {
const ExtraLineDetailWidget(this.item, {Key? key}) : super(key: key);
final InvenTreeExtraLineItem item;
@override
_ExtraLineDetailWidgetState createState() => _ExtraLineDetailWidgetState();
}
class _ExtraLineDetailWidgetState extends RefreshableState<ExtraLineDetailWidget> {
_ExtraLineDetailWidgetState();
@override
String getAppBarTitle() => L10().extraLineItem;
@override
List<Widget> appBarActions(BuildContext context) {
List<Widget> actions = [];
if (widget.item.canEdit) {
actions.add(
IconButton(
icon: Icon(TablerIcons.edit),
onPressed: () {
_editLineItem(context);
}
)
);
}
return actions;
}
// Function to request data for this page
@override
Future<void> request(BuildContext context) async {
await widget.item.reload();
}
// Callback to edit this line item
Future<void> _editLineItem(BuildContext context) async {
var fields = widget.item.formFields();
widget.item.editForm(
context,
L10().editLineItem,
fields: fields,
onSuccess: (data) async {
refresh(context);
showSnackIcon(L10().lineItemUpdated, success: true);
}
);
}
@override
List<Widget> getTiles(BuildContext context) {
List<Widget> tiles = [];
tiles.add(
ListTile(
title: Text(L10().reference),
trailing: Text(widget.item.reference),
)
);
tiles.add(
ListTile(
title: Text(L10().description),
trailing: Text(widget.item.description),
)
);
tiles.add(
ListTile(
title: Text(L10().quantity),
trailing: Text(widget.item.quantity.toString()),
)
);
tiles.add(
ListTile(
title: Text(L10().unitPrice),
trailing: Text(
renderCurrency(widget.item.price, widget.item.priceCurrency)
)
)
);
if (widget.item.notes.isNotEmpty) {
tiles.add(
ListTile(
title: Text(L10().notes),
subtitle: Text(widget.item.notes),
)
);
}
return tiles;
}
}

View File

@ -0,0 +1,116 @@
import "package:flutter/material.dart";
import "package:flutter_speed_dial/flutter_speed_dial.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/l10.dart";
import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/purchase_order.dart";
import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart";
class POExtraLineListWidget extends StatefulWidget {
const POExtraLineListWidget(this.order, {this.filters = const {}, Key? key}) : super(key: key);
final InvenTreePurchaseOrder order;
final Map<String, String> filters;
@override
_PurchaseOrderExtraLineListWidgetState createState() => _PurchaseOrderExtraLineListWidgetState();
}
class _PurchaseOrderExtraLineListWidgetState extends RefreshableState<POExtraLineListWidget> {
_PurchaseOrderExtraLineListWidgetState();
@override
String getAppBarTitle() => L10().extraLineItems;
Future<void> _addLineItem(BuildContext context) async {
var fields = InvenTreePOExtraLineItem().formFields();
fields["order"]?["value"] = widget.order.pk;
InvenTreePOExtraLineItem().createForm(
context,
L10().lineItemAdd,
fields: fields,
onSuccess: (data) async {
refresh(context);
showSnackIcon(L10().lineItemUpdated, success: true);
}
);
}
@override
List<SpeedDialChild> actionButtons(BuildContext context) {
List<SpeedDialChild> actions = [];
if (widget.order.canEdit) {
actions.add(
SpeedDialChild(
child: Icon(TablerIcons.circle_plus, color: Colors.green),
label: L10().lineItemAdd,
onTap: () {
_addLineItem(context);
}
)
);
}
return actions;
}
@override
Widget getBody(BuildContext context) {
return PaginatedPOExtraLineList(widget.filters);
}
}
class PaginatedPOExtraLineList extends PaginatedSearchWidget {
const PaginatedPOExtraLineList(Map<String, String> filters) : super(filters: filters);
@override
String get searchTitle => L10().extraLineItems;
@override
_PaginatedPOExtraLineListState createState() => _PaginatedPOExtraLineListState();
}
class _PaginatedPOExtraLineListState extends PaginatedSearchState<PaginatedPOExtraLineList> {
_PaginatedPOExtraLineListState() : super();
@override
String get prefix => "po_extra_line_";
@override
Future<InvenTreePageResponse?> requestPage(int limit, int offset, Map<String, String> params) async {
final page = await InvenTreePOExtraLineItem().listPaginated(limit, offset, filters: params);
return page;
}
@override
Widget buildItem(BuildContext context, InvenTreeModel model) {
InvenTreePOExtraLineItem line = model as InvenTreePOExtraLineItem;
return ListTile(
title: Text(line.reference),
subtitle: Text(line.description),
trailing: Text(line.quantity.toString()),
onTap: () {
line.goToDetailPage(context).then((_) {
refresh();
});
},
);
}
}

View File

@ -13,8 +13,6 @@ import "package:inventree/inventree/purchase_order.dart";
import "package:inventree/inventree/stock.dart"; import "package:inventree/inventree/stock.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/stock/location_display.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/company/supplier_part_detail.dart"; import "package:inventree/widget/company/supplier_part_detail.dart";
@ -157,7 +155,7 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part))); part.goToDetailPage(context);
} }
}, },
) )
@ -187,14 +185,8 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
title: Text(L10().destination), title: Text(L10().destination),
subtitle: Text(destination!.name), subtitle: Text(destination!.name),
leading: Icon(TablerIcons.map_pin, color: COLOR_ACTION), leading: Icon(TablerIcons.map_pin, color: COLOR_ACTION),
onTap: () => onTap: () => {
{ destination!.goToDetailPage(context)
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LocationDisplayWidget(destination)
)
)
} }
)); ));
} }

View File

@ -14,12 +14,12 @@ import "package:inventree/inventree/stock.dart";
import "package:inventree/inventree/purchase_order.dart"; import "package:inventree/inventree/purchase_order.dart";
import "package:inventree/widget/dialogs.dart"; import "package:inventree/widget/dialogs.dart";
import "package:inventree/widget/order/po_extra_line_list.dart";
import "package:inventree/widget/stock/location_display.dart"; import "package:inventree/widget/stock/location_display.dart";
import "package:inventree/widget/order/po_line_list.dart"; import "package:inventree/widget/order/po_line_list.dart";
import "package:inventree/widget/attachment_widget.dart"; import "package:inventree/widget/attachment_widget.dart";
import "package:inventree/widget/company/company_detail.dart";
import "package:inventree/widget/notes_widget.dart"; import "package:inventree/widget/notes_widget.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -47,11 +47,11 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
_PurchaseOrderDetailState(); _PurchaseOrderDetailState();
List<InvenTreePOLineItem> lines = []; List<InvenTreePOLineItem> lines = [];
int extraLineCount = 0;
InvenTreeStockLocation? destination; InvenTreeStockLocation? destination;
int completedLines = 0; int completedLines = 0;
int attachmentCount = 0; int attachmentCount = 0;
bool showCameraShortcut = true; bool showCameraShortcut = true;
@ -296,6 +296,15 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
}); });
} }
} }
// Count number of "extra line items" against this order
InvenTreePOExtraLineItem().count(filters: {"order": widget.order.pk.toString() }).then((int value) {
if (mounted) {
setState(() {
extraLineCount = value;
});
}
});
} }
// Edit the currently displayed PurchaseOrder // Edit the currently displayed PurchaseOrder
@ -368,12 +377,7 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
subtitle: Text(supplier.name), subtitle: Text(supplier.name),
leading: Icon(TablerIcons.building, color: COLOR_ACTION), leading: Icon(TablerIcons.building, color: COLOR_ACTION),
onTap: () { onTap: () {
Navigator.push( supplier.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => CompanyDetailWidget(supplier)
)
);
}, },
)); ));
} }
@ -415,6 +419,21 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
trailing: Text("${completedLines} / ${widget.order.lineItemCount}", style: TextStyle(color: lineColor)), trailing: Text("${completedLines} / ${widget.order.lineItemCount}", style: TextStyle(color: lineColor)),
)); ));
// Extra line items
tiles.add(ListTile(
title: Text(L10().extraLineItems),
leading: Icon(TablerIcons.clipboard_list, color: COLOR_ACTION),
trailing: Text(extraLineCount.toString()),
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => POExtraLineListWidget(widget.order, filters: {"order": widget.order.pk.toString()})
)
)
},
));
tiles.add(ListTile( tiles.add(ListTile(
title: Text(L10().totalPrice), title: Text(L10().totalPrice),
leading: Icon(TablerIcons.currency_dollar), leading: Icon(TablerIcons.currency_dollar),

View File

@ -5,7 +5,6 @@ import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/order/purchase_order_detail.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/l10.dart"; import "package:inventree/l10.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
@ -69,13 +68,7 @@ class _PurchaseOrderListWidgetState extends RefreshableState<PurchaseOrderListWi
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var order = InvenTreePurchaseOrder.fromJson(data); var order = InvenTreePurchaseOrder.fromJson(data);
order.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PurchaseOrderDetailWidget(order)
)
);
} }
} }
); );
@ -184,12 +177,7 @@ class _PaginatedPurchaseOrderListState extends PaginatedSearchState<PaginatedPur
), ),
), ),
onTap: () async { onTap: () async {
Navigator.push( order.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => PurchaseOrderDetailWidget(order)
)
);
}, },
); );
} }

View File

@ -7,6 +7,7 @@ import "package:inventree/barcode/sales_order.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/sales_order.dart"; import "package:inventree/inventree/sales_order.dart";
import "package:inventree/preferences.dart"; import "package:inventree/preferences.dart";
import "package:inventree/widget/order/so_extra_line_list.dart";
import "package:inventree/widget/order/so_line_list.dart"; import "package:inventree/widget/order/so_line_list.dart";
import "package:inventree/widget/order/so_shipment_list.dart"; import "package:inventree/widget/order/so_shipment_list.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -18,7 +19,6 @@ import "package:inventree/widget/attachment_widget.dart";
import "package:inventree/widget/dialogs.dart"; import "package:inventree/widget/dialogs.dart";
import "package:inventree/widget/notes_widget.dart"; import "package:inventree/widget/notes_widget.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/company/company_detail.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
/* /*
@ -40,6 +40,7 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
_SalesOrderDetailState(); _SalesOrderDetailState();
List<InvenTreeSOLineItem> lines = []; List<InvenTreeSOLineItem> lines = [];
int extraLineCount = 0;
bool showCameraShortcut = true; bool showCameraShortcut = true;
bool supportsProjectCodes = false; bool supportsProjectCodes = false;
@ -270,6 +271,15 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
}); });
} }
}); });
// Count number of "extra line items" against this order
InvenTreeSOExtraLineItem().count(filters: {"order": widget.order.pk.toString() }).then((int value) {
if (mounted) {
setState(() {
extraLineCount = value;
});
}
});
} }
// Edit the current SalesOrder instance // Edit the current SalesOrder instance
@ -340,12 +350,7 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
subtitle: Text(customer.name), subtitle: Text(customer.name),
leading: Icon(TablerIcons.user, color: COLOR_ACTION), leading: Icon(TablerIcons.user, color: COLOR_ACTION),
onTap: () { onTap: () {
Navigator.push( customer.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => CompanyDetailWidget(customer)
)
);
} }
)); ));
} }
@ -370,6 +375,21 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
trailing: Text("${widget.order.completedLineItemCount} / ${widget.order.lineItemCount}", style: TextStyle(color: lineColor)), trailing: Text("${widget.order.completedLineItemCount} / ${widget.order.lineItemCount}", style: TextStyle(color: lineColor)),
)); ));
// Extra line items
tiles.add(ListTile(
title: Text(L10().extraLineItems),
leading: Icon(TablerIcons.clipboard_list, color: COLOR_ACTION),
trailing: Text(extraLineCount.toString()),
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SOExtraLineListWidget(widget.order, filters: {"order": widget.order.pk.toString()})
)
)
},
));
// Shipment progress // Shipment progress
if (widget.order.shipmentCount > 0) { if (widget.order.shipmentCount > 0) {
tiles.add(ListTile( tiles.add(ListTile(

View File

@ -3,7 +3,6 @@ import "package:flutter/material.dart";
import "package:flutter_speed_dial/flutter_speed_dial.dart"; import "package:flutter_speed_dial/flutter_speed_dial.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart"; import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/inventree/sales_order.dart"; import "package:inventree/inventree/sales_order.dart";
import "package:inventree/widget/order/sales_order_detail.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -67,13 +66,7 @@ class _SalesOrderListWidgetState extends RefreshableState<SalesOrderListWidget>
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var order = InvenTreeSalesOrder.fromJson(data); var order = InvenTreeSalesOrder.fromJson(data);
order.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SalesOrderDetailWidget(order)
)
);
} }
} }
); );
@ -167,12 +160,7 @@ class _PaginatedSalesOrderListState extends PaginatedSearchState<PaginatedSalesO
) )
), ),
onTap: () async { onTap: () async {
Navigator.push( order.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => SalesOrderDetailWidget(order)
)
);
} }
); );

View File

@ -0,0 +1,118 @@
import "package:flutter/material.dart";
import "package:flutter_speed_dial/flutter_speed_dial.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/l10.dart";
import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/sales_order.dart";
import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart";
class SOExtraLineListWidget extends StatefulWidget {
const SOExtraLineListWidget(this.order, {this.filters = const {}, Key? key}) : super(key: key);
final InvenTreeSalesOrder order;
final Map<String, String> filters;
@override
_SalesOrderExtraLineListWidgetState createState() => _SalesOrderExtraLineListWidgetState();
}
class _SalesOrderExtraLineListWidgetState extends RefreshableState<SOExtraLineListWidget> {
_SalesOrderExtraLineListWidgetState();
@override
String getAppBarTitle() => L10().extraLineItems;
Future<void> _addLineItem(BuildContext context) async {
var fields = InvenTreeSOExtraLineItem().formFields();
fields["order"]?["value"] = widget.order.pk;
InvenTreeSOExtraLineItem().createForm(
context,
L10().lineItemAdd,
fields: fields,
onSuccess: (data) async {
refresh(context);
showSnackIcon(L10().lineItemUpdated, success: true);
}
);
}
@override
List<SpeedDialChild> actionButtons(BuildContext context) {
List<SpeedDialChild> actions = [];
if (widget.order.canEdit) {
actions.add(
SpeedDialChild(
child: Icon(TablerIcons.circle_plus, color: Colors.green),
label: L10().lineItemAdd,
onTap: () {
_addLineItem(context);
}
)
);
}
return actions;
}
@override
Widget getBody(BuildContext context) {
return PaginatedSOExtraLineList(widget.filters);
}
}
class PaginatedSOExtraLineList extends PaginatedSearchWidget {
const PaginatedSOExtraLineList(Map<String, String> filters) : super(filters: filters);
@override
String get searchTitle => L10().extraLineItems;
@override
_PaginatedSOExtraLineListState createState() => _PaginatedSOExtraLineListState();
}
class _PaginatedSOExtraLineListState extends PaginatedSearchState<PaginatedSOExtraLineList> {
_PaginatedSOExtraLineListState() : super();
@override
String get prefix => "so_extra_line_";
@override
Future<InvenTreePageResponse?> requestPage(int limit, int offset, Map<String, String> params) async {
final page = await InvenTreeSOExtraLineItem().listPaginated(limit, offset, filters: params);
return page;
}
@override
Widget buildItem(BuildContext context, InvenTreeModel model) {
InvenTreeSOExtraLineItem line = model as InvenTreeSOExtraLineItem;
return ListTile(
title: Text(line.reference),
subtitle: Text(line.description),
trailing: Text(line.quantity.toString()),
onTap: () {
line.goToDetailPage(context).then((_) {
refresh();
});
},
);
}
}

View File

@ -15,7 +15,6 @@ import "package:inventree/inventree/sales_order.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/app_colors.dart"; import "package:inventree/app_colors.dart";
@ -192,7 +191,7 @@ class _SOLineDetailWidgetState extends RefreshableState<SoLineDetailWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part))); part.goToDetailPage(context);
} }
} }
) )

View File

@ -257,6 +257,10 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
// Pagination controller // Pagination controller
final PagingController<int, InvenTreeModel> _pagingController = PagingController(firstPageKey: 0); final PagingController<int, InvenTreeModel> _pagingController = PagingController(firstPageKey: 0);
void refresh() {
_pagingController.refresh();
}
@override @override
void initState() { void initState() {
_pagingController.addPageRequestListener((pageKey) { _pagingController.addPageRequestListener((pageKey) {

View File

@ -11,7 +11,6 @@ import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/part.dart"; import "package:inventree/inventree/part.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -159,7 +158,7 @@ class _PaginatedBomListState extends PaginatedSearchState<PaginatedBomList> {
hideLoadingOverlay(); hideLoadingOverlay();
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part))); part.goToDetailPage(context);
} }
}, },
); );

View File

@ -11,7 +11,6 @@ import "package:inventree/widget/part/category_list.dart";
import "package:inventree/widget/part/part_list.dart"; import "package:inventree/widget/part/part_list.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -164,7 +163,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (cat is InvenTreePartCategory) { if (cat is InvenTreePartCategory) {
Navigator.push(context, MaterialPageRoute(builder: (context) => CategoryDisplayWidget(cat))); cat.goToDetailPage(context);
} }
} }
}, },
@ -255,13 +254,9 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var cat = InvenTreePartCategory.fromJson(data); var cat = InvenTreePartCategory.fromJson(data);
cat.goToDetailPage(context).then((_) {
Navigator.push( refresh(context);
context, });
MaterialPageRoute(
builder: (context) => CategoryDisplayWidget(cat)
)
);
} else { } else {
refresh(context); refresh(context);
} }
@ -285,13 +280,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var part = InvenTreePart.fromJson(data); var part = InvenTreePart.fromJson(data);
part.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PartDetailWidget(part)
)
);
} }
} }
); );

View File

@ -2,7 +2,6 @@ import "package:flutter/material.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/part.dart"; import "package:inventree/inventree/part.dart";
import "package:inventree/widget/part/category_display.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -100,12 +99,7 @@ class _PaginatedPartCategoryListState extends PaginatedSearchState<PaginatedPart
trailing: Text("${category.partcount}"), trailing: Text("${category.partcount}"),
leading: category.customIcon == null ? null : Icon(category.customIcon), leading: category.customIcon == null ? null : Icon(category.customIcon),
onTap: () { onTap: () {
Navigator.push( category.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => CategoryDisplayWidget(category)
)
);
}, },
); );
} }

View File

@ -23,7 +23,6 @@ import "package:inventree/widget/part/category_display.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/part/part_image_widget.dart"; import "package:inventree/widget/part/part_image_widget.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/stock/stock_detail.dart";
import "package:inventree/widget/stock/stock_list.dart"; import "package:inventree/widget/stock/stock_list.dart";
import "package:inventree/widget/company/supplier_part_list.dart"; import "package:inventree/widget/company/supplier_part_list.dart";
@ -347,10 +346,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
height: 32, height: 32,
), ),
onTap: () { onTap: () {
Navigator.push( parentPart?.goToDetailPage(context);
context,
MaterialPageRoute(builder: (context) => PartDetailWidget(parentPart!))
);
} }
) )
); );
@ -371,8 +367,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (cat is InvenTreePartCategory) { if (cat is InvenTreePartCategory) {
Navigator.push(context, MaterialPageRoute( cat.goToDetailPage(context);
builder: (context) => CategoryDisplayWidget(cat)));
} }
} }
}, },
@ -674,13 +669,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var item = InvenTreeStockItem.fromJson(data); var item = InvenTreeStockItem.fromJson(data);
item.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StockDetailWidget(item)
)
);
} }
} }
); );

View File

@ -7,7 +7,6 @@ import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/part.dart"; import "package:inventree/inventree/part.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -132,7 +131,7 @@ class _PaginatedPartListState extends PaginatedSearchState<PaginatedPartList> {
), ),
leading: InvenTreeAPI().getThumbnail(part.thumbnail), leading: InvenTreeAPI().getThumbnail(part.thumbnail),
onTap: () { onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part))); part.goToDetailPage(context);
}, },
); );
} }

View File

@ -7,7 +7,6 @@ import "package:inventree/api.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:inventree/inventree/part.dart"; import "package:inventree/inventree/part.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/widget/company/company_detail.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
class PartSupplierWidget extends StatefulWidget { class PartSupplierWidget extends StatefulWidget {
@ -58,12 +57,7 @@ class _PartSupplierState extends RefreshableState<PartSupplierWidget> {
var company = await InvenTreeCompany().get(_part.supplierId); var company = await InvenTreeCompany().get(_part.supplierId);
if (company != null && company is InvenTreeCompany) { if (company != null && company is InvenTreeCompany) {
Navigator.push( company.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => CompanyDetailWidget(company)
)
);
} }
}, },
); );

View File

@ -15,7 +15,6 @@ import "package:inventree/widget/stock/location_list.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
import "package:inventree/widget/stock/stock_detail.dart";
import "package:inventree/widget/stock/stock_list.dart"; import "package:inventree/widget/stock/stock_list.dart";
import "package:inventree/labels.dart"; import "package:inventree/labels.dart";
@ -279,13 +278,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var loc = InvenTreeStockLocation.fromJson(data); var loc = InvenTreeStockLocation.fromJson(data);
loc.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LocationDisplayWidget(loc)
)
);
} }
} }
); );
@ -317,13 +310,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
if (data.containsKey("pk")) { if (data.containsKey("pk")) {
var item = InvenTreeStockItem.fromJson(data); var item = InvenTreeStockItem.fromJson(data);
item.goToDetailPage(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StockDetailWidget(item)
)
);
} }
} }
); );
@ -367,8 +354,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (loc is InvenTreeStockLocation) { if (loc is InvenTreeStockLocation) {
Navigator.push(context, MaterialPageRoute( loc.goToDetailPage(context);
builder: (context) => LocationDisplayWidget(loc)));
} }
} }
}, },

View File

@ -2,7 +2,6 @@ import "package:flutter/material.dart";
import "package:inventree/inventree/model.dart"; import "package:inventree/inventree/model.dart";
import "package:inventree/inventree/stock.dart"; import "package:inventree/inventree/stock.dart";
import "package:inventree/widget/stock/location_display.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
@ -87,12 +86,7 @@ class _PaginatedStockLocationListState extends PaginatedSearchState<PaginatedSto
trailing: Text("${location.itemcount}"), trailing: Text("${location.itemcount}"),
leading: location.customIcon == null ? null : Icon(location.customIcon), leading: location.customIcon == null ? null : Icon(location.customIcon),
onTap: () { onTap: () {
Navigator.push( location.goToDetailPage(context);
context,
MaterialPageRoute(
builder: (context) => LocationDisplayWidget(location)
)
);
}, },
); );
} }

View File

@ -17,14 +17,10 @@ import "package:inventree/preferences.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
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/company/company_detail.dart";
import "package:inventree/widget/company/supplier_part_detail.dart"; import "package:inventree/widget/company/supplier_part_detail.dart";
import "package:inventree/widget/dialogs.dart"; import "package:inventree/widget/dialogs.dart";
import "package:inventree/widget/attachment_widget.dart"; import "package:inventree/widget/attachment_widget.dart";
import "package:inventree/widget/order/sales_order_detail.dart";
import "package:inventree/widget/stock/location_display.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
@ -531,7 +527,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (part is InvenTreePart) { if (part is InvenTreePart) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PartDetailWidget(part))); part.goToDetailPage(context);
} }
} }
}, },
@ -574,8 +570,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
hideLoadingOverlay(); hideLoadingOverlay();
if (loc is InvenTreeStockLocation) { if (loc is InvenTreeStockLocation) {
Navigator.push(context, MaterialPageRoute( loc.goToDetailPage(context);
builder: (context) => LocationDisplayWidget(loc)));
} }
} }
}, },
@ -690,9 +685,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
leading: Icon(TablerIcons.truck_delivery, color: COLOR_ACTION), leading: Icon(TablerIcons.truck_delivery, color: COLOR_ACTION),
trailing: Text(salesOrder?.reference ?? ""), trailing: Text(salesOrder?.reference ?? ""),
onTap: () { onTap: () {
Navigator.push(context, MaterialPageRoute( salesOrder?.goToDetailPage(context);
builder: (context) => SalesOrderDetailWidget(salesOrder!)
));
} }
) )
); );
@ -706,9 +699,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
leading: Icon(TablerIcons.building_store, color: COLOR_ACTION), leading: Icon(TablerIcons.building_store, color: COLOR_ACTION),
trailing: Text(customer?.name ?? ""), trailing: Text(customer?.name ?? ""),
onTap: () { onTap: () {
Navigator.push(context, MaterialPageRoute( customer?.goToDetailPage(context);
builder: (context) => CompanyDetailWidget(customer!)
));
}, },
) )
); );

View File

@ -5,7 +5,6 @@ import "package:inventree/inventree/stock.dart";
import "package:inventree/widget/paginator.dart"; import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/refreshable_state.dart"; import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/l10.dart"; import "package:inventree/l10.dart";
import "package:inventree/widget/stock/stock_detail.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
@ -146,7 +145,7 @@ class _PaginatedStockItemListState extends PaginatedSearchState<PaginatedStockIt
) )
), ),
onTap: () { onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => StockDetailWidget(item))); item.goToDetailPage(context);
}, },
); );
} }