Skip to content

Commit

Permalink
StockItem Updates (#550)
Browse files Browse the repository at this point in the history
* bump version

* Add new helpers for StockItem

* Navigate to sales order from stock item

* Navigate to customer (if specified)

* linting fix
  • Loading branch information
SchrodingersGat authored Nov 20, 2024
1 parent 1a1521e commit 20e454d
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 28 deletions.
5 changes: 5 additions & 0 deletions assets/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### 0.17.0 - November 2024
---

- Clearly indicate if a StockItem is unavailable

### 0.16.5 - September 2024
---

Expand Down
42 changes: 26 additions & 16 deletions lib/inventree/stock.dart
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,9 @@ class InvenTreeStockItem extends InvenTreeModel {
}

int get status => getInt("status");


bool get isInStock => getBool("in_stock", backup: true);

String get packaging => getString("packaging");

String get batch => getString("batch");
Expand Down Expand Up @@ -321,27 +323,35 @@ class InvenTreeStockItem extends InvenTreeModel {

bool get isBuilding => getBool("is_building");

// Date of last update
DateTime? get updatedDate {
if (jsondata.containsKey("updated")) {
return DateTime.tryParse((jsondata["updated"] ?? "") as String);
} else {
return null;
}
}
int get salesOrderId => getInt("sales_order");

String get updatedDateString {
var _updated = updatedDate;
bool get hasSalesOrder => salesOrderId > 0;

if (_updated == null) {
return "";
}
int get customerId => getInt("customer");

final DateFormat _format = DateFormat("yyyy-MM-dd");
bool get hasCustomer => customerId > 0;

return _format.format(_updated);
// Date of last update
DateTime? get updatedDate {
if (jsondata.containsKey("updated")) {
return DateTime.tryParse((jsondata["updated"] ?? "") as String);
} else {
return null;
}
}

String get updatedDateString {
var _updated = updatedDate;

if (_updated == null) {
return "";
}

final DateFormat _format = DateFormat("yyyy-MM-dd");

return _format.format(_updated);
}

DateTime? get stocktakeDate {
if (jsondata.containsKey("stocktake_date")) {
return DateTime.tryParse((jsondata["stocktake_date"] ?? "") as String);
Expand Down
6 changes: 6 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,12 @@
"translateHelp": "Help translate the InvenTree app",
"@translateHelp": {},

"unavailable": "Unavailable",
"@unavailable": {},

"unavailableDetail": "Item is not available",
"@unavailableDetail": {},

"unitPrice": "Unit Price",
"@unitPrice": {},

Expand Down
128 changes: 117 additions & 11 deletions lib/widget/stock/stock_detail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";
Expand Down Expand Up @@ -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 = [];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -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),
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: inventree
description: InvenTree stock management

version: 0.16.5+91
version: 0.17.0+92

environment:
sdk: ">=2.19.5 <3.13.0"
Expand Down

0 comments on commit 20e454d

Please sign in to comment.