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

Merge pull request #572 from inventree/order-updates

Order updates
This commit is contained in:
Oliver 2024-12-11 16:44:36 +11:00 committed by GitHub
commit 9745bcfdb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 143 additions and 11 deletions

View File

@ -2,6 +2,7 @@
--- ---
- Fixes barcode scanning bug which prevents scanning of DataMatrix codes - Fixes barcode scanning bug which prevents scanning of DataMatrix codes
- Display "destination" information in PurchaseOrder detail view
- Adds "assigned to me" filter for Purchase Order list - Adds "assigned to me" filter for Purchase Order list
- Adds "assigned to me" filter for Sales Order list - Adds "assigned to me" filter for Sales Order list

View File

@ -333,6 +333,10 @@ class InvenTreeAPI {
// Ref: https://github.com/inventree/InvenTree/pull/7420 // Ref: https://github.com/inventree/InvenTree/pull/7420
bool get supportsModernAttachments => isConnected() && apiVersion >= 207; bool get supportsModernAttachments => isConnected() && apiVersion >= 207;
// Does the server support the "destination" field on the PurchaseOrder model?
// Ref: https://github.com/inventree/InvenTree/pull/8403
bool get supportsPurchaseOrderDestination => isConnected() && apiVersion >= 276;
// Cached list of plugins (refreshed when we connect to the server) // Cached list of plugins (refreshed when we connect to the server)
List<InvenTreePlugin> _plugins = []; List<InvenTreePlugin> _plugins = [];

View File

@ -40,6 +40,7 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
"supplier_reference": {}, "supplier_reference": {},
"description": {}, "description": {},
"project_code": {}, "project_code": {},
"destination": {},
"target_date": {}, "target_date": {},
"link": {}, "link": {},
"responsible": {}, "responsible": {},
@ -54,6 +55,10 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
fields.remove("project_code"); fields.remove("project_code");
} }
if (!InvenTreeAPI().supportsPurchaseOrderDestination) {
fields.remove("destination");
}
return fields; return fields;
} }
@ -87,6 +92,8 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
String get supplierReference => getString("supplier_reference"); String get supplierReference => getString("supplier_reference");
int get destinationId => getInt("destination");
bool get isOpen => api.PurchaseOrderStatus.isNameIn(status, ["PENDING", "PLACED", "ON_HOLD"]); bool get isOpen => api.PurchaseOrderStatus.isNameIn(status, ["PENDING", "PLACED", "ON_HOLD"]);
bool get isPending => api.PurchaseOrderStatus.isNameIn(status, ["PENDING", "ON_HOLD"]); bool get isPending => api.PurchaseOrderStatus.isNameIn(status, ["PENDING", "ON_HOLD"]);
@ -219,7 +226,7 @@ class InvenTreePOLineItem extends InvenTreeOrderLine {
String get purchasePriceCurrency => getString("purchase_price_currency"); String get purchasePriceCurrency => getString("purchase_price_currency");
int get destination => getInt("destination"); int get destinationId => getInt("destination");
Map<String, dynamic> get destinationDetail => getMap("destination_detail"); Map<String, dynamic> get destinationDetail => getMap("destination_detail");
} }

View File

@ -310,6 +310,9 @@
"description": "Description", "description": "Description",
"@description": {}, "@description": {},
"destination": "Destination",
"@destination": {},
"destroyed": "Destroyed", "destroyed": "Destroyed",
"@destroyed": {}, "@destroyed": {},

View File

