api integrated for main views

design_3.0_asset_inventory_module
WaseemAbbasi22 4 weeks ago
parent f9b101c233
commit c19fdb173b

@ -38,12 +38,12 @@ android {
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "21" // Must match the compileOptions target
jvmTarget = "17" // Must match the compileOptions target
}
defaultConfig {

@ -298,5 +298,7 @@ class URLs {
// asset inventory Urls.
static get getAssetInventoryById => '$_baseUrl/AssetInventory/GetAssetInventoryById';
// AssetInventory/GetAssetInventoryById
static get getAssetsInSession => '$_baseUrl/AssetInventory/GetAssetsInSeassion';
static get getInventoryDetailsByFilter => '$_baseUrl/AssetInventory/GetInventoryDetailsByFilter';
}

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:test_sa/models/base.dart';
import 'package:test_sa/models/new_models/floor.dart';
@ -10,15 +12,20 @@ class Building extends Base {
}) : super(identifier: id?.toString() ?? '', name: name); // Handle potential null id
Building.fromJson(dynamic json) {
id = json['id'];
identifier = id?.toString() ?? ''; // Handle potential null id
name = json['name'];
id = json['id'] ?? json['buildingId'];
identifier = id?.toString() ?? '';
name = json['name'] ?? json['buildingName'];
value = json['value'];
if (json['floors'] != null) {
floors = [];
json['floors'].forEach((v) {
floors!.add(Floor.fromJson(v));
});
} else if (json['assetInventoryFloors'] != null) {
floors = [];
json['assetInventoryFloors'].forEach((v) {
floors!.add(Floor.fromJson(v));
});
}
}

@ -13,7 +13,7 @@ class Department extends Base {
}) : super(identifier: id?.toString() ?? '', name: departmentName); // Handle potential null id
Department.fromJson(dynamic json) {
id = json['id'];
id = json['id']??json['departmentId'];
identifier = id?.toString() ?? ''; // Handle potential null id
departmentName = json['departmentName'] ?? json['name'];
name = departmentName;
@ -25,6 +25,11 @@ class Department extends Base {
json['rooms'].forEach((v) {
rooms!.add(Rooms.fromJson(v)); // Use '!' since rooms is non-nullable after initialization
});
} else if (json['assetInventoryRooms'] != null) {
rooms = [];
json['assetInventoryRooms'].forEach((v) {
rooms!.add(Rooms.fromJson(v)); // Use '!' since rooms is non-nullable after initialization
});
}
}

@ -10,9 +10,9 @@ class Floor extends Base {
}) : super(identifier: id?.toString() ?? '', name: name); // Handle potentialnull id
Floor.fromJson(dynamic json) {
id = json['id'];
id = json['id']??json['floorId'];
identifier = id?.toString() ?? ''; // Handle potential null id
name = json['name'];
name = json['name']??json['floorName'];
value = json['value'];
if (json['departments'] != null) {
departments = [];
@ -20,6 +20,12 @@ class Floor extends Base {
departments!.add(Department.fromJson(v)); // Use '!' since departments is non-nullable after initialization
});
}
else if (json['assetInventoryDepartments'] != null) {
departments = [];
json['assetInventoryDepartments'].forEach((v) {
departments!.add(Department.fromJson(v)); // Use '!' since departments is non-nullable after initialization
});
}
}
num? id; // Now nullable

@ -10,8 +10,8 @@ class Rooms extends Base {
Rooms.fromJson(Map<String, dynamic>? json) {
// Handle potential null json input
id = json?['id']; // Use null-aware operator
name = json?['name'];
id = json?['id']?? json?['roomId'];
name = json?['name']??json?['roomName'];
value = json?['value'];
}

@ -9,9 +9,9 @@ class Site extends Base {
}) : super(identifier: id?.toString() ?? '', name: custName); // Handle potential null id
Site.fromJson(dynamic json) {
id = json['id'];
id = json['siteId'] ?? json['id'];
identifier = id?.toString() ?? ''; // Handle potential null id
custName = json['custName']?? json['siteName'];
custName = json['custName']?? json['siteName'];
name = custName;
if (json['buildings'] != null) {
buildings = [];
@ -19,6 +19,12 @@ class Site extends Base {
buildings!.add(Building.fromJson(v)); // Use '!' since buildings is initialized here
});
}
else if (json['assetInventoryBuildings'] != null) {
buildings = [];
json['assetInventoryBuildings'].forEach((v) {
buildings!.add(Building.fromJson(v));
});
}
}
num? id; // Now nullable

