asset predication implemented in asset inventory

main_production_copilot
WaseemAbbasi22 12 hours ago
parent 0501ec7c92
commit 9168c07fb5

@ -81,6 +81,8 @@ class PredictedAssetMetadata {
String? assetNumber;
String? departmentId;
String? departmentName;
String? modelName;
String? manufacturerName;
PredictedAssetMetadata({
this.siteId,
@ -90,6 +92,8 @@ class PredictedAssetMetadata {
this.assetNumber,
this.departmentId,
this.departmentName,
this.modelName,
this.manufacturerName,
});
PredictedAssetMetadata.fromJson(Map<String, dynamic> json) {
@ -100,6 +104,8 @@ class PredictedAssetMetadata {
assetNumber = json['asset_number'];
departmentId = json['department_id'];
departmentName = json['department_name'];
modelName = json['model_name'];
manufacturerName = json['manufacturer_name'];
}
Map<String, dynamic> toJson() {
@ -111,6 +117,8 @@ class PredictedAssetMetadata {
'asset_number': assetNumber,
'department_id': departmentId,
'department_name': departmentName,
'model_name': modelName,
'manufacturer_name': manufacturerName,
};
}
}

@ -12,11 +12,13 @@ import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/device/predict_device_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
import 'package:test_sa/modules/asset_inventory_module/pages/search_asset_view.dart';
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
import 'package:test_sa/modules/cm_module/cm_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/copilot/copilot_helper.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
@ -331,9 +333,35 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.miniEndFloat,
floatingActionButton: Padding(
padding: const EdgeInsets.only(bottom: 70),
child: FloatingActionButton(
heroTag: "asset_inventory_form_scan_fab",
backgroundColor: AppColor.primary10,
onPressed: () => _predictAsset(),
child: "asset_scan".toSvgAsset(height: 36, color: AppColor.addItemButtonColor(context)),
),
),
);
}
Future<void> _predictAsset() async {
final PredictedAsset? predicted = await CopilotHelper.pickImageFromCamera(context, pickMode: true);
if (predicted != null) _applyPredictedAsset(predicted);
}
void _applyPredictedAsset(PredictedAsset predicted) {
final String? assetNumber = predicted.metadata?.assetNumber ?? predicted.assetId;
if (assetNumber == null || assetNumber.isEmpty) {
"Predicted asset has no asset number".showToast;
return;
}
resetData();
setState(() {});
searchAsset(assetNo: assetNumber);
}
Future<void> searchAsset({required String assetNo}) async {
AssetInventoryProvider provider = Provider.of<AssetInventoryProvider>(context, listen: false);
Map<String, dynamic> payload = {

@ -0,0 +1,77 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/predict_device_model.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/views/widgets/equipment/predict_device_list.dart';
class CopilotHelper {
static Future<PredictedAsset?> pickImageFromCamera(BuildContext context, {bool pickMode = false}) async {
final status = await Permission.camera.status;
if (status.isGranted) {
return openCamera(context, pickMode: pickMode);
}
final permission = await Permission.camera.request();
if (permission.isGranted) {
return openCamera(context, pickMode: pickMode);
}
if (permission.isPermanentlyDenied) {
await openAppSettings();
return null;
}
debugPrint('Camera permission denied');
return null;
}
static Future<PredictedAsset?> openCamera(BuildContext context, {bool pickMode = false}) async {
final XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
imageQuality: 70,
);
if (pickedFile == null) {
return null;
}
final File imageFile = File(pickedFile.path);
return uploadImage(imageFile, context, pickMode: pickMode);
}
static Future<PredictedAsset?> uploadImage(File imageFile, BuildContext context, {bool pickMode = false}) async {
try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
AssetProvider assetProvider = Provider.of<AssetProvider>(context, listen: false);
PredictDeviceResponse? response = await assetProvider.predictDevice(imageFile);
Navigator.pop(context);
if (response != null && response.success == true) {
final List<PredictedAsset> predictedAssetList = response.predictedAsset ?? [];
if (predictedAssetList.isNotEmpty) {
return Navigator.push<PredictedAsset?>(
context,
MaterialPageRoute(builder: (context) => PredictDeviceView(predictedAsset: predictedAssetList, pickMode: pickMode)),
);
} else {
context.showInfoDialog("No Predicted asset found");
}
} else {
context.showInfoDialog("Failed to recognize the asset. Please try again.");
}
} catch (e) {
debugPrint('Upload error: $e');
}
return null;
}
}

