mirror of
https://github.com/inventree/inventree-app.git
synced 2025-06-14 11:15:26 +00:00
StockItem Updates (#550)
* bump version * Add new helpers for StockItem * Navigate to sales order from stock item * Navigate to customer (if specified) * linting fix
This commit is contained in:
@ -7,6 +7,7 @@ import "package:inventree/app_colors.dart";
|
||||
import "package:inventree/barcode/barcode.dart";
|
||||
import "package:inventree/barcode/stock.dart";
|
||||
import "package:inventree/helpers.dart";
|
||||
import "package:inventree/inventree/sales_order.dart";
|
||||
import "package:inventree/l10.dart";
|
||||
import "package:inventree/api.dart";
|
||||
import "package:inventree/api_form.dart";
|
||||
@ -16,10 +17,12 @@ import "package:inventree/preferences.dart";
|
||||
import "package:inventree/inventree/company.dart";
|
||||
import "package:inventree/inventree/stock.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/dialogs.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";
|
||||
@ -51,6 +54,11 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
bool stockShowHistory = false;
|
||||
bool stockShowTests = true;
|
||||
|
||||
// Linked data fields
|
||||
InvenTreePart? part;
|
||||
InvenTreeSalesOrder? salesOrder;
|
||||
InvenTreeCompany? customer;
|
||||
|
||||
@override
|
||||
List<Widget> appBarActions(BuildContext context) {
|
||||
List<Widget> actions = [];
|
||||
@ -199,9 +207,6 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
// This will be determined when the widget is loaded
|
||||
List<Map<String, dynamic>> labels = [];
|
||||
|
||||
// Part object
|
||||
InvenTreePart? part;
|
||||
|
||||
int attachmentCount = 0;
|
||||
|
||||
@override
|
||||
@ -252,6 +257,40 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
}
|
||||
});
|
||||
|
||||
// Request SalesOrder information
|
||||
if (widget.item.hasSalesOrder) {
|
||||
InvenTreeSalesOrder().get(widget.item.salesOrderId).then((instance) => {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
salesOrder = instance as InvenTreeSalesOrder?;
|
||||
})
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
salesOrder = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Request Customer information
|
||||
if (widget.item.hasCustomer) {
|
||||
InvenTreeCompany().get(widget.item.customerId).then((instance) => {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
customer = instance as InvenTreeCompany?;
|
||||
})
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
customer = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> _labels = [];
|
||||
bool allowLabelPrinting = await InvenTreeSettingsManager().getBool(INV_ENABLE_LABEL_PRINTING, true);
|
||||
allowLabelPrinting &= api.supportsMixin("labels");
|
||||
@ -455,18 +494,32 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
}
|
||||
|
||||
Widget headerTile() {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
title: Text("${widget.item.partName}"),
|
||||
subtitle: Text("${widget.item.partDescription}"),
|
||||
leading: InvenTreeAPI().getThumbnail(widget.item.partImage),
|
||||
trailing: widget.item.isSerialized() ? null : Text(
|
||||
|
||||
Widget? trailing;
|
||||
|
||||
if (!widget.item.isInStock) {
|
||||
trailing = Text(
|
||||
L10().unavailable,
|
||||
style: TextStyle(
|
||||
color: COLOR_DANGER
|
||||
)
|
||||
);
|
||||
} else if (!widget.item.isSerialized()) {
|
||||
trailing = Text(
|
||||
widget.item.quantityString(),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: api.StockStatus.color(widget.item.status),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Card(
|
||||
child: ListTile(
|
||||
title: Text("${widget.item.partName}"),
|
||||
subtitle: Text("${widget.item.partDescription}"),
|
||||
leading: InvenTreeAPI().getThumbnail(widget.item.partImage),
|
||||
trailing: trailing,
|
||||
onTap: () async {
|
||||
if (widget.item.partId > 0) {
|
||||
|
||||
@ -544,7 +597,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
subtitle: Text("${widget.item.serialNumber}"),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
} else if (widget.item.isInStock) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: widget.item.allocated > 0 ? Text(L10().quantityAvailable) : Text(L10().quantity),
|
||||
@ -554,6 +607,27 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
if (!widget.item.isInStock) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
leading: Icon(TablerIcons.box_off),
|
||||
title: Text(
|
||||
L10().unavailable,
|
||||
style: TextStyle(
|
||||
color: COLOR_DANGER,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
L10().unavailableDetail,
|
||||
style: TextStyle(
|
||||
color: COLOR_DANGER
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Stock item status information
|
||||
tiles.add(
|
||||
ListTile(
|
||||
@ -605,6 +679,38 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.item.hasSalesOrder && salesOrder != null) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().salesOrder),
|
||||
subtitle: Text(salesOrder?.description ?? ""),
|
||||
leading: Icon(TablerIcons.truck_delivery, color: COLOR_ACTION),
|
||||
trailing: Text(salesOrder?.reference ?? ""),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => SalesOrderDetailWidget(salesOrder!)
|
||||
));
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.item.hasCustomer && customer != null) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
title: Text(L10().customer),
|
||||
subtitle: Text(customer?.description ?? ""),
|
||||
leading: Icon(TablerIcons.building_store, color: COLOR_ACTION),
|
||||
trailing: Text(customer?.name ?? ""),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) => CompanyDetailWidget(customer!)
|
||||
));
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (widget.item.batch.isNotEmpty) {
|
||||
tiles.add(
|
||||
ListTile(
|
||||
|
Reference in New Issue
Block a user