@ -0,0 +1,251 @@
class AssetInventoryResponse {
num? totalRows;
num? count;
String? message;
String? title;
String? innerMessage;
num? responseCode;
bool? isSuccess;
List<AssetInventoryModel>? assetList;
AssetInventoryResponse({
this.totalRows,
this.count,
this.message,
this.title,
this.innerMessage,
this.responseCode,
this.isSuccess,
this.assetList,
});
AssetInventoryResponse.fromJson(Map<String, dynamic> json) {
totalRows = json['totalRows'];
count = json['count'];
message = json['message'];
title = json['title'];
innerMessage = json['innerMessage'];
responseCode = json['responseCode'];
isSuccess = json['isSuccess'];
if (json['data'] != null) {
assetList = (json['data'] as List)
.map((item) => AssetInventoryModel.fromJson(item))
.toList();
}
}
Map<String, dynamic> toJson() {
return {
'totalRows': totalRows,
'count': count,
'message': message,
'title': title,
'innerMessage': innerMessage,
'responseCode': responseCode,
'isSuccess': isSuccess,
// assetList not needed in toJson because youll likely only send AssetInventoryModel for updates
};
}
}
class AssetInventoryModel {
num? id;
num? assetId;
String? assetNumber;
String? serialNo;
String? assetName;
String? model;
String? manufacturer;
String? supplierName;
String? site;
String? building;
String? floor;
String? department;
String? room;
num? statusId;
String? status;
num? statusValue;
num? statusByAdminId;
String? statusByAdmin;
num? statusByAdminValue;
bool? isNotRegistered;
num? sessionId;
num? assetImportId;
num? siteId;
num? buildingId;
num? floorId;
num? departmentId;
num? roomId;
String? oldAssetNumber;
String? newAssetNumber;
String? oldSerialNo;
String? newSerialNo;
num? oldAssetNameId;
num? newAssetNameId;
String? newAssetNameText;
num? oldModelId;
num? newModelId;
String? newModelName;
num? oldManufacturerId;
num? newManufacturerId;
String? newManufacturerName;
num? oldSupplierId;
num? newSupplierId;
String? newSupplierName;
String? photo;
String? photoOriginName;
String? remarks;
num? oldSiteId;
num? oldBuildingId;
num? oldFloorId;
num? oldDepartmentId;
num? oldRoomId;
AssetInventoryModel({
this.id,
this.assetId,
this.assetNumber,
this.serialNo,
this.assetName,
this.model,
this.manufacturer,
this.supplierName,
this.site,
this.building,
this.floor,
this.department,
this.room,
this.statusId,
this.status,
this.statusValue,
this.statusByAdminId,
this.statusByAdmin,
this.statusByAdminValue,
this.isNotRegistered,
this.sessionId,
this.assetImportId,
this.siteId,
this.buildingId,
this.floorId,
this.departmentId,
this.roomId,
this.oldAssetNumber,
this.newAssetNumber,
this.oldSerialNo,
this.newSerialNo,
this.oldAssetNameId,
this.newAssetNameId,
this.newAssetNameText,
this.oldModelId,
this.newModelId,
this.newModelName,
this.oldManufacturerId,
this.newManufacturerId,
this.newManufacturerName,
this.oldSupplierId,
this.newSupplierId,
this.newSupplierName,
this.photo,
this.photoOriginName,
this.remarks,
this.oldSiteId,
this.oldBuildingId,
this.oldFloorId,
this.oldDepartmentId,
this.oldRoomId,
});
AssetInventoryModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
assetId = json['assetId'];
assetNumber = json['assetNumber'];
serialNo = json['serialNo'];
assetName = json['assetName'];
model = json['model'];
manufacturer = json['manufacturer'];
supplierName = json['supplierName'];
site = json['site'];
building = json['building'];
floor = json['floor'];
department = json['department'];
room = json['room'];
statusId = json['statusId'];
status = json['status'];
statusValue = json['statusValue'];
statusByAdminId = json['statusByAdminId'];
statusByAdmin = json['statusByAdmin'];
statusByAdminValue = json['statusByAdminValue'];
isNotRegistered = json['isNotRegistered'];
sessionId = json['sessionId'];
assetImportId = json['assetImportId'];
siteId = json['siteId'];
buildingId = json['buildingId'];
floorId = json['floorId'];
departmentId = json['departmentId'];
roomId = json['roomId'];
oldAssetNumber = json['oldAssetNumber'];
newAssetNumber = json['newAssetNumber'];
oldSerialNo = json['oldSerialNo'];
newSerialNo = json['newSerialNo'];
oldAssetNameId = json['oldAssetNameId'];
newAssetNameId = json['newAssetNameId'];
newAssetNameText = json['newAssetNameText'];
oldModelId = json['oldModelId'];
newModelId = json['newModelId'];
newModelName = json['newModelName'];
oldManufacturerId = json['oldManufacturerId'];
newManufacturerId = json['newManufacturerId'];
newManufacturerName = json['newManufacturerName'];
oldSupplierId = json['oldSupplierId'];
newSupplierId = json['newSupplierId'];
newSupplierName = json['newSupplierName'];
photo = json['photo'];
photoOriginName = json['photoOriginName'];
remarks = json['remarks'];
oldSiteId = json['oldSiteId'];
oldBuildingId = json['oldBuildingId'];
oldFloorId = json['oldFloorId'];
oldDepartmentId = json['oldDepartmentId'];
oldRoomId = json['oldRoomId'];
}
Map<String, dynamic> toJson() {
return {
'isNotRegistered': isNotRegistered,
'sessionId': sessionId,
'assetImportId': assetImportId,
'assetId': assetId,
'siteId': siteId,
'buildingId': buildingId,
'floorId': floorId,
'departmentId': departmentId,
'roomId': roomId,
'oldAssetNumber': oldAssetNumber,
'newAssetNumber': newAssetNumber,
'oldSerialNo': oldSerialNo,
'newSerialNo': newSerialNo,
'oldAssetNameId': oldAssetNameId,
'newAssetNameId': newAssetNameId,
'newAssetNameText': newAssetNameText,
'oldModelId': oldModelId,
'newModelId': newModelId,
'newModelName': newModelName,
'oldManufacturerId': oldManufacturerId,
'newManufacturerId': newManufacturerId,
'newManufacturerName': newManufacturerName,
'oldSupplierId': oldSupplierId,
'newSupplierId': newSupplierId,
'newSupplierName': newSupplierName,
'photo': photo,
'photoOriginName': photoOriginName,
'remarks': remarks,
'oldSiteId': oldSiteId,
'oldBuildingId': oldBuildingId,
'oldFloorId': oldFloorId,
'oldDepartmentId': oldDepartmentId,
'oldRoomId': oldRoomId,
};
}
}