@ -3,8 +3,6 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
@ -13,16 +11,14 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/predict_device_model.dart';
import 'package:test_sa/modules/copilot/copilot_helper.dart';
import 'package:test_sa/modules/tm_module/device_transfer/device_filter_screen.dart';
import 'package:test_sa/modules/tm_module/device_transfer/device_search_screen.dart';
import 'package:test_sa/modules/export_module/pages/export_form_view.dart';
import 'package:test_sa/modules/export_module/models/export_module_type.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart';
import 'package:test_sa/views/widgets/equipment/asset_item_gridview.dart';
import 'package:test_sa/views/widgets/equipment/asset_item_listview.dart';
import 'package:test_sa/views/widgets/equipment/predict_device_list.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -650,59 +646,6 @@ class _MyAssetsPageState extends State<MyAssetsPage> with SingleTickerProviderSt
}
Future<void> _pickImageFromCamera() async {
final status = await Permission.camera.status;
if (status.isGranted) {
await _openCamera();
return;
}
final permission = await Permission.camera.request();
if (permission.isGranted) {
await _openCamera();
return;
}
if (permission.isPermanentlyDenied) {
await openAppSettings();
return;
}
debugPrint('Camera permission denied');
}
Future<void> _openCamera() async {
final XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
imageQuality: 70,
);
if (pickedFile == null) {
return;
}
final File imageFile = File(pickedFile.path);
await _uploadImage(imageFile);
}
Future<void> _uploadImage(File imageFile) async {
try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
PredictDeviceResponse? response = await _devicesProvider.predictDevice(imageFile);
Navigator.pop(context);
if (response != null && response.success == true) {
final List<PredictedAsset> predictedAssetList = response.predictedAsset ?? [];
if (predictedAssetList.isNotEmpty) {
Navigator.push(context, MaterialPageRoute(builder: (context) => PredictDeviceView(predictedAsset: predictedAssetList)));
} else {
context.showInfoDialog("No Predicted asset found");
// Fluttertoast.showToast(msg: 'No Predicted asset found', toastLength: Toast.LENGTH_LONG);
}
}
} catch (e) {
debugPrint('Upload error: $e');
}
await CopilotHelper.pickImageFromCamera(context);
}
}

@ -1,22 +1,15 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/predict_device_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart';
import 'package:test_sa/views/widgets/equipment/predict_device_item_grid_view.dart';
import 'package:test_sa/views/widgets/equipment/predict_device_item_view.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
class PredictDeviceView extends StatefulWidget {
static const String id = "/predict_device_view";
List<PredictedAsset> predictedAsset;
bool pickMode;
PredictDeviceView({Key? key, required this.predictedAsset}) : super(key: key);
PredictDeviceView({Key? key, required this.predictedAsset, this.pickMode = false}) : super(key: key);
@override
_PredictDeviceViewState createState() => _PredictDeviceViewState();
@ -86,6 +79,10 @@ class _PredictDeviceViewState extends State<PredictDeviceView> with SingleTicker
child: PredictDeviceItemView(
device: widget.predictedAsset[itemIndex],
onPressed: (device) {
if (widget.pickMode) {
Navigator.of(context).pop(device);
return;
}
int? assetId = int.tryParse(device.assetId ?? '');
Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: assetId);
},

Loading…
Cancel
Save