mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 21:16:48 +00:00
commit
9745bcfdb6
@ -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
|
||||||
|
|
||||||
|
@ -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 = [];
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -310,6 +310,9 @@
|
|||||||
"description": "Description",
|
"description": "Description",
|
||||||
"@description": {},
|
"@description": {},
|
||||||
|
|
||||||
|
"destination": "Destination",
|
||||||
|
"@destination": {},
|
||||||
|
|
||||||
"destroyed": "Destroyed",
|
"destroyed": "Destroyed",
|
||||||
"@destroyed": {},
|
"@destroyed": {},
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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(
|
||||||
|
@ -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()}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user