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

Merge pull request #575 from inventree/receive-location

Receive location
This commit is contained in:
Oliver 2024-12-11 23:01:33 +11:00 committed by GitHub
commit e93e0241f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 129 additions and 121 deletions

View File

@ -3,6 +3,8 @@
- 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 - Display "destination" information in PurchaseOrder detail view
- Pre-fill "location" field when receiving items against PurchaseOrder
- Fix display of part name in PurchaseOrderLineItem list
- 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

@ -272,7 +272,6 @@
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/DKImagePickerController/DKImagePickerController.framework", "${BUILT_PRODUCTS_DIR}/DKImagePickerController/DKImagePickerController.framework",
"${BUILT_PRODUCTS_DIR}/DKPhotoGallery/DKPhotoGallery.framework", "${BUILT_PRODUCTS_DIR}/DKPhotoGallery/DKPhotoGallery.framework",
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
"${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework", "${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework",
"${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework", "${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework",
@ -280,21 +279,21 @@
"${BUILT_PRODUCTS_DIR}/camera_avfoundation/camera_avfoundation.framework", "${BUILT_PRODUCTS_DIR}/camera_avfoundation/camera_avfoundation.framework",
"${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework",
"${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework",
"${BUILT_PRODUCTS_DIR}/flutter_zxing/flutter_zxing.framework",
"${BUILT_PRODUCTS_DIR}/image_picker_ios/image_picker_ios.framework", "${BUILT_PRODUCTS_DIR}/image_picker_ios/image_picker_ios.framework",
"${BUILT_PRODUCTS_DIR}/open_filex/open_filex.framework", "${BUILT_PRODUCTS_DIR}/open_filex/open_filex.framework",
"${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework",
"${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
"${BUILT_PRODUCTS_DIR}/qr_code_scanner/qr_code_scanner.framework",
"${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework", "${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework",
"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework", "${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework", "${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
"${BUILT_PRODUCTS_DIR}/wakelock_plus/wakelock_plus.framework",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputPaths = ( outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKImagePickerController.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKImagePickerController.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKPhotoGallery.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKPhotoGallery.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework",
@ -302,15 +301,16 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/camera_avfoundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/camera_avfoundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_zxing.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_filex.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/open_filex.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/qr_code_scanner.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock_plus.framework",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;

View File

@ -977,7 +977,7 @@ Future<void> launchApiForm(
IconData icon = TablerIcons.device_floppy IconData icon = TablerIcons.device_floppy
}) async { }) async {
showLoadingOverlay(context); showLoadingOverlay();
// List of fields defined by the server // List of fields defined by the server
Map<String, dynamic> serverFields = {}; Map<String, dynamic> serverFields = {};
@ -1229,7 +1229,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
if (widget.method == "POST") { if (widget.method == "POST") {
showLoadingOverlay(context); showLoadingOverlay();
final response = await InvenTreeAPI().post( final response = await InvenTreeAPI().post(
widget.url, widget.url,
body: data, body: data,
@ -1240,7 +1240,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
return response; return response;
} else { } else {
showLoadingOverlay(context); showLoadingOverlay();
final response = await InvenTreeAPI().patch( final response = await InvenTreeAPI().patch(
widget.url, widget.url,
body: data, body: data,

View File

@ -1,10 +1,14 @@
import "dart:math"; import "dart:math";
import "dart:typed_data"; import "dart:typed_data";
import "package:camera/camera.dart";
import "package:flutter/material.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/app_colors.dart"; import "package:inventree/app_colors.dart";
import "package:inventree/inventree/sentry.dart";
import "package:inventree/preferences.dart"; import "package:inventree/preferences.dart";
import "package:inventree/widget/snacks.dart";
import "package:one_context/one_context.dart";
import "package:wakelock_plus/wakelock_plus.dart"; import "package:wakelock_plus/wakelock_plus.dart";
import "package:flutter_zxing/flutter_zxing.dart"; import "package:flutter_zxing/flutter_zxing.dart";
@ -133,7 +137,28 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
} }
}); });
} }
}
void onControllerCreated(CameraController? controller, Exception? error) {
if (error != null) {
sentryReportError(
"CameraBarcodeController.onControllerCreated",
error,
null
);
}
if (controller == null) {
showSnackIcon(
L10().cameraCreationError,
icon: TablerIcons.camera_x,
success: false
);
if (OneContext.hasContext) {
Navigator.pop(OneContext().context!);
}
}
} }
/* /*
@ -167,6 +192,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
tryInverted: true, tryInverted: true,
tryRotate: true, tryRotate: true,
showGallery: false, showGallery: false,
onControllerCreated: onControllerCreated,
scanDelay: Duration(milliseconds: scan_delay), scanDelay: Duration(milliseconds: scan_delay),
resolution: ResolutionPreset.high, resolution: ResolutionPreset.high,
lensDirection: CameraLensDirection.back, lensDirection: CameraLensDirection.back,
@ -185,7 +211,12 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
child: Align( child: Align(
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
child: Padding( child: Padding(
padding: EdgeInsets.all(10), padding: EdgeInsets.only(
left: 10,
right: 10,
top: 75,
bottom: 10
),
child: Text( child: Text(
widget.handler.getOverlayText(context), widget.handler.getOverlayText(context),
style: TextStyle( style: TextStyle(
@ -213,7 +244,12 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
child: Align( child: Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Padding( child: Padding(
padding: EdgeInsets.all(10), padding: EdgeInsets.only(
left: 10,
right: 10,
top: 10,
bottom: 75
),
child: Text( child: Text(
text, text,
textAlign: TextAlign.center, textAlign: TextAlign.center,

View File

@ -1,11 +1,7 @@
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:inventree/helpers.dart";
import "package:one_context/one_context.dart";
import "package:inventree/preferences.dart"; import "package:inventree/preferences.dart";
import "package:inventree/barcode/handler.dart"; import "package:inventree/barcode/handler.dart";
import "package:inventree/widget/progress.dart"; import "package:inventree/widget/progress.dart";
/* /*
@ -59,13 +55,7 @@ class InvenTreeBarcodeControllerState extends State<InvenTreeBarcodeController>
processingBarcode = true; processingBarcode = true;
}); });
BuildContext? context; showLoadingOverlay();
if (hasContext()) {
context = OneContext.hasContext ? OneContext().context : null;
}
showLoadingOverlay(context);
await pauseScan(); await pauseScan();
await widget.handler.processBarcode(data); await widget.handler.processBarcode(data);

View File

@ -18,7 +18,7 @@ class InvenTreeBomItem extends InvenTreeModel {
String get URL => "bom/"; String get URL => "bom/";
@override @override
Map<String, String> defaultListFilters() { Map<String, String> defaultFilters() {
return { return {
"sub_part_detail": "true", "sub_part_detail": "true",
"part_detail": "true", "part_detail": "true",
@ -26,13 +26,6 @@ class InvenTreeBomItem extends InvenTreeModel {
}; };
} }
@override
Map<String, String> defaultGetFilters() {
return {
"sub_part_detail": "true",
};
}
// Extract the 'reference' value associated with this BomItem // Extract the 'reference' value associated with this BomItem
String get reference => getString("reference"); String get reference => getString("reference");

View File

@ -155,7 +155,8 @@ class InvenTreeSupplierPart extends InvenTreeModel {
return fields; return fields;
} }
Map<String, String> _filters() { @override
Map<String, String> defaultFilters() {
return { return {
"manufacturer_detail": "true", "manufacturer_detail": "true",
"supplier_detail": "true", "supplier_detail": "true",
@ -163,15 +164,6 @@ class InvenTreeSupplierPart extends InvenTreeModel {
}; };
} }
@override
Map<String, String> defaultListFilters() {
return _filters();
}
@override
Map<String, String> defaultGetFilters() {
return _filters();
}
int get manufacturerId => getInt("pk", subKey: "manufacturer_detail"); int get manufacturerId => getInt("pk", subKey: "manufacturer_detail");
@ -197,8 +189,10 @@ class InvenTreeSupplierPart extends InvenTreeModel {
String get partImage => (jsondata["part_detail"]?["thumbnail"] ?? InvenTreeAPI.staticThumb) as String; String get partImage => (jsondata["part_detail"]?["thumbnail"] ?? InvenTreeAPI.staticThumb) as String;
String get partName => getString("full_name", subKey: "part_detail"); String get partName => getString("name", subKey: "part_detail");
Map<String, dynamic> get partDetail => getMap("part_detail");
String get partDescription => getString("description", subKey: "part_detail"); String get partDescription => getString("description", subKey: "part_detail");
String get note => getString("note"); String get note => getString("note");

View File

@ -227,16 +227,9 @@ class InvenTreePart extends InvenTreeModel {
} }
@override @override
Map<String, String> defaultListFilters() { Map<String, String> defaultFilters() {
return { return {
"location_detail": "true", "category_detail": "true",
};
}
@override
Map<String, String> defaultGetFilters() {
return {
"category_detail": "true", // Include category detail information
}; };
} }

View File

@ -3,6 +3,7 @@ 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/progress.dart";
/* /*
@ -64,14 +65,7 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
} }
@override @override
Map<String, String> defaultGetFilters() { Map<String, String> defaultFilters() {
return {
"supplier_detail": "true",
};
}
@override
Map<String, String> defaultListFilters() {
return { return {
"supplier_detail": "true", "supplier_detail": "true",
}; };
@ -128,7 +122,9 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
return; return;
} }
showLoadingOverlay();
await api.post("${url}issue/", expectedStatusCode: 201); await api.post("${url}issue/", expectedStatusCode: 201);
hideLoadingOverlay();
} }
/// Mark this order as "cancelled" /// Mark this order as "cancelled"
@ -137,7 +133,9 @@ class InvenTreePurchaseOrder extends InvenTreeOrder {
return; return;
} }
showLoadingOverlay();
await api.post("${url}cancel/", expectedStatusCode: 201); await api.post("${url}cancel/", expectedStatusCode: 201);
hideLoadingOverlay();
} }
} }
@ -178,16 +176,10 @@ class InvenTreePOLineItem extends InvenTreeOrderLine {
} }
@override @override
Map<String, String> defaultGetFilters() { Map<String, String> defaultFilters() {
return {
"part_detail": "true",
};
}
@override
Map<String, String> defaultListFilters() {
return { return {
"part_detail": "true", "part_detail": "true",
"order_detail": "true",
}; };
} }
@ -228,6 +220,8 @@ class InvenTreePOLineItem extends InvenTreeOrderLine {
int get destinationId => getInt("destination"); int get destinationId => getInt("destination");
Map<String, dynamic> get orderDetail => getMap("order_detail");
Map<String, dynamic> get destinationDetail => getMap("destination_detail"); Map<String, dynamic> get destinationDetail => getMap("destination_detail");
} }

View File

@ -6,6 +6,7 @@ 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/api.dart";
import "package:inventree/widget/progress.dart";
/* /*
@ -65,14 +66,7 @@ class InvenTreeSalesOrder extends InvenTreeOrder {
} }
@override @override
Map<String, String> defaultGetFilters() { Map<String, String> defaultFilters() {
return {
"customer_detail": "true",
};
}
@override
Map<String, String> defaultListFilters() {
return { return {
"customer_detail": "true", "customer_detail": "true",
}; };
@ -83,7 +77,9 @@ class InvenTreeSalesOrder extends InvenTreeOrder {
return; return;
} }
showLoadingOverlay();
await api.post("${url}issue/", expectedStatusCode: 201); await api.post("${url}issue/", expectedStatusCode: 201);
hideLoadingOverlay();
} }
/// Mark this order as "cancelled" /// Mark this order as "cancelled"
@ -92,7 +88,9 @@ class InvenTreeSalesOrder extends InvenTreeOrder {
return; return;
} }
showLoadingOverlay();
await api.post("${url}cancel/", expectedStatusCode: 201); await api.post("${url}cancel/", expectedStatusCode: 201);
hideLoadingOverlay();
} }
int get customerId => getInt("customer"); int get customerId => getInt("customer");
@ -180,14 +178,7 @@ class InvenTreeSOLineItem extends InvenTreeOrderLine {
} }
@override @override
Map<String, String> defaultGetFilters() { Map<String, String> defaultFilters() {
return {
"part_detail": "true",
};
}
@override
Map<String, String> defaultListFilters() {
return { return {
"part_detail": "true", "part_detail": "true",
}; };

View File

@ -253,7 +253,7 @@ class InvenTreeStockItem extends InvenTreeModel {
} }
@override @override
Map<String, String> defaultGetFilters() { Map<String, String> defaultFilters() {
return { return {
"part_detail": "true", "part_detail": "true",
@ -263,16 +263,6 @@ class InvenTreeStockItem extends InvenTreeModel {
}; };
} }
@override
Map<String, String> defaultListFilters() {
return {
"part_detail": "true",
"location_detail": "true",
"supplier_detail": "true",
};
}
List<InvenTreePartTestTemplate> testTemplates = []; List<InvenTreePartTestTemplate> testTemplates = [];
int get testTemplateCount => testTemplates.length; int get testTemplateCount => testTemplates.length;

View File

@ -202,6 +202,9 @@
"building": "Building", "building": "Building",
"@building": {}, "@building": {},
"cameraCreationError": "Could not open camera controller",
"@cameraCreationError": {},
"cameraInternal": "Internal Camera", "cameraInternal": "Internal Camera",
"@cameraInternal": {}, "@cameraInternal": {},

View File

@ -98,7 +98,7 @@ Future<void> selectAndPrintLabel(
if (labelId != -1 && pluginKey != null) { if (labelId != -1 && pluginKey != null) {
showLoadingOverlay(context); showLoadingOverlay();
if (InvenTreeAPI().supportsModernLabelPrinting) { if (InvenTreeAPI().supportsModernLabelPrinting) {

View File

@ -50,7 +50,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
Future <void> loadSettings(BuildContext context) async { Future <void> loadSettings(BuildContext context) async {
showLoadingOverlay(context); showLoadingOverlay();
barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool; serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;

View File

@ -50,7 +50,7 @@ class _InvenTreeLoginState extends State<InvenTreeLoginWidget> {
currentFocus.unfocus(); currentFocus.unfocus();
} }
showLoadingOverlay(context); showLoadingOverlay();
// Attempt login // Attempt login
final response = await InvenTreeAPI().fetchToken(widget.profile, username, password); final response = await InvenTreeAPI().fetchToken(widget.profile, username, password);

View File

@ -79,7 +79,7 @@ class _AttachmentWidgetState extends RefreshableState<AttachmentWidget> {
if (file == null) return; if (file == null) return;
showLoadingOverlay(context); showLoadingOverlay();
final bool result = await widget.attachmentClass.uploadAttachment( final bool result = await widget.attachmentClass.uploadAttachment(
file, file,
@ -178,7 +178,7 @@ class _AttachmentWidgetState extends RefreshableState<AttachmentWidget> {
subtitle: Text(attachment.comment), subtitle: Text(attachment.comment),
leading: Icon(attachment.icon, color: COLOR_ACTION), leading: Icon(attachment.icon, color: COLOR_ACTION),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
await attachment.downloadAttachment(); await attachment.downloadAttachment();
hideLoadingOverlay(); hideLoadingOverlay();
}, },

View File

@ -119,7 +119,7 @@ class _SupplierPartDisplayState extends RefreshableState<SupplierPartDetailWidge
leading: Icon(TablerIcons.box, color: COLOR_ACTION), leading: Icon(TablerIcons.box, color: COLOR_ACTION),
trailing: InvenTreeAPI().getThumbnail(widget.supplierPart.partImage), trailing: InvenTreeAPI().getThumbnail(widget.supplierPart.partImage),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
final part = await InvenTreePart().get(widget.supplierPart.partId); final part = await InvenTreePart().get(widget.supplierPart.partId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -162,7 +162,7 @@ class _SupplierPartDisplayState extends RefreshableState<SupplierPartDetailWidge
leading: Icon(TablerIcons.building, color: COLOR_ACTION), leading: Icon(TablerIcons.building, color: COLOR_ACTION),
trailing: InvenTreeAPI().getThumbnail(widget.supplierPart.supplierImage), trailing: InvenTreeAPI().getThumbnail(widget.supplierPart.supplierImage),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
var supplier = await InvenTreeCompany().get(widget.supplierPart.supplierId); var supplier = await InvenTreeCompany().get(widget.supplierPart.supplierId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -193,7 +193,7 @@ class _SupplierPartDisplayState extends RefreshableState<SupplierPartDetailWidge
leading: Icon(TablerIcons.building_factory_2, color: COLOR_ACTION), leading: Icon(TablerIcons.building_factory_2, color: COLOR_ACTION),
trailing: InvenTreeAPI().getThumbnail(widget.supplierPart.manufacturerImage), trailing: InvenTreeAPI().getThumbnail(widget.supplierPart.manufacturerImage),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
var supplier = await InvenTreeCompany().get(widget.supplierPart.manufacturerId); var supplier = await InvenTreeCompany().get(widget.supplierPart.manufacturerId);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -133,6 +133,13 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
// Launch a form to 'receive' this line item // Launch a form to 'receive' this line item
Future<void> receiveLineItem(BuildContext context) async { Future<void> receiveLineItem(BuildContext context) async {
// Pre-fill the "destination" to receive into
int destination = widget.item.destinationId;
if (destination < 0) {
destination = (widget.item.orderDetail["destination"] ?? -1) as int;
}
// Construct fields to receive // Construct fields to receive
Map<String, dynamic> fields = { Map<String, dynamic> fields = {
"line_item": { "line_item": {
@ -164,7 +171,11 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
} }
}; };
showLoadingOverlay(context); if (destination > 0) {
fields["location"]?["value"] = destination;
}
showLoadingOverlay();
var order = await InvenTreePurchaseOrder().get(widget.item.orderId); var order = await InvenTreePurchaseOrder().get(widget.item.orderId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -199,7 +210,7 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
leading: Icon(TablerIcons.box, color: COLOR_ACTION), leading: Icon(TablerIcons.box, color: COLOR_ACTION),
trailing: api.getThumbnail(widget.item.partImage), trailing: api.getThumbnail(widget.item.partImage),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
var part = await InvenTreePart().get(widget.item.partId); var part = await InvenTreePart().get(widget.item.partId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -217,7 +228,7 @@ class _POLineDetailWidgetState extends RefreshableState<POLineDetailWidget> {
subtitle: Text(widget.item.SKU), subtitle: Text(widget.item.SKU),
leading: Icon(TablerIcons.building, color: COLOR_ACTION), leading: Icon(TablerIcons.building, color: COLOR_ACTION),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
var part = await InvenTreeSupplierPart().get(widget.item.supplierPartId); var part = await InvenTreeSupplierPart().get(widget.item.supplierPartId);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -71,13 +71,14 @@ class _PaginatedPOLineListState extends PaginatedSearchState<PaginatedPOLineList
InvenTreeSupplierPart? supplierPart = item.supplierPart; InvenTreeSupplierPart? supplierPart = item.supplierPart;
if (supplierPart != null) { if (supplierPart != null) {
return ListTile( return ListTile(
title: Text(supplierPart.SKU), title: Text(supplierPart.SKU),
subtitle: Text(supplierPart.partName), subtitle: Text(item.partName),
trailing: Text(item.progressString, style: TextStyle(color: item.isComplete ? COLOR_SUCCESS : COLOR_WARNING)), trailing: Text(item.progressString, style: TextStyle(color: item.isComplete ? COLOR_SUCCESS : COLOR_WARNING)),
leading: InvenTreeAPI().getThumbnail(supplierPart.partImage), leading: InvenTreeAPI().getThumbnail(supplierPart.partImage),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
await item.reload(); await item.reload();
hideLoadingOverlay(); hideLoadingOverlay();
Navigator.push(context, MaterialPageRoute(builder: (context) => POLineDetailWidget(item))); Navigator.push(context, MaterialPageRoute(builder: (context) => POLineDetailWidget(item)));

View File

@ -185,7 +185,7 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
color: Colors.blue, color: Colors.blue,
acceptText: L10().issue, acceptText: L10().issue,
onAccept: () async { onAccept: () async {
await widget.order.issueOrder().then((dynamic) { widget.order.issueOrder().then((dynamic) {
refresh(context); refresh(context);
}); });
} }
@ -201,7 +201,7 @@ class _PurchaseOrderDetailState extends RefreshableState<PurchaseOrderDetailWidg
color: Colors.red, color: Colors.red,
acceptText: L10().cancel, acceptText: L10().cancel,
onAccept: () async { onAccept: () async {
await widget.order.cancelOrder().then((dynamic) { widget.order.cancelOrder().then((dynamic) {
refresh(context); refresh(context);
}); });
} }

View File

@ -127,7 +127,7 @@ class _SalesOrderDetailState extends RefreshableState<SalesOrderDetailWidget> {
color: Colors.blue, color: Colors.blue,
acceptText: L10().issue, acceptText: L10().issue,
onAccept: () async { onAccept: () async {
await widget.order.issueOrder().then((dynamic) { widget.order.issueOrder().then((dynamic) {
refresh(context); refresh(context);
}); });
} }

View File

@ -187,7 +187,7 @@ class _SOLineDetailWidgetState extends RefreshableState<SoLineDetailWidget> {
leading: Icon(TablerIcons.box, color: COLOR_ACTION), leading: Icon(TablerIcons.box, color: COLOR_ACTION),
trailing: api.getThumbnail(widget.item.partImage), trailing: api.getThumbnail(widget.item.partImage),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
var part = await InvenTreePart().get(widget.item.partId); var part = await InvenTreePart().get(widget.item.partId);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -65,7 +65,7 @@ class _PaginatedSOLineListState extends PaginatedSearchState<PaginatedSOLineList
leading: InvenTreeAPI().getThumbnail(part.thumbnail), leading: InvenTreeAPI().getThumbnail(part.thumbnail),
trailing: Text(item.progressString, style: TextStyle(color: item.isComplete ? COLOR_SUCCESS : COLOR_WARNING)), trailing: Text(item.progressString, style: TextStyle(color: item.isComplete ? COLOR_SUCCESS : COLOR_WARNING)),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
await item.reload(); await item.reload();
hideLoadingOverlay(); hideLoadingOverlay();
Navigator.push( Navigator.push(

View File

@ -154,7 +154,7 @@ class _PaginatedBomListState extends PaginatedSearchState<PaginatedBomList> {
leading: InvenTreeAPI().getThumbnail(subPart?.thumbnail ?? ""), leading: InvenTreeAPI().getThumbnail(subPart?.thumbnail ?? ""),
onTap: subPart == null ? null : () async { onTap: subPart == null ? null : () async {
showLoadingOverlay(context); showLoadingOverlay();
var part = await InvenTreePart().get(subPart.pk); var part = await InvenTreePart().get(subPart.pk);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -159,7 +159,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
Navigator.push(context, MaterialPageRoute(builder: (context) => CategoryDisplayWidget(null))); Navigator.push(context, MaterialPageRoute(builder: (context) => CategoryDisplayWidget(null)));
} else { } else {
showLoadingOverlay(context); showLoadingOverlay();
var cat = await InvenTreePartCategory().get(parentId); var cat = await InvenTreePartCategory().get(parentId);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -366,7 +366,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
onTap: () async { onTap: () async {
if (part.categoryId > 0) { if (part.categoryId > 0) {
showLoadingOverlay(context); showLoadingOverlay();
var cat = await InvenTreePartCategory().get(part.categoryId); var cat = await InvenTreePartCategory().get(part.categoryId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -646,7 +646,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
if (part.isTrackable) { if (part.isTrackable) {
// read the next available serial number // read the next available serial number
showLoadingOverlay(context); showLoadingOverlay();
var response = await api.get("/api/part/${part.pk}/serial-numbers/", expectedStatusCode: null); var response = await api.get("/api/part/${part.pk}/serial-numbers/", expectedStatusCode: null);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -127,7 +127,7 @@ class _PaginatedParameterState extends PaginatedSearchState<PaginatedParameterLi
value: parameter.as_bool, value: parameter.as_bool,
onChanged: (bool value) { onChanged: (bool value) {
if (parameter.canEdit) { if (parameter.canEdit) {
showLoadingOverlay(context); showLoadingOverlay();
parameter.update( parameter.update(
values: { values: {
"data": value.toString() "data": value.toString()

View File

@ -1,8 +1,11 @@
import "dart:io";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_overlay_loader/flutter_overlay_loader.dart"; import "package:flutter_overlay_loader/flutter_overlay_loader.dart";
import "package:inventree/app_colors.dart"; import "package:inventree/app_colors.dart";
import "package:one_context/one_context.dart";
/* /*
@ -42,7 +45,14 @@ Widget progressIndicator() {
} }
void showLoadingOverlay(BuildContext? context) { void showLoadingOverlay() {
// Do not show overlay if running unit tests
if (Platform.environment.containsKey("FLUTTER_TEST")) {
return;
}
BuildContext? context = OneContext.hasContext ? OneContext().context : null;
if (context == null) { if (context == null) {
return; return;

View File

@ -72,7 +72,7 @@ void showSnackIcon(String text, {IconData? icon, Function()? onAction, bool? suc
onAction(); onAction();
} }
), ),
duration: Duration(seconds: onAction == null ? 1 : 2), duration: Duration(seconds: onAction == null ? 5 : 10),
) )
); );

View File

@ -362,7 +362,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
builder: (context) => LocationDisplayWidget(null))); builder: (context) => LocationDisplayWidget(null)));
} else { } else {
showLoadingOverlay(context); showLoadingOverlay();
var loc = await InvenTreeStockLocation().get(parentId); var loc = await InvenTreeStockLocation().get(parentId);
hideLoadingOverlay(); hideLoadingOverlay();

View File

@ -523,7 +523,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
onTap: () async { onTap: () async {
if (widget.item.partId > 0) { if (widget.item.partId > 0) {
showLoadingOverlay(context); showLoadingOverlay();
var part = await InvenTreePart().get(widget.item.partId); var part = await InvenTreePart().get(widget.item.partId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -566,7 +566,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
onTap: () async { onTap: () async {
if (widget.item.locationId > 0) { if (widget.item.locationId > 0) {
showLoadingOverlay(context); showLoadingOverlay();
var loc = await InvenTreeStockLocation().get(widget.item.locationId); var loc = await InvenTreeStockLocation().get(widget.item.locationId);
hideLoadingOverlay(); hideLoadingOverlay();
@ -651,7 +651,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
leading: Icon(TablerIcons.building, color: COLOR_ACTION), leading: Icon(TablerIcons.building, color: COLOR_ACTION),
trailing: InvenTreeAPI().getThumbnail(widget.item.supplierImage, hideIfNull: true), trailing: InvenTreeAPI().getThumbnail(widget.item.supplierImage, hideIfNull: true),
onTap: () async { onTap: () async {
showLoadingOverlay(context); showLoadingOverlay();
var sp = await InvenTreeSupplierPart().get( var sp = await InvenTreeSupplierPart().get(
widget.item.supplierPartId); widget.item.supplierPartId);
hideLoadingOverlay(); hideLoadingOverlay();