@ -48,7 +48,15 @@ class _CompanyDetailState extends RefreshableState<CompanyDetailWidget> {
int attachmentCount = 0; int attachmentCount = 0;
@override @override
String getAppBarTitle() => L10().company; String getAppBarTitle() {
String title = L10().company;
if (widget.company.name.isNotEmpty) {
title += " - ${widget.company.name}";
}
return title;
}
@override @override
List<Widget> appBarActions(BuildContext context) { List<Widget> appBarActions(BuildContext context) {

View File

@ -5,14 +5,18 @@ import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/api_form.dart"; import "package:inventree/api_form.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/model.dart";
import "package:inventree/l10.dart"; import "package:inventree/l10.dart";
import "package:inventree/widget/progress.dart";
import "package:inventree/widget/part/part_detail.dart";
import "package:inventree/widget/refreshable_state.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
import "package:inventree/inventree/part.dart"; import "package:inventree/inventree/part.dart";
import "package:inventree/inventree/purchase_order.dart"; import "package:inventree/inventree/purchase_order.dart";
import "package:inventree/inventree/stock.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/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";
@ -38,6 +42,8 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
_POLineDetailWidgetState(); _POLineDetailWidgetState();
InvenTreeStockLocation? destination;
@override @override
String getAppBarTitle() => L10().lineItem; String getAppBarTitle() => L10().lineItem;
@ -84,6 +90,29 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
@override @override
Future<void> request(BuildContext context) async { Future<void> request(BuildContext context) async {
await widget.item.reload(); await widget.item.reload();
if (widget.item.destinationId > 0) {
InvenTreeStockLocation().get(widget.item.destinationId).then((InvenTreeModel? loc) {
if (mounted) {
if (loc != null && loc is InvenTreeStockLocation) {
setState(() {
destination = loc;
});
} else {
setState(() {
destination = null;
});
}
}
});
} else {
if (mounted) {
setState(() {
destination = null;
});
}
}
} }
// Callback to edit this line item // Callback to edit this line item
@ -199,6 +228,24 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
) )
); );
// Destination
if (destination != null) {
tiles.add(ListTile(
title: Text(L10().destination),
subtitle: Text(destination!.name),
leading: Icon(TablerIcons.map_pin, color: COLOR_ACTION),
onTap: () =>
{
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LocationDisplayWidget(destination)
)
)
}
));
}
// Received quantity // Received quantity
tiles.add( tiles.add(
ListTile( ListTile(

View File

@ -1,8 +1,6 @@
import "package:flutter/material.dart"; 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/widget/dialogs.dart";
import "package:inventree/widget/order/po_line_list.dart";
import "package:inventree/app_colors.dart"; import "package:inventree/app_colors.dart";
import "package:inventree/barcode/barcode.dart"; import "package:inventree/barcode/barcode.dart";
@ -10,8 +8,16 @@ import "package:inventree/barcode/purchase_order.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/model.dart";
import "package:inventree/inventree/company.dart"; import "package:inventree/inventree/company.dart";
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/stock/location_display.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/company/company_detail.dart";
import "package:inventree/widget/notes_widget.dart"; import "package:inventree/widget/notes_widget.dart";
@ -42,6 +48,8 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
List<InvenTreePOLineItem> lines = []; List<InvenTreePOLineItem> lines = [];
InvenTreeStockLocation? destination;
int completedLines = 0; int completedLines = 0;
int attachmentCount = 0; int attachmentCount = 0;
@ -50,7 +58,15 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
bool supportProjectCodes = false; bool supportProjectCodes = false;
@override @override
String getAppBarTitle() => L10().purchaseOrder; String getAppBarTitle() {
String title = L10().purchaseOrder;
if (widget.order.reference.isNotEmpty) {
title += " - ${widget.order.reference}";
}
return title;
}
@override @override
List<Widget> appBarActions(BuildContext context) { List<Widget> appBarActions(BuildContext context) {
@ -258,6 +274,28 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
}); });
} }
}); });
if (api.supportsPurchaseOrderDestination && widget.order.destinationId > 0) {
InvenTreeStockLocation().get(widget.order.destinationId).then((InvenTreeModel? loc) {
if (mounted) {
if (loc != null && loc is InvenTreeStockLocation) {
setState(() {
destination = loc;
});
} else {
setState(() {
destination = null;
});
}
}
});
} else {
if (mounted) {
setState(() {
destination = null;
});
}
}
} }
// Edit the currently displayed PurchaseOrder // Edit the currently displayed PurchaseOrder
@ -348,6 +386,23 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
)); ));
} }
// Order destination
if (destination != null) {
tiles.add(ListTile(
title: Text(L10().destination),
subtitle: Text(destination!.name),
leading: Icon(TablerIcons.map_pin, color: COLOR_ACTION),
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LocationDisplayWidget(destination)
)
)
}
));
}
Color lineColor = completedLines < widget.order.lineItemCount ? COLOR_WARNING : COLOR_SUCCESS; Color lineColor = completedLines < widget.order.lineItemCount ? COLOR_WARNING : COLOR_SUCCESS;
tiles.add(ListTile( tiles.add(ListTile(
@ -444,5 +499,4 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
PaginatedStockItemList({"purchase_order": widget.order.pk.toString()}), PaginatedStockItemList({"purchase_order": widget.order.pk.toString()}),
]; ];
} }
}
}

View File

@ -46,7 +46,15 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
int attachmentCount = 0; int attachmentCount = 0;
@override @override
String getAppBarTitle() => L10().salesOrder; String getAppBarTitle() {
String title = L10().salesOrder;
if (widget.order.reference.isNotEmpty) {
title += " - ${widget.order.reference}";
}
return title;
}
@override @override
List<Widget> appBarActions(BuildContext context) { List<Widget> appBarActions(BuildContext context) {