@ -1,4 +1,6 @@
import 'package:test_sa/models/new_models/site.dart';
class SessionModel {
int? id;
String? sessionName;
@ -8,7 +10,7 @@ class SessionModel {
String? statusName;
String? startDate;
String? endDate;
List<AssetInventorySite> assetInventorySites = [];
List<Site> assetInventorySites = [];
List<AssetInventoryAssignedEmployee> assetInventoryAssignedEmployee = [];
SessionModel({
@ -20,7 +22,7 @@ class SessionModel {
this.statusName,
this.startDate,
this.endDate,
List<AssetInventorySite>? assetInventorySites,
List<Site>? assetInventorySites,
List<AssetInventoryAssignedEmployee>? assetInventoryAssignedEmployee,
}) {
this.assetInventorySites = assetInventorySites ?? [];
@ -38,7 +40,7 @@ class SessionModel {
endDate = json['endDate'];
if (json['assetInventorySites'] != null) {
assetInventorySites = (json['assetInventorySites'] as List).map((e) => AssetInventorySite.fromJson(e)).toList();
assetInventorySites = (json['assetInventorySites'] as List).map((e) => Site.fromJson(e)).toList();
}
if (json['assetInventoryAssignedEmployee'] != null) {
@ -62,148 +64,148 @@ class SessionModel {
}
}
class AssetInventorySite {
int? siteId;
String? siteName;
List<AssetInventoryBuilding> assetInventoryBuildings = [];
AssetInventorySite({
this.siteId,
this.siteName,
List<AssetInventoryBuilding>? assetInventoryBuildings,
}) {
this.assetInventoryBuildings = assetInventoryBuildings ?? [];
}
AssetInventorySite.fromJson(Map<String, dynamic> json) {
siteId = json['siteId'];
siteName = json['siteName'];
if (json['assetInventoryBuildings'] != null) {
assetInventoryBuildings = (json['assetInventoryBuildings'] as List).map((e) => AssetInventoryBuilding.fromJson(e)).toList();
}
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['siteId'] = siteId;
map['siteName'] = siteName;
map['assetInventoryBuildings'] = assetInventoryBuildings.map((e) => e.toJson()).toList();
return map;
}
}
class AssetInventoryBuilding {
int? buildingId;
String? buildingName;
List<AssetInventoryFloor> assetInventoryFloors = [];
AssetInventoryBuilding({
this.buildingId,
this.buildingName,
List<AssetInventoryFloor>? assetInventoryFloors,
}) {
this.assetInventoryFloors = assetInventoryFloors ?? [];
}
AssetInventoryBuilding.fromJson(Map<String, dynamic> json) {
buildingId = json['buildingId'];
buildingName = json['buildingName'];
if (json['assetInventoryFloors'] != null) {
assetInventoryFloors = (json['assetInventoryFloors'] as List).map((e) => AssetInventoryFloor.fromJson(e)).toList();
}
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['buildingId'] = buildingId;
map['buildingName'] = buildingName;
map['assetInventoryFloors'] = assetInventoryFloors.map((e) => e.toJson()).toList();
return map;
}
}
class AssetInventoryFloor {
int? floorId;
String? floorName;
List<AssetInventoryDepartment> assetInventoryDepartments = [];
AssetInventoryFloor({
this.floorId,
this.floorName,
List<AssetInventoryDepartment>? assetInventoryDepartments,
}) {
this.assetInventoryDepartments = assetInventoryDepartments ?? [];
}
AssetInventoryFloor.fromJson(Map<String, dynamic> json) {
floorId = json['floorId'];
floorName = json['floorName'];
if (json['assetInventoryDepartments'] != null) {
assetInventoryDepartments = (json['assetInventoryDepartments'] as List).map((e) => AssetInventoryDepartment.fromJson(e)).toList();
}
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['floorId'] = floorId;
map['floorName'] = floorName;
map['assetInventoryDepartments'] = assetInventoryDepartments.map((e) => e.toJson()).toList();
return map;
}
}
class AssetInventoryDepartment {
int? departmentId;
String? departmentName;
List<AssetInventoryRoom> assetInventoryRooms = [];
AssetInventoryDepartment({
this.departmentId,
this.departmentName,
List<AssetInventoryRoom>? assetInventoryRooms,
}) {
this.assetInventoryRooms = assetInventoryRooms ?? [];
}
AssetInventoryDepartment.fromJson(Map<String, dynamic> json) {
departmentId = json['departmentId'];
departmentName = json['departmentName'];
if (json['assetInventoryRooms'] != null) {
assetInventoryRooms = (json['assetInventoryRooms'] as List).map((e) => AssetInventoryRoom.fromJson(e)).toList();
}
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['departmentId'] = departmentId;
map['departmentName'] = departmentName;
map['assetInventoryRooms'] = assetInventoryRooms.map((e) => e.toJson()).toList();
return map;
}
}
class AssetInventoryRoom {
int? roomId;
String? roomName;
AssetInventoryRoom({this.roomId, this.roomName});
AssetInventoryRoom.fromJson(Map<String, dynamic> json) {
roomId = json['roomId'];
roomName = json['roomName'];
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['roomId'] = roomId;
map['roomName'] = roomName;
return map;
}
}
// class AssetInventorySite {
// int? siteId;
// String? siteName;
// List<AssetInventoryBuilding> assetInventoryBuildings = [];
//
// AssetInventorySite({
// this.siteId,
// this.siteName,
// List<AssetInventoryBuilding>? assetInventoryBuildings,
// }) {
// this.assetInventoryBuildings = assetInventoryBuildings ?? [];
// }
//
// AssetInventorySite.fromJson(Map<String, dynamic> json) {
// siteId = json['siteId'];
// siteName = json['siteName'];
//
// if (json['assetInventoryBuildings'] != null) {
// assetInventoryBuildings = (json['assetInventoryBuildings'] as List).map((e) => AssetInventoryBuilding.fromJson(e)).toList();
// }
// }
//
// Map<String, dynamic> toJson() {
// final map = <String, dynamic>{};
// map['siteId'] = siteId;
// map['siteName'] = siteName;
// map['assetInventoryBuildings'] = assetInventoryBuildings.map((e) => e.toJson()).toList();
// return map;
// }
// }
//
// class AssetInventoryBuilding {
// int? buildingId;
// String? buildingName;
// List<AssetInventoryFloor> assetInventoryFloors = [];
//
// AssetInventoryBuilding({
// this.buildingId,
// this.buildingName,
// List<AssetInventoryFloor>? assetInventoryFloors,
// }) {
// this.assetInventoryFloors = assetInventoryFloors ?? [];
// }
//
// AssetInventoryBuilding.fromJson(Map<String, dynamic> json) {
// buildingId = json['buildingId'];
// buildingName = json['buildingName'];
//
// if (json['assetInventoryFloors'] != null) {
// assetInventoryFloors = (json['assetInventoryFloors'] as List).map((e) => AssetInventoryFloor.fromJson(e)).toList();
// }
// }
//
// Map<String, dynamic> toJson() {
// final map = <String, dynamic>{};
// map['buildingId'] = buildingId;
// map['buildingName'] = buildingName;
// map['assetInventoryFloors'] = assetInventoryFloors.map((e) => e.toJson()).toList();
// return map;
// }
// }
//
// class AssetInventoryFloor {
// int? floorId;
// String? floorName;
// List<AssetInventoryDepartment> assetInventoryDepartments = [];
//
// AssetInventoryFloor({
// this.floorId,
// this.floorName,
// List<AssetInventoryDepartment>? assetInventoryDepartments,
// }) {
// this.assetInventoryDepartments = assetInventoryDepartments ?? [];
// }
//
// AssetInventoryFloor.fromJson(Map<String, dynamic> json) {
// floorId = json['floorId'];
// floorName = json['floorName'];
//
// if (json['assetInventoryDepartments'] != null) {
// assetInventoryDepartments = (json['assetInventoryDepartments'] as List).map((e) => AssetInventoryDepartment.fromJson(e)).toList();
// }
// }
//
// Map<String, dynamic> toJson() {
// final map = <String, dynamic>{};
// map['floorId'] = floorId;
// map['floorName'] = floorName;
// map['assetInventoryDepartments'] = assetInventoryDepartments.map((e) => e.toJson()).toList();
// return map;
// }
// }
//
// class AssetInventoryDepartment {
// int? departmentId;
// String? departmentName;
// List<AssetInventoryRoom> assetInventoryRooms = [];
//
// AssetInventoryDepartment({
// this.departmentId,
// this.departmentName,
// List<AssetInventoryRoom>? assetInventoryRooms,
// }) {
// this.assetInventoryRooms = assetInventoryRooms ?? [];
// }
//
// AssetInventoryDepartment.fromJson(Map<String, dynamic> json) {
// departmentId = json['departmentId'];
// departmentName = json['departmentName'];
//
// if (json['assetInventoryRooms'] != null) {
// assetInventoryRooms = (json['assetInventoryRooms'] as List).map((e) => AssetInventoryRoom.fromJson(e)).toList();
// }
// }
//
// Map<String, dynamic> toJson() {
// final map = <String, dynamic>{};
// map['departmentId'] = departmentId;
// map['departmentName'] = departmentName;
// map['assetInventoryRooms'] = assetInventoryRooms.map((e) => e.toJson()).toList();
// return map;
// }
// }
//
// class AssetInventoryRoom {
// int? roomId;
// String? roomName;
//
// AssetInventoryRoom({this.roomId, this.roomName});
//
// AssetInventoryRoom.fromJson(Map<String, dynamic> json) {
// roomId = json['roomId'];
// roomName = json['roomName'];
// }
//
// Map<String, dynamic> toJson() {
// final map = <String, dynamic>{};
// map['roomId'] = roomId;
// map['roomName'] = roomName;
// return map;
// }
// }
class AssetInventoryAssignedEmployee {
String? assignedEngineerId;

@ -1,18 +1,20 @@
import 'package:flutter/material.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
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/new_models/work_order_detail_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart';
class AssetDetailCardView extends StatelessWidget {
// WorkOrderData workOrder;
AssetInventoryModel assetInventoryModel;
AssetDetailCardView({
super.key,
required this.assetInventoryModel,
});
@override
@ -23,45 +25,37 @@ class AssetDetailCardView extends StatelessWidget {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// StatusLabel(
// label: workOrder.priority?.name,
// id: workOrder.priority!.id!,
// radius: 4,
// textColor: AppColor.getPriorityStatusTextColor(context, workOrder.priority!.id!),
// backgroundColor: AppColor.getPriorityStatusColor(context, workOrder.priority!.id!),
// ),
// 8.height,
Text(
context.translation.assetInformation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
// 8.height,
Text(
'${context.translation.serialNo}: ${"workOrder.workOrderContactPerson[0].name" ?? '-'}',
'${context.translation.serialNo}: ${assetInventoryModel.serialNo ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.manufacture}: ${"workOrder.workOrderContactPerson[0].name"}',
'${context.translation.manufacture}: ${assetInventoryModel.manufacturer ?? ''}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.model}: ${"workOrder.workOrderContactPerson[0].name"}',
'${context.translation.model}: ${assetInventoryModel.model ?? ''}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.site}: ${"workOrder.workOrderContactPerson[0].name"}',
'${context.translation.site}: ${assetInventoryModel.site ?? ''}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.department}: ${"workOrder.workOrderContactPerson[0].name"}',
'${context.translation.department}: ${assetInventoryModel.department ?? ''}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.supplier}: ${"workOrder.workOrderContactPerson[0].name"}',
'${context.translation.supplier}: ${assetInventoryModel.supplierName ?? ''}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${'Remarks'.addTranslation}: ${"workOrder.workOrderContactPerson[0].name"}',
'${'Remarks'.addTranslation}: ${assetInventoryModel.remarks ?? ''}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
],
@ -85,10 +79,19 @@ class AssetDetailCardView extends StatelessWidget {
),
20.height,
Container(
height: 100,
width: 100,
color: Colors.red,
child: 'edit_icon'.toSvgAsset().center,
decoration: BoxDecoration(color: AppColor.neutral100, borderRadius: BorderRadius.circular(15)),
height: 115.toScreenHeight,
width: 115.toScreenWidth,
child: assetInventoryModel.photo != null && assetInventoryModel.photo!.isNotEmpty
? ClipRRect(
borderRadius: BorderRadius.circular(8),
child: ImageLoader(
url: URLs.getFileUrl(assetInventoryModel.photo),
boxFit: BoxFit.cover,
height: 48,
width: 48,
))
: 'image_placeholder'.toSvgAsset().center,
)
],
)

@ -1,13 +1,10 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
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/new_models/work_order_detail_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart';
import 'package:test_sa/modules/cm_module/service_request_detail_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
@ -29,54 +26,37 @@ class _AssetInventoryDetailViewState extends State<AssetInventoryDetailView> {
@override
Widget build(BuildContext context) {
//TODO remove this provider and loading obj as well don't need here ...
return Consumer<ServiceRequestDetailProvider>(builder: (pContext, requestProvider, _) {
return requestProvider.isLoading
? const CircularProgressIndicator(color: AppColor.primary10).center
: requestProvider.currentWorkOrder == null
? const NoDataFound()
: ListView(
padding: const EdgeInsets.all(16),
children: [
requestDetailCard(context, requestProvider.currentWorkOrder!.data!),
12.height,
siteListCard(context, requestProvider.currentWorkOrder!.data!),
],
);
});
return widget.sessionModel.id == null
? const NoDataFound()
: ListView(
padding: const EdgeInsets.all(16),
children: [
requestDetailCard(context, widget.sessionModel),
12.height,
siteListCard(context, widget.sessionModel),
],
);
}
TextStyle infoTextStyle(context) => AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120);
Widget requestDetailCard(BuildContext context, WorkOrderData workOrder) {
Widget requestDetailCard(BuildContext context, SessionModel sessionModel) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Wrap(
runSpacing: 8,
children: [
StatusLabel(
label: workOrder.priority?.name,
id: workOrder.priority!.id!,
radius: 4,
textColor: AppColor.getPriorityStatusTextColor(context, workOrder.priority!.id!),
backgroundColor: AppColor.getPriorityStatusColor(context, workOrder.priority!.id!),
),
8.width,
StatusLabel(
radius: 4,
label: workOrder.status!.name,
textColor: AppColor.getHistoryLogStatusTextColorByName(workOrder.status!.name!),
backgroundColor: AppColor.getHistoryLogStatusColorByName(workOrder.status!.name!),
),
],
).expanded,
StatusLabel(
label: sessionModel.statusName,
id: sessionModel.statusId,
radius: 4,
textColor: AppColor.green15,
backgroundColor: AppColor.greenStatus(context),
),
Text(
workOrder.requestedDate!.toString().toServiceRequestCardFormat,
sessionModel.startDate!.toString().toServiceRequestCardFormat,
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
)
@ -89,63 +69,91 @@ class _AssetInventoryDetailViewState extends State<AssetInventoryDetailView> {
),
8.height,
Text(
'${'Session Name'.addTranslation}: ${workOrder.assetNdModel!.name?.cleanupWhitespace.capitalizeFirstOfEach}',
'${'Session Name'.addTranslation}: ${sessionModel.sessionName?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
// 8.height,
Text(
'${'Session Typ'.addTranslation}: ${workOrder.asset!.assetNumber}',
'${'Session Typ'.addTranslation}: ${sessionModel.sessionTypeName}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${'Start Date:'.addTranslation}: ${workOrder.asset!.assetSerialNo}',
'${'Start Date:'.addTranslation}: ${sessionModel.startDate}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${'End Date:'.addTranslation}: ${workOrder.asset!.assetSerialNo}',
'${'End Date:'.addTranslation}: ${sessionModel.endDate}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
],
).paddingOnly(start: 16, end: 16, top: 16, bottom: 8).toShadowContainer(context, padding: 0);
}
Widget siteListCard(BuildContext context, WorkOrderData workOrder) {
Widget siteListCard(BuildContext context, SessionModel sessionModel) {
final sites = sessionModel.assetInventorySites ?? [];
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemBuilder: (cxt, index) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${workOrder.workOrderContactPerson[0].name ?? '-'}',
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
Text(
'${context.translation.building}: ${workOrder.workOrderContactPerson[0].employeeId ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.floor}: ${workOrder.workOrderContactPerson[0].mobilePhone ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.department} ${workOrder.workOrderContactPerson[0].position ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.room}: ${workOrder.workOrderContactPerson[0].email ?? '-'}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
],
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemCount: sites.length,
itemBuilder: (cxt, siteIndex) {
final site = sites[siteIndex];
final buildingNames = (site.buildings ?? []).map((b) => b.name).where((name) => name != null && name!.trim().isNotEmpty).join(', ');
final floorNames = (site.buildings ?? []).expand((b) => b.floors ?? []).map((f) => f.name).where((name) => name != null && name!.trim().isNotEmpty).join(', ');
final departmentNames =
(site.buildings ?? []).expand((b) => b.floors ?? []).expand((f) => f.departments ?? []).map((d) => d.name).where((name) => name != null && name!.trim().isNotEmpty).join(', ');
final roomNames = (site.buildings ?? [])
.expand((b) => b.floors ?? [])
.expand((f) => f.departments ?? [])
.expand((d) => d.rooms ?? [])
.map((r) => r.name)
.where((name) => name != null && name!.trim().isNotEmpty)
.join(', ');
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
site.name ?? '-',
style: AppTextStyles.heading6.copyWith(
color: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
),
),
separatorBuilder: (cxt, index) => const Divider().defaultStyle(context),
itemCount: 4),
Text(
'${context.translation.building}: ${buildingNames.isNotEmpty ? buildingNames : '-'}',
style: AppTextStyles.bodyText.copyWith(
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
),
),
Text(
'${context.translation.floor}: ${floorNames.isNotEmpty ? floorNames : '-'}',
style: AppTextStyles.bodyText.copyWith(
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
),
),
Text(
'${context.translation.department}: ${departmentNames.isNotEmpty ? departmentNames : '-'}',
style: AppTextStyles.bodyText.copyWith(
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
),
),
Text(
'${context.translation.room}: ${roomNames.isNotEmpty ? roomNames : '-'}',
style: AppTextStyles.bodyText.copyWith(
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
),
),
],
);
},
separatorBuilder: (cxt, index) => const Divider().defaultStyle(context),
),
],
).toShadowContainer(context, padding: 12);
}

@ -1,116 +1,85 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/common_widgets/autocomplete_generic_field.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/dashboard_latest/dashboard_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
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/device/asset.dart';
import 'package:test_sa/models/device/asset_transfer_attachment.dart';
import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/service_request/pending_service_request_model.dart';
import 'package:test_sa/models/service_request/spare_parts.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/providers/ppm_service_provider.dart';
import 'package:test_sa/providers/work_order/vendor_provider.dart';
import 'package:test_sa/views/pages/user/requests/pending_requests_screen.dart';
import 'package:test_sa/views/widgets/equipment/asset_picker.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker_item.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import '../../../models/new_models/building.dart';
import '../../../models/new_models/site.dart';
import '../../../new_views/common_widgets/app_filled_button.dart';
import '../../../new_views/common_widgets/default_app_bar.dart';
import '../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../../providers/gas_request_providers/site_provider.dart';
import '../../../providers/loading_list_notifier.dart';
class AssetInventoryFormView extends StatefulWidget {
static const String id = "/request-device-transfer";
static const String id = "/asset-inventory-form";
// TODO need to use only one model AssetInventoryModel everywhere after completing flow .
Asset ? assetLocation;
const AssetInventoryFormView({Key? key}) : super(key: key);
AssetInventoryFormView({Key? key,this.assetLocation}) : super(key: key);
@override
State<AssetInventoryFormView> createState() => _AssetInventoryFormViewState();
}
class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
//TODO Need to replace with provider and models we have ...
late DeviceTransferProvider _deviceTransferProvider;
final DeviceTransfer _transferModel = DeviceTransfer(id: 0);
final AssetInventoryModel _assetInventoryModel = AssetInventoryModel();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Asset _assetDestination = Asset();
Asset? _pickedAsset;
final List<GenericAttachmentModel> attachments = [];
void _onSubmit() async {
_transferModel.assetId = _pickedAsset?.id;
_transferModel.destSiteId = _assetDestination.site?.id;
_transferModel.destBuildingId = _assetDestination.building?.id;
_transferModel.destFloorId = _assetDestination.floor?.id;
_transferModel.destDepartmentId = _assetDestination.department?.id;
_transferModel.destRoomId = _assetDestination.room?.id;
_assetInventoryModel.assetId = _pickedAsset?.id;
_assetInventoryModel.oldSiteId = widget.assetLocation?.site?.id;
_assetInventoryModel.oldBuildingId = widget.assetLocation?.building?.id;
_assetInventoryModel.oldFloorId = widget.assetLocation?.floor?.id;
_assetInventoryModel.oldDepartmentId = widget.assetLocation?.department?.id;
_assetInventoryModel.oldRoomId = widget.assetLocation?.room?.id;
if (!_formKey.currentState!.validate() || !(await validateRequest())) {
return;
}
_formKey.currentState!.save();
List<AssetTransferAttachment> attachement = [];
for (var item in attachments) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
attachement.add(AssetTransferAttachment(id: item.id, attachmentName: fileName));
}
_transferModel.attachments = attachement;
await _deviceTransferProvider.createRequest(
context: context,
model: _transferModel,
);
if (_deviceTransferProvider.stateCode == 200) {
DashBoardProvider dashBoardProvider = Provider.of<DashBoardProvider>(context, listen: false);
dashBoardProvider.refreshDashboard(context: context, userType: UsersTypes.nurse);
}
//TODO need to confirm attachment structure and final api calling .
// List<AssetTransferAttachment> attachement = [];
// for (var item in attachments) {
// String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
// attachement.add(AssetTransferAttachment(id: item.id, attachmentName: fileName));
// }
// _assetInventoryModel.attachments = attachement;
// await _deviceTransferProvider.createRequest(
// context: context,
// model: _transferModel,
// );
// if (_deviceTransferProvider.stateCode == 200) {
// DashBoardProvider dashBoardProvider = Provider.of<DashBoardProvider>(context, listen: false);
// dashBoardProvider.refreshDashboard(context: context, userType: UsersTypes.nurse);
// }
}
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
//need to get internal and external request type data..
await Provider.of<PpmServiceProvider>(context, listen: false).getData();
});
super.initState();
}
@override
void dispose() {
_deviceTransferProvider.reset();
super.dispose();
}
@override
Widget build(BuildContext context) {
_deviceTransferProvider = Provider.of<DeviceTransferProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(
@ -136,18 +105,19 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
showBorder: true,
onPick: (asset) async {
_pickedAsset = asset;
if (_pickedAsset?.site != null && _transferModel.transferType?.value == 1) {
await _deviceTransferProvider.getSiteData(siteId: int.tryParse(_pickedAsset!.site!.id.toString()));
_assetDestination.site = _deviceTransferProvider.internalAssetDestination?.site;
_assetDestination.building = null;
_assetDestination.floor = null;
_assetDestination.department = null;
} else if (_pickedAsset?.site != null && _transferModel.transferType?.value == 2) {
_assetDestination.site = null;
_assetDestination.building = null;
_assetDestination.floor = null;
_assetDestination.department = null;
}
//TODO set value to model .
// if (_pickedAsset?.site != null && _transferModel.transferType?.value == 1) {
// await _deviceTransferProvider.getSiteData(siteId: int.tryParse(_pickedAsset!.site!.id.toString()));
// _assetDestination.site = _deviceTransferProvider.internalAssetDestination?.site;
// _assetDestination.building = null;
// _assetDestination.floor = null;
// _assetDestination.department = null;
// } else if (_pickedAsset?.site != null && _transferModel.transferType?.value == 2) {
// _assetDestination.site = null;
// _assetDestination.building = null;
// _assetDestination.floor = null;
// _assetDestination.department = null;
// }
setState(() {});
}),
@ -170,9 +140,6 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
style: Theme.of(context).textTheme.titleMedium,
),
12.height,
//TODO need to indentify where to
12.height,
//model..
AutoCompleteGenericField<SparePartsWorkOrders>(
clearAfterPick: false,
label: 'Asset Name'.addTranslation,
@ -256,75 +223,16 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
setState(() {});
},
),
12.height,
SingleItemDropDownMenu<Site, SiteProvider>(
context: context,
title: context.translation.site,
initialValue: _assetDestination.site,
disableValue: _pickedAsset?.site,
showShadow: false,
loading: _deviceTransferProvider.isSiteLoading,
enabled: false,
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
onSelect: (value) {
_assetDestination.site = value;
_assetDestination.building = null;
_assetDestination.floor = null;
_assetDestination.department = null;
setState(() {});
},
),
siteInfoContainer(label: context.translation.site, value:widget.assetLocation?.site?.name??'-' ),
12.height,
SingleItemDropDownMenu<Building, NullableLoadingProvider>(
context: context,
title: context.translation.building,
initialValue: _assetDestination.building,
showShadow: false,
showAsBottomSheet: true,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.site?.buildings?.isNotEmpty ?? false,
staticData: _assetDestination.site?.buildings ?? [],
onSelect: (value) {
_assetDestination.building = value;
_assetDestination.floor = null;
_assetDestination.department = null;
setState(() {});
},
),
siteInfoContainer(label: context.translation.building, value:widget.assetLocation?.building?.name??'-' ),
12.height,
SingleItemDropDownMenu<Floor, NullableLoadingProvider>(
context: context,
title: context.translation.floor,
showShadow: false,
showAsBottomSheet: true,
initialValue: _assetDestination.floor,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.building?.floors?.isNotEmpty ?? false,
staticData: _assetDestination.building?.floors ?? [],
onSelect: (value) {
_assetDestination.floor = value;
_assetDestination.department = null;
setState(() {});
},
),
siteInfoContainer(label: context.translation.floor, value:widget.assetLocation?.floor?.name??'-' ),
12.height,
SingleItemDropDownMenu<Department, NullableLoadingProvider>(
context: context,
title: context.translation.department,
showShadow: false,
showAsBottomSheet: true,
initialValue: _assetDestination.department,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.floor?.departments?.isNotEmpty ?? false,
staticData: _assetDestination.floor?.departments ?? [],
onSelect: (value) {
_assetDestination.department = value;
_assetDestination.room = null;
setState(() {});
},
),
siteInfoContainer(label: context.translation.department, value:widget.assetLocation?.department?.name??'-' ),
12.height,
siteInfoContainer(label: context.translation.room, value:widget.assetLocation?.room?.name??'-' ),
12.height,
classificationWidget(label: 'Found'),
12.height,
@ -362,7 +270,7 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
textInputType: TextInputType.multiline,
showShadow: false,
onSaved: (text) {
_transferModel.comment = text;
_assetInventoryModel.remarks = text;
},
),
// 100.height,
@ -380,6 +288,26 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
);
}
Widget siteInfoContainer({required String label , required String value}){
//TODO may be need to hide value for if empty or null .
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth,vertical: 12.toScreenHeight),
decoration: BoxDecoration(
color: AppColor.neutral80,
borderRadius: BorderRadius.circular(8)
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label,style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500)),
Text(value,style:Theme.of(context).textTheme.bodyLarge,),
],
),
);
}
Widget classificationWidget({String? label}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -404,22 +332,22 @@ class _AssetInventoryFormViewState extends State<AssetInventoryFormView> {
await Fluttertoast.showToast(msg: "Please Select Asset");
return false;
}
if (_assetDestination.site == null) {
await Fluttertoast.showToast(msg: "Please Select Site");
return false;
}
if (_assetDestination.building == null) {
await Fluttertoast.showToast(msg: "Please Select Building");
return false;
}
if (_assetDestination.floor == null) {
await Fluttertoast.showToast(msg: "Please Select Floor");
return false;
}
if (_assetDestination.department == null) {
await Fluttertoast.showToast(msg: "Please Select Department");
return false;
}
// if (_assetDestination.site == null) {
// await Fluttertoast.showToast(msg: "Please Select Site");
// return false;
// }
// if (_assetDestination.building == null) {
// await Fluttertoast.showToast(msg: "Please Select Building");
// return false;
// }
// if (_assetDestination.floor == null) {
// await Fluttertoast.showToast(msg: "Please Select Floor");
// return false;
// }
// if (_assetDestination.department == null) {
// await Fluttertoast.showToast(msg: "Please Select Department");
// return false;
// }
return true;
}
}

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
@ -9,7 +11,6 @@ import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_detail_view.dart';
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_scan_assets_view.dart';
import 'package:test_sa/modules/asset_inventory_module/pages/pick_site_information_view.dart';
import 'package:test_sa/modules/cm_module/service_request_detail_provider.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
@ -33,15 +34,18 @@ class _AssetInventoryPageState extends State<AssetInventoryPage> {
@override
void initState() {
super.initState();
_assetInventoryProvider = Provider.of<AssetInventoryProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
});
}
Future<void> getInitialData() async {
_assetInventoryProvider = Provider.of<AssetInventoryProvider>(context, listen: false);
// ServiceRequestDetailProvider _provider = Provider.of<ServiceRequestDetailProvider>(context, listen: false);
// await _provider.getWorkOrderById(id: widget.sessionId);
_assetInventoryProvider.reset();
await _assetInventoryProvider.getSessionById(id: widget.sessionId);
await _assetInventoryProvider.getAssetsInSession(
sessionId: widget.sessionId,
);
}
@override
@ -59,53 +63,64 @@ class _AssetInventoryPageState extends State<AssetInventoryPage> {
Navigator.pop(context);
},
),
body: DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)),
child: TabBar(
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)),
onTap: (index) {
},
tabs: [
Tab(text: 'Request Details'.addTranslation, height: 57.toScreenHeight),
Tab(text: '${'Scan Assets'.addTranslation} (1)', height: 57.toScreenHeight),
],
body: Consumer<AssetInventoryProvider>(builder: (context, provider, child) {
return DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)),
child: TabBar(
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)),
onTap: (index) {},
tabs: [
Tab(text: 'Request Details'.addTranslation, height: 57.toScreenHeight),
Tab(
text:
'${'Scan Assets'.addTranslation} ${provider.assetInventoryResponse?.totalRows != null && provider.assetInventoryResponse!.totalRows! > 0 ? '(${provider.assetInventoryResponse?.totalRows})' : ''}',
height: 57.toScreenHeight),
],
),
),
),
12.height,
TabBarView(
children: [
AssetInventoryDetailView(sessionModel: SessionModel(),),
AssetInventoryScanAssetView(),
],
).expanded,
FooterActionButton.footerContainer(
context: context,
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: 'Scan Assets'.addTranslation,
onPressed: _scanAsset,
// buttonColor: AppColor.primary10,
),
).toShadowContainer(context, padding: 0, showShadow: false, borderRadius: 0),
],
),
));
12.height,
TabBarView(
children: [
provider.isLoading
? const CircularProgressIndicator(color: AppColor.primary10).center
: AssetInventoryDetailView(
sessionModel: provider.sessionModel ?? SessionModel(),
),
AssetInventoryScanAssetView(
sessionId: provider.sessionModel?.id ?? 0,
),
],
).expanded,
FooterActionButton.footerContainer(
context: context,
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: 'Scan Assets'.addTranslation,
onPressed: () => _scanAsset(provider: provider),
// buttonColor: AppColor.primary10,
),
).toShadowContainer(context, padding: 0, showShadow: false, borderRadius: 0),
],
),
);
}));
}
Future<void> _scanAsset() async {
Navigator.push(context, MaterialPageRoute(builder: (contxt) => PickSiteInformationView(sessionModel: SessionModel())));
Future<void> _scanAsset({required AssetInventoryProvider provider}) async {
Navigator.push(context, MaterialPageRoute(builder: (contxt) => PickSiteInformationView(sessionModel: provider.sessionModel ?? SessionModel())));
}
}

@ -1,51 +1,77 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_form_view.dart';
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import 'asset_detail_card_view.dart';
class AssetInventoryScanAssetView extends StatelessWidget {
AssetInventoryScanAssetView({Key? key}) : super(key: key);
class AssetInventoryScanAssetView extends StatefulWidget {
int sessionId ;
AssetInventoryScanAssetView({Key? key,required this.sessionId}) : super(key: key);
@override
State<AssetInventoryScanAssetView> createState() => _AssetInventoryScanAssetViewState();
}
class _AssetInventoryScanAssetViewState extends State<AssetInventoryScanAssetView> {
late AssetInventoryProvider assetInventoryProvider;
@override
void initState() {
assetInventoryProvider = Provider.of<AssetInventoryProvider>(context,listen:false);
super.initState();
}
Future<void> getAssetList({bool reset = false}) async {
if (reset) {
assetInventoryProvider.pageNo = 1;
assetInventoryProvider.assetInventoryResponse = null;
}
await assetInventoryProvider.getAssetsInSession(
sessionId: widget.sessionId,
);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemBuilder: (cxt, index) => AssetDetailCardView(),
separatorBuilder: (cxt, index) => 12.height,
itemCount: 4),
12.height,
AppFilledButton(
label: "Add Asset".addTranslation,
maxWidth: true,
height: 70,
textColor: AppColor.textColor(context),
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)),
showIcon: true,
onPressed: () => _addAsset(context),
return Consumer<AssetInventoryProvider>(
builder: (context, provider, _) {
if (provider.isLoading && provider.assetInventoryResponse == null) {
//TODO need use existing loader if found..
return const Center(child: CircularProgressIndicator());
}
final assets = provider.assetInventoryResponse?.assetList ?? [];
if (assets.isEmpty) {
return const Center(child: NoDataFound());
}
return LazyLoading(
nextPage: provider.nextPage,
onLazyLoad: () async {
await getAssetList();
},
child: ListView.separated(
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
return AssetDetailCardView(assetInventoryModel: assets[index]);
},
separatorBuilder: (context, index) => 12.height,
itemCount: assets.length,
),
],
),
);
},
);
}
void _addAsset(BuildContext context) {
//TODO need to confirm navigation...
Navigator.push(context, MaterialPageRoute(builder: (contxt) => const AssetInventoryFormView()));
Navigator.push(context, MaterialPageRoute(builder: (contxt) => AssetInventoryFormView()));
}
}

@ -11,18 +11,19 @@ import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/room_model.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart';
import 'package:test_sa/modules/asset_inventory_module/pages/asset_detail_card_view.dart';
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_form_view.dart';
import 'package:test_sa/modules/cm_module/service_request_detail_provider.dart';
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import '../../../models/new_models/site.dart';
@ -36,17 +37,13 @@ class PickSiteInformationView extends StatefulWidget {
}
class _PickSiteInformationViewState extends State<PickSiteInformationView> {
late SessionModel _sessionModel;
//TODO need to remove this ...
Asset _assetDestination = Asset();
late ServiceRequestDetailProvider _requestDetailProvider;
// TODO need to use only one model AssetInventoryModel everywhere after completing flow .
Asset assetLocation = Asset();
void _onSave() async {}
@override
void initState() {
_sessionModel = widget.sessionModel;
super.initState();
}
@ -54,7 +51,6 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
@override
Widget build(BuildContext context) {
_requestDetailProvider = Provider.of<ServiceRequestDetailProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(
@ -66,13 +62,16 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
ListView(
padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
children: [
siteInfoCard(context),
12.height,
assetDetailCard(context, _requestDetailProvider.currentWorkOrder!.data!),
siteInfoCard(context, widget.sessionModel),
12.height,
//TODO need to implement when api is working ...
// assetDetailList(),
// 12.height,
AppFilledButton(
label: "Add Asset".addTranslation,
maxWidth: true,
height: 70,
textColor: AppColor.textColor(context),
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
@ -92,37 +91,78 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
}
void _addAsset() {
Navigator.push(context, MaterialPageRoute(builder: (contxt) => const AssetInventoryFormView()));
Navigator.push(
context,
MaterialPageRoute(
builder: (contxt) => AssetInventoryFormView(
assetLocation: assetLocation,
)));
}
Widget assetDetailCard(BuildContext context, WorkOrderData workOrder) {
return ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemBuilder: (cxt, index) => AssetDetailCardView(),
separatorBuilder: (cxt, index) => 12.height,
itemCount: 4);
Future<void> getAssetList({bool reset = false}) async {
AssetInventoryProvider assetInventoryProvider = Provider.of<AssetInventoryProvider>(context,listen: false);
if (reset) {
assetInventoryProvider.pageNo = 1;
assetInventoryProvider.assetInventoryResponse = null;
}
await assetInventoryProvider.getAssetsInSession(
sessionId: widget.sessionModel.id??0,
);
}
Widget siteInfoCard(BuildContext context) {
Widget assetDetailList() {
return Consumer<AssetInventoryProvider>(
builder: (context, provider,child) {
return Consumer<AssetInventoryProvider>(
builder: (context, provider, _) {
if (provider.isLoading && provider.assetInventoryResponse == null) {
//TODO need use existing loader if found..
return const Center(child: CircularProgressIndicator());
}
final assets = provider.assetInventoryResponse?.assetList ?? [];
if (assets.isEmpty) {
return const Center(child: NoDataFound());
}
return LazyLoading(
nextPage: provider.nextPage,
onLazyLoad: () async {
await getAssetList();
},
child: ListView.separated(
padding: const EdgeInsets.all(16),
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return AssetDetailCardView(assetInventoryModel: assets[index]);
},
separatorBuilder: (context, index) => 12.height,
itemCount: assets.length,
),
);
},
);
}
);
}
Widget siteInfoCard(BuildContext context, SessionModel sessionModel) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
12.height,
SingleItemDropDownMenu<Site, SiteProvider>(
SingleItemDropDownMenu<Site, NullableLoadingProvider>(
context: context,
title: context.translation.site,
initialValue: _assetDestination.site,
initialValue: assetLocation.site,
showShadow: false,
// loading: _deviceTransferProvider.isSiteLoading,
staticData: sessionModel.assetInventorySites,
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
onSelect: (value) {
_assetDestination.site = value;
_assetDestination.building = null;
_assetDestination.floor = null;
_assetDestination.department = null;
assetLocation.site = value;
assetLocation.building = null;
assetLocation.floor = null;
assetLocation.department = null;
setState(() {});
},
),
@ -130,16 +170,16 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
SingleItemDropDownMenu<Building, NullableLoadingProvider>(
context: context,
title: context.translation.building,
initialValue: _assetDestination.building,
initialValue: assetLocation.building,
showShadow: false,
showAsBottomSheet: true,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.site?.buildings?.isNotEmpty ?? false,
staticData: _assetDestination.site?.buildings ?? [],
enabled: assetLocation.site?.buildings?.isNotEmpty ?? false,
staticData: assetLocation.site?.buildings ?? [],
onSelect: (value) {
_assetDestination.building = value;
_assetDestination.floor = null;
_assetDestination.department = null;
assetLocation.building = value;
assetLocation.floor = null;
assetLocation.department = null;
setState(() {});
},
),
@ -149,13 +189,13 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
title: context.translation.floor,
showShadow: false,
showAsBottomSheet: true,
initialValue: _assetDestination.floor,
initialValue: assetLocation.floor,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.building?.floors?.isNotEmpty ?? false,
staticData: _assetDestination.building?.floors ?? [],
enabled: assetLocation.building?.floors?.isNotEmpty ?? false,
staticData: assetLocation.building?.floors ?? [],
onSelect: (value) {
_assetDestination.floor = value;
_assetDestination.department = null;
assetLocation.floor = value;
assetLocation.department = null;
setState(() {});
},
),
@ -165,13 +205,13 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
title: context.translation.department,
showShadow: false,
showAsBottomSheet: true,
initialValue: _assetDestination.department,
initialValue: assetLocation.department,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.floor?.departments?.isNotEmpty ?? false,
staticData: _assetDestination.floor?.departments ?? [],
enabled: assetLocation.floor?.departments?.isNotEmpty ?? false,
staticData: assetLocation.floor?.departments ?? [],
onSelect: (value) {
_assetDestination.department = value;
_assetDestination.room = null;
assetLocation.department = value;
assetLocation.room = null;
setState(() {});
},
),
@ -181,12 +221,12 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
title: context.translation.room,
showShadow: false,
showAsBottomSheet: true,
initialValue: _assetDestination.room,
initialValue: assetLocation.room,
backgroundColor: AppColor.fieldBgColor(context),
enabled: _assetDestination.department?.rooms?.isNotEmpty ?? false,
staticData: _assetDestination.department?.rooms ?? [],
enabled: assetLocation.department?.rooms?.isNotEmpty ?? false,
staticData: assetLocation.department?.rooms ?? [],
onSelect: (value) {
_assetDestination.room = value;
assetLocation.room = value;
setState(() {});
},
),
@ -196,19 +236,19 @@ class _PickSiteInformationViewState extends State<PickSiteInformationView> {
}
Future<bool> validateRequest() async {
if (_assetDestination.site == null) {
if (assetLocation.site == null) {
await Fluttertoast.showToast(msg: "Please Select Site");
return false;
}
if (_assetDestination.building == null) {
if (assetLocation.building == null) {
await Fluttertoast.showToast(msg: "Please Select Building");
return false;
}
if (_assetDestination.floor == null) {
if (assetLocation.floor == null) {
await Fluttertoast.showToast(msg: "Please Select Floor");
return false;
}
if (_assetDestination.department == null) {
if (assetLocation.department == null) {
await Fluttertoast.showToast(msg: "Please Select Department");
return false;
}

@ -16,6 +16,7 @@ import 'package:test_sa/models/service_request/spare_parts.dart';
import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart';
import 'package:test_sa/models/service_request/supplier_engineer_model.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart';
import '../../../models/service_request/search_work_order.dart';
@ -25,11 +26,17 @@ import '../../../new_views/common_widgets/app_lazy_loading.dart';
class AssetInventoryProvider extends ChangeNotifier {
final pageItemNumber = 10;
int pageNo = 1;
SessionModel? sessionModel;
AssetInventoryResponse? assetInventoryResponse;
List<AssetInventoryModel> sessionAssetList = [];
void reset() {
nextPage = true;
pageNo = 1;
assetInventoryResponse = null;
sessionModel = null;
sessionAssetList = [];
stateCode = null;
}
@ -37,15 +44,18 @@ class AssetInventoryProvider extends ChangeNotifier {
bool isDetailLoading = false;
bool nextPage = true;
bool isLoading = false;
bool isAllAssetLoading = false;
Future getSessionById({required int id}) async {
try {
sessionModel = SessionModel();
isLoading = true;
notifyListeners();
final response = await ApiManager.instance.get(URLs.getAssetInventoryById + "?assetInventoryId=$id");
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
sessionModel = await SessionModel.fromJson(json.decode(response.body));
sessionModel = SessionModel.fromJson(json.decode(response.body)["data"]);
} else {
sessionModel = null;
}
@ -59,4 +69,52 @@ class AssetInventoryProvider extends ChangeNotifier {
return null;
}
}
Future<int> getAssetsInSession({
required int sessionId,
}) async {
if (isLoading == true) return -2;
isLoading = true;
try {
final payload = {
"pageSize": pageItemNumber,
"pageNumber": pageNo,
"sessionId": sessionId,
};
final response = await ApiManager.instance.post(URLs.getAssetsInSession, body: payload);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
final Map<String, dynamic> jsonData = json.decode(response.body);
final newResponse = AssetInventoryResponse.fromJson(jsonData);
if (pageNo == 1) {
assetInventoryResponse = newResponse;
sessionAssetList = newResponse.assetList ?? [];
} else {
sessionAssetList.addAll(newResponse.assetList ?? []);
assetInventoryResponse?.totalRows = newResponse.totalRows; // update total rows
}
if ((sessionAssetList.length) < (assetInventoryResponse?.totalRows ?? 0)) {
nextPage = true;
} else {
nextPage = false;
}
isLoading = false;
notifyListeners();
return response.statusCode;
} else {
sessionAssetList = [];
isLoading = false;
notifyListeners();
return response.statusCode;
}
} catch (error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -50,8 +50,8 @@ class AppFilledButton extends StatelessWidget {
),
child: loading
? SizedBox(
width: 24,
height: 24,
width: 24.toScreenHeight,
height: 24.toScreenHeight,
child: CircularProgressIndicator(
color: textColor ?? AppColor.background(context),
strokeWidth: 2,

Loading…
Cancel
Save